1 /* Functions for the X window system.
2 Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 01, 02, 03
3 Free Software Foundation.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
31 /* This makes the fields of a Display accessible, in Xlib header files. */
33 #define XLIB_ILLEGAL_ACCESS
40 #include "intervals.h"
41 #include "dispextern.h"
43 #include "blockinput.h"
49 #include "termhooks.h"
55 #include <sys/types.h>
59 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
60 #include "bitmaps/gray.xbm"
62 #include <X11/bitmaps/gray>
65 #include "[.bitmaps]gray.xbm"
73 #include <X11/Shell.h>
76 #include <X11/Xaw/Paned.h>
77 #include <X11/Xaw/Label.h>
78 #endif /* USE_MOTIF */
81 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
90 #include "../lwlib/lwlib.h"
94 #include <Xm/DialogS.h>
95 #include <Xm/FileSB.h>
98 /* Do the EDITRES protocol if running X11R5
99 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
101 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
103 extern void _XEditResCheckMessages ();
104 #endif /* R5 + Athena */
106 /* Unique id counter for widgets created by the Lucid Widget Library. */
108 extern LWLIB_ID widget_id_tick
;
111 /* This is part of a kludge--see lwlib/xlwmenu.c. */
112 extern XFontStruct
*xlwmenu_default_font
;
115 extern void free_frame_menubar ();
116 extern double atof ();
120 /* LessTif/Motif version info. */
122 static Lisp_Object Vmotif_version_string
;
124 #endif /* USE_MOTIF */
126 #endif /* USE_X_TOOLKIT */
130 /* GTK+ version info */
132 static Lisp_Object Vgtk_version_string
;
137 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
139 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
142 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
143 it, and including `bitmaps/gray' more than once is a problem when
144 config.h defines `static' as an empty replacement string. */
146 int gray_bitmap_width
= gray_width
;
147 int gray_bitmap_height
= gray_height
;
148 char *gray_bitmap_bits
= gray_bits
;
150 /* Non-zero means we're allowed to display an hourglass cursor. */
152 int display_hourglass_p
;
154 /* The background and shape of the mouse pointer, and shape when not
155 over text or in the modeline. */
157 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
158 Lisp_Object Vx_hourglass_pointer_shape
;
160 /* The shape when over mouse-sensitive text. */
162 Lisp_Object Vx_sensitive_text_pointer_shape
;
164 /* If non-nil, the pointer shape to indicate that windows can be
165 dragged horizontally. */
167 Lisp_Object Vx_window_horizontal_drag_shape
;
169 /* Color of chars displayed in cursor box. */
171 Lisp_Object Vx_cursor_fore_pixel
;
173 /* Nonzero if using X. */
177 /* Non nil if no window manager is in use. */
179 Lisp_Object Vx_no_window_manager
;
181 /* Search path for bitmap files. */
183 Lisp_Object Vx_bitmap_file_path
;
185 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
187 Lisp_Object Vx_pixel_size_width_font_regexp
;
190 Lisp_Object Qsuppress_icon
;
191 Lisp_Object Qundefined_color
;
193 Lisp_Object Qcompound_text
, Qcancel_timer
;
197 extern Lisp_Object Vwindow_system_version
;
199 /* The below are defined in frame.c. */
202 int image_cache_refcount
, dpyinfo_refcount
;
207 /* Error if we are not connected to X. */
213 error ("X windows are not in use or not initialized");
216 /* Nonzero if we can use mouse menus.
217 You should not call this unless HAVE_MENUS is defined. */
225 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
226 and checking validity for X. */
229 check_x_frame (frame
)
235 frame
= selected_frame
;
236 CHECK_LIVE_FRAME (frame
);
239 error ("Non-X frame used");
243 /* Let the user specify an X display with a frame.
244 nil stands for the selected frame--or, if that is not an X frame,
245 the first X display on the list. */
247 struct x_display_info
*
248 check_x_display_info (frame
)
251 struct x_display_info
*dpyinfo
= NULL
;
255 struct frame
*sf
= XFRAME (selected_frame
);
257 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
258 dpyinfo
= FRAME_X_DISPLAY_INFO (sf
);
259 else if (x_display_list
!= 0)
260 dpyinfo
= x_display_list
;
262 error ("X windows are not in use or not initialized");
264 else if (STRINGP (frame
))
265 dpyinfo
= x_display_info_for_name (frame
);
268 FRAME_PTR f
= check_x_frame (frame
);
269 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
276 /* Return the Emacs frame-object corresponding to an X window.
277 It could be the frame's main window or an icon window. */
279 /* This function can be called during GC, so use GC_xxx type test macros. */
282 x_window_to_frame (dpyinfo
, wdesc
)
283 struct x_display_info
*dpyinfo
;
286 Lisp_Object tail
, frame
;
289 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
292 if (!GC_FRAMEP (frame
))
295 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
297 if (f
->output_data
.x
->hourglass_window
== wdesc
)
300 if ((f
->output_data
.x
->edit_widget
301 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
302 /* A tooltip frame? */
303 || (!f
->output_data
.x
->edit_widget
304 && FRAME_X_WINDOW (f
) == wdesc
)
305 || f
->output_data
.x
->icon_desc
== wdesc
)
307 #else /* not USE_X_TOOLKIT */
309 if (f
->output_data
.x
->edit_widget
)
311 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
312 struct x_output
*x
= f
->output_data
.x
;
313 if (gwdesc
!= 0 && gwdesc
== x
->edit_widget
)
317 if (FRAME_X_WINDOW (f
) == wdesc
318 || f
->output_data
.x
->icon_desc
== wdesc
)
320 #endif /* not USE_X_TOOLKIT */
325 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
326 /* Like x_window_to_frame but also compares the window with the widget's
330 x_any_window_to_frame (dpyinfo
, wdesc
)
331 struct x_display_info
*dpyinfo
;
334 Lisp_Object tail
, frame
;
335 struct frame
*f
, *found
;
339 for (tail
= Vframe_list
; GC_CONSP (tail
) && !found
; tail
= XCDR (tail
))
342 if (!GC_FRAMEP (frame
))
346 if (FRAME_X_P (f
) && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
348 /* This frame matches if the window is any of its widgets. */
349 x
= f
->output_data
.x
;
350 if (x
->hourglass_window
== wdesc
)
355 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
357 && (gwdesc
== x
->widget
358 || gwdesc
== x
->edit_widget
359 || gwdesc
== x
->vbox_widget
360 || gwdesc
== x
->menubar_widget
))
363 if (wdesc
== XtWindow (x
->widget
)
364 || wdesc
== XtWindow (x
->column_widget
)
365 || wdesc
== XtWindow (x
->edit_widget
))
367 /* Match if the window is this frame's menubar. */
368 else if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
372 else if (FRAME_X_WINDOW (f
) == wdesc
)
373 /* A tooltip frame. */
381 /* Likewise, but exclude the menu bar widget. */
384 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
385 struct x_display_info
*dpyinfo
;
388 Lisp_Object tail
, frame
;
392 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
395 if (!GC_FRAMEP (frame
))
398 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
400 x
= f
->output_data
.x
;
401 /* This frame matches if the window is any of its widgets. */
402 if (x
->hourglass_window
== wdesc
)
407 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
409 && (gwdesc
== x
->widget
410 || gwdesc
== x
->edit_widget
411 || gwdesc
== x
->vbox_widget
))
414 if (wdesc
== XtWindow (x
->widget
)
415 || wdesc
== XtWindow (x
->column_widget
)
416 || wdesc
== XtWindow (x
->edit_widget
))
420 else if (FRAME_X_WINDOW (f
) == wdesc
)
421 /* A tooltip frame. */
427 /* Likewise, but consider only the menu bar widget. */
430 x_menubar_window_to_frame (dpyinfo
, wdesc
)
431 struct x_display_info
*dpyinfo
;
434 Lisp_Object tail
, frame
;
438 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
441 if (!GC_FRAMEP (frame
))
444 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
446 x
= f
->output_data
.x
;
447 /* Match if the window is this frame's menubar. */
449 if (x
->menubar_widget
)
451 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
456 && (gwdesc
== x
->menubar_widget
457 || gtk_widget_get_parent (gwdesc
) == x
->menubar_widget
))
463 if (x
->menubar_widget
464 && lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
471 /* Return the frame whose principal (outermost) window is WDESC.
472 If WDESC is some other (smaller) window, we return 0. */
475 x_top_window_to_frame (dpyinfo
, wdesc
)
476 struct x_display_info
*dpyinfo
;
479 Lisp_Object tail
, frame
;
483 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
486 if (!GC_FRAMEP (frame
))
489 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
491 x
= f
->output_data
.x
;
495 /* This frame matches if the window is its topmost widget. */
497 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
498 if (gwdesc
== x
->widget
)
501 if (wdesc
== XtWindow (x
->widget
))
503 #if 0 /* I don't know why it did this,
504 but it seems logically wrong,
505 and it causes trouble for MapNotify events. */
506 /* Match if the window is this frame's menubar. */
507 if (x
->menubar_widget
508 && wdesc
== XtWindow (x
->menubar_widget
))
513 else if (FRAME_X_WINDOW (f
) == wdesc
)
519 #endif /* USE_X_TOOLKIT || USE_GTK */
523 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
524 id, which is just an int that this section returns. Bitmaps are
525 reference counted so they can be shared among frames.
527 Bitmap indices are guaranteed to be > 0, so a negative number can
528 be used to indicate no bitmap.
530 If you use x_create_bitmap_from_data, then you must keep track of
531 the bitmaps yourself. That is, creating a bitmap from the same
532 data more than once will not be caught. */
535 /* Functions to access the contents of a bitmap, given an id. */
538 x_bitmap_height (f
, id
)
542 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
546 x_bitmap_width (f
, id
)
550 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
554 x_bitmap_pixmap (f
, id
)
558 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
562 x_bitmap_mask (f
, id
)
566 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].mask
;
570 /* Allocate a new bitmap record. Returns index of new record. */
573 x_allocate_bitmap_record (f
)
576 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
579 if (dpyinfo
->bitmaps
== NULL
)
581 dpyinfo
->bitmaps_size
= 10;
583 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
584 dpyinfo
->bitmaps_last
= 1;
588 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
589 return ++dpyinfo
->bitmaps_last
;
591 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
592 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
595 dpyinfo
->bitmaps_size
*= 2;
597 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
598 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
599 return ++dpyinfo
->bitmaps_last
;
602 /* Add one reference to the reference count of the bitmap with id ID. */
605 x_reference_bitmap (f
, id
)
609 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
612 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
615 x_create_bitmap_from_data (f
, bits
, width
, height
)
618 unsigned int width
, height
;
620 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
624 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
625 bits
, width
, height
);
632 id
= x_allocate_bitmap_record (f
);
633 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
634 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
635 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
636 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
637 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
638 dpyinfo
->bitmaps
[id
- 1].height
= height
;
639 dpyinfo
->bitmaps
[id
- 1].width
= width
;
644 /* Create bitmap from file FILE for frame F. */
647 x_create_bitmap_from_file (f
, file
)
651 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
652 unsigned int width
, height
;
654 int xhot
, yhot
, result
, id
;
659 /* Look for an existing bitmap with the same name. */
660 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
662 if (dpyinfo
->bitmaps
[id
].refcount
663 && dpyinfo
->bitmaps
[id
].file
664 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) SDATA (file
)))
666 ++dpyinfo
->bitmaps
[id
].refcount
;
671 /* Search bitmap-file-path for the file, if appropriate. */
672 fd
= openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, Qnil
);
677 filename
= (char *) SDATA (found
);
679 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
680 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
681 if (result
!= BitmapSuccess
)
684 id
= x_allocate_bitmap_record (f
);
685 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
686 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
687 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
688 dpyinfo
->bitmaps
[id
- 1].file
689 = (char *) xmalloc (SBYTES (file
) + 1);
690 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
691 dpyinfo
->bitmaps
[id
- 1].height
= height
;
692 dpyinfo
->bitmaps
[id
- 1].width
= width
;
693 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
698 /* Remove reference to bitmap with id number ID. */
701 x_destroy_bitmap (f
, id
)
705 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
709 --dpyinfo
->bitmaps
[id
- 1].refcount
;
710 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
713 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
714 if (dpyinfo
->bitmaps
[id
- 1].have_mask
)
715 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].mask
);
716 if (dpyinfo
->bitmaps
[id
- 1].file
)
718 xfree (dpyinfo
->bitmaps
[id
- 1].file
);
719 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
726 /* Free all the bitmaps for the display specified by DPYINFO. */
729 x_destroy_all_bitmaps (dpyinfo
)
730 struct x_display_info
*dpyinfo
;
733 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
734 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
736 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
737 if (dpyinfo
->bitmaps
[i
].have_mask
)
738 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].mask
);
739 if (dpyinfo
->bitmaps
[i
].file
)
740 xfree (dpyinfo
->bitmaps
[i
].file
);
742 dpyinfo
->bitmaps_last
= 0;
748 /* Useful functions defined in the section
749 `Image type independent image structures' below. */
751 static unsigned long four_corners_best
P_ ((XImage
*ximg
, unsigned long width
,
752 unsigned long height
));
754 static int x_create_x_image_and_pixmap
P_ ((struct frame
*f
, int width
, int height
,
755 int depth
, XImage
**ximg
,
758 static void x_destroy_x_image
P_ ((XImage
*ximg
));
761 /* Create a mask of a bitmap. Note is this not a perfect mask.
762 It's nicer with some borders in this context */
765 x_create_bitmap_mask(f
, id
)
770 XImage
*ximg
, *mask_img
;
771 unsigned long width
, height
;
774 unsigned long x
, y
, xp
, xm
, yp
, ym
;
777 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
778 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
783 pixmap
= x_bitmap_pixmap(f
, id
);
784 width
= x_bitmap_width(f
, id
);
785 height
= x_bitmap_height(f
, id
);
788 ximg
= XGetImage (FRAME_X_DISPLAY (f
), pixmap
, 0, 0, width
, height
,
797 result
= x_create_x_image_and_pixmap (f
, width
, height
, 1, &mask_img
, &mask
);
806 bg
= four_corners_best (ximg
, width
, height
);
808 for (y
= 0; y
< ximg
->height
; ++y
)
810 for (x
= 0; x
< ximg
->width
; ++x
)
812 xp
= x
!= ximg
->width
- 1 ? x
+ 1 : 0;
813 xm
= x
!= 0 ? x
- 1 : ximg
->width
- 1;
814 yp
= y
!= ximg
->height
- 1 ? y
+ 1 : 0;
815 ym
= y
!= 0 ? y
- 1 : ximg
->height
- 1;
816 if (XGetPixel (ximg
, x
, y
) == bg
817 && XGetPixel (ximg
, x
, yp
) == bg
818 && XGetPixel (ximg
, x
, ym
) == bg
819 && XGetPixel (ximg
, xp
, y
) == bg
820 && XGetPixel (ximg
, xp
, yp
) == bg
821 && XGetPixel (ximg
, xp
, ym
) == bg
822 && XGetPixel (ximg
, xm
, y
) == bg
823 && XGetPixel (ximg
, xm
, yp
) == bg
824 && XGetPixel (ximg
, xm
, ym
) == bg
)
825 XPutPixel (mask_img
, x
, y
, 0);
827 XPutPixel (mask_img
, x
, y
, 1);
831 xassert (interrupt_input_blocked
);
832 gc
= XCreateGC (FRAME_X_DISPLAY (f
), mask
, 0, NULL
);
833 XPutImage (FRAME_X_DISPLAY (f
), mask
, gc
, mask_img
, 0, 0, 0, 0,
835 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
837 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
838 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
840 XDestroyImage (ximg
);
841 x_destroy_x_image(mask_img
);
846 static Lisp_Object unwind_create_frame
P_ ((Lisp_Object
));
847 static Lisp_Object unwind_create_tip_frame
P_ ((Lisp_Object
));
848 static void x_disable_image
P_ ((struct frame
*, struct image
*));
850 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
851 static void x_set_wait_for_wm
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
852 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
853 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
854 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
855 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
856 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
857 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
858 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
859 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
860 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
861 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
862 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
863 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
865 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
867 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
872 static void x_edge_detection
P_ ((struct frame
*, struct image
*, Lisp_Object
,
874 static void init_color_table
P_ ((void));
875 static void free_color_table
P_ ((void));
876 static unsigned long *colors_in_color_table
P_ ((int *n
));
877 static unsigned long lookup_rgb_color
P_ ((struct frame
*f
, int r
, int g
, int b
));
878 static unsigned long lookup_pixel_color
P_ ((struct frame
*f
, unsigned long p
));
884 /* Store the screen positions of frame F into XPTR and YPTR.
885 These are the positions of the containing window manager window,
886 not Emacs's own window. */
889 x_real_positions (f
, xptr
, yptr
)
893 int win_x
, win_y
, outer_x
, outer_y
;
894 int real_x
= 0, real_y
= 0;
896 Window win
= f
->output_data
.x
->parent_desc
;
902 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
904 if (win
== FRAME_X_DISPLAY_INFO (f
)->root_window
)
905 win
= FRAME_OUTER_WINDOW (f
);
907 /* This loop traverses up the containment tree until we hit the root
908 window. Window managers may intersect many windows between our window
909 and the root window. The window we find just before the root window
910 should be the outer WM window. */
913 Window wm_window
, rootw
;
914 Window
*tmp_children
;
915 unsigned int tmp_nchildren
;
918 success
= XQueryTree (FRAME_X_DISPLAY (f
), win
, &rootw
,
919 &wm_window
, &tmp_children
, &tmp_nchildren
);
921 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
923 /* Don't free tmp_children if XQueryTree failed. */
927 XFree ((char *) tmp_children
);
929 if (wm_window
== rootw
|| had_errors
)
940 /* Get the real coordinates for the WM window upper left corner */
941 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
942 &rootw
, &real_x
, &real_y
, &ign
, &ign
, &ign
, &ign
);
944 /* Translate real coordinates to coordinates relative to our
945 window. For our window, the upper left corner is 0, 0.
946 Since the upper left corner of the WM window is outside
947 our window, win_x and win_y will be negative:
949 ------------------ ---> x
951 | ----------------- v y
954 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
956 /* From-window, to-window. */
957 FRAME_X_DISPLAY_INFO (f
)->root_window
,
960 /* From-position, to-position. */
961 real_x
, real_y
, &win_x
, &win_y
,
966 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
973 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
975 /* From-window, to-window. */
976 FRAME_X_DISPLAY_INFO (f
)->root_window
,
977 FRAME_OUTER_WINDOW (f
),
979 /* From-position, to-position. */
980 real_x
, real_y
, &outer_x
, &outer_y
,
986 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
989 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
993 if (had_errors
) return;
995 f
->x_pixels_diff
= -win_x
;
996 f
->y_pixels_diff
= -win_y
;
998 FRAME_X_OUTPUT (f
)->x_pixels_outer_diff
= -outer_x
;
999 FRAME_X_OUTPUT (f
)->y_pixels_outer_diff
= -outer_y
;
1008 /* Gamma-correct COLOR on frame F. */
1011 gamma_correct (f
, color
)
1017 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
1018 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
1019 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
1024 /* Decide if color named COLOR_NAME is valid for use on frame F. If
1025 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
1026 allocate the color. Value is zero if COLOR_NAME is invalid, or
1027 no color could be allocated. */
1030 x_defined_color (f
, color_name
, color
, alloc_p
)
1037 Display
*dpy
= FRAME_X_DISPLAY (f
);
1038 Colormap cmap
= FRAME_X_COLORMAP (f
);
1041 success_p
= XParseColor (dpy
, cmap
, color_name
, color
);
1042 if (success_p
&& alloc_p
)
1043 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
1050 /* Return the pixel color value for color COLOR_NAME on frame F. If F
1051 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
1052 Signal an error if color can't be allocated. */
1055 x_decode_color (f
, color_name
, mono_color
)
1057 Lisp_Object color_name
;
1062 CHECK_STRING (color_name
);
1064 #if 0 /* Don't do this. It's wrong when we're not using the default
1065 colormap, it makes freeing difficult, and it's probably not
1066 an important optimization. */
1067 if (strcmp (SDATA (color_name
), "black") == 0)
1068 return BLACK_PIX_DEFAULT (f
);
1069 else if (strcmp (SDATA (color_name
), "white") == 0)
1070 return WHITE_PIX_DEFAULT (f
);
1073 /* Return MONO_COLOR for monochrome frames. */
1074 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1077 /* x_defined_color is responsible for coping with failures
1078 by looking for a near-miss. */
1079 if (x_defined_color (f
, SDATA (color_name
), &cdef
, 1))
1082 Fsignal (Qerror
, Fcons (build_string ("Undefined color"),
1083 Fcons (color_name
, Qnil
)));
1089 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
1090 the previous value of that parameter, NEW_VALUE is the new value.
1091 See also the comment of wait_for_wm in struct x_output. */
1094 x_set_wait_for_wm (f
, new_value
, old_value
)
1096 Lisp_Object new_value
, old_value
;
1098 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
1103 static Lisp_Object x_find_image_file
P_ ((Lisp_Object file
));
1105 /* Set icon from FILE for frame F. By using GTK functions the icon
1106 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
1109 xg_set_icon(f
, file
)
1113 struct gcpro gcpro1
;
1119 found
= x_find_image_file (file
);
1127 filename
= SDATA (found
);
1130 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
1134 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1136 g_object_unref (pixbuf
);
1149 #endif /* USE_GTK */
1152 /* Functions called only from `x_set_frame_param'
1153 to set individual parameters.
1155 If FRAME_X_WINDOW (f) is 0,
1156 the frame is being created and its X-window does not exist yet.
1157 In that case, just record the parameter's new value
1158 in the standard place; do not attempt to change the window. */
1161 x_set_foreground_color (f
, arg
, oldval
)
1163 Lisp_Object arg
, oldval
;
1165 struct x_output
*x
= f
->output_data
.x
;
1166 unsigned long fg
, old_fg
;
1168 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1169 old_fg
= x
->foreground_pixel
;
1170 x
->foreground_pixel
= fg
;
1172 if (FRAME_X_WINDOW (f
) != 0)
1174 Display
*dpy
= FRAME_X_DISPLAY (f
);
1177 XSetForeground (dpy
, x
->normal_gc
, fg
);
1178 XSetBackground (dpy
, x
->reverse_gc
, fg
);
1180 if (x
->cursor_pixel
== old_fg
)
1182 unload_color (f
, x
->cursor_pixel
);
1183 x
->cursor_pixel
= x_copy_color (f
, fg
);
1184 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
1189 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
1191 if (FRAME_VISIBLE_P (f
))
1195 unload_color (f
, old_fg
);
1199 x_set_background_color (f
, arg
, oldval
)
1201 Lisp_Object arg
, oldval
;
1203 struct x_output
*x
= f
->output_data
.x
;
1206 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1207 unload_color (f
, x
->background_pixel
);
1208 x
->background_pixel
= bg
;
1210 if (FRAME_X_WINDOW (f
) != 0)
1212 Display
*dpy
= FRAME_X_DISPLAY (f
);
1215 XSetBackground (dpy
, x
->normal_gc
, bg
);
1216 XSetForeground (dpy
, x
->reverse_gc
, bg
);
1217 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
1218 XSetForeground (dpy
, x
->cursor_gc
, bg
);
1221 xg_set_background_color (f
, bg
);
1224 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
1225 toolkit scroll bars. */
1228 for (bar
= FRAME_SCROLL_BARS (f
);
1230 bar
= XSCROLL_BAR (bar
)->next
)
1232 Window window
= SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
));
1233 XSetWindowBackground (dpy
, window
, bg
);
1236 #endif /* USE_TOOLKIT_SCROLL_BARS */
1239 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
1241 if (FRAME_VISIBLE_P (f
))
1247 x_set_mouse_color (f
, arg
, oldval
)
1249 Lisp_Object arg
, oldval
;
1251 struct x_output
*x
= f
->output_data
.x
;
1252 Display
*dpy
= FRAME_X_DISPLAY (f
);
1253 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
1254 Cursor hourglass_cursor
, horizontal_drag_cursor
;
1256 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1257 unsigned long mask_color
= x
->background_pixel
;
1259 /* Don't let pointers be invisible. */
1260 if (mask_color
== pixel
)
1262 x_free_colors (f
, &pixel
, 1);
1263 pixel
= x_copy_color (f
, x
->foreground_pixel
);
1266 unload_color (f
, x
->mouse_pixel
);
1267 x
->mouse_pixel
= pixel
;
1271 /* It's not okay to crash if the user selects a screwy cursor. */
1272 count
= x_catch_errors (dpy
);
1274 if (!NILP (Vx_pointer_shape
))
1276 CHECK_NUMBER (Vx_pointer_shape
);
1277 cursor
= XCreateFontCursor (dpy
, XINT (Vx_pointer_shape
));
1280 cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1281 x_check_errors (dpy
, "bad text pointer cursor: %s");
1283 if (!NILP (Vx_nontext_pointer_shape
))
1285 CHECK_NUMBER (Vx_nontext_pointer_shape
);
1287 = XCreateFontCursor (dpy
, XINT (Vx_nontext_pointer_shape
));
1290 nontext_cursor
= XCreateFontCursor (dpy
, XC_left_ptr
);
1291 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
1293 if (!NILP (Vx_hourglass_pointer_shape
))
1295 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
1297 = XCreateFontCursor (dpy
, XINT (Vx_hourglass_pointer_shape
));
1300 hourglass_cursor
= XCreateFontCursor (dpy
, XC_watch
);
1301 x_check_errors (dpy
, "bad hourglass pointer cursor: %s");
1303 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
1304 if (!NILP (Vx_mode_pointer_shape
))
1306 CHECK_NUMBER (Vx_mode_pointer_shape
);
1307 mode_cursor
= XCreateFontCursor (dpy
, XINT (Vx_mode_pointer_shape
));
1310 mode_cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1311 x_check_errors (dpy
, "bad modeline pointer cursor: %s");
1313 if (!NILP (Vx_sensitive_text_pointer_shape
))
1315 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
1317 = XCreateFontCursor (dpy
, XINT (Vx_sensitive_text_pointer_shape
));
1320 hand_cursor
= XCreateFontCursor (dpy
, XC_hand2
);
1322 if (!NILP (Vx_window_horizontal_drag_shape
))
1324 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
1325 horizontal_drag_cursor
1326 = XCreateFontCursor (dpy
, XINT (Vx_window_horizontal_drag_shape
));
1329 horizontal_drag_cursor
1330 = XCreateFontCursor (dpy
, XC_sb_h_double_arrow
);
1332 /* Check and report errors with the above calls. */
1333 x_check_errors (dpy
, "can't set cursor shape: %s");
1334 x_uncatch_errors (dpy
, count
);
1337 XColor fore_color
, back_color
;
1339 fore_color
.pixel
= x
->mouse_pixel
;
1340 x_query_color (f
, &fore_color
);
1341 back_color
.pixel
= mask_color
;
1342 x_query_color (f
, &back_color
);
1344 XRecolorCursor (dpy
, cursor
, &fore_color
, &back_color
);
1345 XRecolorCursor (dpy
, nontext_cursor
, &fore_color
, &back_color
);
1346 XRecolorCursor (dpy
, mode_cursor
, &fore_color
, &back_color
);
1347 XRecolorCursor (dpy
, hand_cursor
, &fore_color
, &back_color
);
1348 XRecolorCursor (dpy
, hourglass_cursor
, &fore_color
, &back_color
);
1349 XRecolorCursor (dpy
, horizontal_drag_cursor
, &fore_color
, &back_color
);
1352 if (FRAME_X_WINDOW (f
) != 0)
1353 XDefineCursor (dpy
, FRAME_X_WINDOW (f
), cursor
);
1355 if (cursor
!= x
->text_cursor
1356 && x
->text_cursor
!= 0)
1357 XFreeCursor (dpy
, x
->text_cursor
);
1358 x
->text_cursor
= cursor
;
1360 if (nontext_cursor
!= x
->nontext_cursor
1361 && x
->nontext_cursor
!= 0)
1362 XFreeCursor (dpy
, x
->nontext_cursor
);
1363 x
->nontext_cursor
= nontext_cursor
;
1365 if (hourglass_cursor
!= x
->hourglass_cursor
1366 && x
->hourglass_cursor
!= 0)
1367 XFreeCursor (dpy
, x
->hourglass_cursor
);
1368 x
->hourglass_cursor
= hourglass_cursor
;
1370 if (mode_cursor
!= x
->modeline_cursor
1371 && x
->modeline_cursor
!= 0)
1372 XFreeCursor (dpy
, f
->output_data
.x
->modeline_cursor
);
1373 x
->modeline_cursor
= mode_cursor
;
1375 if (hand_cursor
!= x
->hand_cursor
1376 && x
->hand_cursor
!= 0)
1377 XFreeCursor (dpy
, x
->hand_cursor
);
1378 x
->hand_cursor
= hand_cursor
;
1380 if (horizontal_drag_cursor
!= x
->horizontal_drag_cursor
1381 && x
->horizontal_drag_cursor
!= 0)
1382 XFreeCursor (dpy
, x
->horizontal_drag_cursor
);
1383 x
->horizontal_drag_cursor
= horizontal_drag_cursor
;
1388 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1392 x_set_cursor_color (f
, arg
, oldval
)
1394 Lisp_Object arg
, oldval
;
1396 unsigned long fore_pixel
, pixel
;
1397 int fore_pixel_allocated_p
= 0, pixel_allocated_p
= 0;
1398 struct x_output
*x
= f
->output_data
.x
;
1400 if (!NILP (Vx_cursor_fore_pixel
))
1402 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1403 WHITE_PIX_DEFAULT (f
));
1404 fore_pixel_allocated_p
= 1;
1407 fore_pixel
= x
->background_pixel
;
1409 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1410 pixel_allocated_p
= 1;
1412 /* Make sure that the cursor color differs from the background color. */
1413 if (pixel
== x
->background_pixel
)
1415 if (pixel_allocated_p
)
1417 x_free_colors (f
, &pixel
, 1);
1418 pixel_allocated_p
= 0;
1421 pixel
= x
->mouse_pixel
;
1422 if (pixel
== fore_pixel
)
1424 if (fore_pixel_allocated_p
)
1426 x_free_colors (f
, &fore_pixel
, 1);
1427 fore_pixel_allocated_p
= 0;
1429 fore_pixel
= x
->background_pixel
;
1433 unload_color (f
, x
->cursor_foreground_pixel
);
1434 if (!fore_pixel_allocated_p
)
1435 fore_pixel
= x_copy_color (f
, fore_pixel
);
1436 x
->cursor_foreground_pixel
= fore_pixel
;
1438 unload_color (f
, x
->cursor_pixel
);
1439 if (!pixel_allocated_p
)
1440 pixel
= x_copy_color (f
, pixel
);
1441 x
->cursor_pixel
= pixel
;
1443 if (FRAME_X_WINDOW (f
) != 0)
1446 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
1447 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
1450 if (FRAME_VISIBLE_P (f
))
1452 x_update_cursor (f
, 0);
1453 x_update_cursor (f
, 1);
1457 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1460 /* Set the border-color of frame F to pixel value PIX.
1461 Note that this does not fully take effect if done before
1462 F has an x-window. */
1465 x_set_border_pixel (f
, pix
)
1469 unload_color (f
, f
->output_data
.x
->border_pixel
);
1470 f
->output_data
.x
->border_pixel
= pix
;
1472 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
1475 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1476 (unsigned long)pix
);
1479 if (FRAME_VISIBLE_P (f
))
1484 /* Set the border-color of frame F to value described by ARG.
1485 ARG can be a string naming a color.
1486 The border-color is used for the border that is drawn by the X server.
1487 Note that this does not fully take effect if done before
1488 F has an x-window; it must be redone when the window is created.
1490 Note: this is done in two routines because of the way X10 works.
1492 Note: under X11, this is normally the province of the window manager,
1493 and so emacs' border colors may be overridden. */
1496 x_set_border_color (f
, arg
, oldval
)
1498 Lisp_Object arg
, oldval
;
1503 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1504 x_set_border_pixel (f
, pix
);
1505 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1510 x_set_cursor_type (f
, arg
, oldval
)
1512 Lisp_Object arg
, oldval
;
1514 set_frame_cursor_types (f
, arg
);
1516 /* Make sure the cursor gets redrawn. */
1517 cursor_type_changed
= 1;
1521 x_set_icon_type (f
, arg
, oldval
)
1523 Lisp_Object arg
, oldval
;
1529 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1532 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1537 result
= x_text_icon (f
,
1538 (char *) SDATA ((!NILP (f
->icon_name
)
1542 result
= x_bitmap_icon (f
, arg
);
1547 error ("No icon window available");
1550 XFlush (FRAME_X_DISPLAY (f
));
1555 x_set_icon_name (f
, arg
, oldval
)
1557 Lisp_Object arg
, oldval
;
1563 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1566 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1571 if (f
->output_data
.x
->icon_bitmap
!= 0)
1576 result
= x_text_icon (f
,
1577 (char *) SDATA ((!NILP (f
->icon_name
)
1586 error ("No icon window available");
1589 XFlush (FRAME_X_DISPLAY (f
));
1595 x_set_menu_bar_lines (f
, value
, oldval
)
1597 Lisp_Object value
, oldval
;
1600 #ifndef USE_X_TOOLKIT
1601 int olines
= FRAME_MENU_BAR_LINES (f
);
1604 /* Right now, menu bars don't work properly in minibuf-only frames;
1605 most of the commands try to apply themselves to the minibuffer
1606 frame itself, and get an error because you can't switch buffers
1607 in or split the minibuffer window. */
1608 if (FRAME_MINIBUF_ONLY_P (f
))
1611 if (INTEGERP (value
))
1612 nlines
= XINT (value
);
1616 /* Make sure we redisplay all windows in this frame. */
1617 windows_or_buffers_changed
++;
1619 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1620 FRAME_MENU_BAR_LINES (f
) = 0;
1623 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1624 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1625 /* Make sure next redisplay shows the menu bar. */
1626 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1630 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1631 free_frame_menubar (f
);
1632 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1634 f
->output_data
.x
->menubar_widget
= 0;
1636 #else /* not USE_X_TOOLKIT && not USE_GTK */
1637 FRAME_MENU_BAR_LINES (f
) = nlines
;
1638 change_window_heights (f
->root_window
, nlines
- olines
);
1639 #endif /* not USE_X_TOOLKIT */
1644 /* Set the number of lines used for the tool bar of frame F to VALUE.
1645 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1646 is the old number of tool bar lines. This function changes the
1647 height of all windows on frame F to match the new tool bar height.
1648 The frame's height doesn't change. */
1651 x_set_tool_bar_lines (f
, value
, oldval
)
1653 Lisp_Object value
, oldval
;
1655 int delta
, nlines
, root_height
;
1656 Lisp_Object root_window
;
1658 /* Treat tool bars like menu bars. */
1659 if (FRAME_MINIBUF_ONLY_P (f
))
1662 /* Use VALUE only if an integer >= 0. */
1663 if (INTEGERP (value
) && XINT (value
) >= 0)
1664 nlines
= XFASTINT (value
);
1669 FRAME_TOOL_BAR_LINES (f
) = 0;
1672 FRAME_EXTERNAL_TOOL_BAR (f
) = 1;
1673 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1674 /* Make sure next redisplay shows the tool bar. */
1675 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1676 update_frame_tool_bar (f
);
1680 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1681 free_frame_tool_bar (f
);
1682 FRAME_EXTERNAL_TOOL_BAR (f
) = 0;
1688 /* Make sure we redisplay all windows in this frame. */
1689 ++windows_or_buffers_changed
;
1691 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
1693 /* Don't resize the tool-bar to more than we have room for. */
1694 root_window
= FRAME_ROOT_WINDOW (f
);
1695 root_height
= WINDOW_TOTAL_LINES (XWINDOW (root_window
));
1696 if (root_height
- delta
< 1)
1698 delta
= root_height
- 1;
1699 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
1702 FRAME_TOOL_BAR_LINES (f
) = nlines
;
1703 change_window_heights (root_window
, delta
);
1706 /* We also have to make sure that the internal border at the top of
1707 the frame, below the menu bar or tool bar, is redrawn when the
1708 tool bar disappears. This is so because the internal border is
1709 below the tool bar if one is displayed, but is below the menu bar
1710 if there isn't a tool bar. The tool bar draws into the area
1711 below the menu bar. */
1712 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
1716 clear_current_matrices (f
);
1717 updating_frame
= NULL
;
1720 /* If the tool bar gets smaller, the internal border below it
1721 has to be cleared. It was formerly part of the display
1722 of the larger tool bar, and updating windows won't clear it. */
1725 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1726 int width
= FRAME_PIXEL_WIDTH (f
);
1727 int y
= nlines
* FRAME_LINE_HEIGHT (f
);
1730 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1731 0, y
, width
, height
, False
);
1734 if (WINDOWP (f
->tool_bar_window
))
1735 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1740 /* Set the foreground color for scroll bars on frame F to VALUE.
1741 VALUE should be a string, a color name. If it isn't a string or
1742 isn't a valid color name, do nothing. OLDVAL is the old value of
1743 the frame parameter. */
1746 x_set_scroll_bar_foreground (f
, value
, oldval
)
1748 Lisp_Object value
, oldval
;
1750 unsigned long pixel
;
1752 if (STRINGP (value
))
1753 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1757 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1758 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1760 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1761 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1763 /* Remove all scroll bars because they have wrong colors. */
1764 if (condemn_scroll_bars_hook
)
1765 (*condemn_scroll_bars_hook
) (f
);
1766 if (judge_scroll_bars_hook
)
1767 (*judge_scroll_bars_hook
) (f
);
1769 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1775 /* Set the background color for scroll bars on frame F to VALUE VALUE
1776 should be a string, a color name. If it isn't a string or isn't a
1777 valid color name, do nothing. OLDVAL is the old value of the frame
1781 x_set_scroll_bar_background (f
, value
, oldval
)
1783 Lisp_Object value
, oldval
;
1785 unsigned long pixel
;
1787 if (STRINGP (value
))
1788 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1792 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1793 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1795 #ifdef USE_TOOLKIT_SCROLL_BARS
1796 /* Scrollbar shadow colors. */
1797 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1799 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1800 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1802 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1804 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1805 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1807 #endif /* USE_TOOLKIT_SCROLL_BARS */
1809 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1810 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1812 /* Remove all scroll bars because they have wrong colors. */
1813 if (condemn_scroll_bars_hook
)
1814 (*condemn_scroll_bars_hook
) (f
);
1815 if (judge_scroll_bars_hook
)
1816 (*judge_scroll_bars_hook
) (f
);
1818 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1824 /* Encode Lisp string STRING as a text in a format appropriate for
1825 XICCC (X Inter Client Communication Conventions).
1827 If STRING contains only ASCII characters, do no conversion and
1828 return the string data of STRING. Otherwise, encode the text by
1829 CODING_SYSTEM, and return a newly allocated memory area which
1830 should be freed by `xfree' by a caller.
1832 SELECTIONP non-zero means the string is being encoded for an X
1833 selection, so it is safe to run pre-write conversions (which
1836 Store the byte length of resulting text in *TEXT_BYTES.
1838 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1839 which means that the `encoding' of the result can be `STRING'.
1840 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1841 the result should be `COMPOUND_TEXT'. */
1844 x_encode_text (string
, coding_system
, selectionp
, text_bytes
, stringp
)
1845 Lisp_Object string
, coding_system
;
1846 int *text_bytes
, *stringp
;
1849 unsigned char *str
= SDATA (string
);
1850 int chars
= SCHARS (string
);
1851 int bytes
= SBYTES (string
);
1855 struct coding_system coding
;
1856 extern Lisp_Object Qcompound_text_with_extensions
;
1858 charset_info
= find_charset_in_text (str
, chars
, bytes
, NULL
, Qnil
);
1859 if (charset_info
== 0)
1861 /* No multibyte character in OBJ. We need not encode it. */
1862 *text_bytes
= bytes
;
1867 setup_coding_system (coding_system
, &coding
);
1869 && SYMBOLP (coding
.pre_write_conversion
)
1870 && !NILP (Ffboundp (coding
.pre_write_conversion
)))
1872 string
= run_pre_post_conversion_on_str (string
, &coding
, 1);
1873 str
= SDATA (string
);
1874 chars
= SCHARS (string
);
1875 bytes
= SBYTES (string
);
1877 coding
.src_multibyte
= 1;
1878 coding
.dst_multibyte
= 0;
1879 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1880 if (coding
.type
== coding_type_iso2022
)
1881 coding
.flags
|= CODING_FLAG_ISO_SAFE
;
1882 /* We suppress producing escape sequences for composition. */
1883 coding
.composing
= COMPOSITION_DISABLED
;
1884 bufsize
= encoding_buffer_size (&coding
, bytes
);
1885 buf
= (unsigned char *) xmalloc (bufsize
);
1886 encode_coding (&coding
, str
, buf
, bytes
, bufsize
);
1887 *text_bytes
= coding
.produced
;
1888 *stringp
= (charset_info
== 1
1889 || (!EQ (coding_system
, Qcompound_text
)
1890 && !EQ (coding_system
, Qcompound_text_with_extensions
)));
1895 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1898 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1899 name; if NAME is a string, set F's name to NAME and set
1900 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1902 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1903 suggesting a new name, which lisp code should override; if
1904 F->explicit_name is set, ignore the new name; otherwise, set it. */
1907 x_set_name (f
, name
, explicit)
1912 /* Make sure that requests from lisp code override requests from
1913 Emacs redisplay code. */
1916 /* If we're switching from explicit to implicit, we had better
1917 update the mode lines and thereby update the title. */
1918 if (f
->explicit_name
&& NILP (name
))
1919 update_mode_lines
= 1;
1921 f
->explicit_name
= ! NILP (name
);
1923 else if (f
->explicit_name
)
1926 /* If NAME is nil, set the name to the x_id_name. */
1929 /* Check for no change needed in this very common case
1930 before we do any consing. */
1931 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1934 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1937 CHECK_STRING (name
);
1939 /* Don't change the name if it's already NAME. */
1940 if (! NILP (Fstring_equal (name
, f
->name
)))
1945 /* For setting the frame title, the title parameter should override
1946 the name parameter. */
1947 if (! NILP (f
->title
))
1950 if (FRAME_X_WINDOW (f
))
1955 XTextProperty text
, icon
;
1957 Lisp_Object coding_system
;
1959 /* Note: Encoding strategy
1961 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1962 text.encoding. But, there are non-internationalized window
1963 managers which don't support that encoding. So, if NAME
1964 contains only ASCII and 8859-1 characters, encode it by
1965 iso-latin-1, and use "STRING" in text.encoding hoping that
1966 such window managers at least analyze this format correctly,
1967 i.e. treat 8-bit bytes as 8859-1 characters.
1969 We may also be able to use "UTF8_STRING" in text.encoding
1970 in the future which can encode all Unicode characters.
1971 But, for the moment, there's no way to know that the
1972 current window manager supports it or not. */
1973 coding_system
= Qcompound_text
;
1974 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
1975 text
.encoding
= (stringp
? XA_STRING
1976 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1978 text
.nitems
= bytes
;
1980 if (NILP (f
->icon_name
))
1986 /* See the above comment "Note: Encoding strategy". */
1987 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
1989 icon
.encoding
= (stringp
? XA_STRING
1990 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1992 icon
.nitems
= bytes
;
1995 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1997 #else /* not USE_GTK */
1998 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1999 #endif /* not USE_GTK */
2001 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
2003 if (!NILP (f
->icon_name
)
2004 && icon
.value
!= (unsigned char *) SDATA (f
->icon_name
))
2006 if (text
.value
!= (unsigned char *) SDATA (name
))
2009 #else /* not HAVE_X11R4 */
2010 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2012 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2014 #endif /* not HAVE_X11R4 */
2019 /* This function should be called when the user's lisp code has
2020 specified a name for the frame; the name will override any set by the
2023 x_explicitly_set_name (f
, arg
, oldval
)
2025 Lisp_Object arg
, oldval
;
2027 x_set_name (f
, arg
, 1);
2030 /* This function should be called by Emacs redisplay code to set the
2031 name; names set this way will never override names set by the user's
2034 x_implicitly_set_name (f
, arg
, oldval
)
2036 Lisp_Object arg
, oldval
;
2038 x_set_name (f
, arg
, 0);
2041 /* Change the title of frame F to NAME.
2042 If NAME is nil, use the frame name as the title.
2044 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2045 name; if NAME is a string, set F's name to NAME and set
2046 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2048 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2049 suggesting a new name, which lisp code should override; if
2050 F->explicit_name is set, ignore the new name; otherwise, set it. */
2053 x_set_title (f
, name
, old_name
)
2055 Lisp_Object name
, old_name
;
2057 /* Don't change the title if it's already NAME. */
2058 if (EQ (name
, f
->title
))
2061 update_mode_lines
= 1;
2068 CHECK_STRING (name
);
2070 if (FRAME_X_WINDOW (f
))
2075 XTextProperty text
, icon
;
2077 Lisp_Object coding_system
;
2079 coding_system
= Qcompound_text
;
2080 /* See the comment "Note: Encoding strategy" in x_set_name. */
2081 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
2082 text
.encoding
= (stringp
? XA_STRING
2083 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
2085 text
.nitems
= bytes
;
2087 if (NILP (f
->icon_name
))
2093 /* See the comment "Note: Encoding strategy" in x_set_name. */
2094 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
2096 icon
.encoding
= (stringp
? XA_STRING
2097 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
2099 icon
.nitems
= bytes
;
2103 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
2105 #else /* not USE_GTK */
2106 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
2107 #endif /* not USE_GTK */
2109 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
2112 if (!NILP (f
->icon_name
)
2113 && icon
.value
!= (unsigned char *) SDATA (f
->icon_name
))
2115 if (text
.value
!= (unsigned char *) SDATA (name
))
2118 #else /* not HAVE_X11R4 */
2119 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2121 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2123 #endif /* not HAVE_X11R4 */
2129 x_set_scroll_bar_default_width (f
)
2132 int wid
= FRAME_COLUMN_WIDTH (f
);
2134 #ifdef USE_TOOLKIT_SCROLL_BARS
2135 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
2136 int width
= 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
2137 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (width
+ wid
- 1) / wid
;
2138 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = width
;
2140 /* Make the actual width at least 14 pixels and a multiple of a
2142 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
2144 /* Use all of that space (aside from required margins) for the
2146 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 0;
2151 /* Record in frame F the specified or default value according to ALIST
2152 of the parameter named PROP (a Lisp symbol). If no value is
2153 specified for PROP, look for an X default for XPROP on the frame
2154 named NAME. If that is not found either, use the value DEFLT. */
2157 x_default_scroll_bar_color_parameter (f
, alist
, prop
, xprop
, xclass
,
2166 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2169 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
2170 if (EQ (tem
, Qunbound
))
2172 #ifdef USE_TOOLKIT_SCROLL_BARS
2174 /* See if an X resource for the scroll bar color has been
2176 tem
= display_x_get_resource (dpyinfo
,
2177 build_string (foreground_p
2181 build_string ("verticalScrollBar"),
2185 /* If nothing has been specified, scroll bars will use a
2186 toolkit-dependent default. Because these defaults are
2187 difficult to get at without actually creating a scroll
2188 bar, use nil to indicate that no color has been
2193 #else /* not USE_TOOLKIT_SCROLL_BARS */
2197 #endif /* not USE_TOOLKIT_SCROLL_BARS */
2200 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2206 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2209 XSetWMProtocols (dpy
, w
, protocols
, count
)
2216 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2217 if (prop
== None
) return False
;
2218 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2219 (unsigned char *) protocols
, count
);
2222 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2224 #ifdef USE_X_TOOLKIT
2226 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2227 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2228 already be present because of the toolkit (Motif adds some of them,
2229 for example, but Xt doesn't). */
2232 hack_wm_protocols (f
, widget
)
2236 Display
*dpy
= XtDisplay (widget
);
2237 Window w
= XtWindow (widget
);
2238 int need_delete
= 1;
2244 Atom type
, *atoms
= 0;
2246 unsigned long nitems
= 0;
2247 unsigned long bytes_after
;
2249 if ((XGetWindowProperty (dpy
, w
,
2250 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2251 (long)0, (long)100, False
, XA_ATOM
,
2252 &type
, &format
, &nitems
, &bytes_after
,
2253 (unsigned char **) &atoms
)
2255 && format
== 32 && type
== XA_ATOM
)
2259 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2261 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2263 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2266 if (atoms
) XFree ((char *) atoms
);
2272 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2274 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2276 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2278 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2279 XA_ATOM
, 32, PropModeAppend
,
2280 (unsigned char *) props
, count
);
2288 /* Support routines for XIC (X Input Context). */
2292 static XFontSet xic_create_xfontset
P_ ((struct frame
*, char *));
2293 static XIMStyle best_xim_style
P_ ((XIMStyles
*, XIMStyles
*));
2296 /* Supported XIM styles, ordered by preference. */
2298 static XIMStyle supported_xim_styles
[] =
2300 XIMPreeditPosition
| XIMStatusArea
,
2301 XIMPreeditPosition
| XIMStatusNothing
,
2302 XIMPreeditPosition
| XIMStatusNone
,
2303 XIMPreeditNothing
| XIMStatusArea
,
2304 XIMPreeditNothing
| XIMStatusNothing
,
2305 XIMPreeditNothing
| XIMStatusNone
,
2306 XIMPreeditNone
| XIMStatusArea
,
2307 XIMPreeditNone
| XIMStatusNothing
,
2308 XIMPreeditNone
| XIMStatusNone
,
2313 /* Create an X fontset on frame F with base font name
2317 xic_create_xfontset (f
, base_fontname
)
2319 char *base_fontname
;
2322 char **missing_list
;
2326 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
2327 base_fontname
, &missing_list
,
2328 &missing_count
, &def_string
);
2330 XFreeStringList (missing_list
);
2332 /* No need to free def_string. */
2337 /* Value is the best input style, given user preferences USER (already
2338 checked to be supported by Emacs), and styles supported by the
2339 input method XIM. */
2342 best_xim_style (user
, xim
)
2348 for (i
= 0; i
< user
->count_styles
; ++i
)
2349 for (j
= 0; j
< xim
->count_styles
; ++j
)
2350 if (user
->supported_styles
[i
] == xim
->supported_styles
[j
])
2351 return user
->supported_styles
[i
];
2353 /* Return the default style. */
2354 return XIMPreeditNothing
| XIMStatusNothing
;
2357 /* Create XIC for frame F. */
2359 static XIMStyle xic_style
;
2362 create_frame_xic (f
)
2367 XFontSet xfs
= NULL
;
2372 xim
= FRAME_X_XIM (f
);
2377 XVaNestedList preedit_attr
;
2378 XVaNestedList status_attr
;
2379 char *base_fontname
;
2382 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2383 spot
.x
= 0; spot
.y
= 1;
2384 /* Create X fontset. */
2385 fontset
= FRAME_FONTSET (f
);
2387 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2390 /* Determine the base fontname from the ASCII font name of
2392 char *ascii_font
= (char *) SDATA (fontset_ascii (fontset
));
2393 char *p
= ascii_font
;
2396 for (i
= 0; *p
; p
++)
2399 /* As the font name doesn't conform to XLFD, we can't
2400 modify it to get a suitable base fontname for the
2402 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2405 int len
= strlen (ascii_font
) + 1;
2408 for (i
= 0, p
= ascii_font
; i
< 8; p
++)
2417 base_fontname
= (char *) alloca (len
);
2418 bzero (base_fontname
, len
);
2419 strcpy (base_fontname
, "-*-*-");
2420 bcopy (p1
, base_fontname
+ 5, p
- p1
);
2421 strcat (base_fontname
, "*-*-*-*-*-*-*");
2424 xfs
= xic_create_xfontset (f
, base_fontname
);
2426 /* Determine XIC style. */
2429 XIMStyles supported_list
;
2430 supported_list
.count_styles
= (sizeof supported_xim_styles
2431 / sizeof supported_xim_styles
[0]);
2432 supported_list
.supported_styles
= supported_xim_styles
;
2433 xic_style
= best_xim_style (&supported_list
,
2434 FRAME_X_XIM_STYLES (f
));
2437 preedit_attr
= XVaCreateNestedList (0,
2440 FRAME_FOREGROUND_PIXEL (f
),
2442 FRAME_BACKGROUND_PIXEL (f
),
2443 (xic_style
& XIMPreeditPosition
2448 status_attr
= XVaCreateNestedList (0,
2454 FRAME_FOREGROUND_PIXEL (f
),
2456 FRAME_BACKGROUND_PIXEL (f
),
2459 xic
= XCreateIC (xim
,
2460 XNInputStyle
, xic_style
,
2461 XNClientWindow
, FRAME_X_WINDOW(f
),
2462 XNFocusWindow
, FRAME_X_WINDOW(f
),
2463 XNStatusAttributes
, status_attr
,
2464 XNPreeditAttributes
, preedit_attr
,
2466 XFree (preedit_attr
);
2467 XFree (status_attr
);
2470 FRAME_XIC (f
) = xic
;
2471 FRAME_XIC_STYLE (f
) = xic_style
;
2472 FRAME_XIC_FONTSET (f
) = xfs
;
2476 /* Destroy XIC and free XIC fontset of frame F, if any. */
2482 if (FRAME_XIC (f
) == NULL
)
2485 XDestroyIC (FRAME_XIC (f
));
2486 if (FRAME_XIC_FONTSET (f
))
2487 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2489 FRAME_XIC (f
) = NULL
;
2490 FRAME_XIC_FONTSET (f
) = NULL
;
2494 /* Place preedit area for XIC of window W's frame to specified
2495 pixel position X/Y. X and Y are relative to window W. */
2498 xic_set_preeditarea (w
, x
, y
)
2502 struct frame
*f
= XFRAME (w
->frame
);
2506 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2507 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2508 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2509 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2514 /* Place status area for XIC in bottom right corner of frame F.. */
2517 xic_set_statusarea (f
)
2520 XIC xic
= FRAME_XIC (f
);
2525 /* Negotiate geometry of status area. If input method has existing
2526 status area, use its current size. */
2527 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2528 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2529 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2532 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2533 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2536 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2538 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2539 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2543 area
.width
= needed
->width
;
2544 area
.height
= needed
->height
;
2545 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2546 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2547 - FRAME_MENUBAR_HEIGHT (f
)
2548 - FRAME_TOOLBAR_HEIGHT (f
)
2549 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2552 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2553 XSetICValues(xic
, XNStatusAttributes
, attr
, NULL
);
2558 /* Set X fontset for XIC of frame F, using base font name
2559 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2562 xic_set_xfontset (f
, base_fontname
)
2564 char *base_fontname
;
2569 xfs
= xic_create_xfontset (f
, base_fontname
);
2571 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2572 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2573 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2574 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2575 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2578 if (FRAME_XIC_FONTSET (f
))
2579 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2580 FRAME_XIC_FONTSET (f
) = xfs
;
2583 #endif /* HAVE_X_I18N */
2587 #ifdef USE_X_TOOLKIT
2589 /* Create and set up the X widget for frame F. */
2592 x_window (f
, window_prompting
, minibuffer_only
)
2594 long window_prompting
;
2595 int minibuffer_only
;
2597 XClassHint class_hints
;
2598 XSetWindowAttributes attributes
;
2599 unsigned long attribute_mask
;
2600 Widget shell_widget
;
2602 Widget frame_widget
;
2608 /* Use the resource name as the top-level widget name
2609 for looking up resources. Make a non-Lisp copy
2610 for the window manager, so GC relocation won't bother it.
2612 Elsewhere we specify the window name for the window manager. */
2615 char *str
= (char *) SDATA (Vx_resource_name
);
2616 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2617 strcpy (f
->namebuf
, str
);
2621 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2622 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2623 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2624 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2625 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2626 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2627 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2628 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2629 applicationShellWidgetClass
,
2630 FRAME_X_DISPLAY (f
), al
, ac
);
2632 f
->output_data
.x
->widget
= shell_widget
;
2633 /* maybe_set_screen_title_format (shell_widget); */
2635 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2636 (widget_value
*) NULL
,
2637 shell_widget
, False
,
2641 (lw_callback
) NULL
);
2644 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2645 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2646 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2647 XtSetValues (pane_widget
, al
, ac
);
2648 f
->output_data
.x
->column_widget
= pane_widget
;
2650 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2651 the emacs screen when changing menubar. This reduces flickering. */
2654 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2655 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2656 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2657 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2658 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2659 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2660 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2661 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2662 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2665 f
->output_data
.x
->edit_widget
= frame_widget
;
2667 XtManageChild (frame_widget
);
2669 /* Do some needed geometry management. */
2672 char *tem
, shell_position
[32];
2675 int extra_borders
= 0;
2677 = (f
->output_data
.x
->menubar_widget
2678 ? (f
->output_data
.x
->menubar_widget
->core
.height
2679 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2682 #if 0 /* Experimentally, we now get the right results
2683 for -geometry -0-0 without this. 24 Aug 96, rms. */
2684 if (FRAME_EXTERNAL_MENU_BAR (f
))
2687 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2688 menubar_size
+= ibw
;
2692 f
->output_data
.x
->menubar_height
= menubar_size
;
2695 /* Motif seems to need this amount added to the sizes
2696 specified for the shell widget. The Athena/Lucid widgets don't.
2697 Both conclusions reached experimentally. -- rms. */
2698 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2699 &extra_borders
, NULL
);
2703 /* Convert our geometry parameters into a geometry string
2705 Note that we do not specify here whether the position
2706 is a user-specified or program-specified one.
2707 We pass that information later, in x_wm_set_size_hints. */
2709 int left
= f
->left_pos
;
2710 int xneg
= window_prompting
& XNegative
;
2711 int top
= f
->top_pos
;
2712 int yneg
= window_prompting
& YNegative
;
2718 if (window_prompting
& USPosition
)
2719 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2720 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2721 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2722 (xneg
? '-' : '+'), left
,
2723 (yneg
? '-' : '+'), top
);
2725 sprintf (shell_position
, "=%dx%d",
2726 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2727 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2730 len
= strlen (shell_position
) + 1;
2731 /* We don't free this because we don't know whether
2732 it is safe to free it while the frame exists.
2733 It isn't worth the trouble of arranging to free it
2734 when the frame is deleted. */
2735 tem
= (char *) xmalloc (len
);
2736 strncpy (tem
, shell_position
, len
);
2737 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2738 XtSetValues (shell_widget
, al
, ac
);
2741 XtManageChild (pane_widget
);
2742 XtRealizeWidget (shell_widget
);
2744 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2746 validate_x_resource_name ();
2748 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2749 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2750 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2753 FRAME_XIC (f
) = NULL
;
2755 create_frame_xic (f
);
2758 f
->output_data
.x
->wm_hints
.input
= True
;
2759 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2760 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2761 &f
->output_data
.x
->wm_hints
);
2763 hack_wm_protocols (f
, shell_widget
);
2766 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2769 /* Do a stupid property change to force the server to generate a
2770 PropertyNotify event so that the event_stream server timestamp will
2771 be initialized to something relevant to the time we created the window.
2773 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2774 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2775 XA_ATOM
, 32, PropModeAppend
,
2776 (unsigned char*) NULL
, 0);
2778 /* Make all the standard events reach the Emacs frame. */
2779 attributes
.event_mask
= STANDARD_EVENT_SET
;
2784 /* XIM server might require some X events. */
2785 unsigned long fevent
= NoEventMask
;
2786 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2787 attributes
.event_mask
|= fevent
;
2789 #endif /* HAVE_X_I18N */
2791 attribute_mask
= CWEventMask
;
2792 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2793 attribute_mask
, &attributes
);
2795 XtMapWidget (frame_widget
);
2797 /* x_set_name normally ignores requests to set the name if the
2798 requested name is the same as the current name. This is the one
2799 place where that assumption isn't correct; f->name is set, but
2800 the X server hasn't been told. */
2803 int explicit = f
->explicit_name
;
2805 f
->explicit_name
= 0;
2808 x_set_name (f
, name
, explicit);
2811 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2812 f
->output_data
.x
->text_cursor
);
2816 /* This is a no-op, except under Motif. Make sure main areas are
2817 set to something reasonable, in case we get an error later. */
2818 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2821 #else /* not USE_X_TOOLKIT */
2827 if (! xg_create_frame_widgets (f
))
2828 error ("Unable to create window");
2831 FRAME_XIC (f
) = NULL
;
2835 create_frame_xic (f
);
2838 /* XIM server might require some X events. */
2839 unsigned long fevent
= NoEventMask
;
2840 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2842 if (fevent
!= NoEventMask
)
2844 XSetWindowAttributes attributes
;
2845 XWindowAttributes wattr
;
2846 unsigned long attribute_mask
;
2848 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2850 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2851 attribute_mask
= CWEventMask
;
2852 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2853 attribute_mask
, &attributes
);
2861 #else /*! USE_GTK */
2862 /* Create and set up the X window for frame F. */
2869 XClassHint class_hints
;
2870 XSetWindowAttributes attributes
;
2871 unsigned long attribute_mask
;
2873 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2874 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2875 attributes
.bit_gravity
= StaticGravity
;
2876 attributes
.backing_store
= NotUseful
;
2877 attributes
.save_under
= True
;
2878 attributes
.event_mask
= STANDARD_EVENT_SET
;
2879 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2880 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2885 = XCreateWindow (FRAME_X_DISPLAY (f
),
2886 f
->output_data
.x
->parent_desc
,
2889 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2891 CopyFromParent
, /* depth */
2892 InputOutput
, /* class */
2894 attribute_mask
, &attributes
);
2899 create_frame_xic (f
);
2902 /* XIM server might require some X events. */
2903 unsigned long fevent
= NoEventMask
;
2904 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2905 attributes
.event_mask
|= fevent
;
2906 attribute_mask
= CWEventMask
;
2907 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2908 attribute_mask
, &attributes
);
2911 #endif /* HAVE_X_I18N */
2913 validate_x_resource_name ();
2915 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2916 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2917 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2919 /* The menubar is part of the ordinary display;
2920 it does not count in addition to the height of the window. */
2921 f
->output_data
.x
->menubar_height
= 0;
2923 /* This indicates that we use the "Passive Input" input model.
2924 Unless we do this, we don't get the Focus{In,Out} events that we
2925 need to draw the cursor correctly. Accursed bureaucrats.
2926 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2928 f
->output_data
.x
->wm_hints
.input
= True
;
2929 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2930 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2931 &f
->output_data
.x
->wm_hints
);
2932 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2934 /* Request "save yourself" and "delete window" commands from wm. */
2937 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2938 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2939 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2942 /* x_set_name normally ignores requests to set the name if the
2943 requested name is the same as the current name. This is the one
2944 place where that assumption isn't correct; f->name is set, but
2945 the X server hasn't been told. */
2948 int explicit = f
->explicit_name
;
2950 f
->explicit_name
= 0;
2953 x_set_name (f
, name
, explicit);
2956 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2957 f
->output_data
.x
->text_cursor
);
2961 if (FRAME_X_WINDOW (f
) == 0)
2962 error ("Unable to create window");
2965 #endif /* not USE_GTK */
2966 #endif /* not USE_X_TOOLKIT */
2968 /* Handle the icon stuff for this window. Perhaps later we might
2969 want an x_set_icon_position which can be called interactively as
2977 Lisp_Object icon_x
, icon_y
;
2978 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2980 /* Set the position of the icon. Note that twm groups all
2981 icons in an icon window. */
2982 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2983 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2984 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2986 CHECK_NUMBER (icon_x
);
2987 CHECK_NUMBER (icon_y
);
2989 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2990 error ("Both left and top icon corners of icon must be specified");
2994 if (! EQ (icon_x
, Qunbound
))
2995 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2997 /* Start up iconic or window? */
2998 x_wm_set_window_state
2999 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
3004 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
3011 /* Make the GCs needed for this window, setting the
3012 background, border and mouse colors; also create the
3013 mouse cursor and the gray border tile. */
3015 static char cursor_bits
[] =
3017 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3018 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3019 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3020 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3027 XGCValues gc_values
;
3031 /* Create the GCs of this frame.
3032 Note that many default values are used. */
3035 gc_values
.font
= FRAME_FONT (f
)->fid
;
3036 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
3037 gc_values
.background
= f
->output_data
.x
->background_pixel
;
3038 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
3039 f
->output_data
.x
->normal_gc
3040 = XCreateGC (FRAME_X_DISPLAY (f
),
3042 GCLineWidth
| GCFont
| GCForeground
| GCBackground
,
3045 /* Reverse video style. */
3046 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3047 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
3048 f
->output_data
.x
->reverse_gc
3049 = XCreateGC (FRAME_X_DISPLAY (f
),
3051 GCFont
| GCForeground
| GCBackground
| GCLineWidth
,
3054 /* Cursor has cursor-color background, background-color foreground. */
3055 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3056 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
3057 gc_values
.fill_style
= FillOpaqueStippled
;
3059 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
3060 FRAME_X_DISPLAY_INFO (f
)->root_window
,
3061 cursor_bits
, 16, 16);
3062 f
->output_data
.x
->cursor_gc
3063 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3064 (GCFont
| GCForeground
| GCBackground
3065 | GCFillStyle
/* | GCStipple */ | GCLineWidth
),
3069 f
->output_data
.x
->white_relief
.gc
= 0;
3070 f
->output_data
.x
->black_relief
.gc
= 0;
3072 /* Create the gray border tile used when the pointer is not in
3073 the frame. Since this depends on the frame's pixel values,
3074 this must be done on a per-frame basis. */
3075 f
->output_data
.x
->border_tile
3076 = (XCreatePixmapFromBitmapData
3077 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
3078 gray_bits
, gray_width
, gray_height
,
3079 f
->output_data
.x
->foreground_pixel
,
3080 f
->output_data
.x
->background_pixel
,
3081 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
3087 /* Free what was was allocated in x_make_gc. */
3093 Display
*dpy
= FRAME_X_DISPLAY (f
);
3097 if (f
->output_data
.x
->normal_gc
)
3099 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
3100 f
->output_data
.x
->normal_gc
= 0;
3103 if (f
->output_data
.x
->reverse_gc
)
3105 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
3106 f
->output_data
.x
->reverse_gc
= 0;
3109 if (f
->output_data
.x
->cursor_gc
)
3111 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
3112 f
->output_data
.x
->cursor_gc
= 0;
3115 if (f
->output_data
.x
->border_tile
)
3117 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
3118 f
->output_data
.x
->border_tile
= 0;
3125 /* Handler for signals raised during x_create_frame and
3126 x_create_top_frame. FRAME is the frame which is partially
3130 unwind_create_frame (frame
)
3133 struct frame
*f
= XFRAME (frame
);
3135 /* If frame is ``official'', nothing to do. */
3136 if (!CONSP (Vframe_list
) || !EQ (XCAR (Vframe_list
), frame
))
3139 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3142 x_free_frame_resources (f
);
3144 /* Check that reference counts are indeed correct. */
3145 xassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
3146 xassert (dpyinfo
->image_cache
->refcount
== image_cache_refcount
);
3154 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3156 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
3157 Returns an Emacs frame object.
3158 ALIST is an alist of frame parameters.
3159 If the parameters specify that the frame should not have a minibuffer,
3160 and do not specify a specific minibuffer window to use,
3161 then `default-minibuffer-frame' must be a frame whose minibuffer can
3162 be shared by the new frame.
3164 This function is an internal primitive--use `make-frame' instead. */)
3169 Lisp_Object frame
, tem
;
3171 int minibuffer_only
= 0;
3172 long window_prompting
= 0;
3174 int count
= SPECPDL_INDEX ();
3175 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3176 Lisp_Object display
;
3177 struct x_display_info
*dpyinfo
= NULL
;
3183 /* Use this general default value to start with
3184 until we know if this frame has a specified name. */
3185 Vx_resource_name
= Vinvocation_name
;
3187 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3188 if (EQ (display
, Qunbound
))
3190 dpyinfo
= check_x_display_info (display
);
3192 kb
= dpyinfo
->kboard
;
3194 kb
= &the_only_kboard
;
3197 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3199 && ! EQ (name
, Qunbound
)
3201 error ("Invalid frame name--not a string or nil");
3204 Vx_resource_name
= name
;
3206 /* See if parent window is specified. */
3207 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3208 if (EQ (parent
, Qunbound
))
3210 if (! NILP (parent
))
3211 CHECK_NUMBER (parent
);
3213 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3214 /* No need to protect DISPLAY because that's not used after passing
3215 it to make_frame_without_minibuffer. */
3217 GCPRO4 (parms
, parent
, name
, frame
);
3218 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3220 if (EQ (tem
, Qnone
) || NILP (tem
))
3221 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3222 else if (EQ (tem
, Qonly
))
3224 f
= make_minibuffer_frame ();
3225 minibuffer_only
= 1;
3227 else if (WINDOWP (tem
))
3228 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3232 XSETFRAME (frame
, f
);
3234 /* Note that X Windows does support scroll bars. */
3235 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3237 f
->output_method
= output_x_window
;
3238 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3239 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3240 f
->output_data
.x
->icon_bitmap
= -1;
3241 FRAME_FONTSET (f
) = -1;
3242 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3243 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3244 #ifdef USE_TOOLKIT_SCROLL_BARS
3245 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3246 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3247 #endif /* USE_TOOLKIT_SCROLL_BARS */
3248 record_unwind_protect (unwind_create_frame
, frame
);
3251 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3253 if (! STRINGP (f
->icon_name
))
3254 f
->icon_name
= Qnil
;
3256 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3258 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
3259 dpyinfo_refcount
= dpyinfo
->reference_count
;
3260 #endif /* GLYPH_DEBUG */
3262 FRAME_KBOARD (f
) = kb
;
3265 /* These colors will be set anyway later, but it's important
3266 to get the color reference counts right, so initialize them! */
3269 struct gcpro gcpro1
;
3271 /* Function x_decode_color can signal an error. Make
3272 sure to initialize color slots so that we won't try
3273 to free colors we haven't allocated. */
3274 f
->output_data
.x
->foreground_pixel
= -1;
3275 f
->output_data
.x
->background_pixel
= -1;
3276 f
->output_data
.x
->cursor_pixel
= -1;
3277 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3278 f
->output_data
.x
->border_pixel
= -1;
3279 f
->output_data
.x
->mouse_pixel
= -1;
3281 black
= build_string ("black");
3283 f
->output_data
.x
->foreground_pixel
3284 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3285 f
->output_data
.x
->background_pixel
3286 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3287 f
->output_data
.x
->cursor_pixel
3288 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3289 f
->output_data
.x
->cursor_foreground_pixel
3290 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3291 f
->output_data
.x
->border_pixel
3292 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3293 f
->output_data
.x
->mouse_pixel
3294 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3298 /* Specify the parent under which to make this X window. */
3302 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3303 f
->output_data
.x
->explicit_parent
= 1;
3307 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3308 f
->output_data
.x
->explicit_parent
= 0;
3311 /* Set the name; the functions to which we pass f expect the name to
3313 if (EQ (name
, Qunbound
) || NILP (name
))
3315 f
->name
= build_string (dpyinfo
->x_id_name
);
3316 f
->explicit_name
= 0;
3321 f
->explicit_name
= 1;
3322 /* use the frame's title when getting resources for this frame. */
3323 specbind (Qx_resource_name
, name
);
3326 /* Extract the window parameters from the supplied values
3327 that are needed to determine window geometry. */
3331 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3334 /* First, try whatever font the caller has specified. */
3337 tem
= Fquery_fontset (font
, Qnil
);
3339 font
= x_new_fontset (f
, SDATA (tem
));
3341 font
= x_new_font (f
, SDATA (font
));
3344 /* Try out a font which we hope has bold and italic variations. */
3345 if (!STRINGP (font
))
3346 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
3347 if (!STRINGP (font
))
3348 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3349 if (! STRINGP (font
))
3350 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3351 if (! STRINGP (font
))
3352 /* This was formerly the first thing tried, but it finds too many fonts
3353 and takes too long. */
3354 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3355 /* If those didn't work, look for something which will at least work. */
3356 if (! STRINGP (font
))
3357 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3359 if (! STRINGP (font
))
3360 font
= build_string ("fixed");
3362 x_default_parameter (f
, parms
, Qfont
, font
,
3363 "font", "Font", RES_TYPE_STRING
);
3367 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3368 whereby it fails to get any font. */
3369 xlwmenu_default_font
= FRAME_FONT (f
);
3372 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3373 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3375 /* This defaults to 1 in order to match xterm. We recognize either
3376 internalBorderWidth or internalBorder (which is what xterm calls
3378 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3382 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3383 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3384 if (! EQ (value
, Qunbound
))
3385 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3388 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3389 "internalBorderWidth", "internalBorderWidth",
3391 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3392 "verticalScrollBars", "ScrollBars",
3395 /* Also do the stuff which must be set before the window exists. */
3396 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3397 "foreground", "Foreground", RES_TYPE_STRING
);
3398 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3399 "background", "Background", RES_TYPE_STRING
);
3400 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3401 "pointerColor", "Foreground", RES_TYPE_STRING
);
3402 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3403 "cursorColor", "Foreground", RES_TYPE_STRING
);
3404 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3405 "borderColor", "BorderColor", RES_TYPE_STRING
);
3406 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3407 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3408 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3409 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3410 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3411 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3412 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3413 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3415 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3416 "scrollBarForeground",
3417 "ScrollBarForeground", 1);
3418 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3419 "scrollBarBackground",
3420 "ScrollBarBackground", 0);
3422 /* Init faces before x_default_parameter is called for scroll-bar
3423 parameters because that function calls x_set_scroll_bar_width,
3424 which calls change_frame_size, which calls Fset_window_buffer,
3425 which runs hooks, which call Fvertical_motion. At the end, we
3426 end up in init_iterator with a null face cache, which should not
3428 init_frame_faces (f
);
3430 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3431 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3432 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (1),
3433 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3434 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3435 "bufferPredicate", "BufferPredicate",
3437 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3438 "title", "Title", RES_TYPE_STRING
);
3439 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3440 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3441 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3442 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3444 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3446 /* Compute the size of the X window. */
3447 window_prompting
= x_figure_window_size (f
, parms
, 1);
3449 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3450 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3452 /* Create the X widget or window. */
3453 #ifdef USE_X_TOOLKIT
3454 x_window (f
, window_prompting
, minibuffer_only
);
3462 /* Now consider the frame official. */
3463 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3464 Vframe_list
= Fcons (frame
, Vframe_list
);
3466 /* We need to do this after creating the X window, so that the
3467 icon-creation functions can say whose icon they're describing. */
3468 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3469 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
3471 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3472 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3473 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3474 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3475 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3476 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3477 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3478 "scrollBarWidth", "ScrollBarWidth",
3481 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3482 Change will not be effected unless different from the current
3484 width
= FRAME_COLS (f
);
3485 height
= FRAME_LINES (f
);
3487 SET_FRAME_COLS (f
, 0);
3488 FRAME_LINES (f
) = 0;
3489 change_frame_size (f
, height
, width
, 1, 0, 0);
3491 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3492 /* Create the menu bar. */
3493 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3495 /* If this signals an error, we haven't set size hints for the
3496 frame and we didn't make it visible. */
3497 initialize_frame_menubar (f
);
3500 /* This is a no-op, except under Motif where it arranges the
3501 main window for the widgets on it. */
3502 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3503 f
->output_data
.x
->menubar_widget
,
3504 f
->output_data
.x
->edit_widget
);
3505 #endif /* not USE_GTK */
3507 #endif /* USE_X_TOOLKIT || USE_GTK */
3509 /* Tell the server what size and position, etc, we want, and how
3510 badly we want them. This should be done after we have the menu
3511 bar so that its size can be taken into account. */
3513 x_wm_set_size_hint (f
, window_prompting
, 0);
3516 /* Make the window appear on the frame and enable display, unless
3517 the caller says not to. However, with explicit parent, Emacs
3518 cannot control visibility, so don't try. */
3519 if (! f
->output_data
.x
->explicit_parent
)
3521 Lisp_Object visibility
;
3523 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3525 if (EQ (visibility
, Qunbound
))
3528 if (EQ (visibility
, Qicon
))
3529 x_iconify_frame (f
);
3530 else if (! NILP (visibility
))
3531 x_make_frame_visible (f
);
3533 /* Must have been Qnil. */
3537 /* Set the WM leader property. GTK does this itself, so this is not
3538 needed when using GTK. */
3539 if (dpyinfo
->client_leader_window
!= 0)
3542 XChangeProperty (FRAME_X_DISPLAY (f
),
3543 FRAME_OUTER_WINDOW (f
),
3544 dpyinfo
->Xatom_wm_client_leader
,
3545 XA_WINDOW
, 32, PropModeReplace
,
3546 (char *) &dpyinfo
->client_leader_window
, 1);
3552 /* Make sure windows on this frame appear in calls to next-window
3553 and similar functions. */
3554 Vwindow_list
= Qnil
;
3556 return unbind_to (count
, frame
);
3560 /* FRAME is used only to get a handle on the X display. We don't pass the
3561 display info directly because we're called from frame.c, which doesn't
3562 know about that structure. */
3565 x_get_focus_frame (frame
)
3566 struct frame
*frame
;
3568 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3570 if (! dpyinfo
->x_focus_frame
)
3573 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3578 /* In certain situations, when the window manager follows a
3579 click-to-focus policy, there seems to be no way around calling
3580 XSetInputFocus to give another frame the input focus .
3582 In an ideal world, XSetInputFocus should generally be avoided so
3583 that applications don't interfere with the window manager's focus
3584 policy. But I think it's okay to use when it's clearly done
3585 following a user-command. */
3587 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
3588 doc
: /* Set the input focus to FRAME.
3589 FRAME nil means use the selected frame. */)
3593 struct frame
*f
= check_x_frame (frame
);
3594 Display
*dpy
= FRAME_X_DISPLAY (f
);
3598 count
= x_catch_errors (dpy
);
3599 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3600 RevertToParent
, CurrentTime
);
3601 x_uncatch_errors (dpy
, count
);
3608 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3609 doc
: /* Internal function called by `color-defined-p', which see. */)
3611 Lisp_Object color
, frame
;
3614 FRAME_PTR f
= check_x_frame (frame
);
3616 CHECK_STRING (color
);
3618 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3624 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3625 doc
: /* Internal function called by `color-values', which see. */)
3627 Lisp_Object color
, frame
;
3630 FRAME_PTR f
= check_x_frame (frame
);
3632 CHECK_STRING (color
);
3634 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3638 rgb
[0] = make_number (foo
.red
);
3639 rgb
[1] = make_number (foo
.green
);
3640 rgb
[2] = make_number (foo
.blue
);
3641 return Flist (3, rgb
);
3647 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3648 doc
: /* Internal function called by `display-color-p', which see. */)
3650 Lisp_Object display
;
3652 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3654 if (dpyinfo
->n_planes
<= 2)
3657 switch (dpyinfo
->visual
->class)
3670 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3672 doc
: /* Return t if the X display supports shades of gray.
3673 Note that color displays do support shades of gray.
3674 The optional argument DISPLAY specifies which display to ask about.
3675 DISPLAY should be either a frame or a display name (a string).
3676 If omitted or nil, that stands for the selected frame's display. */)
3678 Lisp_Object display
;
3680 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3682 if (dpyinfo
->n_planes
<= 1)
3685 switch (dpyinfo
->visual
->class)
3700 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3702 doc
: /* Returns the width in pixels of the X display DISPLAY.
3703 The optional argument DISPLAY specifies which display to ask about.
3704 DISPLAY should be either a frame or a display name (a string).
3705 If omitted or nil, that stands for the selected frame's display. */)
3707 Lisp_Object display
;
3709 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3711 return make_number (dpyinfo
->width
);
3714 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3715 Sx_display_pixel_height
, 0, 1, 0,
3716 doc
: /* Returns the height in pixels of the X display DISPLAY.
3717 The optional argument DISPLAY specifies which display to ask about.
3718 DISPLAY should be either a frame or a display name (a string).
3719 If omitted or nil, that stands for the selected frame's display. */)
3721 Lisp_Object display
;
3723 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3725 return make_number (dpyinfo
->height
);
3728 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3730 doc
: /* Returns the number of bitplanes of the X display DISPLAY.
3731 The optional argument DISPLAY specifies which display to ask about.
3732 DISPLAY should be either a frame or a display name (a string).
3733 If omitted or nil, that stands for the selected frame's display. */)
3735 Lisp_Object display
;
3737 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3739 return make_number (dpyinfo
->n_planes
);
3742 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3744 doc
: /* Returns the number of color cells of the X display DISPLAY.
3745 The optional argument DISPLAY specifies which display to ask about.
3746 DISPLAY should be either a frame or a display name (a string).
3747 If omitted or nil, that stands for the selected frame's display. */)
3749 Lisp_Object display
;
3751 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3753 return make_number (DisplayCells (dpyinfo
->display
,
3754 XScreenNumberOfScreen (dpyinfo
->screen
)));
3757 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3758 Sx_server_max_request_size
,
3760 doc
: /* Returns the maximum request size of the X server of display DISPLAY.
3761 The optional argument DISPLAY specifies which display to ask about.
3762 DISPLAY should be either a frame or a display name (a string).
3763 If omitted or nil, that stands for the selected frame's display. */)
3765 Lisp_Object display
;
3767 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3769 return make_number (MAXREQUEST (dpyinfo
->display
));
3772 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3773 doc
: /* Returns the vendor ID string of the X server of display DISPLAY.
3774 The optional argument DISPLAY specifies which display to ask about.
3775 DISPLAY should be either a frame or a display name (a string).
3776 If omitted or nil, that stands for the selected frame's display. */)
3778 Lisp_Object display
;
3780 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3781 char *vendor
= ServerVendor (dpyinfo
->display
);
3783 if (! vendor
) vendor
= "";
3784 return build_string (vendor
);
3787 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3788 doc
: /* Returns the version numbers of the X server of display DISPLAY.
3789 The value is a list of three integers: the major and minor
3790 version numbers of the X Protocol in use, and the vendor-specific release
3791 number. See also the function `x-server-vendor'.
3793 The optional argument DISPLAY specifies which display to ask about.
3794 DISPLAY should be either a frame or a display name (a string).
3795 If omitted or nil, that stands for the selected frame's display. */)
3797 Lisp_Object display
;
3799 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3800 Display
*dpy
= dpyinfo
->display
;
3802 return Fcons (make_number (ProtocolVersion (dpy
)),
3803 Fcons (make_number (ProtocolRevision (dpy
)),
3804 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3807 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3808 doc
: /* Return the number of screens on the X server of display DISPLAY.
3809 The optional argument DISPLAY specifies which display to ask about.
3810 DISPLAY should be either a frame or a display name (a string).
3811 If omitted or nil, that stands for the selected frame's display. */)
3813 Lisp_Object display
;
3815 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3817 return make_number (ScreenCount (dpyinfo
->display
));
3820 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3821 doc
: /* Return the height in millimeters of the X display DISPLAY.
3822 The optional argument DISPLAY specifies which display to ask about.
3823 DISPLAY should be either a frame or a display name (a string).
3824 If omitted or nil, that stands for the selected frame's display. */)
3826 Lisp_Object display
;
3828 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3830 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3833 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3834 doc
: /* Return the width in millimeters of the X display DISPLAY.
3835 The optional argument DISPLAY specifies which display to ask about.
3836 DISPLAY should be either a frame or a display name (a string).
3837 If omitted or nil, that stands for the selected frame's display. */)
3839 Lisp_Object display
;
3841 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3843 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3846 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3847 Sx_display_backing_store
, 0, 1, 0,
3848 doc
: /* Returns an indication of whether X display DISPLAY does backing store.
3849 The value may be `always', `when-mapped', or `not-useful'.
3850 The optional argument DISPLAY specifies which display to ask about.
3851 DISPLAY should be either a frame or a display name (a string).
3852 If omitted or nil, that stands for the selected frame's display. */)
3854 Lisp_Object display
;
3856 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3859 switch (DoesBackingStore (dpyinfo
->screen
))
3862 result
= intern ("always");
3866 result
= intern ("when-mapped");
3870 result
= intern ("not-useful");
3874 error ("Strange value for BackingStore parameter of screen");
3881 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3882 Sx_display_visual_class
, 0, 1, 0,
3883 doc
: /* Return the visual class of the X display DISPLAY.
3884 The value is one of the symbols `static-gray', `gray-scale',
3885 `static-color', `pseudo-color', `true-color', or `direct-color'.
3887 The optional argument DISPLAY specifies which display to ask about.
3888 DISPLAY should be either a frame or a display name (a string).
3889 If omitted or nil, that stands for the selected frame's display. */)
3891 Lisp_Object display
;
3893 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3896 switch (dpyinfo
->visual
->class)
3899 result
= intern ("static-gray");
3902 result
= intern ("gray-scale");
3905 result
= intern ("static-color");
3908 result
= intern ("pseudo-color");
3911 result
= intern ("true-color");
3914 result
= intern ("direct-color");
3917 error ("Display has an unknown visual class");
3924 DEFUN ("x-display-save-under", Fx_display_save_under
,
3925 Sx_display_save_under
, 0, 1, 0,
3926 doc
: /* Returns t if the X display DISPLAY supports the save-under feature.
3927 The optional argument DISPLAY specifies which display to ask about.
3928 DISPLAY should be either a frame or a display name (a string).
3929 If omitted or nil, that stands for the selected frame's display. */)
3931 Lisp_Object display
;
3933 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3935 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3943 register struct frame
*f
;
3945 return FRAME_PIXEL_WIDTH (f
);
3950 register struct frame
*f
;
3952 return FRAME_PIXEL_HEIGHT (f
);
3957 register struct frame
*f
;
3959 return FRAME_COLUMN_WIDTH (f
);
3964 register struct frame
*f
;
3966 return FRAME_LINE_HEIGHT (f
);
3971 register struct frame
*f
;
3973 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
3978 /************************************************************************
3980 ************************************************************************/
3983 /* Mapping visual names to visuals. */
3985 static struct visual_class
3992 {"StaticGray", StaticGray
},
3993 {"GrayScale", GrayScale
},
3994 {"StaticColor", StaticColor
},
3995 {"PseudoColor", PseudoColor
},
3996 {"TrueColor", TrueColor
},
3997 {"DirectColor", DirectColor
},
4002 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4004 /* Value is the screen number of screen SCR. This is a substitute for
4005 the X function with the same name when that doesn't exist. */
4008 XScreenNumberOfScreen (scr
)
4009 register Screen
*scr
;
4011 Display
*dpy
= scr
->display
;
4014 for (i
= 0; i
< dpy
->nscreens
; ++i
)
4015 if (scr
== dpy
->screens
+ i
)
4021 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4024 /* Select the visual that should be used on display DPYINFO. Set
4025 members of DPYINFO appropriately. Called from x_term_init. */
4028 select_visual (dpyinfo
)
4029 struct x_display_info
*dpyinfo
;
4031 Display
*dpy
= dpyinfo
->display
;
4032 Screen
*screen
= dpyinfo
->screen
;
4035 /* See if a visual is specified. */
4036 value
= display_x_get_resource (dpyinfo
,
4037 build_string ("visualClass"),
4038 build_string ("VisualClass"),
4040 if (STRINGP (value
))
4042 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4043 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4044 depth, a decimal number. NAME is compared with case ignored. */
4045 char *s
= (char *) alloca (SBYTES (value
) + 1);
4050 strcpy (s
, SDATA (value
));
4051 dash
= index (s
, '-');
4054 dpyinfo
->n_planes
= atoi (dash
+ 1);
4058 /* We won't find a matching visual with depth 0, so that
4059 an error will be printed below. */
4060 dpyinfo
->n_planes
= 0;
4062 /* Determine the visual class. */
4063 for (i
= 0; visual_classes
[i
].name
; ++i
)
4064 if (xstricmp (s
, visual_classes
[i
].name
) == 0)
4066 class = visual_classes
[i
].class;
4070 /* Look up a matching visual for the specified class. */
4072 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4073 dpyinfo
->n_planes
, class, &vinfo
))
4074 fatal ("Invalid visual specification `%s'", SDATA (value
));
4076 dpyinfo
->visual
= vinfo
.visual
;
4081 XVisualInfo
*vinfo
, vinfo_template
;
4083 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4086 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4088 vinfo_template
.visualid
= dpyinfo
->visual
->visualid
;
4090 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4091 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4092 &vinfo_template
, &n_visuals
);
4094 fatal ("Can't get proper X visual info");
4096 dpyinfo
->n_planes
= vinfo
->depth
;
4097 XFree ((char *) vinfo
);
4102 /* Return the X display structure for the display named NAME.
4103 Open a new connection if necessary. */
4105 struct x_display_info
*
4106 x_display_info_for_name (name
)
4110 struct x_display_info
*dpyinfo
;
4112 CHECK_STRING (name
);
4114 if (! EQ (Vwindow_system
, intern ("x")))
4115 error ("Not using X Windows");
4117 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4119 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4122 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4127 /* Use this general default value to start with. */
4128 Vx_resource_name
= Vinvocation_name
;
4130 validate_x_resource_name ();
4132 dpyinfo
= x_term_init (name
, (char *)0,
4133 (char *) SDATA (Vx_resource_name
));
4136 error ("Cannot connect to X server %s", SDATA (name
));
4139 XSETFASTINT (Vwindow_system_version
, 11);
4145 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4147 doc
: /* Open a connection to an X server.
4148 DISPLAY is the name of the display to connect to.
4149 Optional second arg XRM-STRING is a string of resources in xrdb format.
4150 If the optional third arg MUST-SUCCEED is non-nil,
4151 terminate Emacs if we can't open the connection. */)
4152 (display
, xrm_string
, must_succeed
)
4153 Lisp_Object display
, xrm_string
, must_succeed
;
4155 unsigned char *xrm_option
;
4156 struct x_display_info
*dpyinfo
;
4158 CHECK_STRING (display
);
4159 if (! NILP (xrm_string
))
4160 CHECK_STRING (xrm_string
);
4162 if (! EQ (Vwindow_system
, intern ("x")))
4163 error ("Not using X Windows");
4165 if (! NILP (xrm_string
))
4166 xrm_option
= (unsigned char *) SDATA (xrm_string
);
4168 xrm_option
= (unsigned char *) 0;
4170 validate_x_resource_name ();
4172 /* This is what opens the connection and sets x_current_display.
4173 This also initializes many symbols, such as those used for input. */
4174 dpyinfo
= x_term_init (display
, xrm_option
,
4175 (char *) SDATA (Vx_resource_name
));
4179 if (!NILP (must_succeed
))
4180 fatal ("Cannot connect to X server %s.\n\
4181 Check the DISPLAY environment variable or use `-d'.\n\
4182 Also use the `xauth' program to verify that you have the proper\n\
4183 authorization information needed to connect the X server.\n\
4184 An insecure way to solve the problem may be to use `xhost'.\n",
4187 error ("Cannot connect to X server %s", SDATA (display
));
4192 XSETFASTINT (Vwindow_system_version
, 11);
4196 DEFUN ("x-close-connection", Fx_close_connection
,
4197 Sx_close_connection
, 1, 1, 0,
4198 doc
: /* Close the connection to DISPLAY's X server.
4199 For DISPLAY, specify either a frame or a display name (a string).
4200 If DISPLAY is nil, that stands for the selected frame's display. */)
4202 Lisp_Object display
;
4204 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4207 if (dpyinfo
->reference_count
> 0)
4208 error ("Display still has frames on it");
4211 /* Free the fonts in the font table. */
4212 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4213 if (dpyinfo
->font_table
[i
].name
)
4215 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4218 x_destroy_all_bitmaps (dpyinfo
);
4219 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4221 #ifdef USE_X_TOOLKIT
4222 XtCloseDisplay (dpyinfo
->display
);
4224 XCloseDisplay (dpyinfo
->display
);
4227 x_delete_display (dpyinfo
);
4233 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4234 doc
: /* Return the list of display names that Emacs has connections to. */)
4237 Lisp_Object tail
, result
;
4240 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
4241 result
= Fcons (XCAR (XCAR (tail
)), result
);
4246 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4247 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4248 If ON is nil, allow buffering of requests.
4249 Turning on synchronization prohibits the Xlib routines from buffering
4250 requests and seriously degrades performance, but makes debugging much
4252 The optional second argument DISPLAY specifies which display to act on.
4253 DISPLAY should be either a frame or a display name (a string).
4254 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4256 Lisp_Object display
, on
;
4258 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4260 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4265 /* Wait for responses to all X commands issued so far for frame F. */
4272 XSync (FRAME_X_DISPLAY (f
), False
);
4277 /***********************************************************************
4279 ***********************************************************************/
4281 /* Value is the number of elements of vector VECTOR. */
4283 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
4285 /* List of supported image types. Use define_image_type to add new
4286 types. Use lookup_image_type to find a type for a given symbol. */
4288 static struct image_type
*image_types
;
4290 /* The symbol `image' which is the car of the lists used to represent
4293 extern Lisp_Object Qimage
;
4295 /* The symbol `xbm' which is used as the type symbol for XBM images. */
4301 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
4302 extern Lisp_Object QCdata
, QCtype
;
4303 Lisp_Object QCascent
, QCmargin
, QCrelief
;
4304 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
4305 Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
;
4307 /* Other symbols. */
4309 Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
4311 /* Time in seconds after which images should be removed from the cache
4312 if not displayed. */
4314 Lisp_Object Vimage_cache_eviction_delay
;
4316 /* Function prototypes. */
4318 static void define_image_type
P_ ((struct image_type
*type
));
4319 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
4320 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
4321 static void x_laplace
P_ ((struct frame
*, struct image
*));
4322 static void x_emboss
P_ ((struct frame
*, struct image
*));
4323 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
4327 /* Define a new image type from TYPE. This adds a copy of TYPE to
4328 image_types and adds the symbol *TYPE->type to Vimage_types. */
4331 define_image_type (type
)
4332 struct image_type
*type
;
4334 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
4335 The initialized data segment is read-only. */
4336 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
4337 bcopy (type
, p
, sizeof *p
);
4338 p
->next
= image_types
;
4340 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
4344 /* Look up image type SYMBOL, and return a pointer to its image_type
4345 structure. Value is null if SYMBOL is not a known image type. */
4347 static INLINE
struct image_type
*
4348 lookup_image_type (symbol
)
4351 struct image_type
*type
;
4353 for (type
= image_types
; type
; type
= type
->next
)
4354 if (EQ (symbol
, *type
->type
))
4361 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
4362 valid image specification is a list whose car is the symbol
4363 `image', and whose rest is a property list. The property list must
4364 contain a value for key `:type'. That value must be the name of a
4365 supported image type. The rest of the property list depends on the
4369 valid_image_p (object
)
4374 if (CONSP (object
) && EQ (XCAR (object
), Qimage
))
4378 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
4379 if (EQ (XCAR (tem
), QCtype
))
4382 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
4384 struct image_type
*type
;
4385 type
= lookup_image_type (XCAR (tem
));
4387 valid_p
= type
->valid_p (object
);
4398 /* Log error message with format string FORMAT and argument ARG.
4399 Signaling an error, e.g. when an image cannot be loaded, is not a
4400 good idea because this would interrupt redisplay, and the error
4401 message display would lead to another redisplay. This function
4402 therefore simply displays a message. */
4405 image_error (format
, arg1
, arg2
)
4407 Lisp_Object arg1
, arg2
;
4409 add_to_log (format
, arg1
, arg2
);
4414 /***********************************************************************
4415 Image specifications
4416 ***********************************************************************/
4418 enum image_value_type
4420 IMAGE_DONT_CHECK_VALUE_TYPE
,
4422 IMAGE_STRING_OR_NIL_VALUE
,
4424 IMAGE_POSITIVE_INTEGER_VALUE
,
4425 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
4426 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
4428 IMAGE_INTEGER_VALUE
,
4429 IMAGE_FUNCTION_VALUE
,
4434 /* Structure used when parsing image specifications. */
4436 struct image_keyword
4438 /* Name of keyword. */
4441 /* The type of value allowed. */
4442 enum image_value_type type
;
4444 /* Non-zero means key must be present. */
4447 /* Used to recognize duplicate keywords in a property list. */
4450 /* The value that was found. */
4455 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
4457 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
4460 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
4461 has the format (image KEYWORD VALUE ...). One of the keyword/
4462 value pairs must be `:type TYPE'. KEYWORDS is a vector of
4463 image_keywords structures of size NKEYWORDS describing other
4464 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
4467 parse_image_spec (spec
, keywords
, nkeywords
, type
)
4469 struct image_keyword
*keywords
;
4476 if (!CONSP (spec
) || !EQ (XCAR (spec
), Qimage
))
4479 plist
= XCDR (spec
);
4480 while (CONSP (plist
))
4482 Lisp_Object key
, value
;
4484 /* First element of a pair must be a symbol. */
4486 plist
= XCDR (plist
);
4490 /* There must follow a value. */
4493 value
= XCAR (plist
);
4494 plist
= XCDR (plist
);
4496 /* Find key in KEYWORDS. Error if not found. */
4497 for (i
= 0; i
< nkeywords
; ++i
)
4498 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
4504 /* Record that we recognized the keyword. If a keywords
4505 was found more than once, it's an error. */
4506 keywords
[i
].value
= value
;
4507 ++keywords
[i
].count
;
4509 if (keywords
[i
].count
> 1)
4512 /* Check type of value against allowed type. */
4513 switch (keywords
[i
].type
)
4515 case IMAGE_STRING_VALUE
:
4516 if (!STRINGP (value
))
4520 case IMAGE_STRING_OR_NIL_VALUE
:
4521 if (!STRINGP (value
) && !NILP (value
))
4525 case IMAGE_SYMBOL_VALUE
:
4526 if (!SYMBOLP (value
))
4530 case IMAGE_POSITIVE_INTEGER_VALUE
:
4531 if (!INTEGERP (value
) || XINT (value
) <= 0)
4535 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
4536 if (INTEGERP (value
) && XINT (value
) >= 0)
4539 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
4540 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
4544 case IMAGE_ASCENT_VALUE
:
4545 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
4547 else if (INTEGERP (value
)
4548 && XINT (value
) >= 0
4549 && XINT (value
) <= 100)
4553 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
4554 if (!INTEGERP (value
) || XINT (value
) < 0)
4558 case IMAGE_DONT_CHECK_VALUE_TYPE
:
4561 case IMAGE_FUNCTION_VALUE
:
4562 value
= indirect_function (value
);
4564 || COMPILEDP (value
)
4565 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
4569 case IMAGE_NUMBER_VALUE
:
4570 if (!INTEGERP (value
) && !FLOATP (value
))
4574 case IMAGE_INTEGER_VALUE
:
4575 if (!INTEGERP (value
))
4579 case IMAGE_BOOL_VALUE
:
4580 if (!NILP (value
) && !EQ (value
, Qt
))
4589 if (EQ (key
, QCtype
) && !EQ (type
, value
))
4593 /* Check that all mandatory fields are present. */
4594 for (i
= 0; i
< nkeywords
; ++i
)
4595 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
4598 return NILP (plist
);
4602 /* Return the value of KEY in image specification SPEC. Value is nil
4603 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
4604 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
4607 image_spec_value (spec
, key
, found
)
4608 Lisp_Object spec
, key
;
4613 xassert (valid_image_p (spec
));
4615 for (tail
= XCDR (spec
);
4616 CONSP (tail
) && CONSP (XCDR (tail
));
4617 tail
= XCDR (XCDR (tail
)))
4619 if (EQ (XCAR (tail
), key
))
4623 return XCAR (XCDR (tail
));
4633 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
4634 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
4635 PIXELS non-nil means return the size in pixels, otherwise return the
4636 size in canonical character units.
4637 FRAME is the frame on which the image will be displayed. FRAME nil
4638 or omitted means use the selected frame. */)
4639 (spec
, pixels
, frame
)
4640 Lisp_Object spec
, pixels
, frame
;
4645 if (valid_image_p (spec
))
4647 struct frame
*f
= check_x_frame (frame
);
4648 int id
= lookup_image (f
, spec
);
4649 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4650 int width
= img
->width
+ 2 * img
->hmargin
;
4651 int height
= img
->height
+ 2 * img
->vmargin
;
4654 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
4655 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
4657 size
= Fcons (make_number (width
), make_number (height
));
4660 error ("Invalid image specification");
4666 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
4667 doc
: /* Return t if image SPEC has a mask bitmap.
4668 FRAME is the frame on which the image will be displayed. FRAME nil
4669 or omitted means use the selected frame. */)
4671 Lisp_Object spec
, frame
;
4676 if (valid_image_p (spec
))
4678 struct frame
*f
= check_x_frame (frame
);
4679 int id
= lookup_image (f
, spec
);
4680 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4685 error ("Invalid image specification");
4692 /***********************************************************************
4693 Image type independent image structures
4694 ***********************************************************************/
4696 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
4697 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
4700 /* Allocate and return a new image structure for image specification
4701 SPEC. SPEC has a hash value of HASH. */
4703 static struct image
*
4704 make_image (spec
, hash
)
4708 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
4710 xassert (valid_image_p (spec
));
4711 bzero (img
, sizeof *img
);
4712 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
4713 xassert (img
->type
!= NULL
);
4715 img
->data
.lisp_val
= Qnil
;
4716 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
4722 /* Free image IMG which was used on frame F, including its resources. */
4731 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4733 /* Remove IMG from the hash table of its cache. */
4735 img
->prev
->next
= img
->next
;
4737 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
4740 img
->next
->prev
= img
->prev
;
4742 c
->images
[img
->id
] = NULL
;
4744 /* Free resources, then free IMG. */
4745 img
->type
->free (f
, img
);
4751 /* Prepare image IMG for display on frame F. Must be called before
4752 drawing an image. */
4755 prepare_image_for_display (f
, img
)
4761 /* We're about to display IMG, so set its timestamp to `now'. */
4763 img
->timestamp
= EMACS_SECS (t
);
4765 /* If IMG doesn't have a pixmap yet, load it now, using the image
4766 type dependent loader function. */
4767 if (img
->pixmap
== None
&& !img
->load_failed_p
)
4768 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
4772 /* Value is the number of pixels for the ascent of image IMG when
4773 drawn in face FACE. */
4776 image_ascent (img
, face
)
4780 int height
= img
->height
+ img
->vmargin
;
4783 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
4786 /* This expression is arranged so that if the image can't be
4787 exactly centered, it will be moved slightly up. This is
4788 because a typical font is `top-heavy' (due to the presence
4789 uppercase letters), so the image placement should err towards
4790 being top-heavy too. It also just generally looks better. */
4791 ascent
= (height
+ face
->font
->ascent
- face
->font
->descent
+ 1) / 2;
4793 ascent
= height
/ 2;
4796 ascent
= height
* img
->ascent
/ 100.0;
4802 /* Image background colors. */
4804 static unsigned long
4805 four_corners_best (ximg
, width
, height
)
4807 unsigned long width
, height
;
4809 unsigned long corners
[4], best
;
4812 /* Get the colors at the corners of ximg. */
4813 corners
[0] = XGetPixel (ximg
, 0, 0);
4814 corners
[1] = XGetPixel (ximg
, width
- 1, 0);
4815 corners
[2] = XGetPixel (ximg
, width
- 1, height
- 1);
4816 corners
[3] = XGetPixel (ximg
, 0, height
- 1);
4818 /* Choose the most frequently found color as background. */
4819 for (i
= best_count
= 0; i
< 4; ++i
)
4823 for (j
= n
= 0; j
< 4; ++j
)
4824 if (corners
[i
] == corners
[j
])
4828 best
= corners
[i
], best_count
= n
;
4834 /* Return the `background' field of IMG. If IMG doesn't have one yet,
4835 it is guessed heuristically. If non-zero, XIMG is an existing XImage
4836 object to use for the heuristic. */
4839 image_background (img
, f
, ximg
)
4844 if (! img
->background_valid
)
4845 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4847 int free_ximg
= !ximg
;
4850 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4851 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4853 img
->background
= four_corners_best (ximg
, img
->width
, img
->height
);
4856 XDestroyImage (ximg
);
4858 img
->background_valid
= 1;
4861 return img
->background
;
4864 /* Return the `background_transparent' field of IMG. If IMG doesn't
4865 have one yet, it is guessed heuristically. If non-zero, MASK is an
4866 existing XImage object to use for the heuristic. */
4869 image_background_transparent (img
, f
, mask
)
4874 if (! img
->background_transparent_valid
)
4875 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4879 int free_mask
= !mask
;
4882 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
4883 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4885 img
->background_transparent
4886 = !four_corners_best (mask
, img
->width
, img
->height
);
4889 XDestroyImage (mask
);
4892 img
->background_transparent
= 0;
4894 img
->background_transparent_valid
= 1;
4897 return img
->background_transparent
;
4901 /***********************************************************************
4902 Helper functions for X image types
4903 ***********************************************************************/
4905 static void x_clear_image_1
P_ ((struct frame
*, struct image
*, int,
4907 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
4908 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
4910 Lisp_Object color_name
,
4911 unsigned long dflt
));
4914 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
4915 free the pixmap if any. MASK_P non-zero means clear the mask
4916 pixmap if any. COLORS_P non-zero means free colors allocated for
4917 the image, if any. */
4920 x_clear_image_1 (f
, img
, pixmap_p
, mask_p
, colors_p
)
4923 int pixmap_p
, mask_p
, colors_p
;
4925 if (pixmap_p
&& img
->pixmap
)
4927 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
4929 img
->background_valid
= 0;
4932 if (mask_p
&& img
->mask
)
4934 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4936 img
->background_transparent_valid
= 0;
4939 if (colors_p
&& img
->ncolors
)
4941 x_free_colors (f
, img
->colors
, img
->ncolors
);
4942 xfree (img
->colors
);
4948 /* Free X resources of image IMG which is used on frame F. */
4951 x_clear_image (f
, img
)
4956 x_clear_image_1 (f
, img
, 1, 1, 1);
4961 /* Allocate color COLOR_NAME for image IMG on frame F. If color
4962 cannot be allocated, use DFLT. Add a newly allocated color to
4963 IMG->colors, so that it can be freed again. Value is the pixel
4966 static unsigned long
4967 x_alloc_image_color (f
, img
, color_name
, dflt
)
4970 Lisp_Object color_name
;
4974 unsigned long result
;
4976 xassert (STRINGP (color_name
));
4978 if (x_defined_color (f
, SDATA (color_name
), &color
, 1))
4980 /* This isn't called frequently so we get away with simply
4981 reallocating the color vector to the needed size, here. */
4984 (unsigned long *) xrealloc (img
->colors
,
4985 img
->ncolors
* sizeof *img
->colors
);
4986 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
4987 result
= color
.pixel
;
4997 /***********************************************************************
4999 ***********************************************************************/
5001 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
5002 static void postprocess_image
P_ ((struct frame
*, struct image
*));
5005 /* Return a new, initialized image cache that is allocated from the
5006 heap. Call free_image_cache to free an image cache. */
5008 struct image_cache
*
5011 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
5014 bzero (c
, sizeof *c
);
5016 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
5017 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
5018 c
->buckets
= (struct image
**) xmalloc (size
);
5019 bzero (c
->buckets
, size
);
5024 /* Free image cache of frame F. Be aware that X frames share images
5028 free_image_cache (f
)
5031 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5036 /* Cache should not be referenced by any frame when freed. */
5037 xassert (c
->refcount
== 0);
5039 for (i
= 0; i
< c
->used
; ++i
)
5040 free_image (f
, c
->images
[i
]);
5044 FRAME_X_IMAGE_CACHE (f
) = NULL
;
5049 /* Clear image cache of frame F. FORCE_P non-zero means free all
5050 images. FORCE_P zero means clear only images that haven't been
5051 displayed for some time. Should be called from time to time to
5052 reduce the number of loaded images. If image-eviction-seconds is
5053 non-nil, this frees images in the cache which weren't displayed for
5054 at least that many seconds. */
5057 clear_image_cache (f
, force_p
)
5061 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5063 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
5070 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
5072 /* Block input so that we won't be interrupted by a SIGIO
5073 while being in an inconsistent state. */
5076 for (i
= nfreed
= 0; i
< c
->used
; ++i
)
5078 struct image
*img
= c
->images
[i
];
5080 && (force_p
|| img
->timestamp
< old
))
5082 free_image (f
, img
);
5087 /* We may be clearing the image cache because, for example,
5088 Emacs was iconified for a longer period of time. In that
5089 case, current matrices may still contain references to
5090 images freed above. So, clear these matrices. */
5093 Lisp_Object tail
, frame
;
5095 FOR_EACH_FRAME (tail
, frame
)
5097 struct frame
*f
= XFRAME (frame
);
5099 && FRAME_X_IMAGE_CACHE (f
) == c
)
5100 clear_current_matrices (f
);
5103 ++windows_or_buffers_changed
;
5111 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
5113 doc
: /* Clear the image cache of FRAME.
5114 FRAME nil or omitted means use the selected frame.
5115 FRAME t means clear the image caches of all frames. */)
5123 FOR_EACH_FRAME (tail
, frame
)
5124 if (FRAME_X_P (XFRAME (frame
)))
5125 clear_image_cache (XFRAME (frame
), 1);
5128 clear_image_cache (check_x_frame (frame
), 1);
5134 /* Compute masks and transform image IMG on frame F, as specified
5135 by the image's specification, */
5138 postprocess_image (f
, img
)
5142 /* Manipulation of the image's mask. */
5145 Lisp_Object conversion
, spec
;
5150 /* `:heuristic-mask t'
5152 means build a mask heuristically.
5153 `:heuristic-mask (R G B)'
5154 `:mask (heuristic (R G B))'
5155 means build a mask from color (R G B) in the
5158 means remove a mask, if any. */
5160 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
5162 x_build_heuristic_mask (f
, img
, mask
);
5167 mask
= image_spec_value (spec
, QCmask
, &found_p
);
5169 if (EQ (mask
, Qheuristic
))
5170 x_build_heuristic_mask (f
, img
, Qt
);
5171 else if (CONSP (mask
)
5172 && EQ (XCAR (mask
), Qheuristic
))
5174 if (CONSP (XCDR (mask
)))
5175 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
5177 x_build_heuristic_mask (f
, img
, XCDR (mask
));
5179 else if (NILP (mask
) && found_p
&& img
->mask
)
5181 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
5187 /* Should we apply an image transformation algorithm? */
5188 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
5189 if (EQ (conversion
, Qdisabled
))
5190 x_disable_image (f
, img
);
5191 else if (EQ (conversion
, Qlaplace
))
5193 else if (EQ (conversion
, Qemboss
))
5195 else if (CONSP (conversion
)
5196 && EQ (XCAR (conversion
), Qedge_detection
))
5199 tem
= XCDR (conversion
);
5201 x_edge_detection (f
, img
,
5202 Fplist_get (tem
, QCmatrix
),
5203 Fplist_get (tem
, QCcolor_adjustment
));
5209 /* Return the id of image with Lisp specification SPEC on frame F.
5210 SPEC must be a valid Lisp image specification (see valid_image_p). */
5213 lookup_image (f
, spec
)
5217 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5221 struct gcpro gcpro1
;
5224 /* F must be a window-system frame, and SPEC must be a valid image
5226 xassert (FRAME_WINDOW_P (f
));
5227 xassert (valid_image_p (spec
));
5231 /* Look up SPEC in the hash table of the image cache. */
5232 hash
= sxhash (spec
, 0);
5233 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5235 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
5236 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
5239 /* If not found, create a new image and cache it. */
5242 extern Lisp_Object Qpostscript
;
5245 img
= make_image (spec
, hash
);
5246 cache_image (f
, img
);
5247 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5249 /* If we can't load the image, and we don't have a width and
5250 height, use some arbitrary width and height so that we can
5251 draw a rectangle for it. */
5252 if (img
->load_failed_p
)
5256 value
= image_spec_value (spec
, QCwidth
, NULL
);
5257 img
->width
= (INTEGERP (value
)
5258 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
5259 value
= image_spec_value (spec
, QCheight
, NULL
);
5260 img
->height
= (INTEGERP (value
)
5261 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
5265 /* Handle image type independent image attributes
5266 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
5267 `:background COLOR'. */
5268 Lisp_Object ascent
, margin
, relief
, bg
;
5270 ascent
= image_spec_value (spec
, QCascent
, NULL
);
5271 if (INTEGERP (ascent
))
5272 img
->ascent
= XFASTINT (ascent
);
5273 else if (EQ (ascent
, Qcenter
))
5274 img
->ascent
= CENTERED_IMAGE_ASCENT
;
5276 margin
= image_spec_value (spec
, QCmargin
, NULL
);
5277 if (INTEGERP (margin
) && XINT (margin
) >= 0)
5278 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
5279 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
5280 && INTEGERP (XCDR (margin
)))
5282 if (XINT (XCAR (margin
)) > 0)
5283 img
->hmargin
= XFASTINT (XCAR (margin
));
5284 if (XINT (XCDR (margin
)) > 0)
5285 img
->vmargin
= XFASTINT (XCDR (margin
));
5288 relief
= image_spec_value (spec
, QCrelief
, NULL
);
5289 if (INTEGERP (relief
))
5291 img
->relief
= XINT (relief
);
5292 img
->hmargin
+= abs (img
->relief
);
5293 img
->vmargin
+= abs (img
->relief
);
5296 if (! img
->background_valid
)
5298 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
5302 = x_alloc_image_color (f
, img
, bg
,
5303 FRAME_BACKGROUND_PIXEL (f
));
5304 img
->background_valid
= 1;
5308 /* Do image transformations and compute masks, unless we
5309 don't have the image yet. */
5310 if (!EQ (*img
->type
->type
, Qpostscript
))
5311 postprocess_image (f
, img
);
5315 xassert (!interrupt_input_blocked
);
5318 /* We're using IMG, so set its timestamp to `now'. */
5319 EMACS_GET_TIME (now
);
5320 img
->timestamp
= EMACS_SECS (now
);
5324 /* Value is the image id. */
5329 /* Cache image IMG in the image cache of frame F. */
5332 cache_image (f
, img
)
5336 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5339 /* Find a free slot in c->images. */
5340 for (i
= 0; i
< c
->used
; ++i
)
5341 if (c
->images
[i
] == NULL
)
5344 /* If no free slot found, maybe enlarge c->images. */
5345 if (i
== c
->used
&& c
->used
== c
->size
)
5348 c
->images
= (struct image
**) xrealloc (c
->images
,
5349 c
->size
* sizeof *c
->images
);
5352 /* Add IMG to c->images, and assign IMG an id. */
5358 /* Add IMG to the cache's hash table. */
5359 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5360 img
->next
= c
->buckets
[i
];
5362 img
->next
->prev
= img
;
5364 c
->buckets
[i
] = img
;
5368 /* Call FN on every image in the image cache of frame F. Used to mark
5369 Lisp Objects in the image cache. */
5372 forall_images_in_image_cache (f
, fn
)
5374 void (*fn
) P_ ((struct image
*img
));
5376 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
))
5378 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5382 for (i
= 0; i
< c
->used
; ++i
)
5391 /***********************************************************************
5393 ***********************************************************************/
5395 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
5396 XImage
**, Pixmap
*));
5397 static void x_destroy_x_image
P_ ((XImage
*));
5398 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
5401 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
5402 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
5403 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
5404 via xmalloc. Print error messages via image_error if an error
5405 occurs. Value is non-zero if successful. */
5408 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
5410 int width
, height
, depth
;
5414 Display
*display
= FRAME_X_DISPLAY (f
);
5415 Screen
*screen
= FRAME_X_SCREEN (f
);
5416 Window window
= FRAME_X_WINDOW (f
);
5418 xassert (interrupt_input_blocked
);
5421 depth
= DefaultDepthOfScreen (screen
);
5422 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
5423 depth
, ZPixmap
, 0, NULL
, width
, height
,
5424 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
5427 image_error ("Unable to allocate X image", Qnil
, Qnil
);
5431 /* Allocate image raster. */
5432 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
5434 /* Allocate a pixmap of the same size. */
5435 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
5436 if (*pixmap
== None
)
5438 x_destroy_x_image (*ximg
);
5440 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
5448 /* Destroy XImage XIMG. Free XIMG->data. */
5451 x_destroy_x_image (ximg
)
5454 xassert (interrupt_input_blocked
);
5459 XDestroyImage (ximg
);
5464 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
5465 are width and height of both the image and pixmap. */
5468 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
5476 xassert (interrupt_input_blocked
);
5477 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
5478 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
5479 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5484 /***********************************************************************
5486 ***********************************************************************/
5488 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
5489 static char *slurp_file
P_ ((char *, int *));
5492 /* Find image file FILE. Look in data-directory, then
5493 x-bitmap-file-path. Value is the full name of the file found, or
5494 nil if not found. */
5497 x_find_image_file (file
)
5500 Lisp_Object file_found
, search_path
;
5501 struct gcpro gcpro1
, gcpro2
;
5505 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
5506 GCPRO2 (file_found
, search_path
);
5508 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
5509 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
5521 /* Read FILE into memory. Value is a pointer to a buffer allocated
5522 with xmalloc holding FILE's contents. Value is null if an error
5523 occurred. *SIZE is set to the size of the file. */
5526 slurp_file (file
, size
)
5534 if (stat (file
, &st
) == 0
5535 && (fp
= fopen (file
, "r")) != NULL
5536 && (buf
= (char *) xmalloc (st
.st_size
),
5537 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5558 /***********************************************************************
5560 ***********************************************************************/
5562 static int xbm_scan
P_ ((char **, char *, char *, int *));
5563 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
5564 static int xbm_load_image
P_ ((struct frame
*f
, struct image
*img
,
5566 static int xbm_image_p
P_ ((Lisp_Object object
));
5567 static int xbm_read_bitmap_data
P_ ((char *, char *, int *, int *,
5569 static int xbm_file_p
P_ ((Lisp_Object
));
5572 /* Indices of image specification fields in xbm_format, below. */
5574 enum xbm_keyword_index
5592 /* Vector of image_keyword structures describing the format
5593 of valid XBM image specifications. */
5595 static struct image_keyword xbm_format
[XBM_LAST
] =
5597 {":type", IMAGE_SYMBOL_VALUE
, 1},
5598 {":file", IMAGE_STRING_VALUE
, 0},
5599 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5600 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5601 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5602 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
5603 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
5604 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5605 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5606 {":relief", IMAGE_INTEGER_VALUE
, 0},
5607 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5608 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5609 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5612 /* Structure describing the image type XBM. */
5614 static struct image_type xbm_type
=
5623 /* Tokens returned from xbm_scan. */
5632 /* Return non-zero if OBJECT is a valid XBM-type image specification.
5633 A valid specification is a list starting with the symbol `image'
5634 The rest of the list is a property list which must contain an
5637 If the specification specifies a file to load, it must contain
5638 an entry `:file FILENAME' where FILENAME is a string.
5640 If the specification is for a bitmap loaded from memory it must
5641 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
5642 WIDTH and HEIGHT are integers > 0. DATA may be:
5644 1. a string large enough to hold the bitmap data, i.e. it must
5645 have a size >= (WIDTH + 7) / 8 * HEIGHT
5647 2. a bool-vector of size >= WIDTH * HEIGHT
5649 3. a vector of strings or bool-vectors, one for each line of the
5652 4. A string containing an in-memory XBM file. WIDTH and HEIGHT
5653 may not be specified in this case because they are defined in the
5656 Both the file and data forms may contain the additional entries
5657 `:background COLOR' and `:foreground COLOR'. If not present,
5658 foreground and background of the frame on which the image is
5659 displayed is used. */
5662 xbm_image_p (object
)
5665 struct image_keyword kw
[XBM_LAST
];
5667 bcopy (xbm_format
, kw
, sizeof kw
);
5668 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
5671 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
5673 if (kw
[XBM_FILE
].count
)
5675 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
5678 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
5680 /* In-memory XBM file. */
5681 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
5689 /* Entries for `:width', `:height' and `:data' must be present. */
5690 if (!kw
[XBM_WIDTH
].count
5691 || !kw
[XBM_HEIGHT
].count
5692 || !kw
[XBM_DATA
].count
)
5695 data
= kw
[XBM_DATA
].value
;
5696 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
5697 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
5699 /* Check type of data, and width and height against contents of
5705 /* Number of elements of the vector must be >= height. */
5706 if (XVECTOR (data
)->size
< height
)
5709 /* Each string or bool-vector in data must be large enough
5710 for one line of the image. */
5711 for (i
= 0; i
< height
; ++i
)
5713 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
5718 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
5721 else if (BOOL_VECTOR_P (elt
))
5723 if (XBOOL_VECTOR (elt
)->size
< width
)
5730 else if (STRINGP (data
))
5733 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
5736 else if (BOOL_VECTOR_P (data
))
5738 if (XBOOL_VECTOR (data
)->size
< width
* height
)
5749 /* Scan a bitmap file. FP is the stream to read from. Value is
5750 either an enumerator from enum xbm_token, or a character for a
5751 single-character token, or 0 at end of file. If scanning an
5752 identifier, store the lexeme of the identifier in SVAL. If
5753 scanning a number, store its value in *IVAL. */
5756 xbm_scan (s
, end
, sval
, ival
)
5765 /* Skip white space. */
5766 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5771 else if (isdigit (c
))
5773 int value
= 0, digit
;
5775 if (c
== '0' && *s
< end
)
5778 if (c
== 'x' || c
== 'X')
5785 else if (c
>= 'a' && c
<= 'f')
5786 digit
= c
- 'a' + 10;
5787 else if (c
>= 'A' && c
<= 'F')
5788 digit
= c
- 'A' + 10;
5791 value
= 16 * value
+ digit
;
5794 else if (isdigit (c
))
5798 && (c
= *(*s
)++, isdigit (c
)))
5799 value
= 8 * value
+ c
- '0';
5806 && (c
= *(*s
)++, isdigit (c
)))
5807 value
= 10 * value
+ c
- '0';
5815 else if (isalpha (c
) || c
== '_')
5819 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
5826 else if (c
== '/' && **s
== '*')
5828 /* C-style comment. */
5830 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
5843 /* Replacement for XReadBitmapFileData which isn't available under old
5844 X versions. CONTENTS is a pointer to a buffer to parse; END is the
5845 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
5846 the image. Return in *DATA the bitmap data allocated with xmalloc.
5847 Value is non-zero if successful. DATA null means just test if
5848 CONTENTS looks like an in-memory XBM file. */
5851 xbm_read_bitmap_data (contents
, end
, width
, height
, data
)
5852 char *contents
, *end
;
5853 int *width
, *height
;
5854 unsigned char **data
;
5857 char buffer
[BUFSIZ
];
5860 int bytes_per_line
, i
, nbytes
;
5866 LA1 = xbm_scan (&s, end, buffer, &value)
5868 #define expect(TOKEN) \
5869 if (LA1 != (TOKEN)) \
5874 #define expect_ident(IDENT) \
5875 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
5880 *width
= *height
= -1;
5883 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
5885 /* Parse defines for width, height and hot-spots. */
5889 expect_ident ("define");
5890 expect (XBM_TK_IDENT
);
5892 if (LA1
== XBM_TK_NUMBER
);
5894 char *p
= strrchr (buffer
, '_');
5895 p
= p
? p
+ 1 : buffer
;
5896 if (strcmp (p
, "width") == 0)
5898 else if (strcmp (p
, "height") == 0)
5901 expect (XBM_TK_NUMBER
);
5904 if (*width
< 0 || *height
< 0)
5906 else if (data
== NULL
)
5909 /* Parse bits. Must start with `static'. */
5910 expect_ident ("static");
5911 if (LA1
== XBM_TK_IDENT
)
5913 if (strcmp (buffer
, "unsigned") == 0)
5916 expect_ident ("char");
5918 else if (strcmp (buffer
, "short") == 0)
5922 if (*width
% 16 && *width
% 16 < 9)
5925 else if (strcmp (buffer
, "char") == 0)
5933 expect (XBM_TK_IDENT
);
5939 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
5940 nbytes
= bytes_per_line
* *height
;
5941 p
= *data
= (char *) xmalloc (nbytes
);
5945 for (i
= 0; i
< nbytes
; i
+= 2)
5948 expect (XBM_TK_NUMBER
);
5951 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
5954 if (LA1
== ',' || LA1
== '}')
5962 for (i
= 0; i
< nbytes
; ++i
)
5965 expect (XBM_TK_NUMBER
);
5969 if (LA1
== ',' || LA1
== '}')
5994 /* Load XBM image IMG which will be displayed on frame F from buffer
5995 CONTENTS. END is the end of the buffer. Value is non-zero if
5999 xbm_load_image (f
, img
, contents
, end
)
6002 char *contents
, *end
;
6005 unsigned char *data
;
6008 rc
= xbm_read_bitmap_data (contents
, end
, &img
->width
, &img
->height
, &data
);
6011 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6012 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6013 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6016 xassert (img
->width
> 0 && img
->height
> 0);
6018 /* Get foreground and background colors, maybe allocate colors. */
6019 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
6021 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
6022 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
6025 background
= x_alloc_image_color (f
, img
, value
, background
);
6026 img
->background
= background
;
6027 img
->background_valid
= 1;
6031 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
6034 img
->width
, img
->height
,
6035 foreground
, background
,
6039 if (img
->pixmap
== None
)
6041 x_clear_image (f
, img
);
6042 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
6048 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6054 /* Value is non-zero if DATA looks like an in-memory XBM file. */
6061 return (STRINGP (data
)
6062 && xbm_read_bitmap_data (SDATA (data
),
6069 /* Fill image IMG which is used on frame F with pixmap data. Value is
6070 non-zero if successful. */
6078 Lisp_Object file_name
;
6080 xassert (xbm_image_p (img
->spec
));
6082 /* If IMG->spec specifies a file name, create a non-file spec from it. */
6083 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
6084 if (STRINGP (file_name
))
6089 struct gcpro gcpro1
;
6091 file
= x_find_image_file (file_name
);
6093 if (!STRINGP (file
))
6095 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
6100 contents
= slurp_file (SDATA (file
), &size
);
6101 if (contents
== NULL
)
6103 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6108 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
6113 struct image_keyword fmt
[XBM_LAST
];
6116 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6117 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6120 int in_memory_file_p
= 0;
6122 /* See if data looks like an in-memory XBM file. */
6123 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6124 in_memory_file_p
= xbm_file_p (data
);
6126 /* Parse the image specification. */
6127 bcopy (xbm_format
, fmt
, sizeof fmt
);
6128 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
6131 /* Get specified width, and height. */
6132 if (!in_memory_file_p
)
6134 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
6135 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
6136 xassert (img
->width
> 0 && img
->height
> 0);
6139 /* Get foreground and background colors, maybe allocate colors. */
6140 if (fmt
[XBM_FOREGROUND
].count
6141 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
6142 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
6144 if (fmt
[XBM_BACKGROUND
].count
6145 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
6146 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
6149 if (in_memory_file_p
)
6150 success_p
= xbm_load_image (f
, img
, SDATA (data
),
6159 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
6161 p
= bits
= (char *) alloca (nbytes
* img
->height
);
6162 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
6164 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
6166 bcopy (SDATA (line
), p
, nbytes
);
6168 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
6171 else if (STRINGP (data
))
6172 bits
= SDATA (data
);
6174 bits
= XBOOL_VECTOR (data
)->data
;
6176 /* Create the pixmap. */
6177 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6179 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
6182 img
->width
, img
->height
,
6183 foreground
, background
,
6189 image_error ("Unable to create pixmap for XBM image `%s'",
6191 x_clear_image (f
, img
);
6201 /***********************************************************************
6203 ***********************************************************************/
6207 static int xpm_image_p
P_ ((Lisp_Object object
));
6208 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
6209 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
6211 #include "X11/xpm.h"
6213 /* The symbol `xpm' identifying XPM-format images. */
6217 /* Indices of image specification fields in xpm_format, below. */
6219 enum xpm_keyword_index
6235 /* Vector of image_keyword structures describing the format
6236 of valid XPM image specifications. */
6238 static struct image_keyword xpm_format
[XPM_LAST
] =
6240 {":type", IMAGE_SYMBOL_VALUE
, 1},
6241 {":file", IMAGE_STRING_VALUE
, 0},
6242 {":data", IMAGE_STRING_VALUE
, 0},
6243 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6244 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6245 {":relief", IMAGE_INTEGER_VALUE
, 0},
6246 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6247 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6248 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6249 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6250 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6253 /* Structure describing the image type XBM. */
6255 static struct image_type xpm_type
=
6265 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
6266 functions for allocating image colors. Our own functions handle
6267 color allocation failures more gracefully than the ones on the XPM
6270 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
6271 #define ALLOC_XPM_COLORS
6274 #ifdef ALLOC_XPM_COLORS
6276 static void xpm_init_color_cache
P_ ((struct frame
*, XpmAttributes
*));
6277 static void xpm_free_color_cache
P_ ((void));
6278 static int xpm_lookup_color
P_ ((struct frame
*, char *, XColor
*));
6279 static int xpm_color_bucket
P_ ((char *));
6280 static struct xpm_cached_color
*xpm_cache_color
P_ ((struct frame
*, char *,
6283 /* An entry in a hash table used to cache color definitions of named
6284 colors. This cache is necessary to speed up XPM image loading in
6285 case we do color allocations ourselves. Without it, we would need
6286 a call to XParseColor per pixel in the image. */
6288 struct xpm_cached_color
6290 /* Next in collision chain. */
6291 struct xpm_cached_color
*next
;
6293 /* Color definition (RGB and pixel color). */
6300 /* The hash table used for the color cache, and its bucket vector
6303 #define XPM_COLOR_CACHE_BUCKETS 1001
6304 struct xpm_cached_color
**xpm_color_cache
;
6306 /* Initialize the color cache. */
6309 xpm_init_color_cache (f
, attrs
)
6311 XpmAttributes
*attrs
;
6313 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
6314 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
6315 memset (xpm_color_cache
, 0, nbytes
);
6316 init_color_table ();
6318 if (attrs
->valuemask
& XpmColorSymbols
)
6323 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
6324 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6325 attrs
->colorsymbols
[i
].value
, &color
))
6327 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
6329 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
6335 /* Free the color cache. */
6338 xpm_free_color_cache ()
6340 struct xpm_cached_color
*p
, *next
;
6343 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
6344 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
6350 xfree (xpm_color_cache
);
6351 xpm_color_cache
= NULL
;
6352 free_color_table ();
6356 /* Return the bucket index for color named COLOR_NAME in the color
6360 xpm_color_bucket (color_name
)
6366 for (s
= color_name
; *s
; ++s
)
6368 return h
%= XPM_COLOR_CACHE_BUCKETS
;
6372 /* On frame F, cache values COLOR for color with name COLOR_NAME.
6373 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
6376 static struct xpm_cached_color
*
6377 xpm_cache_color (f
, color_name
, color
, bucket
)
6384 struct xpm_cached_color
*p
;
6387 bucket
= xpm_color_bucket (color_name
);
6389 nbytes
= sizeof *p
+ strlen (color_name
);
6390 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
6391 strcpy (p
->name
, color_name
);
6393 p
->next
= xpm_color_cache
[bucket
];
6394 xpm_color_cache
[bucket
] = p
;
6399 /* Look up color COLOR_NAME for frame F in the color cache. If found,
6400 return the cached definition in *COLOR. Otherwise, make a new
6401 entry in the cache and allocate the color. Value is zero if color
6402 allocation failed. */
6405 xpm_lookup_color (f
, color_name
, color
)
6410 struct xpm_cached_color
*p
;
6411 int h
= xpm_color_bucket (color_name
);
6413 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
6414 if (strcmp (p
->name
, color_name
) == 0)
6419 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6422 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
6424 p
= xpm_cache_color (f
, color_name
, color
, h
);
6426 /* You get `opaque' at least from ImageMagick converting pbm to xpm
6427 with transparency, and it's useful. */
6428 else if (strcmp ("opaque", color_name
) == 0)
6430 bzero (color
, sizeof (XColor
)); /* Is this necessary/correct? */
6431 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
6432 p
= xpm_cache_color (f
, color_name
, color
, h
);
6439 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
6440 CLOSURE is a pointer to the frame on which we allocate the
6441 color. Return in *COLOR the allocated color. Value is non-zero
6445 xpm_alloc_color (dpy
, cmap
, color_name
, color
, closure
)
6452 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
6456 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
6457 is a pointer to the frame on which we allocate the color. Value is
6458 non-zero if successful. */
6461 xpm_free_colors (dpy
, cmap
, pixels
, npixels
, closure
)
6471 #endif /* ALLOC_XPM_COLORS */
6474 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
6475 for XPM images. Such a list must consist of conses whose car and
6479 xpm_valid_color_symbols_p (color_symbols
)
6480 Lisp_Object color_symbols
;
6482 while (CONSP (color_symbols
))
6484 Lisp_Object sym
= XCAR (color_symbols
);
6486 || !STRINGP (XCAR (sym
))
6487 || !STRINGP (XCDR (sym
)))
6489 color_symbols
= XCDR (color_symbols
);
6492 return NILP (color_symbols
);
6496 /* Value is non-zero if OBJECT is a valid XPM image specification. */
6499 xpm_image_p (object
)
6502 struct image_keyword fmt
[XPM_LAST
];
6503 bcopy (xpm_format
, fmt
, sizeof fmt
);
6504 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
6505 /* Either `:file' or `:data' must be present. */
6506 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
6507 /* Either no `:color-symbols' or it's a list of conses
6508 whose car and cdr are strings. */
6509 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
6510 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
6514 /* Load image IMG which will be displayed on frame F. Value is
6515 non-zero if successful. */
6523 XpmAttributes attrs
;
6524 Lisp_Object specified_file
, color_symbols
;
6526 /* Configure the XPM lib. Use the visual of frame F. Allocate
6527 close colors. Return colors allocated. */
6528 bzero (&attrs
, sizeof attrs
);
6529 attrs
.visual
= FRAME_X_VISUAL (f
);
6530 attrs
.colormap
= FRAME_X_COLORMAP (f
);
6531 attrs
.valuemask
|= XpmVisual
;
6532 attrs
.valuemask
|= XpmColormap
;
6534 #ifdef ALLOC_XPM_COLORS
6535 /* Allocate colors with our own functions which handle
6536 failing color allocation more gracefully. */
6537 attrs
.color_closure
= f
;
6538 attrs
.alloc_color
= xpm_alloc_color
;
6539 attrs
.free_colors
= xpm_free_colors
;
6540 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
6541 #else /* not ALLOC_XPM_COLORS */
6542 /* Let the XPM lib allocate colors. */
6543 attrs
.valuemask
|= XpmReturnAllocPixels
;
6544 #ifdef XpmAllocCloseColors
6545 attrs
.alloc_close_colors
= 1;
6546 attrs
.valuemask
|= XpmAllocCloseColors
;
6547 #else /* not XpmAllocCloseColors */
6548 attrs
.closeness
= 600;
6549 attrs
.valuemask
|= XpmCloseness
;
6550 #endif /* not XpmAllocCloseColors */
6551 #endif /* ALLOC_XPM_COLORS */
6553 /* If image specification contains symbolic color definitions, add
6554 these to `attrs'. */
6555 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
6556 if (CONSP (color_symbols
))
6559 XpmColorSymbol
*xpm_syms
;
6562 attrs
.valuemask
|= XpmColorSymbols
;
6564 /* Count number of symbols. */
6565 attrs
.numsymbols
= 0;
6566 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
6569 /* Allocate an XpmColorSymbol array. */
6570 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
6571 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
6572 bzero (xpm_syms
, size
);
6573 attrs
.colorsymbols
= xpm_syms
;
6575 /* Fill the color symbol array. */
6576 for (tail
= color_symbols
, i
= 0;
6578 ++i
, tail
= XCDR (tail
))
6580 Lisp_Object name
= XCAR (XCAR (tail
));
6581 Lisp_Object color
= XCDR (XCAR (tail
));
6582 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
6583 strcpy (xpm_syms
[i
].name
, SDATA (name
));
6584 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
6585 strcpy (xpm_syms
[i
].value
, SDATA (color
));
6589 /* Create a pixmap for the image, either from a file, or from a
6590 string buffer containing data in the same format as an XPM file. */
6591 #ifdef ALLOC_XPM_COLORS
6592 xpm_init_color_cache (f
, &attrs
);
6595 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6596 if (STRINGP (specified_file
))
6598 Lisp_Object file
= x_find_image_file (specified_file
);
6599 if (!STRINGP (file
))
6601 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6605 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6606 SDATA (file
), &img
->pixmap
, &img
->mask
,
6611 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
6612 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6614 &img
->pixmap
, &img
->mask
,
6618 if (rc
== XpmSuccess
)
6620 #ifdef ALLOC_XPM_COLORS
6621 img
->colors
= colors_in_color_table (&img
->ncolors
);
6622 #else /* not ALLOC_XPM_COLORS */
6625 img
->ncolors
= attrs
.nalloc_pixels
;
6626 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
6627 * sizeof *img
->colors
);
6628 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
6630 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
6631 #ifdef DEBUG_X_COLORS
6632 register_color (img
->colors
[i
]);
6635 #endif /* not ALLOC_XPM_COLORS */
6637 img
->width
= attrs
.width
;
6638 img
->height
= attrs
.height
;
6639 xassert (img
->width
> 0 && img
->height
> 0);
6641 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
6642 XpmFreeAttributes (&attrs
);
6649 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
6652 case XpmFileInvalid
:
6653 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
6657 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
6660 case XpmColorFailed
:
6661 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
6665 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
6670 #ifdef ALLOC_XPM_COLORS
6671 xpm_free_color_cache ();
6673 return rc
== XpmSuccess
;
6676 #endif /* HAVE_XPM != 0 */
6679 /***********************************************************************
6681 ***********************************************************************/
6683 /* An entry in the color table mapping an RGB color to a pixel color. */
6688 unsigned long pixel
;
6690 /* Next in color table collision list. */
6691 struct ct_color
*next
;
6694 /* The bucket vector size to use. Must be prime. */
6698 /* Value is a hash of the RGB color given by R, G, and B. */
6700 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
6702 /* The color hash table. */
6704 struct ct_color
**ct_table
;
6706 /* Number of entries in the color table. */
6708 int ct_colors_allocated
;
6710 /* Initialize the color table. */
6715 int size
= CT_SIZE
* sizeof (*ct_table
);
6716 ct_table
= (struct ct_color
**) xmalloc (size
);
6717 bzero (ct_table
, size
);
6718 ct_colors_allocated
= 0;
6722 /* Free memory associated with the color table. */
6728 struct ct_color
*p
, *next
;
6730 for (i
= 0; i
< CT_SIZE
; ++i
)
6731 for (p
= ct_table
[i
]; p
; p
= next
)
6742 /* Value is a pixel color for RGB color R, G, B on frame F. If an
6743 entry for that color already is in the color table, return the
6744 pixel color of that entry. Otherwise, allocate a new color for R,
6745 G, B, and make an entry in the color table. */
6747 static unsigned long
6748 lookup_rgb_color (f
, r
, g
, b
)
6752 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
6753 int i
= hash
% CT_SIZE
;
6755 struct x_display_info
*dpyinfo
;
6757 /* Handle TrueColor visuals specially, which improves performance by
6758 two orders of magnitude. Freeing colors on TrueColor visuals is
6759 a nop, and pixel colors specify RGB values directly. See also
6760 the Xlib spec, chapter 3.1. */
6761 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6762 if (dpyinfo
->red_bits
> 0)
6764 unsigned long pr
, pg
, pb
;
6766 /* Apply gamma-correction like normal color allocation does. */
6770 color
.red
= r
, color
.green
= g
, color
.blue
= b
;
6771 gamma_correct (f
, &color
);
6772 r
= color
.red
, g
= color
.green
, b
= color
.blue
;
6775 /* Scale down RGB values to the visual's bits per RGB, and shift
6776 them to the right position in the pixel color. Note that the
6777 original RGB values are 16-bit values, as usual in X. */
6778 pr
= (r
>> (16 - dpyinfo
->red_bits
)) << dpyinfo
->red_offset
;
6779 pg
= (g
>> (16 - dpyinfo
->green_bits
)) << dpyinfo
->green_offset
;
6780 pb
= (b
>> (16 - dpyinfo
->blue_bits
)) << dpyinfo
->blue_offset
;
6782 /* Assemble the pixel color. */
6783 return pr
| pg
| pb
;
6786 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6787 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
6800 cmap
= FRAME_X_COLORMAP (f
);
6801 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6805 ++ct_colors_allocated
;
6807 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6811 p
->pixel
= color
.pixel
;
6812 p
->next
= ct_table
[i
];
6816 return FRAME_FOREGROUND_PIXEL (f
);
6823 /* Look up pixel color PIXEL which is used on frame F in the color
6824 table. If not already present, allocate it. Value is PIXEL. */
6826 static unsigned long
6827 lookup_pixel_color (f
, pixel
)
6829 unsigned long pixel
;
6831 int i
= pixel
% CT_SIZE
;
6834 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6835 if (p
->pixel
== pixel
)
6844 cmap
= FRAME_X_COLORMAP (f
);
6845 color
.pixel
= pixel
;
6846 x_query_color (f
, &color
);
6847 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6851 ++ct_colors_allocated
;
6853 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6858 p
->next
= ct_table
[i
];
6862 return FRAME_FOREGROUND_PIXEL (f
);
6869 /* Value is a vector of all pixel colors contained in the color table,
6870 allocated via xmalloc. Set *N to the number of colors. */
6872 static unsigned long *
6873 colors_in_color_table (n
)
6878 unsigned long *colors
;
6880 if (ct_colors_allocated
== 0)
6887 colors
= (unsigned long *) xmalloc (ct_colors_allocated
6889 *n
= ct_colors_allocated
;
6891 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
6892 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6893 colors
[j
++] = p
->pixel
;
6901 /***********************************************************************
6903 ***********************************************************************/
6905 static XColor
*x_to_xcolors
P_ ((struct frame
*, struct image
*, int));
6906 static void x_from_xcolors
P_ ((struct frame
*, struct image
*, XColor
*));
6907 static void x_detect_edges
P_ ((struct frame
*, struct image
*, int[9], int));
6909 /* Non-zero means draw a cross on images having `:conversion
6912 int cross_disabled_images
;
6914 /* Edge detection matrices for different edge-detection
6917 static int emboss_matrix
[9] = {
6919 2, -1, 0, /* y - 1 */
6921 0, 1, -2 /* y + 1 */
6924 static int laplace_matrix
[9] = {
6926 1, 0, 0, /* y - 1 */
6928 0, 0, -1 /* y + 1 */
6931 /* Value is the intensity of the color whose red/green/blue values
6934 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
6937 /* On frame F, return an array of XColor structures describing image
6938 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
6939 non-zero means also fill the red/green/blue members of the XColor
6940 structures. Value is a pointer to the array of XColors structures,
6941 allocated with xmalloc; it must be freed by the caller. */
6944 x_to_xcolors (f
, img
, rgb_p
)
6953 colors
= (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *colors
);
6955 /* Get the X image IMG->pixmap. */
6956 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
6957 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
6959 /* Fill the `pixel' members of the XColor array. I wished there
6960 were an easy and portable way to circumvent XGetPixel. */
6962 for (y
= 0; y
< img
->height
; ++y
)
6966 for (x
= 0; x
< img
->width
; ++x
, ++p
)
6967 p
->pixel
= XGetPixel (ximg
, x
, y
);
6970 x_query_colors (f
, row
, img
->width
);
6973 XDestroyImage (ximg
);
6978 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
6979 RGB members are set. F is the frame on which this all happens.
6980 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
6983 x_from_xcolors (f
, img
, colors
)
6993 init_color_table ();
6995 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
6998 for (y
= 0; y
< img
->height
; ++y
)
6999 for (x
= 0; x
< img
->width
; ++x
, ++p
)
7001 unsigned long pixel
;
7002 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
7003 XPutPixel (oimg
, x
, y
, pixel
);
7007 x_clear_image_1 (f
, img
, 1, 0, 1);
7009 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
7010 x_destroy_x_image (oimg
);
7011 img
->pixmap
= pixmap
;
7012 img
->colors
= colors_in_color_table (&img
->ncolors
);
7013 free_color_table ();
7017 /* On frame F, perform edge-detection on image IMG.
7019 MATRIX is a nine-element array specifying the transformation
7020 matrix. See emboss_matrix for an example.
7022 COLOR_ADJUST is a color adjustment added to each pixel of the
7026 x_detect_edges (f
, img
, matrix
, color_adjust
)
7029 int matrix
[9], color_adjust
;
7031 XColor
*colors
= x_to_xcolors (f
, img
, 1);
7035 for (i
= sum
= 0; i
< 9; ++i
)
7036 sum
+= abs (matrix
[i
]);
7038 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
7040 new = (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *new);
7042 for (y
= 0; y
< img
->height
; ++y
)
7044 p
= COLOR (new, 0, y
);
7045 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7046 p
= COLOR (new, img
->width
- 1, y
);
7047 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7050 for (x
= 1; x
< img
->width
- 1; ++x
)
7052 p
= COLOR (new, x
, 0);
7053 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7054 p
= COLOR (new, x
, img
->height
- 1);
7055 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7058 for (y
= 1; y
< img
->height
- 1; ++y
)
7060 p
= COLOR (new, 1, y
);
7062 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
7064 int r
, g
, b
, y1
, x1
;
7067 for (y1
= y
- 1; y1
< y
+ 2; ++y1
)
7068 for (x1
= x
- 1; x1
< x
+ 2; ++x1
, ++i
)
7071 XColor
*t
= COLOR (colors
, x1
, y1
);
7072 r
+= matrix
[i
] * t
->red
;
7073 g
+= matrix
[i
] * t
->green
;
7074 b
+= matrix
[i
] * t
->blue
;
7077 r
= (r
/ sum
+ color_adjust
) & 0xffff;
7078 g
= (g
/ sum
+ color_adjust
) & 0xffff;
7079 b
= (b
/ sum
+ color_adjust
) & 0xffff;
7080 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
7085 x_from_xcolors (f
, img
, new);
7091 /* Perform the pre-defined `emboss' edge-detection on image IMG
7099 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
7103 /* Perform the pre-defined `laplace' edge-detection on image IMG
7111 x_detect_edges (f
, img
, laplace_matrix
, 45000);
7115 /* Perform edge-detection on image IMG on frame F, with specified
7116 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
7118 MATRIX must be either
7120 - a list of at least 9 numbers in row-major form
7121 - a vector of at least 9 numbers
7123 COLOR_ADJUST nil means use a default; otherwise it must be a
7127 x_edge_detection (f
, img
, matrix
, color_adjust
)
7130 Lisp_Object matrix
, color_adjust
;
7138 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
7139 ++i
, matrix
= XCDR (matrix
))
7140 trans
[i
] = XFLOATINT (XCAR (matrix
));
7142 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
7144 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
7145 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
7148 if (NILP (color_adjust
))
7149 color_adjust
= make_number (0xffff / 2);
7151 if (i
== 9 && NUMBERP (color_adjust
))
7152 x_detect_edges (f
, img
, trans
, (int) XFLOATINT (color_adjust
));
7156 /* Transform image IMG on frame F so that it looks disabled. */
7159 x_disable_image (f
, img
)
7163 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7165 if (dpyinfo
->n_planes
>= 2)
7167 /* Color (or grayscale). Convert to gray, and equalize. Just
7168 drawing such images with a stipple can look very odd, so
7169 we're using this method instead. */
7170 XColor
*colors
= x_to_xcolors (f
, img
, 1);
7172 const int h
= 15000;
7173 const int l
= 30000;
7175 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
7179 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
7180 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
7181 p
->red
= p
->green
= p
->blue
= i2
;
7184 x_from_xcolors (f
, img
, colors
);
7187 /* Draw a cross over the disabled image, if we must or if we
7189 if (dpyinfo
->n_planes
< 2 || cross_disabled_images
)
7191 Display
*dpy
= FRAME_X_DISPLAY (f
);
7194 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
7195 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
7196 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
7197 img
->width
- 1, img
->height
- 1);
7198 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
7204 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
7205 XSetForeground (dpy
, gc
, WHITE_PIX_DEFAULT (f
));
7206 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
7207 img
->width
- 1, img
->height
- 1);
7208 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
7216 /* Build a mask for image IMG which is used on frame F. FILE is the
7217 name of an image file, for error messages. HOW determines how to
7218 determine the background color of IMG. If it is a list '(R G B)',
7219 with R, G, and B being integers >= 0, take that as the color of the
7220 background. Otherwise, determine the background color of IMG
7221 heuristically. Value is non-zero if successful. */
7224 x_build_heuristic_mask (f
, img
, how
)
7229 Display
*dpy
= FRAME_X_DISPLAY (f
);
7230 XImage
*ximg
, *mask_img
;
7231 int x
, y
, rc
, use_img_background
;
7232 unsigned long bg
= 0;
7236 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
7238 img
->background_transparent_valid
= 0;
7241 /* Create an image and pixmap serving as mask. */
7242 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
7243 &mask_img
, &img
->mask
);
7247 /* Get the X image of IMG->pixmap. */
7248 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
7251 /* Determine the background color of ximg. If HOW is `(R G B)'
7252 take that as color. Otherwise, use the image's background color. */
7253 use_img_background
= 1;
7259 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
7261 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
7265 if (i
== 3 && NILP (how
))
7267 char color_name
[30];
7268 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
7269 bg
= x_alloc_image_color (f
, img
, build_string (color_name
), 0);
7270 use_img_background
= 0;
7274 if (use_img_background
)
7275 bg
= four_corners_best (ximg
, img
->width
, img
->height
);
7277 /* Set all bits in mask_img to 1 whose color in ximg is different
7278 from the background color bg. */
7279 for (y
= 0; y
< img
->height
; ++y
)
7280 for (x
= 0; x
< img
->width
; ++x
)
7281 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
7283 /* Fill in the background_transparent field while we have the mask handy. */
7284 image_background_transparent (img
, f
, mask_img
);
7286 /* Put mask_img into img->mask. */
7287 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
7288 x_destroy_x_image (mask_img
);
7289 XDestroyImage (ximg
);
7296 /***********************************************************************
7297 PBM (mono, gray, color)
7298 ***********************************************************************/
7300 static int pbm_image_p
P_ ((Lisp_Object object
));
7301 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
7302 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
7304 /* The symbol `pbm' identifying images of this type. */
7308 /* Indices of image specification fields in gs_format, below. */
7310 enum pbm_keyword_index
7326 /* Vector of image_keyword structures describing the format
7327 of valid user-defined image specifications. */
7329 static struct image_keyword pbm_format
[PBM_LAST
] =
7331 {":type", IMAGE_SYMBOL_VALUE
, 1},
7332 {":file", IMAGE_STRING_VALUE
, 0},
7333 {":data", IMAGE_STRING_VALUE
, 0},
7334 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7335 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7336 {":relief", IMAGE_INTEGER_VALUE
, 0},
7337 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7338 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7339 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7340 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
7341 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7344 /* Structure describing the image type `pbm'. */
7346 static struct image_type pbm_type
=
7356 /* Return non-zero if OBJECT is a valid PBM image specification. */
7359 pbm_image_p (object
)
7362 struct image_keyword fmt
[PBM_LAST
];
7364 bcopy (pbm_format
, fmt
, sizeof fmt
);
7366 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
7369 /* Must specify either :data or :file. */
7370 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
7374 /* Scan a decimal number from *S and return it. Advance *S while
7375 reading the number. END is the end of the string. Value is -1 at
7379 pbm_scan_number (s
, end
)
7380 unsigned char **s
, *end
;
7382 int c
= 0, val
= -1;
7386 /* Skip white-space. */
7387 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
7392 /* Skip comment to end of line. */
7393 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
7396 else if (isdigit (c
))
7398 /* Read decimal number. */
7400 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
7401 val
= 10 * val
+ c
- '0';
7412 /* Load PBM image IMG for use on frame F. */
7420 int width
, height
, max_color_idx
= 0;
7422 Lisp_Object file
, specified_file
;
7423 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
7424 struct gcpro gcpro1
;
7425 unsigned char *contents
= NULL
;
7426 unsigned char *end
, *p
;
7429 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7433 if (STRINGP (specified_file
))
7435 file
= x_find_image_file (specified_file
);
7436 if (!STRINGP (file
))
7438 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7443 contents
= slurp_file (SDATA (file
), &size
);
7444 if (contents
== NULL
)
7446 image_error ("Error reading `%s'", file
, Qnil
);
7452 end
= contents
+ size
;
7457 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7459 end
= p
+ SBYTES (data
);
7462 /* Check magic number. */
7463 if (end
- p
< 2 || *p
++ != 'P')
7465 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7475 raw_p
= 0, type
= PBM_MONO
;
7479 raw_p
= 0, type
= PBM_GRAY
;
7483 raw_p
= 0, type
= PBM_COLOR
;
7487 raw_p
= 1, type
= PBM_MONO
;
7491 raw_p
= 1, type
= PBM_GRAY
;
7495 raw_p
= 1, type
= PBM_COLOR
;
7499 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7503 /* Read width, height, maximum color-component. Characters
7504 starting with `#' up to the end of a line are ignored. */
7505 width
= pbm_scan_number (&p
, end
);
7506 height
= pbm_scan_number (&p
, end
);
7508 if (type
!= PBM_MONO
)
7510 max_color_idx
= pbm_scan_number (&p
, end
);
7511 if (raw_p
&& max_color_idx
> 255)
7512 max_color_idx
= 255;
7517 || (type
!= PBM_MONO
&& max_color_idx
< 0))
7520 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7521 &ximg
, &img
->pixmap
))
7524 /* Initialize the color hash table. */
7525 init_color_table ();
7527 if (type
== PBM_MONO
)
7530 struct image_keyword fmt
[PBM_LAST
];
7531 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
7532 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
7534 /* Parse the image specification. */
7535 bcopy (pbm_format
, fmt
, sizeof fmt
);
7536 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
7538 /* Get foreground and background colors, maybe allocate colors. */
7539 if (fmt
[PBM_FOREGROUND
].count
7540 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
7541 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
7542 if (fmt
[PBM_BACKGROUND
].count
7543 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
7545 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
7546 img
->background
= bg
;
7547 img
->background_valid
= 1;
7550 for (y
= 0; y
< height
; ++y
)
7551 for (x
= 0; x
< width
; ++x
)
7561 g
= pbm_scan_number (&p
, end
);
7563 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
7568 for (y
= 0; y
< height
; ++y
)
7569 for (x
= 0; x
< width
; ++x
)
7573 if (type
== PBM_GRAY
)
7574 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
7583 r
= pbm_scan_number (&p
, end
);
7584 g
= pbm_scan_number (&p
, end
);
7585 b
= pbm_scan_number (&p
, end
);
7588 if (r
< 0 || g
< 0 || b
< 0)
7592 XDestroyImage (ximg
);
7593 image_error ("Invalid pixel value in image `%s'",
7598 /* RGB values are now in the range 0..max_color_idx.
7599 Scale this to the range 0..0xffff supported by X. */
7600 r
= (double) r
* 65535 / max_color_idx
;
7601 g
= (double) g
* 65535 / max_color_idx
;
7602 b
= (double) b
* 65535 / max_color_idx
;
7603 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7607 /* Store in IMG->colors the colors allocated for the image, and
7608 free the color table. */
7609 img
->colors
= colors_in_color_table (&img
->ncolors
);
7610 free_color_table ();
7612 /* Maybe fill in the background field while we have ximg handy. */
7613 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7614 IMAGE_BACKGROUND (img
, f
, ximg
);
7616 /* Put the image into a pixmap. */
7617 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7618 x_destroy_x_image (ximg
);
7621 img
->height
= height
;
7630 /***********************************************************************
7632 ***********************************************************************/
7636 #if defined HAVE_LIBPNG_PNG_H
7637 # include <libpng/png.h>
7642 /* Function prototypes. */
7644 static int png_image_p
P_ ((Lisp_Object object
));
7645 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
7647 /* The symbol `png' identifying images of this type. */
7651 /* Indices of image specification fields in png_format, below. */
7653 enum png_keyword_index
7668 /* Vector of image_keyword structures describing the format
7669 of valid user-defined image specifications. */
7671 static struct image_keyword png_format
[PNG_LAST
] =
7673 {":type", IMAGE_SYMBOL_VALUE
, 1},
7674 {":data", IMAGE_STRING_VALUE
, 0},
7675 {":file", IMAGE_STRING_VALUE
, 0},
7676 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7677 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7678 {":relief", IMAGE_INTEGER_VALUE
, 0},
7679 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7680 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7681 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7682 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7685 /* Structure describing the image type `png'. */
7687 static struct image_type png_type
=
7697 /* Return non-zero if OBJECT is a valid PNG image specification. */
7700 png_image_p (object
)
7703 struct image_keyword fmt
[PNG_LAST
];
7704 bcopy (png_format
, fmt
, sizeof fmt
);
7706 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
7709 /* Must specify either the :data or :file keyword. */
7710 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
7714 /* Error and warning handlers installed when the PNG library
7718 my_png_error (png_ptr
, msg
)
7719 png_struct
*png_ptr
;
7722 xassert (png_ptr
!= NULL
);
7723 image_error ("PNG error: %s", build_string (msg
), Qnil
);
7724 longjmp (png_ptr
->jmpbuf
, 1);
7729 my_png_warning (png_ptr
, msg
)
7730 png_struct
*png_ptr
;
7733 xassert (png_ptr
!= NULL
);
7734 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
7737 /* Memory source for PNG decoding. */
7739 struct png_memory_storage
7741 unsigned char *bytes
; /* The data */
7742 size_t len
; /* How big is it? */
7743 int index
; /* Where are we? */
7747 /* Function set as reader function when reading PNG image from memory.
7748 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
7749 bytes from the input to DATA. */
7752 png_read_from_memory (png_ptr
, data
, length
)
7753 png_structp png_ptr
;
7757 struct png_memory_storage
*tbr
7758 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
7760 if (length
> tbr
->len
- tbr
->index
)
7761 png_error (png_ptr
, "Read error");
7763 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
7764 tbr
->index
= tbr
->index
+ length
;
7767 /* Load PNG image IMG for use on frame F. Value is non-zero if
7775 Lisp_Object file
, specified_file
;
7776 Lisp_Object specified_data
;
7778 XImage
*ximg
, *mask_img
= NULL
;
7779 struct gcpro gcpro1
;
7780 png_struct
*png_ptr
= NULL
;
7781 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
7782 FILE *volatile fp
= NULL
;
7784 png_byte
* volatile pixels
= NULL
;
7785 png_byte
** volatile rows
= NULL
;
7786 png_uint_32 width
, height
;
7787 int bit_depth
, color_type
, interlace_type
;
7789 png_uint_32 row_bytes
;
7791 double screen_gamma
;
7792 struct png_memory_storage tbr
; /* Data to be read */
7794 /* Find out what file to load. */
7795 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7796 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7800 if (NILP (specified_data
))
7802 file
= x_find_image_file (specified_file
);
7803 if (!STRINGP (file
))
7805 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7810 /* Open the image file. */
7811 fp
= fopen (SDATA (file
), "rb");
7814 image_error ("Cannot open image file `%s'", file
, Qnil
);
7820 /* Check PNG signature. */
7821 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
7822 || !png_check_sig (sig
, sizeof sig
))
7824 image_error ("Not a PNG file: `%s'", file
, Qnil
);
7832 /* Read from memory. */
7833 tbr
.bytes
= SDATA (specified_data
);
7834 tbr
.len
= SBYTES (specified_data
);
7837 /* Check PNG signature. */
7838 if (tbr
.len
< sizeof sig
7839 || !png_check_sig (tbr
.bytes
, sizeof sig
))
7841 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
7846 /* Need to skip past the signature. */
7847 tbr
.bytes
+= sizeof (sig
);
7850 /* Initialize read and info structs for PNG lib. */
7851 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
7852 my_png_error
, my_png_warning
);
7855 if (fp
) fclose (fp
);
7860 info_ptr
= png_create_info_struct (png_ptr
);
7863 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
7864 if (fp
) fclose (fp
);
7869 end_info
= png_create_info_struct (png_ptr
);
7872 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
7873 if (fp
) fclose (fp
);
7878 /* Set error jump-back. We come back here when the PNG library
7879 detects an error. */
7880 if (setjmp (png_ptr
->jmpbuf
))
7884 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7887 if (fp
) fclose (fp
);
7892 /* Read image info. */
7893 if (!NILP (specified_data
))
7894 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
7896 png_init_io (png_ptr
, fp
);
7898 png_set_sig_bytes (png_ptr
, sizeof sig
);
7899 png_read_info (png_ptr
, info_ptr
);
7900 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
7901 &interlace_type
, NULL
, NULL
);
7903 /* If image contains simply transparency data, we prefer to
7904 construct a clipping mask. */
7905 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
7910 /* This function is easier to write if we only have to handle
7911 one data format: RGB or RGBA with 8 bits per channel. Let's
7912 transform other formats into that format. */
7914 /* Strip more than 8 bits per channel. */
7915 if (bit_depth
== 16)
7916 png_set_strip_16 (png_ptr
);
7918 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
7920 png_set_expand (png_ptr
);
7922 /* Convert grayscale images to RGB. */
7923 if (color_type
== PNG_COLOR_TYPE_GRAY
7924 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
7925 png_set_gray_to_rgb (png_ptr
);
7927 screen_gamma
= (f
->gamma
? 1 / f
->gamma
/ 0.45455 : 2.2);
7929 #if 0 /* Avoid double gamma correction for PNG images. */
7930 { /* Tell the PNG lib to handle gamma correction for us. */
7933 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
7934 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
7935 /* The libpng documentation says this is right in this case. */
7936 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7939 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
7940 /* Image contains gamma information. */
7941 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
7943 /* Use the standard default for the image gamma. */
7944 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7948 /* Handle alpha channel by combining the image with a background
7949 color. Do this only if a real alpha channel is supplied. For
7950 simple transparency, we prefer a clipping mask. */
7953 png_color_16
*image_bg
;
7954 Lisp_Object specified_bg
7955 = image_spec_value (img
->spec
, QCbackground
, NULL
);
7957 if (STRINGP (specified_bg
))
7958 /* The user specified `:background', use that. */
7961 if (x_defined_color (f
, SDATA (specified_bg
), &color
, 0))
7963 png_color_16 user_bg
;
7965 bzero (&user_bg
, sizeof user_bg
);
7966 user_bg
.red
= color
.red
;
7967 user_bg
.green
= color
.green
;
7968 user_bg
.blue
= color
.blue
;
7970 png_set_background (png_ptr
, &user_bg
,
7971 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7974 else if (png_get_bKGD (png_ptr
, info_ptr
, &image_bg
))
7975 /* Image contains a background color with which to
7976 combine the image. */
7977 png_set_background (png_ptr
, image_bg
,
7978 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
7981 /* Image does not contain a background color with which
7982 to combine the image data via an alpha channel. Use
7983 the frame's background instead. */
7986 png_color_16 frame_background
;
7988 cmap
= FRAME_X_COLORMAP (f
);
7989 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7990 x_query_color (f
, &color
);
7992 bzero (&frame_background
, sizeof frame_background
);
7993 frame_background
.red
= color
.red
;
7994 frame_background
.green
= color
.green
;
7995 frame_background
.blue
= color
.blue
;
7997 png_set_background (png_ptr
, &frame_background
,
7998 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
8002 /* Update info structure. */
8003 png_read_update_info (png_ptr
, info_ptr
);
8005 /* Get number of channels. Valid values are 1 for grayscale images
8006 and images with a palette, 2 for grayscale images with transparency
8007 information (alpha channel), 3 for RGB images, and 4 for RGB
8008 images with alpha channel, i.e. RGBA. If conversions above were
8009 sufficient we should only have 3 or 4 channels here. */
8010 channels
= png_get_channels (png_ptr
, info_ptr
);
8011 xassert (channels
== 3 || channels
== 4);
8013 /* Number of bytes needed for one row of the image. */
8014 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
8016 /* Allocate memory for the image. */
8017 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
8018 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
8019 for (i
= 0; i
< height
; ++i
)
8020 rows
[i
] = pixels
+ i
* row_bytes
;
8022 /* Read the entire image. */
8023 png_read_image (png_ptr
, rows
);
8024 png_read_end (png_ptr
, info_ptr
);
8031 /* Create the X image and pixmap. */
8032 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
8036 /* Create an image and pixmap serving as mask if the PNG image
8037 contains an alpha channel. */
8040 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
8041 &mask_img
, &img
->mask
))
8043 x_destroy_x_image (ximg
);
8044 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
8049 /* Fill the X image and mask from PNG data. */
8050 init_color_table ();
8052 for (y
= 0; y
< height
; ++y
)
8054 png_byte
*p
= rows
[y
];
8056 for (x
= 0; x
< width
; ++x
)
8063 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
8065 /* An alpha channel, aka mask channel, associates variable
8066 transparency with an image. Where other image formats
8067 support binary transparency---fully transparent or fully
8068 opaque---PNG allows up to 254 levels of partial transparency.
8069 The PNG library implements partial transparency by combining
8070 the image with a specified background color.
8072 I'm not sure how to handle this here nicely: because the
8073 background on which the image is displayed may change, for
8074 real alpha channel support, it would be necessary to create
8075 a new image for each possible background.
8077 What I'm doing now is that a mask is created if we have
8078 boolean transparency information. Otherwise I'm using
8079 the frame's background color to combine the image with. */
8084 XPutPixel (mask_img
, x
, y
, *p
> 0);
8090 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8091 /* Set IMG's background color from the PNG image, unless the user
8095 if (png_get_bKGD (png_ptr
, info_ptr
, &bg
))
8097 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
8098 img
->background_valid
= 1;
8102 /* Remember colors allocated for this image. */
8103 img
->colors
= colors_in_color_table (&img
->ncolors
);
8104 free_color_table ();
8107 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
8112 img
->height
= height
;
8114 /* Maybe fill in the background field while we have ximg handy. */
8115 IMAGE_BACKGROUND (img
, f
, ximg
);
8117 /* Put the image into the pixmap, then free the X image and its buffer. */
8118 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8119 x_destroy_x_image (ximg
);
8121 /* Same for the mask. */
8124 /* Fill in the background_transparent field while we have the mask
8126 image_background_transparent (img
, f
, mask_img
);
8128 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
8129 x_destroy_x_image (mask_img
);
8136 #endif /* HAVE_PNG != 0 */
8140 /***********************************************************************
8142 ***********************************************************************/
8146 /* Work around a warning about HAVE_STDLIB_H being redefined in
8148 #ifdef HAVE_STDLIB_H
8149 #define HAVE_STDLIB_H_1
8150 #undef HAVE_STDLIB_H
8151 #endif /* HAVE_STLIB_H */
8153 #include <jpeglib.h>
8157 #ifdef HAVE_STLIB_H_1
8158 #define HAVE_STDLIB_H 1
8161 static int jpeg_image_p
P_ ((Lisp_Object object
));
8162 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
8164 /* The symbol `jpeg' identifying images of this type. */
8168 /* Indices of image specification fields in gs_format, below. */
8170 enum jpeg_keyword_index
8179 JPEG_HEURISTIC_MASK
,
8185 /* Vector of image_keyword structures describing the format
8186 of valid user-defined image specifications. */
8188 static struct image_keyword jpeg_format
[JPEG_LAST
] =
8190 {":type", IMAGE_SYMBOL_VALUE
, 1},
8191 {":data", IMAGE_STRING_VALUE
, 0},
8192 {":file", IMAGE_STRING_VALUE
, 0},
8193 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8194 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8195 {":relief", IMAGE_INTEGER_VALUE
, 0},
8196 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8197 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8198 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8199 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8202 /* Structure describing the image type `jpeg'. */
8204 static struct image_type jpeg_type
=
8214 /* Return non-zero if OBJECT is a valid JPEG image specification. */
8217 jpeg_image_p (object
)
8220 struct image_keyword fmt
[JPEG_LAST
];
8222 bcopy (jpeg_format
, fmt
, sizeof fmt
);
8224 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
8227 /* Must specify either the :data or :file keyword. */
8228 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
8232 struct my_jpeg_error_mgr
8234 struct jpeg_error_mgr pub
;
8235 jmp_buf setjmp_buffer
;
8240 my_error_exit (cinfo
)
8243 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
8244 longjmp (mgr
->setjmp_buffer
, 1);
8248 /* Init source method for JPEG data source manager. Called by
8249 jpeg_read_header() before any data is actually read. See
8250 libjpeg.doc from the JPEG lib distribution. */
8253 our_init_source (cinfo
)
8254 j_decompress_ptr cinfo
;
8259 /* Fill input buffer method for JPEG data source manager. Called
8260 whenever more data is needed. We read the whole image in one step,
8261 so this only adds a fake end of input marker at the end. */
8264 our_fill_input_buffer (cinfo
)
8265 j_decompress_ptr cinfo
;
8267 /* Insert a fake EOI marker. */
8268 struct jpeg_source_mgr
*src
= cinfo
->src
;
8269 static JOCTET buffer
[2];
8271 buffer
[0] = (JOCTET
) 0xFF;
8272 buffer
[1] = (JOCTET
) JPEG_EOI
;
8274 src
->next_input_byte
= buffer
;
8275 src
->bytes_in_buffer
= 2;
8280 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
8281 is the JPEG data source manager. */
8284 our_skip_input_data (cinfo
, num_bytes
)
8285 j_decompress_ptr cinfo
;
8288 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8292 if (num_bytes
> src
->bytes_in_buffer
)
8293 ERREXIT (cinfo
, JERR_INPUT_EOF
);
8295 src
->bytes_in_buffer
-= num_bytes
;
8296 src
->next_input_byte
+= num_bytes
;
8301 /* Method to terminate data source. Called by
8302 jpeg_finish_decompress() after all data has been processed. */
8305 our_term_source (cinfo
)
8306 j_decompress_ptr cinfo
;
8311 /* Set up the JPEG lib for reading an image from DATA which contains
8312 LEN bytes. CINFO is the decompression info structure created for
8313 reading the image. */
8316 jpeg_memory_src (cinfo
, data
, len
)
8317 j_decompress_ptr cinfo
;
8321 struct jpeg_source_mgr
*src
;
8323 if (cinfo
->src
== NULL
)
8325 /* First time for this JPEG object? */
8326 cinfo
->src
= (struct jpeg_source_mgr
*)
8327 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
8328 sizeof (struct jpeg_source_mgr
));
8329 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8330 src
->next_input_byte
= data
;
8333 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8334 src
->init_source
= our_init_source
;
8335 src
->fill_input_buffer
= our_fill_input_buffer
;
8336 src
->skip_input_data
= our_skip_input_data
;
8337 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
8338 src
->term_source
= our_term_source
;
8339 src
->bytes_in_buffer
= len
;
8340 src
->next_input_byte
= data
;
8344 /* Load image IMG for use on frame F. Patterned after example.c
8345 from the JPEG lib. */
8352 struct jpeg_decompress_struct cinfo
;
8353 struct my_jpeg_error_mgr mgr
;
8354 Lisp_Object file
, specified_file
;
8355 Lisp_Object specified_data
;
8356 FILE * volatile fp
= NULL
;
8358 int row_stride
, x
, y
;
8359 XImage
*ximg
= NULL
;
8361 unsigned long *colors
;
8363 struct gcpro gcpro1
;
8365 /* Open the JPEG file. */
8366 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8367 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8371 if (NILP (specified_data
))
8373 file
= x_find_image_file (specified_file
);
8374 if (!STRINGP (file
))
8376 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8381 fp
= fopen (SDATA (file
), "r");
8384 image_error ("Cannot open `%s'", file
, Qnil
);
8390 /* Customize libjpeg's error handling to call my_error_exit when an
8391 error is detected. This function will perform a longjmp. */
8392 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
8393 mgr
.pub
.error_exit
= my_error_exit
;
8395 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
8399 /* Called from my_error_exit. Display a JPEG error. */
8400 char buffer
[JMSG_LENGTH_MAX
];
8401 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
8402 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
8403 build_string (buffer
));
8406 /* Close the input file and destroy the JPEG object. */
8408 fclose ((FILE *) fp
);
8409 jpeg_destroy_decompress (&cinfo
);
8411 /* If we already have an XImage, free that. */
8412 x_destroy_x_image (ximg
);
8414 /* Free pixmap and colors. */
8415 x_clear_image (f
, img
);
8421 /* Create the JPEG decompression object. Let it read from fp.
8422 Read the JPEG image header. */
8423 jpeg_create_decompress (&cinfo
);
8425 if (NILP (specified_data
))
8426 jpeg_stdio_src (&cinfo
, (FILE *) fp
);
8428 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
8429 SBYTES (specified_data
));
8431 jpeg_read_header (&cinfo
, TRUE
);
8433 /* Customize decompression so that color quantization will be used.
8434 Start decompression. */
8435 cinfo
.quantize_colors
= TRUE
;
8436 jpeg_start_decompress (&cinfo
);
8437 width
= img
->width
= cinfo
.output_width
;
8438 height
= img
->height
= cinfo
.output_height
;
8440 /* Create X image and pixmap. */
8441 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8442 longjmp (mgr
.setjmp_buffer
, 2);
8444 /* Allocate colors. When color quantization is used,
8445 cinfo.actual_number_of_colors has been set with the number of
8446 colors generated, and cinfo.colormap is a two-dimensional array
8447 of color indices in the range 0..cinfo.actual_number_of_colors.
8448 No more than 255 colors will be generated. */
8452 if (cinfo
.out_color_components
> 2)
8453 ir
= 0, ig
= 1, ib
= 2;
8454 else if (cinfo
.out_color_components
> 1)
8455 ir
= 0, ig
= 1, ib
= 0;
8457 ir
= 0, ig
= 0, ib
= 0;
8459 /* Use the color table mechanism because it handles colors that
8460 cannot be allocated nicely. Such colors will be replaced with
8461 a default color, and we don't have to care about which colors
8462 can be freed safely, and which can't. */
8463 init_color_table ();
8464 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
8467 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
8469 /* Multiply RGB values with 255 because X expects RGB values
8470 in the range 0..0xffff. */
8471 int r
= cinfo
.colormap
[ir
][i
] << 8;
8472 int g
= cinfo
.colormap
[ig
][i
] << 8;
8473 int b
= cinfo
.colormap
[ib
][i
] << 8;
8474 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8477 /* Remember those colors actually allocated. */
8478 img
->colors
= colors_in_color_table (&img
->ncolors
);
8479 free_color_table ();
8483 row_stride
= width
* cinfo
.output_components
;
8484 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
8486 for (y
= 0; y
< height
; ++y
)
8488 jpeg_read_scanlines (&cinfo
, buffer
, 1);
8489 for (x
= 0; x
< cinfo
.output_width
; ++x
)
8490 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
8494 jpeg_finish_decompress (&cinfo
);
8495 jpeg_destroy_decompress (&cinfo
);
8497 fclose ((FILE *) fp
);
8499 /* Maybe fill in the background field while we have ximg handy. */
8500 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8501 IMAGE_BACKGROUND (img
, f
, ximg
);
8503 /* Put the image into the pixmap. */
8504 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8505 x_destroy_x_image (ximg
);
8510 #endif /* HAVE_JPEG */
8514 /***********************************************************************
8516 ***********************************************************************/
8522 static int tiff_image_p
P_ ((Lisp_Object object
));
8523 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
8525 /* The symbol `tiff' identifying images of this type. */
8529 /* Indices of image specification fields in tiff_format, below. */
8531 enum tiff_keyword_index
8540 TIFF_HEURISTIC_MASK
,
8546 /* Vector of image_keyword structures describing the format
8547 of valid user-defined image specifications. */
8549 static struct image_keyword tiff_format
[TIFF_LAST
] =
8551 {":type", IMAGE_SYMBOL_VALUE
, 1},
8552 {":data", IMAGE_STRING_VALUE
, 0},
8553 {":file", IMAGE_STRING_VALUE
, 0},
8554 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8555 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8556 {":relief", IMAGE_INTEGER_VALUE
, 0},
8557 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8558 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8559 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8560 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8563 /* Structure describing the image type `tiff'. */
8565 static struct image_type tiff_type
=
8575 /* Return non-zero if OBJECT is a valid TIFF image specification. */
8578 tiff_image_p (object
)
8581 struct image_keyword fmt
[TIFF_LAST
];
8582 bcopy (tiff_format
, fmt
, sizeof fmt
);
8584 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
8587 /* Must specify either the :data or :file keyword. */
8588 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
8592 /* Reading from a memory buffer for TIFF images Based on the PNG
8593 memory source, but we have to provide a lot of extra functions.
8596 We really only need to implement read and seek, but I am not
8597 convinced that the TIFF library is smart enough not to destroy
8598 itself if we only hand it the function pointers we need to
8603 unsigned char *bytes
;
8611 tiff_read_from_memory (data
, buf
, size
)
8616 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8618 if (size
> src
->len
- src
->index
)
8620 bcopy (src
->bytes
+ src
->index
, buf
, size
);
8627 tiff_write_from_memory (data
, buf
, size
)
8637 tiff_seek_in_memory (data
, off
, whence
)
8642 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8647 case SEEK_SET
: /* Go from beginning of source. */
8651 case SEEK_END
: /* Go from end of source. */
8652 idx
= src
->len
+ off
;
8655 case SEEK_CUR
: /* Go from current position. */
8656 idx
= src
->index
+ off
;
8659 default: /* Invalid `whence'. */
8663 if (idx
> src
->len
|| idx
< 0)
8672 tiff_close_memory (data
)
8681 tiff_mmap_memory (data
, pbase
, psize
)
8686 /* It is already _IN_ memory. */
8692 tiff_unmap_memory (data
, base
, size
)
8697 /* We don't need to do this. */
8702 tiff_size_of_memory (data
)
8705 return ((tiff_memory_source
*) data
)->len
;
8710 tiff_error_handler (title
, format
, ap
)
8711 const char *title
, *format
;
8717 len
= sprintf (buf
, "TIFF error: %s ", title
);
8718 vsprintf (buf
+ len
, format
, ap
);
8719 add_to_log (buf
, Qnil
, Qnil
);
8724 tiff_warning_handler (title
, format
, ap
)
8725 const char *title
, *format
;
8731 len
= sprintf (buf
, "TIFF warning: %s ", title
);
8732 vsprintf (buf
+ len
, format
, ap
);
8733 add_to_log (buf
, Qnil
, Qnil
);
8737 /* Load TIFF image IMG for use on frame F. Value is non-zero if
8745 Lisp_Object file
, specified_file
;
8746 Lisp_Object specified_data
;
8748 int width
, height
, x
, y
;
8752 struct gcpro gcpro1
;
8753 tiff_memory_source memsrc
;
8755 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8756 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8760 TIFFSetErrorHandler (tiff_error_handler
);
8761 TIFFSetWarningHandler (tiff_warning_handler
);
8763 if (NILP (specified_data
))
8765 /* Read from a file */
8766 file
= x_find_image_file (specified_file
);
8767 if (!STRINGP (file
))
8769 image_error ("Cannot find image file `%s'", file
, Qnil
);
8774 /* Try to open the image file. */
8775 tiff
= TIFFOpen (SDATA (file
), "r");
8778 image_error ("Cannot open `%s'", file
, Qnil
);
8785 /* Memory source! */
8786 memsrc
.bytes
= SDATA (specified_data
);
8787 memsrc
.len
= SBYTES (specified_data
);
8790 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
8791 (TIFFReadWriteProc
) tiff_read_from_memory
,
8792 (TIFFReadWriteProc
) tiff_write_from_memory
,
8793 tiff_seek_in_memory
,
8795 tiff_size_of_memory
,
8801 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
8807 /* Get width and height of the image, and allocate a raster buffer
8808 of width x height 32-bit values. */
8809 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
8810 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
8811 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
8813 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
8817 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
8823 /* Create the X image and pixmap. */
8824 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8831 /* Initialize the color table. */
8832 init_color_table ();
8834 /* Process the pixel raster. Origin is in the lower-left corner. */
8835 for (y
= 0; y
< height
; ++y
)
8837 uint32
*row
= buf
+ y
* width
;
8839 for (x
= 0; x
< width
; ++x
)
8841 uint32 abgr
= row
[x
];
8842 int r
= TIFFGetR (abgr
) << 8;
8843 int g
= TIFFGetG (abgr
) << 8;
8844 int b
= TIFFGetB (abgr
) << 8;
8845 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
8849 /* Remember the colors allocated for the image. Free the color table. */
8850 img
->colors
= colors_in_color_table (&img
->ncolors
);
8851 free_color_table ();
8854 img
->height
= height
;
8856 /* Maybe fill in the background field while we have ximg handy. */
8857 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8858 IMAGE_BACKGROUND (img
, f
, ximg
);
8860 /* Put the image into the pixmap, then free the X image and its buffer. */
8861 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8862 x_destroy_x_image (ximg
);
8869 #endif /* HAVE_TIFF != 0 */
8873 /***********************************************************************
8875 ***********************************************************************/
8879 #include <gif_lib.h>
8881 static int gif_image_p
P_ ((Lisp_Object object
));
8882 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
8884 /* The symbol `gif' identifying images of this type. */
8888 /* Indices of image specification fields in gif_format, below. */
8890 enum gif_keyword_index
8906 /* Vector of image_keyword structures describing the format
8907 of valid user-defined image specifications. */
8909 static struct image_keyword gif_format
[GIF_LAST
] =
8911 {":type", IMAGE_SYMBOL_VALUE
, 1},
8912 {":data", IMAGE_STRING_VALUE
, 0},
8913 {":file", IMAGE_STRING_VALUE
, 0},
8914 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8915 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8916 {":relief", IMAGE_INTEGER_VALUE
, 0},
8917 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8918 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8919 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8920 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8921 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8924 /* Structure describing the image type `gif'. */
8926 static struct image_type gif_type
=
8936 /* Return non-zero if OBJECT is a valid GIF image specification. */
8939 gif_image_p (object
)
8942 struct image_keyword fmt
[GIF_LAST
];
8943 bcopy (gif_format
, fmt
, sizeof fmt
);
8945 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
8948 /* Must specify either the :data or :file keyword. */
8949 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
8953 /* Reading a GIF image from memory
8954 Based on the PNG memory stuff to a certain extent. */
8958 unsigned char *bytes
;
8965 /* Make the current memory source available to gif_read_from_memory.
8966 It's done this way because not all versions of libungif support
8967 a UserData field in the GifFileType structure. */
8968 static gif_memory_source
*current_gif_memory_src
;
8971 gif_read_from_memory (file
, buf
, len
)
8976 gif_memory_source
*src
= current_gif_memory_src
;
8978 if (len
> src
->len
- src
->index
)
8981 bcopy (src
->bytes
+ src
->index
, buf
, len
);
8987 /* Load GIF image IMG for use on frame F. Value is non-zero if
8995 Lisp_Object file
, specified_file
;
8996 Lisp_Object specified_data
;
8997 int rc
, width
, height
, x
, y
, i
;
8999 ColorMapObject
*gif_color_map
;
9000 unsigned long pixel_colors
[256];
9002 struct gcpro gcpro1
;
9004 int ino
, image_left
, image_top
, image_width
, image_height
;
9005 gif_memory_source memsrc
;
9006 unsigned char *raster
;
9008 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
9009 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
9013 if (NILP (specified_data
))
9015 file
= x_find_image_file (specified_file
);
9016 if (!STRINGP (file
))
9018 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
9023 /* Open the GIF file. */
9024 gif
= DGifOpenFileName (SDATA (file
));
9027 image_error ("Cannot open `%s'", file
, Qnil
);
9034 /* Read from memory! */
9035 current_gif_memory_src
= &memsrc
;
9036 memsrc
.bytes
= SDATA (specified_data
);
9037 memsrc
.len
= SBYTES (specified_data
);
9040 gif
= DGifOpen(&memsrc
, gif_read_from_memory
);
9043 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
9049 /* Read entire contents. */
9050 rc
= DGifSlurp (gif
);
9051 if (rc
== GIF_ERROR
)
9053 image_error ("Error reading `%s'", img
->spec
, Qnil
);
9054 DGifCloseFile (gif
);
9059 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
9060 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
9061 if (ino
>= gif
->ImageCount
)
9063 image_error ("Invalid image number `%s' in image `%s'",
9065 DGifCloseFile (gif
);
9070 width
= img
->width
= max (gif
->SWidth
, gif
->Image
.Left
+ gif
->Image
.Width
);
9071 height
= img
->height
= max (gif
->SHeight
, gif
->Image
.Top
+ gif
->Image
.Height
);
9073 /* Create the X image and pixmap. */
9074 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
9076 DGifCloseFile (gif
);
9081 /* Allocate colors. */
9082 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
9084 gif_color_map
= gif
->SColorMap
;
9085 init_color_table ();
9086 bzero (pixel_colors
, sizeof pixel_colors
);
9088 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
9090 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
9091 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
9092 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
9093 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
9096 img
->colors
= colors_in_color_table (&img
->ncolors
);
9097 free_color_table ();
9099 /* Clear the part of the screen image that are not covered by
9100 the image from the GIF file. Full animated GIF support
9101 requires more than can be done here (see the gif89 spec,
9102 disposal methods). Let's simply assume that the part
9103 not covered by a sub-image is in the frame's background color. */
9104 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
9105 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
9106 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
9107 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
9109 for (y
= 0; y
< image_top
; ++y
)
9110 for (x
= 0; x
< width
; ++x
)
9111 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9113 for (y
= image_top
+ image_height
; y
< height
; ++y
)
9114 for (x
= 0; x
< width
; ++x
)
9115 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9117 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
9119 for (x
= 0; x
< image_left
; ++x
)
9120 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9121 for (x
= image_left
+ image_width
; x
< width
; ++x
)
9122 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9125 /* Read the GIF image into the X image. We use a local variable
9126 `raster' here because RasterBits below is a char *, and invites
9127 problems with bytes >= 0x80. */
9128 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
9130 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
9132 static int interlace_start
[] = {0, 4, 2, 1};
9133 static int interlace_increment
[] = {8, 8, 4, 2};
9135 int row
= interlace_start
[0];
9139 for (y
= 0; y
< image_height
; y
++)
9141 if (row
>= image_height
)
9143 row
= interlace_start
[++pass
];
9144 while (row
>= image_height
)
9145 row
= interlace_start
[++pass
];
9148 for (x
= 0; x
< image_width
; x
++)
9150 int i
= raster
[(y
* image_width
) + x
];
9151 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
9155 row
+= interlace_increment
[pass
];
9160 for (y
= 0; y
< image_height
; ++y
)
9161 for (x
= 0; x
< image_width
; ++x
)
9163 int i
= raster
[y
* image_width
+ x
];
9164 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
9168 DGifCloseFile (gif
);
9170 /* Maybe fill in the background field while we have ximg handy. */
9171 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
9172 IMAGE_BACKGROUND (img
, f
, ximg
);
9174 /* Put the image into the pixmap, then free the X image and its buffer. */
9175 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
9176 x_destroy_x_image (ximg
);
9182 #endif /* HAVE_GIF != 0 */
9186 /***********************************************************************
9188 ***********************************************************************/
9190 static int gs_image_p
P_ ((Lisp_Object object
));
9191 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
9192 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
9194 /* The symbol `postscript' identifying images of this type. */
9196 Lisp_Object Qpostscript
;
9198 /* Keyword symbols. */
9200 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
9202 /* Indices of image specification fields in gs_format, below. */
9204 enum gs_keyword_index
9222 /* Vector of image_keyword structures describing the format
9223 of valid user-defined image specifications. */
9225 static struct image_keyword gs_format
[GS_LAST
] =
9227 {":type", IMAGE_SYMBOL_VALUE
, 1},
9228 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9229 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9230 {":file", IMAGE_STRING_VALUE
, 1},
9231 {":loader", IMAGE_FUNCTION_VALUE
, 0},
9232 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
9233 {":ascent", IMAGE_ASCENT_VALUE
, 0},
9234 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
9235 {":relief", IMAGE_INTEGER_VALUE
, 0},
9236 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9237 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9238 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9239 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
9242 /* Structure describing the image type `ghostscript'. */
9244 static struct image_type gs_type
=
9254 /* Free X resources of Ghostscript image IMG which is used on frame F. */
9257 gs_clear_image (f
, img
)
9261 /* IMG->data.ptr_val may contain a recorded colormap. */
9262 xfree (img
->data
.ptr_val
);
9263 x_clear_image (f
, img
);
9267 /* Return non-zero if OBJECT is a valid Ghostscript image
9274 struct image_keyword fmt
[GS_LAST
];
9278 bcopy (gs_format
, fmt
, sizeof fmt
);
9280 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
9283 /* Bounding box must be a list or vector containing 4 integers. */
9284 tem
= fmt
[GS_BOUNDING_BOX
].value
;
9287 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
9288 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
9293 else if (VECTORP (tem
))
9295 if (XVECTOR (tem
)->size
!= 4)
9297 for (i
= 0; i
< 4; ++i
)
9298 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
9308 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
9317 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
9318 struct gcpro gcpro1
, gcpro2
;
9320 double in_width
, in_height
;
9321 Lisp_Object pixel_colors
= Qnil
;
9323 /* Compute pixel size of pixmap needed from the given size in the
9324 image specification. Sizes in the specification are in pt. 1 pt
9325 = 1/72 in, xdpi and ydpi are stored in the frame's X display
9327 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
9328 in_width
= XFASTINT (pt_width
) / 72.0;
9329 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
9330 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
9331 in_height
= XFASTINT (pt_height
) / 72.0;
9332 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
9334 /* Create the pixmap. */
9335 xassert (img
->pixmap
== None
);
9336 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9337 img
->width
, img
->height
,
9338 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
9342 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
9346 /* Call the loader to fill the pixmap. It returns a process object
9347 if successful. We do not record_unwind_protect here because
9348 other places in redisplay like calling window scroll functions
9349 don't either. Let the Lisp loader use `unwind-protect' instead. */
9350 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
9352 sprintf (buffer
, "%lu %lu",
9353 (unsigned long) FRAME_X_WINDOW (f
),
9354 (unsigned long) img
->pixmap
);
9355 window_and_pixmap_id
= build_string (buffer
);
9357 sprintf (buffer
, "%lu %lu",
9358 FRAME_FOREGROUND_PIXEL (f
),
9359 FRAME_BACKGROUND_PIXEL (f
));
9360 pixel_colors
= build_string (buffer
);
9362 XSETFRAME (frame
, f
);
9363 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
9365 loader
= intern ("gs-load-image");
9367 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
9368 make_number (img
->width
),
9369 make_number (img
->height
),
9370 window_and_pixmap_id
,
9373 return PROCESSP (img
->data
.lisp_val
);
9377 /* Kill the Ghostscript process that was started to fill PIXMAP on
9378 frame F. Called from XTread_socket when receiving an event
9379 telling Emacs that Ghostscript has finished drawing. */
9382 x_kill_gs_process (pixmap
, f
)
9386 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
9390 /* Find the image containing PIXMAP. */
9391 for (i
= 0; i
< c
->used
; ++i
)
9392 if (c
->images
[i
]->pixmap
== pixmap
)
9395 /* Should someone in between have cleared the image cache, for
9396 instance, give up. */
9400 /* Kill the GS process. We should have found PIXMAP in the image
9401 cache and its image should contain a process object. */
9403 xassert (PROCESSP (img
->data
.lisp_val
));
9404 Fkill_process (img
->data
.lisp_val
, Qnil
);
9405 img
->data
.lisp_val
= Qnil
;
9407 /* On displays with a mutable colormap, figure out the colors
9408 allocated for the image by looking at the pixels of an XImage for
9410 class = FRAME_X_VISUAL (f
)->class;
9411 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
9417 /* Try to get an XImage for img->pixmep. */
9418 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
9419 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
9424 /* Initialize the color table. */
9425 init_color_table ();
9427 /* For each pixel of the image, look its color up in the
9428 color table. After having done so, the color table will
9429 contain an entry for each color used by the image. */
9430 for (y
= 0; y
< img
->height
; ++y
)
9431 for (x
= 0; x
< img
->width
; ++x
)
9433 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
9434 lookup_pixel_color (f
, pixel
);
9437 /* Record colors in the image. Free color table and XImage. */
9438 img
->colors
= colors_in_color_table (&img
->ncolors
);
9439 free_color_table ();
9440 XDestroyImage (ximg
);
9442 #if 0 /* This doesn't seem to be the case. If we free the colors
9443 here, we get a BadAccess later in x_clear_image when
9444 freeing the colors. */
9445 /* We have allocated colors once, but Ghostscript has also
9446 allocated colors on behalf of us. So, to get the
9447 reference counts right, free them once. */
9449 x_free_colors (f
, img
->colors
, img
->ncolors
);
9453 image_error ("Cannot get X image of `%s'; colors will not be freed",
9459 /* Now that we have the pixmap, compute mask and transform the
9460 image if requested. */
9462 postprocess_image (f
, img
);
9468 /***********************************************************************
9470 ***********************************************************************/
9472 DEFUN ("x-change-window-property", Fx_change_window_property
,
9473 Sx_change_window_property
, 2, 3, 0,
9474 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
9475 PROP and VALUE must be strings. FRAME nil or omitted means use the
9476 selected frame. Value is VALUE. */)
9477 (prop
, value
, frame
)
9478 Lisp_Object frame
, prop
, value
;
9480 struct frame
*f
= check_x_frame (frame
);
9483 CHECK_STRING (prop
);
9484 CHECK_STRING (value
);
9487 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9488 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9489 prop_atom
, XA_STRING
, 8, PropModeReplace
,
9490 SDATA (value
), SCHARS (value
));
9492 /* Make sure the property is set when we return. */
9493 XFlush (FRAME_X_DISPLAY (f
));
9500 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
9501 Sx_delete_window_property
, 1, 2, 0,
9502 doc
: /* Remove window property PROP from X window of FRAME.
9503 FRAME nil or omitted means use the selected frame. Value is PROP. */)
9505 Lisp_Object prop
, frame
;
9507 struct frame
*f
= check_x_frame (frame
);
9510 CHECK_STRING (prop
);
9512 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9513 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
9515 /* Make sure the property is removed when we return. */
9516 XFlush (FRAME_X_DISPLAY (f
));
9523 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
9525 doc
: /* Value is the value of window property PROP on FRAME.
9526 If FRAME is nil or omitted, use the selected frame. Value is nil
9527 if FRAME hasn't a property with name PROP or if PROP has no string
9530 Lisp_Object prop
, frame
;
9532 struct frame
*f
= check_x_frame (frame
);
9535 Lisp_Object prop_value
= Qnil
;
9536 char *tmp_data
= NULL
;
9539 unsigned long actual_size
, bytes_remaining
;
9541 CHECK_STRING (prop
);
9543 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9544 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9545 prop_atom
, 0, 0, False
, XA_STRING
,
9546 &actual_type
, &actual_format
, &actual_size
,
9547 &bytes_remaining
, (unsigned char **) &tmp_data
);
9550 int size
= bytes_remaining
;
9555 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9556 prop_atom
, 0, bytes_remaining
,
9558 &actual_type
, &actual_format
,
9559 &actual_size
, &bytes_remaining
,
9560 (unsigned char **) &tmp_data
);
9561 if (rc
== Success
&& tmp_data
)
9562 prop_value
= make_string (tmp_data
, size
);
9573 /***********************************************************************
9575 ***********************************************************************/
9577 /* If non-null, an asynchronous timer that, when it expires, displays
9578 an hourglass cursor on all frames. */
9580 static struct atimer
*hourglass_atimer
;
9582 /* Non-zero means an hourglass cursor is currently shown. */
9584 static int hourglass_shown_p
;
9586 /* Number of seconds to wait before displaying an hourglass cursor. */
9588 static Lisp_Object Vhourglass_delay
;
9590 /* Default number of seconds to wait before displaying an hourglass
9593 #define DEFAULT_HOURGLASS_DELAY 1
9595 /* Function prototypes. */
9597 static void show_hourglass
P_ ((struct atimer
*));
9598 static void hide_hourglass
P_ ((void));
9601 /* Cancel a currently active hourglass timer, and start a new one. */
9607 int secs
, usecs
= 0;
9609 cancel_hourglass ();
9611 if (INTEGERP (Vhourglass_delay
)
9612 && XINT (Vhourglass_delay
) > 0)
9613 secs
= XFASTINT (Vhourglass_delay
);
9614 else if (FLOATP (Vhourglass_delay
)
9615 && XFLOAT_DATA (Vhourglass_delay
) > 0)
9618 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
9619 secs
= XFASTINT (tem
);
9620 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
9623 secs
= DEFAULT_HOURGLASS_DELAY
;
9625 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
9626 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
9627 show_hourglass
, NULL
);
9631 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
9637 if (hourglass_atimer
)
9639 cancel_atimer (hourglass_atimer
);
9640 hourglass_atimer
= NULL
;
9643 if (hourglass_shown_p
)
9648 /* Timer function of hourglass_atimer. TIMER is equal to
9651 Display an hourglass pointer on all frames by mapping the frames'
9652 hourglass_window. Set the hourglass_p flag in the frames'
9653 output_data.x structure to indicate that an hourglass cursor is
9654 shown on the frames. */
9657 show_hourglass (timer
)
9658 struct atimer
*timer
;
9660 /* The timer implementation will cancel this timer automatically
9661 after this function has run. Set hourglass_atimer to null
9662 so that we know the timer doesn't have to be canceled. */
9663 hourglass_atimer
= NULL
;
9665 if (!hourglass_shown_p
)
9667 Lisp_Object rest
, frame
;
9671 FOR_EACH_FRAME (rest
, frame
)
9673 struct frame
*f
= XFRAME (frame
);
9675 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
9677 Display
*dpy
= FRAME_X_DISPLAY (f
);
9679 #ifdef USE_X_TOOLKIT
9680 if (f
->output_data
.x
->widget
)
9682 if (FRAME_OUTER_WINDOW (f
))
9685 f
->output_data
.x
->hourglass_p
= 1;
9687 if (!f
->output_data
.x
->hourglass_window
)
9689 unsigned long mask
= CWCursor
;
9690 XSetWindowAttributes attrs
;
9692 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
9694 f
->output_data
.x
->hourglass_window
9695 = XCreateWindow (dpy
, FRAME_OUTER_WINDOW (f
),
9696 0, 0, 32000, 32000, 0, 0,
9702 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
9708 hourglass_shown_p
= 1;
9714 /* Hide the hourglass pointer on all frames, if it is currently
9720 if (hourglass_shown_p
)
9722 Lisp_Object rest
, frame
;
9725 FOR_EACH_FRAME (rest
, frame
)
9727 struct frame
*f
= XFRAME (frame
);
9730 /* Watch out for newly created frames. */
9731 && f
->output_data
.x
->hourglass_window
)
9733 XUnmapWindow (FRAME_X_DISPLAY (f
),
9734 f
->output_data
.x
->hourglass_window
);
9735 /* Sync here because XTread_socket looks at the
9736 hourglass_p flag that is reset to zero below. */
9737 XSync (FRAME_X_DISPLAY (f
), False
);
9738 f
->output_data
.x
->hourglass_p
= 0;
9742 hourglass_shown_p
= 0;
9749 /***********************************************************************
9751 ***********************************************************************/
9753 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
9754 Lisp_Object
, Lisp_Object
));
9755 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
9756 Lisp_Object
, int, int, int *, int *));
9758 /* The frame of a currently visible tooltip. */
9760 Lisp_Object tip_frame
;
9762 /* If non-nil, a timer started that hides the last tooltip when it
9765 Lisp_Object tip_timer
;
9768 /* If non-nil, a vector of 3 elements containing the last args
9769 with which x-show-tip was called. See there. */
9771 Lisp_Object last_show_tip_args
;
9773 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
9775 Lisp_Object Vx_max_tooltip_size
;
9779 unwind_create_tip_frame (frame
)
9782 Lisp_Object deleted
;
9784 deleted
= unwind_create_frame (frame
);
9785 if (EQ (deleted
, Qt
))
9795 /* Create a frame for a tooltip on the display described by DPYINFO.
9796 PARMS is a list of frame parameters. TEXT is the string to
9797 display in the tip frame. Value is the frame.
9799 Note that functions called here, esp. x_default_parameter can
9800 signal errors, for instance when a specified color name is
9801 undefined. We have to make sure that we're in a consistent state
9802 when this happens. */
9805 x_create_tip_frame (dpyinfo
, parms
, text
)
9806 struct x_display_info
*dpyinfo
;
9807 Lisp_Object parms
, text
;
9810 Lisp_Object frame
, tem
;
9812 long window_prompting
= 0;
9814 int count
= SPECPDL_INDEX ();
9815 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9817 int face_change_count_before
= face_change_count
;
9819 struct buffer
*old_buffer
;
9823 /* Use this general default value to start with until we know if
9824 this frame has a specified name. */
9825 Vx_resource_name
= Vinvocation_name
;
9828 kb
= dpyinfo
->kboard
;
9830 kb
= &the_only_kboard
;
9833 /* Get the name of the frame to use for resource lookup. */
9834 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
9836 && !EQ (name
, Qunbound
)
9838 error ("Invalid frame name--not a string or nil");
9839 Vx_resource_name
= name
;
9842 GCPRO3 (parms
, name
, frame
);
9844 XSETFRAME (frame
, f
);
9846 buffer
= Fget_buffer_create (build_string (" *tip*"));
9847 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
9848 old_buffer
= current_buffer
;
9849 set_buffer_internal_1 (XBUFFER (buffer
));
9850 current_buffer
->truncate_lines
= Qnil
;
9853 set_buffer_internal_1 (old_buffer
);
9855 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
9856 record_unwind_protect (unwind_create_tip_frame
, frame
);
9858 /* By setting the output method, we're essentially saying that
9859 the frame is live, as per FRAME_LIVE_P. If we get a signal
9860 from this point on, x_destroy_window might screw up reference
9862 f
->output_method
= output_x_window
;
9863 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
9864 bzero (f
->output_data
.x
, sizeof (struct x_output
));
9865 f
->output_data
.x
->icon_bitmap
= -1;
9866 FRAME_FONTSET (f
) = -1;
9867 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
9868 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
9869 #ifdef USE_TOOLKIT_SCROLL_BARS
9870 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
9871 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
9872 #endif /* USE_TOOLKIT_SCROLL_BARS */
9873 f
->icon_name
= Qnil
;
9874 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
9876 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
9877 dpyinfo_refcount
= dpyinfo
->reference_count
;
9878 #endif /* GLYPH_DEBUG */
9880 FRAME_KBOARD (f
) = kb
;
9882 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
9883 f
->output_data
.x
->explicit_parent
= 0;
9885 /* These colors will be set anyway later, but it's important
9886 to get the color reference counts right, so initialize them! */
9889 struct gcpro gcpro1
;
9891 black
= build_string ("black");
9893 f
->output_data
.x
->foreground_pixel
9894 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9895 f
->output_data
.x
->background_pixel
9896 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9897 f
->output_data
.x
->cursor_pixel
9898 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9899 f
->output_data
.x
->cursor_foreground_pixel
9900 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9901 f
->output_data
.x
->border_pixel
9902 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9903 f
->output_data
.x
->mouse_pixel
9904 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9908 /* Set the name; the functions to which we pass f expect the name to
9910 if (EQ (name
, Qunbound
) || NILP (name
))
9912 f
->name
= build_string (dpyinfo
->x_id_name
);
9913 f
->explicit_name
= 0;
9918 f
->explicit_name
= 1;
9919 /* use the frame's title when getting resources for this frame. */
9920 specbind (Qx_resource_name
, name
);
9923 /* Extract the window parameters from the supplied values that are
9924 needed to determine window geometry. */
9928 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
9931 /* First, try whatever font the caller has specified. */
9934 tem
= Fquery_fontset (font
, Qnil
);
9936 font
= x_new_fontset (f
, SDATA (tem
));
9938 font
= x_new_font (f
, SDATA (font
));
9941 /* Try out a font which we hope has bold and italic variations. */
9942 if (!STRINGP (font
))
9943 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
9944 if (!STRINGP (font
))
9945 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9946 if (! STRINGP (font
))
9947 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9948 if (! STRINGP (font
))
9949 /* This was formerly the first thing tried, but it finds too many fonts
9950 and takes too long. */
9951 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
9952 /* If those didn't work, look for something which will at least work. */
9953 if (! STRINGP (font
))
9954 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
9956 if (! STRINGP (font
))
9957 font
= build_string ("fixed");
9959 x_default_parameter (f
, parms
, Qfont
, font
,
9960 "font", "Font", RES_TYPE_STRING
);
9963 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
9964 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
9966 /* This defaults to 2 in order to match xterm. We recognize either
9967 internalBorderWidth or internalBorder (which is what xterm calls
9969 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9973 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
9974 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
9975 if (! EQ (value
, Qunbound
))
9976 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
9980 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
9981 "internalBorderWidth", "internalBorderWidth",
9984 /* Also do the stuff which must be set before the window exists. */
9985 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
9986 "foreground", "Foreground", RES_TYPE_STRING
);
9987 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
9988 "background", "Background", RES_TYPE_STRING
);
9989 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
9990 "pointerColor", "Foreground", RES_TYPE_STRING
);
9991 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
9992 "cursorColor", "Foreground", RES_TYPE_STRING
);
9993 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
9994 "borderColor", "BorderColor", RES_TYPE_STRING
);
9996 /* Init faces before x_default_parameter is called for scroll-bar
9997 parameters because that function calls x_set_scroll_bar_width,
9998 which calls change_frame_size, which calls Fset_window_buffer,
9999 which runs hooks, which call Fvertical_motion. At the end, we
10000 end up in init_iterator with a null face cache, which should not
10002 init_frame_faces (f
);
10004 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
10006 window_prompting
= x_figure_window_size (f
, parms
, 0);
10009 XSetWindowAttributes attrs
;
10010 unsigned long mask
;
10013 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
10014 if (DoesSaveUnders (dpyinfo
->screen
))
10015 mask
|= CWSaveUnder
;
10017 /* Window managers look at the override-redirect flag to determine
10018 whether or net to give windows a decoration (Xlib spec, chapter
10020 attrs
.override_redirect
= True
;
10021 attrs
.save_under
= True
;
10022 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
10023 /* Arrange for getting MapNotify and UnmapNotify events. */
10024 attrs
.event_mask
= StructureNotifyMask
;
10026 = FRAME_X_WINDOW (f
)
10027 = XCreateWindow (FRAME_X_DISPLAY (f
),
10028 FRAME_X_DISPLAY_INFO (f
)->root_window
,
10029 /* x, y, width, height */
10033 CopyFromParent
, InputOutput
, CopyFromParent
,
10040 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
10041 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
10042 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
10043 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
10044 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
10045 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
10047 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
10048 Change will not be effected unless different from the current
10049 FRAME_LINES (f). */
10050 width
= FRAME_COLS (f
);
10051 height
= FRAME_LINES (f
);
10052 SET_FRAME_COLS (f
, 0);
10053 FRAME_LINES (f
) = 0;
10054 change_frame_size (f
, height
, width
, 1, 0, 0);
10056 /* Add `tooltip' frame parameter's default value. */
10057 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
10058 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
10061 /* Set up faces after all frame parameters are known. This call
10062 also merges in face attributes specified for new frames.
10064 Frame parameters may be changed if .Xdefaults contains
10065 specifications for the default font. For example, if there is an
10066 `Emacs.default.attributeBackground: pink', the `background-color'
10067 attribute of the frame get's set, which let's the internal border
10068 of the tooltip frame appear in pink. Prevent this. */
10070 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
10072 /* Set tip_frame here, so that */
10074 call1 (Qface_set_after_frame_default
, frame
);
10076 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
10077 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
10085 /* It is now ok to make the frame official even if we get an error
10086 below. And the frame needs to be on Vframe_list or making it
10087 visible won't work. */
10088 Vframe_list
= Fcons (frame
, Vframe_list
);
10090 /* Now that the frame is official, it counts as a reference to
10092 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
10094 /* Setting attributes of faces of the tooltip frame from resources
10095 and similar will increment face_change_count, which leads to the
10096 clearing of all current matrices. Since this isn't necessary
10097 here, avoid it by resetting face_change_count to the value it
10098 had before we created the tip frame. */
10099 face_change_count
= face_change_count_before
;
10101 /* Discard the unwind_protect. */
10102 return unbind_to (count
, frame
);
10106 /* Compute where to display tip frame F. PARMS is the list of frame
10107 parameters for F. DX and DY are specified offsets from the current
10108 location of the mouse. WIDTH and HEIGHT are the width and height
10109 of the tooltip. Return coordinates relative to the root window of
10110 the display in *ROOT_X, and *ROOT_Y. */
10113 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
10115 Lisp_Object parms
, dx
, dy
;
10117 int *root_x
, *root_y
;
10119 Lisp_Object left
, top
;
10121 Window root
, child
;
10124 /* User-specified position? */
10125 left
= Fcdr (Fassq (Qleft
, parms
));
10126 top
= Fcdr (Fassq (Qtop
, parms
));
10128 /* Move the tooltip window where the mouse pointer is. Resize and
10130 if (!INTEGERP (left
) || !INTEGERP (top
))
10133 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
10134 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
10138 if (INTEGERP (top
))
10139 *root_y
= XINT (top
);
10140 else if (*root_y
+ XINT (dy
) - height
< 0)
10141 *root_y
-= XINT (dy
);
10145 *root_y
+= XINT (dy
);
10148 if (INTEGERP (left
))
10149 *root_x
= XINT (left
);
10150 else if (*root_x
+ XINT (dx
) + width
<= FRAME_X_DISPLAY_INFO (f
)->width
)
10151 /* It fits to the right of the pointer. */
10152 *root_x
+= XINT (dx
);
10153 else if (width
+ XINT (dx
) <= *root_x
)
10154 /* It fits to the left of the pointer. */
10155 *root_x
-= width
+ XINT (dx
);
10157 /* Put it left-justified on the screen--it ought to fit that way. */
10162 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
10163 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
10164 A tooltip window is a small X window displaying a string.
10166 FRAME nil or omitted means use the selected frame.
10168 PARMS is an optional list of frame parameters which can be used to
10169 change the tooltip's appearance.
10171 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
10172 means use the default timeout of 5 seconds.
10174 If the list of frame parameters PARAMS contains a `left' parameters,
10175 the tooltip is displayed at that x-position. Otherwise it is
10176 displayed at the mouse position, with offset DX added (default is 5 if
10177 DX isn't specified). Likewise for the y-position; if a `top' frame
10178 parameter is specified, it determines the y-position of the tooltip
10179 window, otherwise it is displayed at the mouse position, with offset
10180 DY added (default is -10).
10182 A tooltip's maximum size is specified by `x-max-tooltip-size'.
10183 Text larger than the specified size is clipped. */)
10184 (string
, frame
, parms
, timeout
, dx
, dy
)
10185 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
10189 int root_x
, root_y
;
10190 struct buffer
*old_buffer
;
10191 struct text_pos pos
;
10192 int i
, width
, height
;
10193 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
10194 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
10195 int count
= SPECPDL_INDEX ();
10197 specbind (Qinhibit_redisplay
, Qt
);
10199 GCPRO4 (string
, parms
, frame
, timeout
);
10201 CHECK_STRING (string
);
10202 f
= check_x_frame (frame
);
10203 if (NILP (timeout
))
10204 timeout
= make_number (5);
10206 CHECK_NATNUM (timeout
);
10209 dx
= make_number (5);
10214 dy
= make_number (-10);
10218 if (NILP (last_show_tip_args
))
10219 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
10221 if (!NILP (tip_frame
))
10223 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
10224 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
10225 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
10227 if (EQ (frame
, last_frame
)
10228 && !NILP (Fequal (last_string
, string
))
10229 && !NILP (Fequal (last_parms
, parms
)))
10231 struct frame
*f
= XFRAME (tip_frame
);
10233 /* Only DX and DY have changed. */
10234 if (!NILP (tip_timer
))
10236 Lisp_Object timer
= tip_timer
;
10238 call1 (Qcancel_timer
, timer
);
10242 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
10243 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
10244 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10251 /* Hide a previous tip, if any. */
10254 ASET (last_show_tip_args
, 0, string
);
10255 ASET (last_show_tip_args
, 1, frame
);
10256 ASET (last_show_tip_args
, 2, parms
);
10258 /* Add default values to frame parameters. */
10259 if (NILP (Fassq (Qname
, parms
)))
10260 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
10261 if (NILP (Fassq (Qinternal_border_width
, parms
)))
10262 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
10263 if (NILP (Fassq (Qborder_width
, parms
)))
10264 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
10265 if (NILP (Fassq (Qborder_color
, parms
)))
10266 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
10267 if (NILP (Fassq (Qbackground_color
, parms
)))
10268 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
10271 /* Create a frame for the tooltip, and record it in the global
10272 variable tip_frame. */
10273 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
10274 f
= XFRAME (frame
);
10276 /* Set up the frame's root window. */
10277 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
10278 w
->left_col
= w
->top_line
= make_number (0);
10280 if (CONSP (Vx_max_tooltip_size
)
10281 && INTEGERP (XCAR (Vx_max_tooltip_size
))
10282 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
10283 && INTEGERP (XCDR (Vx_max_tooltip_size
))
10284 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
10286 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
10287 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
10291 w
->total_cols
= make_number (80);
10292 w
->total_lines
= make_number (40);
10295 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
10297 w
->pseudo_window_p
= 1;
10299 /* Display the tooltip text in a temporary buffer. */
10300 old_buffer
= current_buffer
;
10301 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
10302 current_buffer
->truncate_lines
= Qnil
;
10303 clear_glyph_matrix (w
->desired_matrix
);
10304 clear_glyph_matrix (w
->current_matrix
);
10305 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
10306 try_window (FRAME_ROOT_WINDOW (f
), pos
);
10308 /* Compute width and height of the tooltip. */
10309 width
= height
= 0;
10310 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
10312 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
10313 struct glyph
*last
;
10316 /* Stop at the first empty row at the end. */
10317 if (!row
->enabled_p
|| !row
->displays_text_p
)
10320 /* Let the row go over the full width of the frame. */
10321 row
->full_width_p
= 1;
10323 /* There's a glyph at the end of rows that is used to place
10324 the cursor there. Don't include the width of this glyph. */
10325 if (row
->used
[TEXT_AREA
])
10327 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
10328 row_width
= row
->pixel_width
- last
->pixel_width
;
10331 row_width
= row
->pixel_width
;
10333 height
+= row
->height
;
10334 width
= max (width
, row_width
);
10337 /* Add the frame's internal border to the width and height the X
10338 window should have. */
10339 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10340 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10342 /* Move the tooltip window where the mouse pointer is. Resize and
10344 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
10347 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10348 root_x
, root_y
, width
, height
);
10349 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
10352 /* Draw into the window. */
10353 w
->must_be_updated_p
= 1;
10354 update_single_window (w
, 1);
10356 /* Restore original current buffer. */
10357 set_buffer_internal_1 (old_buffer
);
10358 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
10361 /* Let the tip disappear after timeout seconds. */
10362 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
10363 intern ("x-hide-tip"));
10366 return unbind_to (count
, Qnil
);
10370 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
10371 doc
: /* Hide the current tooltip window, if there is any.
10372 Value is t if tooltip was open, nil otherwise. */)
10376 Lisp_Object deleted
, frame
, timer
;
10377 struct gcpro gcpro1
, gcpro2
;
10379 /* Return quickly if nothing to do. */
10380 if (NILP (tip_timer
) && NILP (tip_frame
))
10385 GCPRO2 (frame
, timer
);
10386 tip_frame
= tip_timer
= deleted
= Qnil
;
10388 count
= SPECPDL_INDEX ();
10389 specbind (Qinhibit_redisplay
, Qt
);
10390 specbind (Qinhibit_quit
, Qt
);
10393 call1 (Qcancel_timer
, timer
);
10395 if (FRAMEP (frame
))
10397 Fdelete_frame (frame
, Qnil
);
10401 /* Bloodcurdling hack alert: The Lucid menu bar widget's
10402 redisplay procedure is not called when a tip frame over menu
10403 items is unmapped. Redisplay the menu manually... */
10405 struct frame
*f
= SELECTED_FRAME ();
10406 Widget w
= f
->output_data
.x
->menubar_widget
;
10407 extern void xlwmenu_redisplay
P_ ((Widget
));
10409 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
10413 xlwmenu_redisplay (w
);
10417 #endif /* USE_LUCID */
10421 return unbind_to (count
, deleted
);
10426 /***********************************************************************
10427 File selection dialog
10428 ***********************************************************************/
10432 /* Callback for "OK" and "Cancel" on file selection dialog. */
10435 file_dialog_cb (widget
, client_data
, call_data
)
10437 XtPointer call_data
, client_data
;
10439 int *result
= (int *) client_data
;
10440 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
10441 *result
= cb
->reason
;
10445 /* Callback for unmapping a file selection dialog. This is used to
10446 capture the case where a dialog is closed via a window manager's
10447 closer button, for example. Using a XmNdestroyCallback didn't work
10451 file_dialog_unmap_cb (widget
, client_data
, call_data
)
10453 XtPointer call_data
, client_data
;
10455 int *result
= (int *) client_data
;
10456 *result
= XmCR_CANCEL
;
10460 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10461 doc
: /* Read file name, prompting with PROMPT in directory DIR.
10462 Use a file selection dialog.
10463 Select DEFAULT-FILENAME in the dialog's file selection box, if
10464 specified. Don't let the user enter a file name in the file
10465 selection dialog's entry field, if MUSTMATCH is non-nil. */)
10466 (prompt
, dir
, default_filename
, mustmatch
)
10467 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10470 struct frame
*f
= SELECTED_FRAME ();
10471 Lisp_Object file
= Qnil
;
10472 Widget dialog
, text
, list
, help
;
10475 extern XtAppContext Xt_app_con
;
10476 XmString dir_xmstring
, pattern_xmstring
;
10477 int count
= SPECPDL_INDEX ();
10478 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10480 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10481 CHECK_STRING (prompt
);
10482 CHECK_STRING (dir
);
10484 /* Prevent redisplay. */
10485 specbind (Qinhibit_redisplay
, Qt
);
10489 /* Create the dialog with PROMPT as title, using DIR as initial
10490 directory and using "*" as pattern. */
10491 dir
= Fexpand_file_name (dir
, Qnil
);
10492 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
10493 pattern_xmstring
= XmStringCreateLocalized ("*");
10495 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
10496 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
10497 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
10498 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
10499 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
10500 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
10502 XmStringFree (dir_xmstring
);
10503 XmStringFree (pattern_xmstring
);
10505 /* Add callbacks for OK and Cancel. */
10506 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
10507 (XtPointer
) &result
);
10508 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
10509 (XtPointer
) &result
);
10510 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
10511 (XtPointer
) &result
);
10513 /* Disable the help button since we can't display help. */
10514 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
10515 XtSetSensitive (help
, False
);
10517 /* Mark OK button as default. */
10518 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
10519 XmNshowAsDefault
, True
, NULL
);
10521 /* If MUSTMATCH is non-nil, disable the file entry field of the
10522 dialog, so that the user must select a file from the files list
10523 box. We can't remove it because we wouldn't have a way to get at
10524 the result file name, then. */
10525 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
10526 if (!NILP (mustmatch
))
10529 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
10530 XtSetSensitive (text
, False
);
10531 XtSetSensitive (label
, False
);
10534 /* Manage the dialog, so that list boxes get filled. */
10535 XtManageChild (dialog
);
10537 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
10538 must include the path for this to work. */
10539 list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
10540 if (STRINGP (default_filename
))
10542 XmString default_xmstring
;
10546 = XmStringCreateLocalized (SDATA (default_filename
));
10548 if (!XmListItemExists (list
, default_xmstring
))
10550 /* Add a new item if DEFAULT_FILENAME is not in the list. */
10551 XmListAddItem (list
, default_xmstring
, 0);
10555 item_pos
= XmListItemPos (list
, default_xmstring
);
10556 XmStringFree (default_xmstring
);
10558 /* Select the item and scroll it into view. */
10559 XmListSelectPos (list
, item_pos
, True
);
10560 XmListSetPos (list
, item_pos
);
10563 /* Process events until the user presses Cancel or OK. */
10565 while (result
== 0)
10568 XtAppNextEvent (Xt_app_con
, &event
);
10569 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
) );
10572 /* Get the result. */
10573 if (result
== XmCR_OK
)
10578 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
10579 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
10580 XmStringFree (text
);
10581 file
= build_string (data
);
10588 XtUnmanageChild (dialog
);
10589 XtDestroyWidget (dialog
);
10593 /* Make "Cancel" equivalent to C-g. */
10595 Fsignal (Qquit
, Qnil
);
10597 return unbind_to (count
, file
);
10600 #endif /* USE_MOTIF */
10604 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10605 "Read file name, prompting with PROMPT in directory DIR.\n\
10606 Use a file selection dialog.\n\
10607 Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
10608 specified. Don't let the user enter a file name in the file\n\
10609 selection dialog's entry field, if MUSTMATCH is non-nil.")
10610 (prompt
, dir
, default_filename
, mustmatch
)
10611 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10613 FRAME_PTR f
= SELECTED_FRAME ();
10615 Lisp_Object file
= Qnil
;
10616 int count
= specpdl_ptr
- specpdl
;
10617 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10621 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10622 CHECK_STRING (prompt
);
10623 CHECK_STRING (dir
);
10625 /* Prevent redisplay. */
10626 specbind (Qinhibit_redisplay
, Qt
);
10630 if (STRINGP (default_filename
))
10631 cdef_file
= SDATA (default_filename
);
10633 cdef_file
= SDATA (dir
);
10635 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
, ! NILP (mustmatch
));
10639 file
= build_string (fn
);
10646 /* Make "Cancel" equivalent to C-g. */
10648 Fsignal (Qquit
, Qnil
);
10650 return unbind_to (count
, file
);
10653 #endif /* USE_GTK */
10656 /***********************************************************************
10658 ***********************************************************************/
10660 #ifdef HAVE_XKBGETKEYBOARD
10661 #include <X11/XKBlib.h>
10662 #include <X11/keysym.h>
10665 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
10666 Sx_backspace_delete_keys_p
, 0, 1, 0,
10667 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
10668 FRAME nil means use the selected frame.
10669 Value is t if we know that both keys are present, and are mapped to the
10670 usual X keysyms. */)
10674 #ifdef HAVE_XKBGETKEYBOARD
10676 struct frame
*f
= check_x_frame (frame
);
10677 Display
*dpy
= FRAME_X_DISPLAY (f
);
10678 Lisp_Object have_keys
;
10679 int major
, minor
, op
, event
, error
;
10683 /* Check library version in case we're dynamically linked. */
10684 major
= XkbMajorVersion
;
10685 minor
= XkbMinorVersion
;
10686 if (!XkbLibraryVersion (&major
, &minor
))
10692 /* Check that the server supports XKB. */
10693 major
= XkbMajorVersion
;
10694 minor
= XkbMinorVersion
;
10695 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
10702 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
10705 int delete_keycode
= 0, backspace_keycode
= 0, i
;
10707 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
10709 for (i
= kb
->min_key_code
;
10710 (i
< kb
->max_key_code
10711 && (delete_keycode
== 0 || backspace_keycode
== 0));
10714 /* The XKB symbolic key names can be seen most easily in
10715 the PS file generated by `xkbprint -label name
10717 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
10718 delete_keycode
= i
;
10719 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
10720 backspace_keycode
= i
;
10723 XkbFreeNames (kb
, 0, True
);
10726 XkbFreeClientMap (kb
, 0, True
);
10729 && backspace_keycode
10730 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
10731 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
10736 #else /* not HAVE_XKBGETKEYBOARD */
10738 #endif /* not HAVE_XKBGETKEYBOARD */
10743 /***********************************************************************
10745 ***********************************************************************/
10747 /* Keep this list in the same order as frame_parms in frame.c.
10748 Use 0 for unsupported frame parameters. */
10750 frame_parm_handler x_frame_parm_handlers
[] =
10754 x_set_background_color
,
10755 x_set_border_color
,
10756 x_set_border_width
,
10757 x_set_cursor_color
,
10760 x_set_foreground_color
,
10763 x_set_internal_border_width
,
10764 x_set_menu_bar_lines
,
10766 x_explicitly_set_name
,
10767 x_set_scroll_bar_width
,
10769 x_set_unsplittable
,
10770 x_set_vertical_scroll_bars
,
10772 x_set_tool_bar_lines
,
10773 x_set_scroll_bar_foreground
,
10774 x_set_scroll_bar_background
,
10775 x_set_screen_gamma
,
10776 x_set_line_spacing
,
10777 x_set_fringe_width
,
10778 x_set_fringe_width
,
10786 /* This is zero if not using X windows. */
10789 /* The section below is built by the lisp expression at the top of the file,
10790 just above where these variables are declared. */
10791 /*&&& init symbols here &&&*/
10792 Qnone
= intern ("none");
10793 staticpro (&Qnone
);
10794 Qsuppress_icon
= intern ("suppress-icon");
10795 staticpro (&Qsuppress_icon
);
10796 Qundefined_color
= intern ("undefined-color");
10797 staticpro (&Qundefined_color
);
10798 Qcenter
= intern ("center");
10799 staticpro (&Qcenter
);
10800 Qcompound_text
= intern ("compound-text");
10801 staticpro (&Qcompound_text
);
10802 Qcancel_timer
= intern ("cancel-timer");
10803 staticpro (&Qcancel_timer
);
10804 /* This is the end of symbol initialization. */
10806 /* Text property `display' should be nonsticky by default. */
10807 Vtext_property_default_nonsticky
10808 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
10811 Qlaplace
= intern ("laplace");
10812 staticpro (&Qlaplace
);
10813 Qemboss
= intern ("emboss");
10814 staticpro (&Qemboss
);
10815 Qedge_detection
= intern ("edge-detection");
10816 staticpro (&Qedge_detection
);
10817 Qheuristic
= intern ("heuristic");
10818 staticpro (&Qheuristic
);
10819 QCmatrix
= intern (":matrix");
10820 staticpro (&QCmatrix
);
10821 QCcolor_adjustment
= intern (":color-adjustment");
10822 staticpro (&QCcolor_adjustment
);
10823 QCmask
= intern (":mask");
10824 staticpro (&QCmask
);
10826 Fput (Qundefined_color
, Qerror_conditions
,
10827 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
10828 Fput (Qundefined_color
, Qerror_message
,
10829 build_string ("Undefined color"));
10831 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images
,
10832 doc
: /* Non-nil means always draw a cross over disabled images.
10833 Disabled images are those having an `:conversion disabled' property.
10834 A cross is always drawn on black & white displays. */);
10835 cross_disabled_images
= 0;
10837 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
10838 doc
: /* List of directories to search for window system bitmap files. */);
10839 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
10841 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
10842 doc
: /* The shape of the pointer when over text.
10843 Changing the value does not affect existing frames
10844 unless you set the mouse color. */);
10845 Vx_pointer_shape
= Qnil
;
10847 #if 0 /* This doesn't really do anything. */
10848 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
10849 doc
: /* The shape of the pointer when not over text.
10850 This variable takes effect when you create a new frame
10851 or when you set the mouse color. */);
10853 Vx_nontext_pointer_shape
= Qnil
;
10855 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
10856 doc
: /* The shape of the pointer when Emacs is busy.
10857 This variable takes effect when you create a new frame
10858 or when you set the mouse color. */);
10859 Vx_hourglass_pointer_shape
= Qnil
;
10861 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
10862 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
10863 display_hourglass_p
= 1;
10865 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
10866 doc
: /* *Seconds to wait before displaying an hourglass pointer.
10867 Value must be an integer or float. */);
10868 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
10870 #if 0 /* This doesn't really do anything. */
10871 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
10872 doc
: /* The shape of the pointer when over the mode line.
10873 This variable takes effect when you create a new frame
10874 or when you set the mouse color. */);
10876 Vx_mode_pointer_shape
= Qnil
;
10878 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
10879 &Vx_sensitive_text_pointer_shape
,
10880 doc
: /* The shape of the pointer when over mouse-sensitive text.
10881 This variable takes effect when you create a new frame
10882 or when you set the mouse color. */);
10883 Vx_sensitive_text_pointer_shape
= Qnil
;
10885 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
10886 &Vx_window_horizontal_drag_shape
,
10887 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
10888 This variable takes effect when you create a new frame
10889 or when you set the mouse color. */);
10890 Vx_window_horizontal_drag_shape
= Qnil
;
10892 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
10893 doc
: /* A string indicating the foreground color of the cursor box. */);
10894 Vx_cursor_fore_pixel
= Qnil
;
10896 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
10897 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
10898 Text larger than this is clipped. */);
10899 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
10901 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
10902 doc
: /* Non-nil if no X window manager is in use.
10903 Emacs doesn't try to figure this out; this is always nil
10904 unless you set it to something else. */);
10905 /* We don't have any way to find this out, so set it to nil
10906 and maybe the user would like to set it to t. */
10907 Vx_no_window_manager
= Qnil
;
10909 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
10910 &Vx_pixel_size_width_font_regexp
,
10911 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
10913 Since Emacs gets width of a font matching with this regexp from
10914 PIXEL_SIZE field of the name, font finding mechanism gets faster for
10915 such a font. This is especially effective for such large fonts as
10916 Chinese, Japanese, and Korean. */);
10917 Vx_pixel_size_width_font_regexp
= Qnil
;
10919 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
10920 doc
: /* Time after which cached images are removed from the cache.
10921 When an image has not been displayed this many seconds, remove it
10922 from the image cache. Value must be an integer or nil with nil
10923 meaning don't clear the cache. */);
10924 Vimage_cache_eviction_delay
= make_number (30 * 60);
10926 #ifdef USE_X_TOOLKIT
10927 Fprovide (intern ("x-toolkit"), Qnil
);
10929 Fprovide (intern ("motif"), Qnil
);
10931 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
10932 doc
: /* Version info for LessTif/Motif. */);
10933 Vmotif_version_string
= build_string (XmVERSION_STRING
);
10934 #endif /* USE_MOTIF */
10935 #endif /* USE_X_TOOLKIT */
10938 Fprovide (intern ("gtk"), Qnil
);
10940 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string
,
10941 doc
: /* Version info for GTK+. */);
10943 char gtk_version
[40];
10944 g_snprintf (gtk_version
, sizeof (gtk_version
), "%u.%u.%u",
10945 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
10946 Vgtk_version_string
= build_string (gtk_version
);
10948 #endif /* USE_GTK */
10950 /* X window properties. */
10951 defsubr (&Sx_change_window_property
);
10952 defsubr (&Sx_delete_window_property
);
10953 defsubr (&Sx_window_property
);
10955 defsubr (&Sxw_display_color_p
);
10956 defsubr (&Sx_display_grayscale_p
);
10957 defsubr (&Sxw_color_defined_p
);
10958 defsubr (&Sxw_color_values
);
10959 defsubr (&Sx_server_max_request_size
);
10960 defsubr (&Sx_server_vendor
);
10961 defsubr (&Sx_server_version
);
10962 defsubr (&Sx_display_pixel_width
);
10963 defsubr (&Sx_display_pixel_height
);
10964 defsubr (&Sx_display_mm_width
);
10965 defsubr (&Sx_display_mm_height
);
10966 defsubr (&Sx_display_screens
);
10967 defsubr (&Sx_display_planes
);
10968 defsubr (&Sx_display_color_cells
);
10969 defsubr (&Sx_display_visual_class
);
10970 defsubr (&Sx_display_backing_store
);
10971 defsubr (&Sx_display_save_under
);
10972 defsubr (&Sx_create_frame
);
10973 defsubr (&Sx_open_connection
);
10974 defsubr (&Sx_close_connection
);
10975 defsubr (&Sx_display_list
);
10976 defsubr (&Sx_synchronize
);
10977 defsubr (&Sx_focus_frame
);
10978 defsubr (&Sx_backspace_delete_keys_p
);
10980 /* Setting callback functions for fontset handler. */
10981 get_font_info_func
= x_get_font_info
;
10983 #if 0 /* This function pointer doesn't seem to be used anywhere.
10984 And the pointer assigned has the wrong type, anyway. */
10985 list_fonts_func
= x_list_fonts
;
10988 load_font_func
= x_load_font
;
10989 find_ccl_program_func
= x_find_ccl_program
;
10990 query_font_func
= x_query_font
;
10991 set_frame_fontset_func
= x_set_font
;
10992 check_window_system_func
= check_x
;
10995 Qxbm
= intern ("xbm");
10997 QCconversion
= intern (":conversion");
10998 staticpro (&QCconversion
);
10999 QCheuristic_mask
= intern (":heuristic-mask");
11000 staticpro (&QCheuristic_mask
);
11001 QCcolor_symbols
= intern (":color-symbols");
11002 staticpro (&QCcolor_symbols
);
11003 QCascent
= intern (":ascent");
11004 staticpro (&QCascent
);
11005 QCmargin
= intern (":margin");
11006 staticpro (&QCmargin
);
11007 QCrelief
= intern (":relief");
11008 staticpro (&QCrelief
);
11009 Qpostscript
= intern ("postscript");
11010 staticpro (&Qpostscript
);
11011 QCloader
= intern (":loader");
11012 staticpro (&QCloader
);
11013 QCbounding_box
= intern (":bounding-box");
11014 staticpro (&QCbounding_box
);
11015 QCpt_width
= intern (":pt-width");
11016 staticpro (&QCpt_width
);
11017 QCpt_height
= intern (":pt-height");
11018 staticpro (&QCpt_height
);
11019 QCindex
= intern (":index");
11020 staticpro (&QCindex
);
11021 Qpbm
= intern ("pbm");
11025 Qxpm
= intern ("xpm");
11030 Qjpeg
= intern ("jpeg");
11031 staticpro (&Qjpeg
);
11035 Qtiff
= intern ("tiff");
11036 staticpro (&Qtiff
);
11040 Qgif
= intern ("gif");
11045 Qpng
= intern ("png");
11049 defsubr (&Sclear_image_cache
);
11050 defsubr (&Simage_size
);
11051 defsubr (&Simage_mask_p
);
11053 hourglass_atimer
= NULL
;
11054 hourglass_shown_p
= 0;
11056 defsubr (&Sx_show_tip
);
11057 defsubr (&Sx_hide_tip
);
11059 staticpro (&tip_timer
);
11061 staticpro (&tip_frame
);
11063 last_show_tip_args
= Qnil
;
11064 staticpro (&last_show_tip_args
);
11067 defsubr (&Sx_file_dialog
);
11075 image_types
= NULL
;
11076 Vimage_types
= Qnil
;
11078 define_image_type (&xbm_type
);
11079 define_image_type (&gs_type
);
11080 define_image_type (&pbm_type
);
11083 define_image_type (&xpm_type
);
11087 define_image_type (&jpeg_type
);
11091 define_image_type (&tiff_type
);
11095 define_image_type (&gif_type
);
11099 define_image_type (&png_type
);
11103 #endif /* HAVE_X_WINDOWS */
11105 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
11106 (do not change this comment) */