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 (dpyinfo
->display
, 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 (dpyinfo
->display
, 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 (dpyinfo
->display
, 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 (dpyinfo
->display
, 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 (dpyinfo
->display
, 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
);
802 XDestroyImage (ximg
);
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 if (!NILP (Vx_mode_pointer_shape
))
1305 CHECK_NUMBER (Vx_mode_pointer_shape
);
1306 mode_cursor
= XCreateFontCursor (dpy
, XINT (Vx_mode_pointer_shape
));
1309 mode_cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1310 x_check_errors (dpy
, "bad modeline pointer cursor: %s");
1312 if (!NILP (Vx_sensitive_text_pointer_shape
))
1314 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
1316 = XCreateFontCursor (dpy
, XINT (Vx_sensitive_text_pointer_shape
));
1319 hand_cursor
= XCreateFontCursor (dpy
, XC_hand2
);
1321 if (!NILP (Vx_window_horizontal_drag_shape
))
1323 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
1324 horizontal_drag_cursor
1325 = XCreateFontCursor (dpy
, XINT (Vx_window_horizontal_drag_shape
));
1328 horizontal_drag_cursor
1329 = XCreateFontCursor (dpy
, XC_sb_h_double_arrow
);
1331 /* Check and report errors with the above calls. */
1332 x_check_errors (dpy
, "can't set cursor shape: %s");
1333 x_uncatch_errors (dpy
, count
);
1336 XColor fore_color
, back_color
;
1338 fore_color
.pixel
= x
->mouse_pixel
;
1339 x_query_color (f
, &fore_color
);
1340 back_color
.pixel
= mask_color
;
1341 x_query_color (f
, &back_color
);
1343 XRecolorCursor (dpy
, cursor
, &fore_color
, &back_color
);
1344 XRecolorCursor (dpy
, nontext_cursor
, &fore_color
, &back_color
);
1345 XRecolorCursor (dpy
, mode_cursor
, &fore_color
, &back_color
);
1346 XRecolorCursor (dpy
, hand_cursor
, &fore_color
, &back_color
);
1347 XRecolorCursor (dpy
, hourglass_cursor
, &fore_color
, &back_color
);
1348 XRecolorCursor (dpy
, horizontal_drag_cursor
, &fore_color
, &back_color
);
1351 if (FRAME_X_WINDOW (f
) != 0)
1352 XDefineCursor (dpy
, FRAME_X_WINDOW (f
), cursor
);
1354 if (cursor
!= x
->text_cursor
1355 && x
->text_cursor
!= 0)
1356 XFreeCursor (dpy
, x
->text_cursor
);
1357 x
->text_cursor
= cursor
;
1359 if (nontext_cursor
!= x
->nontext_cursor
1360 && x
->nontext_cursor
!= 0)
1361 XFreeCursor (dpy
, x
->nontext_cursor
);
1362 x
->nontext_cursor
= nontext_cursor
;
1364 if (hourglass_cursor
!= x
->hourglass_cursor
1365 && x
->hourglass_cursor
!= 0)
1366 XFreeCursor (dpy
, x
->hourglass_cursor
);
1367 x
->hourglass_cursor
= hourglass_cursor
;
1369 if (mode_cursor
!= x
->modeline_cursor
1370 && x
->modeline_cursor
!= 0)
1371 XFreeCursor (dpy
, f
->output_data
.x
->modeline_cursor
);
1372 x
->modeline_cursor
= mode_cursor
;
1374 if (hand_cursor
!= x
->hand_cursor
1375 && x
->hand_cursor
!= 0)
1376 XFreeCursor (dpy
, x
->hand_cursor
);
1377 x
->hand_cursor
= hand_cursor
;
1379 if (horizontal_drag_cursor
!= x
->horizontal_drag_cursor
1380 && x
->horizontal_drag_cursor
!= 0)
1381 XFreeCursor (dpy
, x
->horizontal_drag_cursor
);
1382 x
->horizontal_drag_cursor
= horizontal_drag_cursor
;
1387 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1391 x_set_cursor_color (f
, arg
, oldval
)
1393 Lisp_Object arg
, oldval
;
1395 unsigned long fore_pixel
, pixel
;
1396 int fore_pixel_allocated_p
= 0, pixel_allocated_p
= 0;
1397 struct x_output
*x
= f
->output_data
.x
;
1399 if (!NILP (Vx_cursor_fore_pixel
))
1401 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1402 WHITE_PIX_DEFAULT (f
));
1403 fore_pixel_allocated_p
= 1;
1406 fore_pixel
= x
->background_pixel
;
1408 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1409 pixel_allocated_p
= 1;
1411 /* Make sure that the cursor color differs from the background color. */
1412 if (pixel
== x
->background_pixel
)
1414 if (pixel_allocated_p
)
1416 x_free_colors (f
, &pixel
, 1);
1417 pixel_allocated_p
= 0;
1420 pixel
= x
->mouse_pixel
;
1421 if (pixel
== fore_pixel
)
1423 if (fore_pixel_allocated_p
)
1425 x_free_colors (f
, &fore_pixel
, 1);
1426 fore_pixel_allocated_p
= 0;
1428 fore_pixel
= x
->background_pixel
;
1432 unload_color (f
, x
->cursor_foreground_pixel
);
1433 if (!fore_pixel_allocated_p
)
1434 fore_pixel
= x_copy_color (f
, fore_pixel
);
1435 x
->cursor_foreground_pixel
= fore_pixel
;
1437 unload_color (f
, x
->cursor_pixel
);
1438 if (!pixel_allocated_p
)
1439 pixel
= x_copy_color (f
, pixel
);
1440 x
->cursor_pixel
= pixel
;
1442 if (FRAME_X_WINDOW (f
) != 0)
1445 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
1446 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
1449 if (FRAME_VISIBLE_P (f
))
1451 x_update_cursor (f
, 0);
1452 x_update_cursor (f
, 1);
1456 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1459 /* Set the border-color of frame F to pixel value PIX.
1460 Note that this does not fully take effect if done before
1461 F has an x-window. */
1464 x_set_border_pixel (f
, pix
)
1468 unload_color (f
, f
->output_data
.x
->border_pixel
);
1469 f
->output_data
.x
->border_pixel
= pix
;
1471 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
1474 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1475 (unsigned long)pix
);
1478 if (FRAME_VISIBLE_P (f
))
1483 /* Set the border-color of frame F to value described by ARG.
1484 ARG can be a string naming a color.
1485 The border-color is used for the border that is drawn by the X server.
1486 Note that this does not fully take effect if done before
1487 F has an x-window; it must be redone when the window is created.
1489 Note: this is done in two routines because of the way X10 works.
1491 Note: under X11, this is normally the province of the window manager,
1492 and so emacs' border colors may be overridden. */
1495 x_set_border_color (f
, arg
, oldval
)
1497 Lisp_Object arg
, oldval
;
1502 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1503 x_set_border_pixel (f
, pix
);
1504 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1509 x_set_cursor_type (f
, arg
, oldval
)
1511 Lisp_Object arg
, oldval
;
1513 set_frame_cursor_types (f
, arg
);
1515 /* Make sure the cursor gets redrawn. */
1516 cursor_type_changed
= 1;
1520 x_set_icon_type (f
, arg
, oldval
)
1522 Lisp_Object arg
, oldval
;
1528 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1531 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1536 result
= x_text_icon (f
,
1537 (char *) SDATA ((!NILP (f
->icon_name
)
1541 result
= x_bitmap_icon (f
, arg
);
1546 error ("No icon window available");
1549 XFlush (FRAME_X_DISPLAY (f
));
1554 x_set_icon_name (f
, arg
, oldval
)
1556 Lisp_Object arg
, oldval
;
1562 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1565 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1570 if (f
->output_data
.x
->icon_bitmap
!= 0)
1575 result
= x_text_icon (f
,
1576 (char *) SDATA ((!NILP (f
->icon_name
)
1585 error ("No icon window available");
1588 XFlush (FRAME_X_DISPLAY (f
));
1594 x_set_menu_bar_lines (f
, value
, oldval
)
1596 Lisp_Object value
, oldval
;
1599 #ifndef USE_X_TOOLKIT
1600 int olines
= FRAME_MENU_BAR_LINES (f
);
1603 /* Right now, menu bars don't work properly in minibuf-only frames;
1604 most of the commands try to apply themselves to the minibuffer
1605 frame itself, and get an error because you can't switch buffers
1606 in or split the minibuffer window. */
1607 if (FRAME_MINIBUF_ONLY_P (f
))
1610 if (INTEGERP (value
))
1611 nlines
= XINT (value
);
1615 /* Make sure we redisplay all windows in this frame. */
1616 windows_or_buffers_changed
++;
1618 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1619 FRAME_MENU_BAR_LINES (f
) = 0;
1622 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1623 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1624 /* Make sure next redisplay shows the menu bar. */
1625 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1629 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1630 free_frame_menubar (f
);
1631 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1633 f
->output_data
.x
->menubar_widget
= 0;
1635 #else /* not USE_X_TOOLKIT && not USE_GTK */
1636 FRAME_MENU_BAR_LINES (f
) = nlines
;
1637 change_window_heights (f
->root_window
, nlines
- olines
);
1638 #endif /* not USE_X_TOOLKIT */
1643 /* Set the number of lines used for the tool bar of frame F to VALUE.
1644 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1645 is the old number of tool bar lines. This function changes the
1646 height of all windows on frame F to match the new tool bar height.
1647 The frame's height doesn't change. */
1650 x_set_tool_bar_lines (f
, value
, oldval
)
1652 Lisp_Object value
, oldval
;
1654 int delta
, nlines
, root_height
;
1655 Lisp_Object root_window
;
1657 /* Treat tool bars like menu bars. */
1658 if (FRAME_MINIBUF_ONLY_P (f
))
1661 /* Use VALUE only if an integer >= 0. */
1662 if (INTEGERP (value
) && XINT (value
) >= 0)
1663 nlines
= XFASTINT (value
);
1668 FRAME_TOOL_BAR_LINES (f
) = 0;
1671 FRAME_EXTERNAL_TOOL_BAR (f
) = 1;
1672 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1673 /* Make sure next redisplay shows the tool bar. */
1674 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1675 update_frame_tool_bar (f
);
1679 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1680 free_frame_tool_bar (f
);
1681 FRAME_EXTERNAL_TOOL_BAR (f
) = 0;
1687 /* Make sure we redisplay all windows in this frame. */
1688 ++windows_or_buffers_changed
;
1690 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
1692 /* Don't resize the tool-bar to more than we have room for. */
1693 root_window
= FRAME_ROOT_WINDOW (f
);
1694 root_height
= WINDOW_TOTAL_LINES (XWINDOW (root_window
));
1695 if (root_height
- delta
< 1)
1697 delta
= root_height
- 1;
1698 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
1701 FRAME_TOOL_BAR_LINES (f
) = nlines
;
1702 change_window_heights (root_window
, delta
);
1705 /* We also have to make sure that the internal border at the top of
1706 the frame, below the menu bar or tool bar, is redrawn when the
1707 tool bar disappears. This is so because the internal border is
1708 below the tool bar if one is displayed, but is below the menu bar
1709 if there isn't a tool bar. The tool bar draws into the area
1710 below the menu bar. */
1711 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
1715 clear_current_matrices (f
);
1716 updating_frame
= NULL
;
1719 /* If the tool bar gets smaller, the internal border below it
1720 has to be cleared. It was formerly part of the display
1721 of the larger tool bar, and updating windows won't clear it. */
1724 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1725 int width
= FRAME_PIXEL_WIDTH (f
);
1726 int y
= nlines
* FRAME_LINE_HEIGHT (f
);
1729 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1730 0, y
, width
, height
, False
);
1733 if (WINDOWP (f
->tool_bar_window
))
1734 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1739 /* Set the foreground color for scroll bars on frame F to VALUE.
1740 VALUE should be a string, a color name. If it isn't a string or
1741 isn't a valid color name, do nothing. OLDVAL is the old value of
1742 the frame parameter. */
1745 x_set_scroll_bar_foreground (f
, value
, oldval
)
1747 Lisp_Object value
, oldval
;
1749 unsigned long pixel
;
1751 if (STRINGP (value
))
1752 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1756 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1757 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1759 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1760 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1762 /* Remove all scroll bars because they have wrong colors. */
1763 if (condemn_scroll_bars_hook
)
1764 (*condemn_scroll_bars_hook
) (f
);
1765 if (judge_scroll_bars_hook
)
1766 (*judge_scroll_bars_hook
) (f
);
1768 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1774 /* Set the background color for scroll bars on frame F to VALUE VALUE
1775 should be a string, a color name. If it isn't a string or isn't a
1776 valid color name, do nothing. OLDVAL is the old value of the frame
1780 x_set_scroll_bar_background (f
, value
, oldval
)
1782 Lisp_Object value
, oldval
;
1784 unsigned long pixel
;
1786 if (STRINGP (value
))
1787 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1791 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1792 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1794 #ifdef USE_TOOLKIT_SCROLL_BARS
1795 /* Scrollbar shadow colors. */
1796 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1798 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1799 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1801 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1803 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1804 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1806 #endif /* USE_TOOLKIT_SCROLL_BARS */
1808 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1809 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1811 /* Remove all scroll bars because they have wrong colors. */
1812 if (condemn_scroll_bars_hook
)
1813 (*condemn_scroll_bars_hook
) (f
);
1814 if (judge_scroll_bars_hook
)
1815 (*judge_scroll_bars_hook
) (f
);
1817 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1823 /* Encode Lisp string STRING as a text in a format appropriate for
1824 XICCC (X Inter Client Communication Conventions).
1826 If STRING contains only ASCII characters, do no conversion and
1827 return the string data of STRING. Otherwise, encode the text by
1828 CODING_SYSTEM, and return a newly allocated memory area which
1829 should be freed by `xfree' by a caller.
1831 SELECTIONP non-zero means the string is being encoded for an X
1832 selection, so it is safe to run pre-write conversions (which
1835 Store the byte length of resulting text in *TEXT_BYTES.
1837 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1838 which means that the `encoding' of the result can be `STRING'.
1839 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1840 the result should be `COMPOUND_TEXT'. */
1843 x_encode_text (string
, coding_system
, selectionp
, text_bytes
, stringp
)
1844 Lisp_Object string
, coding_system
;
1845 int *text_bytes
, *stringp
;
1848 unsigned char *str
= SDATA (string
);
1849 int chars
= SCHARS (string
);
1850 int bytes
= SBYTES (string
);
1854 struct coding_system coding
;
1855 extern Lisp_Object Qcompound_text_with_extensions
;
1857 charset_info
= find_charset_in_text (str
, chars
, bytes
, NULL
, Qnil
);
1858 if (charset_info
== 0)
1860 /* No multibyte character in OBJ. We need not encode it. */
1861 *text_bytes
= bytes
;
1866 setup_coding_system (coding_system
, &coding
);
1868 && SYMBOLP (coding
.pre_write_conversion
)
1869 && !NILP (Ffboundp (coding
.pre_write_conversion
)))
1871 string
= run_pre_post_conversion_on_str (string
, &coding
, 1);
1872 str
= SDATA (string
);
1873 chars
= SCHARS (string
);
1874 bytes
= SBYTES (string
);
1876 coding
.src_multibyte
= 1;
1877 coding
.dst_multibyte
= 0;
1878 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1879 if (coding
.type
== coding_type_iso2022
)
1880 coding
.flags
|= CODING_FLAG_ISO_SAFE
;
1881 /* We suppress producing escape sequences for composition. */
1882 coding
.composing
= COMPOSITION_DISABLED
;
1883 bufsize
= encoding_buffer_size (&coding
, bytes
);
1884 buf
= (unsigned char *) xmalloc (bufsize
);
1885 encode_coding (&coding
, str
, buf
, bytes
, bufsize
);
1886 *text_bytes
= coding
.produced
;
1887 *stringp
= (charset_info
== 1
1888 || (!EQ (coding_system
, Qcompound_text
)
1889 && !EQ (coding_system
, Qcompound_text_with_extensions
)));
1894 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1897 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1898 name; if NAME is a string, set F's name to NAME and set
1899 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1901 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1902 suggesting a new name, which lisp code should override; if
1903 F->explicit_name is set, ignore the new name; otherwise, set it. */
1906 x_set_name (f
, name
, explicit)
1911 /* Make sure that requests from lisp code override requests from
1912 Emacs redisplay code. */
1915 /* If we're switching from explicit to implicit, we had better
1916 update the mode lines and thereby update the title. */
1917 if (f
->explicit_name
&& NILP (name
))
1918 update_mode_lines
= 1;
1920 f
->explicit_name
= ! NILP (name
);
1922 else if (f
->explicit_name
)
1925 /* If NAME is nil, set the name to the x_id_name. */
1928 /* Check for no change needed in this very common case
1929 before we do any consing. */
1930 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1933 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1936 CHECK_STRING (name
);
1938 /* Don't change the name if it's already NAME. */
1939 if (! NILP (Fstring_equal (name
, f
->name
)))
1944 /* For setting the frame title, the title parameter should override
1945 the name parameter. */
1946 if (! NILP (f
->title
))
1949 if (FRAME_X_WINDOW (f
))
1954 XTextProperty text
, icon
;
1956 Lisp_Object coding_system
;
1958 /* Note: Encoding strategy
1960 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1961 text.encoding. But, there are non-internationalized window
1962 managers which don't support that encoding. So, if NAME
1963 contains only ASCII and 8859-1 characters, encode it by
1964 iso-latin-1, and use "STRING" in text.encoding hoping that
1965 such window managers at least analyze this format correctly,
1966 i.e. treat 8-bit bytes as 8859-1 characters.
1968 We may also be able to use "UTF8_STRING" in text.encoding
1969 in the future which can encode all Unicode characters.
1970 But, for the moment, there's no way to know that the
1971 current window manager supports it or not. */
1972 coding_system
= Qcompound_text
;
1973 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
1974 text
.encoding
= (stringp
? XA_STRING
1975 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1977 text
.nitems
= bytes
;
1979 if (NILP (f
->icon_name
))
1985 /* See the above comment "Note: Encoding strategy". */
1986 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
1988 icon
.encoding
= (stringp
? XA_STRING
1989 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1991 icon
.nitems
= bytes
;
1994 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1996 #else /* not USE_GTK */
1997 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1998 #endif /* not USE_GTK */
2000 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
2002 if (!NILP (f
->icon_name
)
2003 && icon
.value
!= (unsigned char *) SDATA (f
->icon_name
))
2005 if (text
.value
!= (unsigned char *) SDATA (name
))
2008 #else /* not HAVE_X11R4 */
2009 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2011 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2013 #endif /* not HAVE_X11R4 */
2018 /* This function should be called when the user's lisp code has
2019 specified a name for the frame; the name will override any set by the
2022 x_explicitly_set_name (f
, arg
, oldval
)
2024 Lisp_Object arg
, oldval
;
2026 x_set_name (f
, arg
, 1);
2029 /* This function should be called by Emacs redisplay code to set the
2030 name; names set this way will never override names set by the user's
2033 x_implicitly_set_name (f
, arg
, oldval
)
2035 Lisp_Object arg
, oldval
;
2037 x_set_name (f
, arg
, 0);
2040 /* Change the title of frame F to NAME.
2041 If NAME is nil, use the frame name as the title.
2043 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2044 name; if NAME is a string, set F's name to NAME and set
2045 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2047 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2048 suggesting a new name, which lisp code should override; if
2049 F->explicit_name is set, ignore the new name; otherwise, set it. */
2052 x_set_title (f
, name
, old_name
)
2054 Lisp_Object name
, old_name
;
2056 /* Don't change the title if it's already NAME. */
2057 if (EQ (name
, f
->title
))
2060 update_mode_lines
= 1;
2067 CHECK_STRING (name
);
2069 if (FRAME_X_WINDOW (f
))
2074 XTextProperty text
, icon
;
2076 Lisp_Object coding_system
;
2078 coding_system
= Qcompound_text
;
2079 /* See the comment "Note: Encoding strategy" in x_set_name. */
2080 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
2081 text
.encoding
= (stringp
? XA_STRING
2082 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
2084 text
.nitems
= bytes
;
2086 if (NILP (f
->icon_name
))
2092 /* See the comment "Note: Encoding strategy" in x_set_name. */
2093 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
2095 icon
.encoding
= (stringp
? XA_STRING
2096 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
2098 icon
.nitems
= bytes
;
2102 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
2104 #else /* not USE_GTK */
2105 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
2106 #endif /* not USE_GTK */
2108 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
2111 if (!NILP (f
->icon_name
)
2112 && icon
.value
!= (unsigned char *) SDATA (f
->icon_name
))
2114 if (text
.value
!= (unsigned char *) SDATA (name
))
2117 #else /* not HAVE_X11R4 */
2118 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2120 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2122 #endif /* not HAVE_X11R4 */
2128 x_set_scroll_bar_default_width (f
)
2131 int wid
= FRAME_COLUMN_WIDTH (f
);
2133 #ifdef USE_TOOLKIT_SCROLL_BARS
2134 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
2135 int width
= 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
2136 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (width
+ wid
- 1) / wid
;
2137 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = width
;
2139 /* Make the actual width at least 14 pixels and a multiple of a
2141 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
2143 /* Use all of that space (aside from required margins) for the
2145 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 0;
2150 /* Record in frame F the specified or default value according to ALIST
2151 of the parameter named PROP (a Lisp symbol). If no value is
2152 specified for PROP, look for an X default for XPROP on the frame
2153 named NAME. If that is not found either, use the value DEFLT. */
2156 x_default_scroll_bar_color_parameter (f
, alist
, prop
, xprop
, xclass
,
2165 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2168 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
2169 if (EQ (tem
, Qunbound
))
2171 #ifdef USE_TOOLKIT_SCROLL_BARS
2173 /* See if an X resource for the scroll bar color has been
2175 tem
= display_x_get_resource (dpyinfo
,
2176 build_string (foreground_p
2180 build_string ("verticalScrollBar"),
2184 /* If nothing has been specified, scroll bars will use a
2185 toolkit-dependent default. Because these defaults are
2186 difficult to get at without actually creating a scroll
2187 bar, use nil to indicate that no color has been
2192 #else /* not USE_TOOLKIT_SCROLL_BARS */
2196 #endif /* not USE_TOOLKIT_SCROLL_BARS */
2199 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2205 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2208 XSetWMProtocols (dpy
, w
, protocols
, count
)
2215 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2216 if (prop
== None
) return False
;
2217 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2218 (unsigned char *) protocols
, count
);
2221 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2223 #ifdef USE_X_TOOLKIT
2225 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2226 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2227 already be present because of the toolkit (Motif adds some of them,
2228 for example, but Xt doesn't). */
2231 hack_wm_protocols (f
, widget
)
2235 Display
*dpy
= XtDisplay (widget
);
2236 Window w
= XtWindow (widget
);
2237 int need_delete
= 1;
2243 Atom type
, *atoms
= 0;
2245 unsigned long nitems
= 0;
2246 unsigned long bytes_after
;
2248 if ((XGetWindowProperty (dpy
, w
,
2249 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2250 (long)0, (long)100, False
, XA_ATOM
,
2251 &type
, &format
, &nitems
, &bytes_after
,
2252 (unsigned char **) &atoms
)
2254 && format
== 32 && type
== XA_ATOM
)
2258 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2260 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2262 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2265 if (atoms
) XFree ((char *) atoms
);
2271 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2273 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2275 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2277 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2278 XA_ATOM
, 32, PropModeAppend
,
2279 (unsigned char *) props
, count
);
2287 /* Support routines for XIC (X Input Context). */
2291 static XFontSet xic_create_xfontset
P_ ((struct frame
*, char *));
2292 static XIMStyle best_xim_style
P_ ((XIMStyles
*, XIMStyles
*));
2295 /* Supported XIM styles, ordered by preference. */
2297 static XIMStyle supported_xim_styles
[] =
2299 XIMPreeditPosition
| XIMStatusArea
,
2300 XIMPreeditPosition
| XIMStatusNothing
,
2301 XIMPreeditPosition
| XIMStatusNone
,
2302 XIMPreeditNothing
| XIMStatusArea
,
2303 XIMPreeditNothing
| XIMStatusNothing
,
2304 XIMPreeditNothing
| XIMStatusNone
,
2305 XIMPreeditNone
| XIMStatusArea
,
2306 XIMPreeditNone
| XIMStatusNothing
,
2307 XIMPreeditNone
| XIMStatusNone
,
2312 /* Create an X fontset on frame F with base font name
2316 xic_create_xfontset (f
, base_fontname
)
2318 char *base_fontname
;
2321 char **missing_list
;
2325 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
2326 base_fontname
, &missing_list
,
2327 &missing_count
, &def_string
);
2329 XFreeStringList (missing_list
);
2331 /* No need to free def_string. */
2336 /* Value is the best input style, given user preferences USER (already
2337 checked to be supported by Emacs), and styles supported by the
2338 input method XIM. */
2341 best_xim_style (user
, xim
)
2347 for (i
= 0; i
< user
->count_styles
; ++i
)
2348 for (j
= 0; j
< xim
->count_styles
; ++j
)
2349 if (user
->supported_styles
[i
] == xim
->supported_styles
[j
])
2350 return user
->supported_styles
[i
];
2352 /* Return the default style. */
2353 return XIMPreeditNothing
| XIMStatusNothing
;
2356 /* Create XIC for frame F. */
2358 static XIMStyle xic_style
;
2361 create_frame_xic (f
)
2366 XFontSet xfs
= NULL
;
2371 xim
= FRAME_X_XIM (f
);
2376 XVaNestedList preedit_attr
;
2377 XVaNestedList status_attr
;
2378 char *base_fontname
;
2381 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2382 spot
.x
= 0; spot
.y
= 1;
2383 /* Create X fontset. */
2384 fontset
= FRAME_FONTSET (f
);
2386 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2389 /* Determine the base fontname from the ASCII font name of
2391 char *ascii_font
= (char *) SDATA (fontset_ascii (fontset
));
2392 char *p
= ascii_font
;
2395 for (i
= 0; *p
; p
++)
2398 /* As the font name doesn't conform to XLFD, we can't
2399 modify it to get a suitable base fontname for the
2401 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2404 int len
= strlen (ascii_font
) + 1;
2407 for (i
= 0, p
= ascii_font
; i
< 8; p
++)
2416 base_fontname
= (char *) alloca (len
);
2417 bzero (base_fontname
, len
);
2418 strcpy (base_fontname
, "-*-*-");
2419 bcopy (p1
, base_fontname
+ 5, p
- p1
);
2420 strcat (base_fontname
, "*-*-*-*-*-*-*");
2423 xfs
= xic_create_xfontset (f
, base_fontname
);
2425 /* Determine XIC style. */
2428 XIMStyles supported_list
;
2429 supported_list
.count_styles
= (sizeof supported_xim_styles
2430 / sizeof supported_xim_styles
[0]);
2431 supported_list
.supported_styles
= supported_xim_styles
;
2432 xic_style
= best_xim_style (&supported_list
,
2433 FRAME_X_XIM_STYLES (f
));
2436 preedit_attr
= XVaCreateNestedList (0,
2439 FRAME_FOREGROUND_PIXEL (f
),
2441 FRAME_BACKGROUND_PIXEL (f
),
2442 (xic_style
& XIMPreeditPosition
2447 status_attr
= XVaCreateNestedList (0,
2453 FRAME_FOREGROUND_PIXEL (f
),
2455 FRAME_BACKGROUND_PIXEL (f
),
2458 xic
= XCreateIC (xim
,
2459 XNInputStyle
, xic_style
,
2460 XNClientWindow
, FRAME_X_WINDOW (f
),
2461 XNFocusWindow
, FRAME_X_WINDOW (f
),
2462 XNStatusAttributes
, status_attr
,
2463 XNPreeditAttributes
, preedit_attr
,
2465 XFree (preedit_attr
);
2466 XFree (status_attr
);
2469 FRAME_XIC (f
) = xic
;
2470 FRAME_XIC_STYLE (f
) = xic_style
;
2471 FRAME_XIC_FONTSET (f
) = xfs
;
2475 /* Destroy XIC and free XIC fontset of frame F, if any. */
2481 if (FRAME_XIC (f
) == NULL
)
2484 XDestroyIC (FRAME_XIC (f
));
2485 if (FRAME_XIC_FONTSET (f
))
2486 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2488 FRAME_XIC (f
) = NULL
;
2489 FRAME_XIC_FONTSET (f
) = NULL
;
2493 /* Place preedit area for XIC of window W's frame to specified
2494 pixel position X/Y. X and Y are relative to window W. */
2497 xic_set_preeditarea (w
, x
, y
)
2501 struct frame
*f
= XFRAME (w
->frame
);
2505 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2506 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2507 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2508 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2513 /* Place status area for XIC in bottom right corner of frame F.. */
2516 xic_set_statusarea (f
)
2519 XIC xic
= FRAME_XIC (f
);
2524 /* Negotiate geometry of status area. If input method has existing
2525 status area, use its current size. */
2526 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2527 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2528 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2531 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2532 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2535 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2537 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2538 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2542 area
.width
= needed
->width
;
2543 area
.height
= needed
->height
;
2544 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2545 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2546 - FRAME_MENUBAR_HEIGHT (f
)
2547 - FRAME_TOOLBAR_HEIGHT (f
)
2548 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2551 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2552 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2557 /* Set X fontset for XIC of frame F, using base font name
2558 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2561 xic_set_xfontset (f
, base_fontname
)
2563 char *base_fontname
;
2568 xfs
= xic_create_xfontset (f
, base_fontname
);
2570 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2571 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2572 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2573 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2574 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2577 if (FRAME_XIC_FONTSET (f
))
2578 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2579 FRAME_XIC_FONTSET (f
) = xfs
;
2582 #endif /* HAVE_X_I18N */
2586 #ifdef USE_X_TOOLKIT
2588 /* Create and set up the X widget for frame F. */
2591 x_window (f
, window_prompting
, minibuffer_only
)
2593 long window_prompting
;
2594 int minibuffer_only
;
2596 XClassHint class_hints
;
2597 XSetWindowAttributes attributes
;
2598 unsigned long attribute_mask
;
2599 Widget shell_widget
;
2601 Widget frame_widget
;
2607 /* Use the resource name as the top-level widget name
2608 for looking up resources. Make a non-Lisp copy
2609 for the window manager, so GC relocation won't bother it.
2611 Elsewhere we specify the window name for the window manager. */
2614 char *str
= (char *) SDATA (Vx_resource_name
);
2615 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2616 strcpy (f
->namebuf
, str
);
2620 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2621 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2622 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2623 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2624 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2625 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2626 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2627 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2628 applicationShellWidgetClass
,
2629 FRAME_X_DISPLAY (f
), al
, ac
);
2631 f
->output_data
.x
->widget
= shell_widget
;
2632 /* maybe_set_screen_title_format (shell_widget); */
2634 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2635 (widget_value
*) NULL
,
2636 shell_widget
, False
,
2640 (lw_callback
) NULL
);
2643 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2644 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2645 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2646 XtSetValues (pane_widget
, al
, ac
);
2647 f
->output_data
.x
->column_widget
= pane_widget
;
2649 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2650 the emacs screen when changing menubar. This reduces flickering. */
2653 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2654 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2655 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2656 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2657 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2658 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2659 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2660 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2661 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2664 f
->output_data
.x
->edit_widget
= frame_widget
;
2666 XtManageChild (frame_widget
);
2668 /* Do some needed geometry management. */
2671 char *tem
, shell_position
[32];
2674 int extra_borders
= 0;
2676 = (f
->output_data
.x
->menubar_widget
2677 ? (f
->output_data
.x
->menubar_widget
->core
.height
2678 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2681 #if 0 /* Experimentally, we now get the right results
2682 for -geometry -0-0 without this. 24 Aug 96, rms. */
2683 if (FRAME_EXTERNAL_MENU_BAR (f
))
2686 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2687 menubar_size
+= ibw
;
2691 f
->output_data
.x
->menubar_height
= menubar_size
;
2694 /* Motif seems to need this amount added to the sizes
2695 specified for the shell widget. The Athena/Lucid widgets don't.
2696 Both conclusions reached experimentally. -- rms. */
2697 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2698 &extra_borders
, NULL
);
2702 /* Convert our geometry parameters into a geometry string
2704 Note that we do not specify here whether the position
2705 is a user-specified or program-specified one.
2706 We pass that information later, in x_wm_set_size_hints. */
2708 int left
= f
->left_pos
;
2709 int xneg
= window_prompting
& XNegative
;
2710 int top
= f
->top_pos
;
2711 int yneg
= window_prompting
& YNegative
;
2717 if (window_prompting
& USPosition
)
2718 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2719 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2720 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2721 (xneg
? '-' : '+'), left
,
2722 (yneg
? '-' : '+'), top
);
2725 sprintf (shell_position
, "=%dx%d",
2726 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2727 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2729 /* Setting x and y when the position is not specified in
2730 the geometry string will set program position in the WM hints.
2731 If Emacs had just one program position, we could set it in
2732 fallback resources, but since each make-frame call can specify
2733 different program positions, this is easier. */
2734 XtSetArg (al
[ac
], XtNx
, left
); ac
++;
2735 XtSetArg (al
[ac
], XtNy
, top
); ac
++;
2739 len
= strlen (shell_position
) + 1;
2740 /* We don't free this because we don't know whether
2741 it is safe to free it while the frame exists.
2742 It isn't worth the trouble of arranging to free it
2743 when the frame is deleted. */
2744 tem
= (char *) xmalloc (len
);
2745 strncpy (tem
, shell_position
, len
);
2746 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2747 XtSetValues (shell_widget
, al
, ac
);
2750 XtManageChild (pane_widget
);
2751 XtRealizeWidget (shell_widget
);
2753 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2755 validate_x_resource_name ();
2757 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2758 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2759 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2762 FRAME_XIC (f
) = NULL
;
2764 create_frame_xic (f
);
2767 f
->output_data
.x
->wm_hints
.input
= True
;
2768 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2769 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2770 &f
->output_data
.x
->wm_hints
);
2772 hack_wm_protocols (f
, shell_widget
);
2775 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2778 /* Do a stupid property change to force the server to generate a
2779 PropertyNotify event so that the event_stream server timestamp will
2780 be initialized to something relevant to the time we created the window.
2782 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2783 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2784 XA_ATOM
, 32, PropModeAppend
,
2785 (unsigned char*) NULL
, 0);
2787 /* Make all the standard events reach the Emacs frame. */
2788 attributes
.event_mask
= STANDARD_EVENT_SET
;
2793 /* XIM server might require some X events. */
2794 unsigned long fevent
= NoEventMask
;
2795 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2796 attributes
.event_mask
|= fevent
;
2798 #endif /* HAVE_X_I18N */
2800 attribute_mask
= CWEventMask
;
2801 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2802 attribute_mask
, &attributes
);
2804 XtMapWidget (frame_widget
);
2806 /* x_set_name normally ignores requests to set the name if the
2807 requested name is the same as the current name. This is the one
2808 place where that assumption isn't correct; f->name is set, but
2809 the X server hasn't been told. */
2812 int explicit = f
->explicit_name
;
2814 f
->explicit_name
= 0;
2817 x_set_name (f
, name
, explicit);
2820 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2821 f
->output_data
.x
->text_cursor
);
2825 /* This is a no-op, except under Motif. Make sure main areas are
2826 set to something reasonable, in case we get an error later. */
2827 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2830 #else /* not USE_X_TOOLKIT */
2836 if (! xg_create_frame_widgets (f
))
2837 error ("Unable to create window");
2840 FRAME_XIC (f
) = NULL
;
2844 create_frame_xic (f
);
2847 /* XIM server might require some X events. */
2848 unsigned long fevent
= NoEventMask
;
2849 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2851 if (fevent
!= NoEventMask
)
2853 XSetWindowAttributes attributes
;
2854 XWindowAttributes wattr
;
2855 unsigned long attribute_mask
;
2857 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2859 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2860 attribute_mask
= CWEventMask
;
2861 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2862 attribute_mask
, &attributes
);
2870 #else /*! USE_GTK */
2871 /* Create and set up the X window for frame F. */
2878 XClassHint class_hints
;
2879 XSetWindowAttributes attributes
;
2880 unsigned long attribute_mask
;
2882 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2883 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2884 attributes
.bit_gravity
= StaticGravity
;
2885 attributes
.backing_store
= NotUseful
;
2886 attributes
.save_under
= True
;
2887 attributes
.event_mask
= STANDARD_EVENT_SET
;
2888 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2889 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2894 = XCreateWindow (FRAME_X_DISPLAY (f
),
2895 f
->output_data
.x
->parent_desc
,
2898 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2900 CopyFromParent
, /* depth */
2901 InputOutput
, /* class */
2903 attribute_mask
, &attributes
);
2908 create_frame_xic (f
);
2911 /* XIM server might require some X events. */
2912 unsigned long fevent
= NoEventMask
;
2913 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2914 attributes
.event_mask
|= fevent
;
2915 attribute_mask
= CWEventMask
;
2916 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2917 attribute_mask
, &attributes
);
2920 #endif /* HAVE_X_I18N */
2922 validate_x_resource_name ();
2924 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2925 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2926 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2928 /* The menubar is part of the ordinary display;
2929 it does not count in addition to the height of the window. */
2930 f
->output_data
.x
->menubar_height
= 0;
2932 /* This indicates that we use the "Passive Input" input model.
2933 Unless we do this, we don't get the Focus{In,Out} events that we
2934 need to draw the cursor correctly. Accursed bureaucrats.
2935 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2937 f
->output_data
.x
->wm_hints
.input
= True
;
2938 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2939 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2940 &f
->output_data
.x
->wm_hints
);
2941 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2943 /* Request "save yourself" and "delete window" commands from wm. */
2946 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2947 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2948 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2951 /* x_set_name normally ignores requests to set the name if the
2952 requested name is the same as the current name. This is the one
2953 place where that assumption isn't correct; f->name is set, but
2954 the X server hasn't been told. */
2957 int explicit = f
->explicit_name
;
2959 f
->explicit_name
= 0;
2962 x_set_name (f
, name
, explicit);
2965 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2966 f
->output_data
.x
->text_cursor
);
2970 if (FRAME_X_WINDOW (f
) == 0)
2971 error ("Unable to create window");
2974 #endif /* not USE_GTK */
2975 #endif /* not USE_X_TOOLKIT */
2977 /* Handle the icon stuff for this window. Perhaps later we might
2978 want an x_set_icon_position which can be called interactively as
2986 Lisp_Object icon_x
, icon_y
;
2987 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2989 /* Set the position of the icon. Note that twm groups all
2990 icons in an icon window. */
2991 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2992 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2993 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2995 CHECK_NUMBER (icon_x
);
2996 CHECK_NUMBER (icon_y
);
2998 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2999 error ("Both left and top icon corners of icon must be specified");
3003 if (! EQ (icon_x
, Qunbound
))
3004 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
3006 /* Start up iconic or window? */
3007 x_wm_set_window_state
3008 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
3013 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
3020 /* Make the GCs needed for this window, setting the
3021 background, border and mouse colors; also create the
3022 mouse cursor and the gray border tile. */
3024 static char cursor_bits
[] =
3026 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3027 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3028 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3029 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3036 XGCValues gc_values
;
3040 /* Create the GCs of this frame.
3041 Note that many default values are used. */
3044 gc_values
.font
= FRAME_FONT (f
)->fid
;
3045 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
3046 gc_values
.background
= f
->output_data
.x
->background_pixel
;
3047 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
3048 f
->output_data
.x
->normal_gc
3049 = XCreateGC (FRAME_X_DISPLAY (f
),
3051 GCLineWidth
| GCFont
| GCForeground
| GCBackground
,
3054 /* Reverse video style. */
3055 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3056 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
3057 f
->output_data
.x
->reverse_gc
3058 = XCreateGC (FRAME_X_DISPLAY (f
),
3060 GCFont
| GCForeground
| GCBackground
| GCLineWidth
,
3063 /* Cursor has cursor-color background, background-color foreground. */
3064 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3065 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
3066 gc_values
.fill_style
= FillOpaqueStippled
;
3068 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
3069 FRAME_X_DISPLAY_INFO (f
)->root_window
,
3070 cursor_bits
, 16, 16);
3071 f
->output_data
.x
->cursor_gc
3072 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3073 (GCFont
| GCForeground
| GCBackground
3074 | GCFillStyle
/* | GCStipple */ | GCLineWidth
),
3078 f
->output_data
.x
->white_relief
.gc
= 0;
3079 f
->output_data
.x
->black_relief
.gc
= 0;
3081 /* Create the gray border tile used when the pointer is not in
3082 the frame. Since this depends on the frame's pixel values,
3083 this must be done on a per-frame basis. */
3084 f
->output_data
.x
->border_tile
3085 = (XCreatePixmapFromBitmapData
3086 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
3087 gray_bits
, gray_width
, gray_height
,
3088 f
->output_data
.x
->foreground_pixel
,
3089 f
->output_data
.x
->background_pixel
,
3090 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
3096 /* Free what was was allocated in x_make_gc. */
3102 Display
*dpy
= FRAME_X_DISPLAY (f
);
3106 if (f
->output_data
.x
->normal_gc
)
3108 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
3109 f
->output_data
.x
->normal_gc
= 0;
3112 if (f
->output_data
.x
->reverse_gc
)
3114 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
3115 f
->output_data
.x
->reverse_gc
= 0;
3118 if (f
->output_data
.x
->cursor_gc
)
3120 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
3121 f
->output_data
.x
->cursor_gc
= 0;
3124 if (f
->output_data
.x
->border_tile
)
3126 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
3127 f
->output_data
.x
->border_tile
= 0;
3134 /* Handler for signals raised during x_create_frame and
3135 x_create_top_frame. FRAME is the frame which is partially
3139 unwind_create_frame (frame
)
3142 struct frame
*f
= XFRAME (frame
);
3144 /* If frame is ``official'', nothing to do. */
3145 if (!CONSP (Vframe_list
) || !EQ (XCAR (Vframe_list
), frame
))
3148 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3151 x_free_frame_resources (f
);
3153 /* Check that reference counts are indeed correct. */
3154 xassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
3155 xassert (dpyinfo
->image_cache
->refcount
== image_cache_refcount
);
3163 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3165 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
3166 Returns an Emacs frame object.
3167 ALIST is an alist of frame parameters.
3168 If the parameters specify that the frame should not have a minibuffer,
3169 and do not specify a specific minibuffer window to use,
3170 then `default-minibuffer-frame' must be a frame whose minibuffer can
3171 be shared by the new frame.
3173 This function is an internal primitive--use `make-frame' instead. */)
3178 Lisp_Object frame
, tem
;
3180 int minibuffer_only
= 0;
3181 long window_prompting
= 0;
3183 int count
= SPECPDL_INDEX ();
3184 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3185 Lisp_Object display
;
3186 struct x_display_info
*dpyinfo
= NULL
;
3192 /* Use this general default value to start with
3193 until we know if this frame has a specified name. */
3194 Vx_resource_name
= Vinvocation_name
;
3196 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3197 if (EQ (display
, Qunbound
))
3199 dpyinfo
= check_x_display_info (display
);
3201 kb
= dpyinfo
->kboard
;
3203 kb
= &the_only_kboard
;
3206 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3208 && ! EQ (name
, Qunbound
)
3210 error ("Invalid frame name--not a string or nil");
3213 Vx_resource_name
= name
;
3215 /* See if parent window is specified. */
3216 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3217 if (EQ (parent
, Qunbound
))
3219 if (! NILP (parent
))
3220 CHECK_NUMBER (parent
);
3222 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3223 /* No need to protect DISPLAY because that's not used after passing
3224 it to make_frame_without_minibuffer. */
3226 GCPRO4 (parms
, parent
, name
, frame
);
3227 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3229 if (EQ (tem
, Qnone
) || NILP (tem
))
3230 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3231 else if (EQ (tem
, Qonly
))
3233 f
= make_minibuffer_frame ();
3234 minibuffer_only
= 1;
3236 else if (WINDOWP (tem
))
3237 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3241 XSETFRAME (frame
, f
);
3243 /* Note that X Windows does support scroll bars. */
3244 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3246 f
->output_method
= output_x_window
;
3247 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3248 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3249 f
->output_data
.x
->icon_bitmap
= -1;
3250 FRAME_FONTSET (f
) = -1;
3251 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3252 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3253 #ifdef USE_TOOLKIT_SCROLL_BARS
3254 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3255 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3256 #endif /* USE_TOOLKIT_SCROLL_BARS */
3257 record_unwind_protect (unwind_create_frame
, frame
);
3260 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3262 if (! STRINGP (f
->icon_name
))
3263 f
->icon_name
= Qnil
;
3265 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3267 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
3268 dpyinfo_refcount
= dpyinfo
->reference_count
;
3269 #endif /* GLYPH_DEBUG */
3271 FRAME_KBOARD (f
) = kb
;
3274 /* These colors will be set anyway later, but it's important
3275 to get the color reference counts right, so initialize them! */
3278 struct gcpro gcpro1
;
3280 /* Function x_decode_color can signal an error. Make
3281 sure to initialize color slots so that we won't try
3282 to free colors we haven't allocated. */
3283 f
->output_data
.x
->foreground_pixel
= -1;
3284 f
->output_data
.x
->background_pixel
= -1;
3285 f
->output_data
.x
->cursor_pixel
= -1;
3286 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3287 f
->output_data
.x
->border_pixel
= -1;
3288 f
->output_data
.x
->mouse_pixel
= -1;
3290 black
= build_string ("black");
3292 f
->output_data
.x
->foreground_pixel
3293 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3294 f
->output_data
.x
->background_pixel
3295 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3296 f
->output_data
.x
->cursor_pixel
3297 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3298 f
->output_data
.x
->cursor_foreground_pixel
3299 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3300 f
->output_data
.x
->border_pixel
3301 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3302 f
->output_data
.x
->mouse_pixel
3303 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3307 /* Specify the parent under which to make this X window. */
3311 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3312 f
->output_data
.x
->explicit_parent
= 1;
3316 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3317 f
->output_data
.x
->explicit_parent
= 0;
3320 /* Set the name; the functions to which we pass f expect the name to
3322 if (EQ (name
, Qunbound
) || NILP (name
))
3324 f
->name
= build_string (dpyinfo
->x_id_name
);
3325 f
->explicit_name
= 0;
3330 f
->explicit_name
= 1;
3331 /* use the frame's title when getting resources for this frame. */
3332 specbind (Qx_resource_name
, name
);
3335 /* Extract the window parameters from the supplied values
3336 that are needed to determine window geometry. */
3340 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3343 /* First, try whatever font the caller has specified. */
3346 tem
= Fquery_fontset (font
, Qnil
);
3348 font
= x_new_fontset (f
, SDATA (tem
));
3350 font
= x_new_font (f
, SDATA (font
));
3353 /* Try out a font which we hope has bold and italic variations. */
3354 if (!STRINGP (font
))
3355 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
3356 if (!STRINGP (font
))
3357 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3358 if (! STRINGP (font
))
3359 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3360 if (! STRINGP (font
))
3361 /* This was formerly the first thing tried, but it finds too many fonts
3362 and takes too long. */
3363 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3364 /* If those didn't work, look for something which will at least work. */
3365 if (! STRINGP (font
))
3366 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3368 if (! STRINGP (font
))
3369 font
= build_string ("fixed");
3371 x_default_parameter (f
, parms
, Qfont
, font
,
3372 "font", "Font", RES_TYPE_STRING
);
3376 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3377 whereby it fails to get any font. */
3378 xlwmenu_default_font
= FRAME_FONT (f
);
3381 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3382 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3384 /* This defaults to 1 in order to match xterm. We recognize either
3385 internalBorderWidth or internalBorder (which is what xterm calls
3387 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3391 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3392 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3393 if (! EQ (value
, Qunbound
))
3394 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3397 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3398 "internalBorderWidth", "internalBorderWidth",
3400 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3401 "verticalScrollBars", "ScrollBars",
3404 /* Also do the stuff which must be set before the window exists. */
3405 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3406 "foreground", "Foreground", RES_TYPE_STRING
);
3407 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3408 "background", "Background", RES_TYPE_STRING
);
3409 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3410 "pointerColor", "Foreground", RES_TYPE_STRING
);
3411 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3412 "cursorColor", "Foreground", RES_TYPE_STRING
);
3413 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3414 "borderColor", "BorderColor", RES_TYPE_STRING
);
3415 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3416 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3417 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3418 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3419 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3420 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3421 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3422 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3424 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3425 "scrollBarForeground",
3426 "ScrollBarForeground", 1);
3427 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3428 "scrollBarBackground",
3429 "ScrollBarBackground", 0);
3431 /* Init faces before x_default_parameter is called for scroll-bar
3432 parameters because that function calls x_set_scroll_bar_width,
3433 which calls change_frame_size, which calls Fset_window_buffer,
3434 which runs hooks, which call Fvertical_motion. At the end, we
3435 end up in init_iterator with a null face cache, which should not
3437 init_frame_faces (f
);
3439 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3440 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3441 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (1),
3442 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3443 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3444 "bufferPredicate", "BufferPredicate",
3446 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3447 "title", "Title", RES_TYPE_STRING
);
3448 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3449 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3450 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3451 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3453 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3455 /* Compute the size of the X window. */
3456 window_prompting
= x_figure_window_size (f
, parms
, 1);
3458 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3459 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3461 /* Create the X widget or window. */
3462 #ifdef USE_X_TOOLKIT
3463 x_window (f
, window_prompting
, minibuffer_only
);
3471 /* Now consider the frame official. */
3472 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3473 Vframe_list
= Fcons (frame
, Vframe_list
);
3475 /* We need to do this after creating the X window, so that the
3476 icon-creation functions can say whose icon they're describing. */
3477 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3478 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
3480 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3481 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3482 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3483 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3484 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3485 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3486 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3487 "scrollBarWidth", "ScrollBarWidth",
3490 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3491 Change will not be effected unless different from the current
3493 width
= FRAME_COLS (f
);
3494 height
= FRAME_LINES (f
);
3496 SET_FRAME_COLS (f
, 0);
3497 FRAME_LINES (f
) = 0;
3498 change_frame_size (f
, height
, width
, 1, 0, 0);
3500 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3501 /* Create the menu bar. */
3502 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3504 /* If this signals an error, we haven't set size hints for the
3505 frame and we didn't make it visible. */
3506 initialize_frame_menubar (f
);
3509 /* This is a no-op, except under Motif where it arranges the
3510 main window for the widgets on it. */
3511 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3512 f
->output_data
.x
->menubar_widget
,
3513 f
->output_data
.x
->edit_widget
);
3514 #endif /* not USE_GTK */
3516 #endif /* USE_X_TOOLKIT || USE_GTK */
3518 /* Tell the server what size and position, etc, we want, and how
3519 badly we want them. This should be done after we have the menu
3520 bar so that its size can be taken into account. */
3522 x_wm_set_size_hint (f
, window_prompting
, 0);
3525 /* Make the window appear on the frame and enable display, unless
3526 the caller says not to. However, with explicit parent, Emacs
3527 cannot control visibility, so don't try. */
3528 if (! f
->output_data
.x
->explicit_parent
)
3530 Lisp_Object visibility
;
3532 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3534 if (EQ (visibility
, Qunbound
))
3537 if (EQ (visibility
, Qicon
))
3538 x_iconify_frame (f
);
3539 else if (! NILP (visibility
))
3540 x_make_frame_visible (f
);
3542 /* Must have been Qnil. */
3546 /* Set the WM leader property. GTK does this itself, so this is not
3547 needed when using GTK. */
3548 if (dpyinfo
->client_leader_window
!= 0)
3551 XChangeProperty (FRAME_X_DISPLAY (f
),
3552 FRAME_OUTER_WINDOW (f
),
3553 dpyinfo
->Xatom_wm_client_leader
,
3554 XA_WINDOW
, 32, PropModeReplace
,
3555 (char *) &dpyinfo
->client_leader_window
, 1);
3561 /* Make sure windows on this frame appear in calls to next-window
3562 and similar functions. */
3563 Vwindow_list
= Qnil
;
3565 return unbind_to (count
, frame
);
3569 /* FRAME is used only to get a handle on the X display. We don't pass the
3570 display info directly because we're called from frame.c, which doesn't
3571 know about that structure. */
3574 x_get_focus_frame (frame
)
3575 struct frame
*frame
;
3577 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3579 if (! dpyinfo
->x_focus_frame
)
3582 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3587 /* In certain situations, when the window manager follows a
3588 click-to-focus policy, there seems to be no way around calling
3589 XSetInputFocus to give another frame the input focus .
3591 In an ideal world, XSetInputFocus should generally be avoided so
3592 that applications don't interfere with the window manager's focus
3593 policy. But I think it's okay to use when it's clearly done
3594 following a user-command. */
3596 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
3597 doc
: /* Set the input focus to FRAME.
3598 FRAME nil means use the selected frame. */)
3602 struct frame
*f
= check_x_frame (frame
);
3603 Display
*dpy
= FRAME_X_DISPLAY (f
);
3607 count
= x_catch_errors (dpy
);
3608 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3609 RevertToParent
, CurrentTime
);
3610 x_uncatch_errors (dpy
, count
);
3617 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3618 doc
: /* Internal function called by `color-defined-p', which see. */)
3620 Lisp_Object color
, frame
;
3623 FRAME_PTR f
= check_x_frame (frame
);
3625 CHECK_STRING (color
);
3627 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3633 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3634 doc
: /* Internal function called by `color-values', which see. */)
3636 Lisp_Object color
, frame
;
3639 FRAME_PTR f
= check_x_frame (frame
);
3641 CHECK_STRING (color
);
3643 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3647 rgb
[0] = make_number (foo
.red
);
3648 rgb
[1] = make_number (foo
.green
);
3649 rgb
[2] = make_number (foo
.blue
);
3650 return Flist (3, rgb
);
3656 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3657 doc
: /* Internal function called by `display-color-p', which see. */)
3659 Lisp_Object display
;
3661 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3663 if (dpyinfo
->n_planes
<= 2)
3666 switch (dpyinfo
->visual
->class)
3679 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3681 doc
: /* Return t if the X display supports shades of gray.
3682 Note that color displays do support shades of gray.
3683 The optional argument DISPLAY specifies which display to ask about.
3684 DISPLAY should be either a frame or a display name (a string).
3685 If omitted or nil, that stands for the selected frame's display. */)
3687 Lisp_Object display
;
3689 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3691 if (dpyinfo
->n_planes
<= 1)
3694 switch (dpyinfo
->visual
->class)
3709 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3711 doc
: /* Returns the width in pixels of the X display DISPLAY.
3712 The optional argument DISPLAY specifies which display to ask about.
3713 DISPLAY should be either a frame or a display name (a string).
3714 If omitted or nil, that stands for the selected frame's display. */)
3716 Lisp_Object display
;
3718 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3720 return make_number (dpyinfo
->width
);
3723 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3724 Sx_display_pixel_height
, 0, 1, 0,
3725 doc
: /* Returns the height in pixels of the X display DISPLAY.
3726 The optional argument DISPLAY specifies which display to ask about.
3727 DISPLAY should be either a frame or a display name (a string).
3728 If omitted or nil, that stands for the selected frame's display. */)
3730 Lisp_Object display
;
3732 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3734 return make_number (dpyinfo
->height
);
3737 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3739 doc
: /* Returns the number of bitplanes of the X display DISPLAY.
3740 The optional argument DISPLAY specifies which display to ask about.
3741 DISPLAY should be either a frame or a display name (a string).
3742 If omitted or nil, that stands for the selected frame's display. */)
3744 Lisp_Object display
;
3746 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3748 return make_number (dpyinfo
->n_planes
);
3751 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3753 doc
: /* Returns the number of color cells of the X display DISPLAY.
3754 The optional argument DISPLAY specifies which display to ask about.
3755 DISPLAY should be either a frame or a display name (a string).
3756 If omitted or nil, that stands for the selected frame's display. */)
3758 Lisp_Object display
;
3760 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3762 return make_number (DisplayCells (dpyinfo
->display
,
3763 XScreenNumberOfScreen (dpyinfo
->screen
)));
3766 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3767 Sx_server_max_request_size
,
3769 doc
: /* Returns the maximum request size of the X server of display DISPLAY.
3770 The optional argument DISPLAY specifies which display to ask about.
3771 DISPLAY should be either a frame or a display name (a string).
3772 If omitted or nil, that stands for the selected frame's display. */)
3774 Lisp_Object display
;
3776 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3778 return make_number (MAXREQUEST (dpyinfo
->display
));
3781 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3782 doc
: /* Returns the vendor ID string of the X server of display DISPLAY.
3783 The optional argument DISPLAY specifies which display to ask about.
3784 DISPLAY should be either a frame or a display name (a string).
3785 If omitted or nil, that stands for the selected frame's display. */)
3787 Lisp_Object display
;
3789 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3790 char *vendor
= ServerVendor (dpyinfo
->display
);
3792 if (! vendor
) vendor
= "";
3793 return build_string (vendor
);
3796 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3797 doc
: /* Returns the version numbers of the X server of display DISPLAY.
3798 The value is a list of three integers: the major and minor
3799 version numbers of the X Protocol in use, and the vendor-specific release
3800 number. See also the function `x-server-vendor'.
3802 The optional argument DISPLAY specifies which display to ask about.
3803 DISPLAY should be either a frame or a display name (a string).
3804 If omitted or nil, that stands for the selected frame's display. */)
3806 Lisp_Object display
;
3808 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3809 Display
*dpy
= dpyinfo
->display
;
3811 return Fcons (make_number (ProtocolVersion (dpy
)),
3812 Fcons (make_number (ProtocolRevision (dpy
)),
3813 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3816 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3817 doc
: /* Return the number of screens on the X server of display DISPLAY.
3818 The optional argument DISPLAY specifies which display to ask about.
3819 DISPLAY should be either a frame or a display name (a string).
3820 If omitted or nil, that stands for the selected frame's display. */)
3822 Lisp_Object display
;
3824 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3826 return make_number (ScreenCount (dpyinfo
->display
));
3829 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3830 doc
: /* Return the height in millimeters of the X display DISPLAY.
3831 The optional argument DISPLAY specifies which display to ask about.
3832 DISPLAY should be either a frame or a display name (a string).
3833 If omitted or nil, that stands for the selected frame's display. */)
3835 Lisp_Object display
;
3837 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3839 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3842 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3843 doc
: /* Return the width in millimeters of the X display DISPLAY.
3844 The optional argument DISPLAY specifies which display to ask about.
3845 DISPLAY should be either a frame or a display name (a string).
3846 If omitted or nil, that stands for the selected frame's display. */)
3848 Lisp_Object display
;
3850 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3852 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3855 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3856 Sx_display_backing_store
, 0, 1, 0,
3857 doc
: /* Returns an indication of whether X display DISPLAY does backing store.
3858 The value may be `always', `when-mapped', or `not-useful'.
3859 The optional argument DISPLAY specifies which display to ask about.
3860 DISPLAY should be either a frame or a display name (a string).
3861 If omitted or nil, that stands for the selected frame's display. */)
3863 Lisp_Object display
;
3865 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3868 switch (DoesBackingStore (dpyinfo
->screen
))
3871 result
= intern ("always");
3875 result
= intern ("when-mapped");
3879 result
= intern ("not-useful");
3883 error ("Strange value for BackingStore parameter of screen");
3890 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3891 Sx_display_visual_class
, 0, 1, 0,
3892 doc
: /* Return the visual class of the X display DISPLAY.
3893 The value is one of the symbols `static-gray', `gray-scale',
3894 `static-color', `pseudo-color', `true-color', or `direct-color'.
3896 The optional argument DISPLAY specifies which display to ask about.
3897 DISPLAY should be either a frame or a display name (a string).
3898 If omitted or nil, that stands for the selected frame's display. */)
3900 Lisp_Object display
;
3902 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3905 switch (dpyinfo
->visual
->class)
3908 result
= intern ("static-gray");
3911 result
= intern ("gray-scale");
3914 result
= intern ("static-color");
3917 result
= intern ("pseudo-color");
3920 result
= intern ("true-color");
3923 result
= intern ("direct-color");
3926 error ("Display has an unknown visual class");
3933 DEFUN ("x-display-save-under", Fx_display_save_under
,
3934 Sx_display_save_under
, 0, 1, 0,
3935 doc
: /* Returns t if the X display DISPLAY supports the save-under feature.
3936 The optional argument DISPLAY specifies which display to ask about.
3937 DISPLAY should be either a frame or a display name (a string).
3938 If omitted or nil, that stands for the selected frame's display. */)
3940 Lisp_Object display
;
3942 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3944 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3952 register struct frame
*f
;
3954 return FRAME_PIXEL_WIDTH (f
);
3959 register struct frame
*f
;
3961 return FRAME_PIXEL_HEIGHT (f
);
3966 register struct frame
*f
;
3968 return FRAME_COLUMN_WIDTH (f
);
3973 register struct frame
*f
;
3975 return FRAME_LINE_HEIGHT (f
);
3980 register struct frame
*f
;
3982 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
3987 /************************************************************************
3989 ************************************************************************/
3992 /* Mapping visual names to visuals. */
3994 static struct visual_class
4001 {"StaticGray", StaticGray
},
4002 {"GrayScale", GrayScale
},
4003 {"StaticColor", StaticColor
},
4004 {"PseudoColor", PseudoColor
},
4005 {"TrueColor", TrueColor
},
4006 {"DirectColor", DirectColor
},
4011 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4013 /* Value is the screen number of screen SCR. This is a substitute for
4014 the X function with the same name when that doesn't exist. */
4017 XScreenNumberOfScreen (scr
)
4018 register Screen
*scr
;
4020 Display
*dpy
= scr
->display
;
4023 for (i
= 0; i
< dpy
->nscreens
; ++i
)
4024 if (scr
== dpy
->screens
+ i
)
4030 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4033 /* Select the visual that should be used on display DPYINFO. Set
4034 members of DPYINFO appropriately. Called from x_term_init. */
4037 select_visual (dpyinfo
)
4038 struct x_display_info
*dpyinfo
;
4040 Display
*dpy
= dpyinfo
->display
;
4041 Screen
*screen
= dpyinfo
->screen
;
4044 /* See if a visual is specified. */
4045 value
= display_x_get_resource (dpyinfo
,
4046 build_string ("visualClass"),
4047 build_string ("VisualClass"),
4049 if (STRINGP (value
))
4051 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4052 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4053 depth, a decimal number. NAME is compared with case ignored. */
4054 char *s
= (char *) alloca (SBYTES (value
) + 1);
4059 strcpy (s
, SDATA (value
));
4060 dash
= index (s
, '-');
4063 dpyinfo
->n_planes
= atoi (dash
+ 1);
4067 /* We won't find a matching visual with depth 0, so that
4068 an error will be printed below. */
4069 dpyinfo
->n_planes
= 0;
4071 /* Determine the visual class. */
4072 for (i
= 0; visual_classes
[i
].name
; ++i
)
4073 if (xstricmp (s
, visual_classes
[i
].name
) == 0)
4075 class = visual_classes
[i
].class;
4079 /* Look up a matching visual for the specified class. */
4081 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4082 dpyinfo
->n_planes
, class, &vinfo
))
4083 fatal ("Invalid visual specification `%s'", SDATA (value
));
4085 dpyinfo
->visual
= vinfo
.visual
;
4090 XVisualInfo
*vinfo
, vinfo_template
;
4092 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4095 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4097 vinfo_template
.visualid
= dpyinfo
->visual
->visualid
;
4099 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4100 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4101 &vinfo_template
, &n_visuals
);
4103 fatal ("Can't get proper X visual info");
4105 dpyinfo
->n_planes
= vinfo
->depth
;
4106 XFree ((char *) vinfo
);
4111 /* Return the X display structure for the display named NAME.
4112 Open a new connection if necessary. */
4114 struct x_display_info
*
4115 x_display_info_for_name (name
)
4119 struct x_display_info
*dpyinfo
;
4121 CHECK_STRING (name
);
4123 if (! EQ (Vwindow_system
, intern ("x")))
4124 error ("Not using X Windows");
4126 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4128 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4131 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4136 /* Use this general default value to start with. */
4137 Vx_resource_name
= Vinvocation_name
;
4139 validate_x_resource_name ();
4141 dpyinfo
= x_term_init (name
, (char *)0,
4142 (char *) SDATA (Vx_resource_name
));
4145 error ("Cannot connect to X server %s", SDATA (name
));
4148 XSETFASTINT (Vwindow_system_version
, 11);
4154 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4156 doc
: /* Open a connection to an X server.
4157 DISPLAY is the name of the display to connect to.
4158 Optional second arg XRM-STRING is a string of resources in xrdb format.
4159 If the optional third arg MUST-SUCCEED is non-nil,
4160 terminate Emacs if we can't open the connection. */)
4161 (display
, xrm_string
, must_succeed
)
4162 Lisp_Object display
, xrm_string
, must_succeed
;
4164 unsigned char *xrm_option
;
4165 struct x_display_info
*dpyinfo
;
4167 CHECK_STRING (display
);
4168 if (! NILP (xrm_string
))
4169 CHECK_STRING (xrm_string
);
4171 if (! EQ (Vwindow_system
, intern ("x")))
4172 error ("Not using X Windows");
4174 if (! NILP (xrm_string
))
4175 xrm_option
= (unsigned char *) SDATA (xrm_string
);
4177 xrm_option
= (unsigned char *) 0;
4179 validate_x_resource_name ();
4181 /* This is what opens the connection and sets x_current_display.
4182 This also initializes many symbols, such as those used for input. */
4183 dpyinfo
= x_term_init (display
, xrm_option
,
4184 (char *) SDATA (Vx_resource_name
));
4188 if (!NILP (must_succeed
))
4189 fatal ("Cannot connect to X server %s.\n\
4190 Check the DISPLAY environment variable or use `-d'.\n\
4191 Also use the `xauth' program to verify that you have the proper\n\
4192 authorization information needed to connect the X server.\n\
4193 An insecure way to solve the problem may be to use `xhost'.\n",
4196 error ("Cannot connect to X server %s", SDATA (display
));
4201 XSETFASTINT (Vwindow_system_version
, 11);
4205 DEFUN ("x-close-connection", Fx_close_connection
,
4206 Sx_close_connection
, 1, 1, 0,
4207 doc
: /* Close the connection to DISPLAY's X server.
4208 For DISPLAY, specify either a frame or a display name (a string).
4209 If DISPLAY is nil, that stands for the selected frame's display. */)
4211 Lisp_Object display
;
4213 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4216 if (dpyinfo
->reference_count
> 0)
4217 error ("Display still has frames on it");
4220 /* Free the fonts in the font table. */
4221 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4222 if (dpyinfo
->font_table
[i
].name
)
4224 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4227 x_destroy_all_bitmaps (dpyinfo
);
4228 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4230 #ifdef USE_X_TOOLKIT
4231 XtCloseDisplay (dpyinfo
->display
);
4233 XCloseDisplay (dpyinfo
->display
);
4236 x_delete_display (dpyinfo
);
4242 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4243 doc
: /* Return the list of display names that Emacs has connections to. */)
4246 Lisp_Object tail
, result
;
4249 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
4250 result
= Fcons (XCAR (XCAR (tail
)), result
);
4255 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4256 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4257 If ON is nil, allow buffering of requests.
4258 Turning on synchronization prohibits the Xlib routines from buffering
4259 requests and seriously degrades performance, but makes debugging much
4261 The optional second argument DISPLAY specifies which display to act on.
4262 DISPLAY should be either a frame or a display name (a string).
4263 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4265 Lisp_Object display
, on
;
4267 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4269 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4274 /* Wait for responses to all X commands issued so far for frame F. */
4281 XSync (FRAME_X_DISPLAY (f
), False
);
4286 /***********************************************************************
4287 General X functions exposed to Elisp.
4288 ***********************************************************************/
4290 DEFUN ("x-send-client-message", Fx_send_client_event
,
4291 Sx_send_client_message
, 6, 6, 0,
4292 doc
: /* Send a client message of MESSAGE-TYPE to window DEST on DISPLAY.
4294 For DISPLAY, specify either a frame or a display name (a string).
4295 If DISPLAY is nil, that stands for the selected frame's display.
4296 DEST may be an integer, in which case it is a Window id. The value 0 may
4297 be used to send to the root window of the DISPLAY.
4298 If DEST is a frame the event is sent to the outer window of that frame.
4299 Nil means the currently selected frame.
4300 If DEST is the string "PointerWindow" the event is sent to the window that
4301 contains the pointer. If DEST is the string "InputFocus" the event is
4302 sent to the window that has the input focus.
4303 FROM is the frame sending the event. Use nil for currently selected frame.
4304 MESSAGE-TYPE is the name of an Atom as a string.
4305 FORMAT must be one of 8, 16 or 32 and determines the size of the values in
4306 bits. VALUES is a list of integer and/or strings containing the values to
4307 send. If a value is a string, it is converted to an Atom and the value of
4308 the Atom is sent. If more values than fits into the event is given,
4309 the excessive values are ignored. */)
4310 (display
, dest
, from
, message_type
, format
, values
)
4311 Lisp_Object display
, dest
, from
, message_type
, format
, values
;
4313 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4318 int max_nr_values
= (int) sizeof (event
.xclient
.data
.b
);
4319 struct frame
*f
= check_x_frame (from
);
4321 CHECK_STRING (message_type
);
4322 CHECK_NUMBER (format
);
4323 CHECK_CONS (values
);
4325 for (cons
= values
; CONSP (cons
); cons
= XCDR (cons
))
4327 Lisp_Object o
= XCAR (cons
);
4329 if (! INTEGERP (o
) && ! STRINGP (o
))
4330 error ("Bad data in VALUES, must be integer or string");
4333 event
.xclient
.type
= ClientMessage
;
4334 event
.xclient
.format
= XFASTINT (format
);
4336 if (event
.xclient
.format
!= 8 && event
.xclient
.format
!= 16
4337 && event
.xclient
.format
!= 32)
4338 error ("FORMAT must be one of 8, 16 or 32");
4339 if (event
.xclient
.format
== 16) max_nr_values
/= 2;
4340 if (event
.xclient
.format
== 32) max_nr_values
/= 4;
4342 if (FRAMEP (dest
) || NILP (dest
))
4344 struct frame
*fdest
= check_x_frame (dest
);
4345 wdest
= FRAME_OUTER_WINDOW (fdest
);
4347 else if (STRINGP (dest
))
4349 if (strcmp (SDATA (dest
), "PointerWindow") == 0)
4350 wdest
= PointerWindow
;
4351 else if (strcmp (SDATA (dest
), "InputFocus") == 0)
4354 error ("DEST as a string must be one of PointerWindow or InputFocus");
4358 CHECK_NUMBER (dest
);
4359 wdest
= (Window
) XFASTINT (dest
);
4360 if (wdest
== 0) wdest
= dpyinfo
->root_window
;
4364 for (cons
= values
, i
= 0;
4365 CONSP (cons
) && i
< max_nr_values
;
4366 cons
= XCDR (cons
), ++i
)
4368 Lisp_Object o
= XCAR (cons
);
4373 else if (STRINGP (o
))
4374 val
= XInternAtom (dpyinfo
->display
, SDATA (o
), False
);
4376 if (event
.xclient
.format
== 8)
4377 event
.xclient
.data
.b
[i
] = (char) val
;
4378 else if (event
.xclient
.format
== 16)
4379 event
.xclient
.data
.s
[i
] = (short) val
;
4381 event
.xclient
.data
.l
[i
] = val
;
4384 for ( ; i
< max_nr_values
; ++i
)
4385 if (event
.xclient
.format
== 8)
4386 event
.xclient
.data
.b
[i
] = 0;
4387 else if (event
.xclient
.format
== 16)
4388 event
.xclient
.data
.s
[i
] = 0;
4390 event
.xclient
.data
.l
[i
] = 0;
4392 event
.xclient
.message_type
4393 = XInternAtom (dpyinfo
->display
, SDATA (message_type
), False
);
4394 event
.xclient
.display
= dpyinfo
->display
;
4395 event
.xclient
.window
= FRAME_OUTER_WINDOW (f
);
4397 XSendEvent (dpyinfo
->display
, wdest
, False
, 0xffff, &event
);
4399 XFlush (dpyinfo
->display
);
4405 /***********************************************************************
4407 ***********************************************************************/
4409 /* Value is the number of elements of vector VECTOR. */
4411 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
4413 /* List of supported image types. Use define_image_type to add new
4414 types. Use lookup_image_type to find a type for a given symbol. */
4416 static struct image_type
*image_types
;
4418 /* The symbol `xbm' which is used as the type symbol for XBM images. */
4424 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
4425 extern Lisp_Object QCdata
, QCtype
;
4426 Lisp_Object QCascent
, QCmargin
, QCrelief
;
4427 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
4428 Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
;
4430 /* Other symbols. */
4432 Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
4434 /* Time in seconds after which images should be removed from the cache
4435 if not displayed. */
4437 Lisp_Object Vimage_cache_eviction_delay
;
4439 /* Function prototypes. */
4441 static void define_image_type
P_ ((struct image_type
*type
));
4442 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
4443 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
4444 static void x_laplace
P_ ((struct frame
*, struct image
*));
4445 static void x_emboss
P_ ((struct frame
*, struct image
*));
4446 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
4450 /* Define a new image type from TYPE. This adds a copy of TYPE to
4451 image_types and adds the symbol *TYPE->type to Vimage_types. */
4454 define_image_type (type
)
4455 struct image_type
*type
;
4457 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
4458 The initialized data segment is read-only. */
4459 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
4460 bcopy (type
, p
, sizeof *p
);
4461 p
->next
= image_types
;
4463 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
4467 /* Look up image type SYMBOL, and return a pointer to its image_type
4468 structure. Value is null if SYMBOL is not a known image type. */
4470 static INLINE
struct image_type
*
4471 lookup_image_type (symbol
)
4474 struct image_type
*type
;
4476 for (type
= image_types
; type
; type
= type
->next
)
4477 if (EQ (symbol
, *type
->type
))
4484 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
4485 valid image specification is a list whose car is the symbol
4486 `image', and whose rest is a property list. The property list must
4487 contain a value for key `:type'. That value must be the name of a
4488 supported image type. The rest of the property list depends on the
4492 valid_image_p (object
)
4497 if (IMAGEP (object
))
4501 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
4502 if (EQ (XCAR (tem
), QCtype
))
4505 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
4507 struct image_type
*type
;
4508 type
= lookup_image_type (XCAR (tem
));
4510 valid_p
= type
->valid_p (object
);
4521 /* Log error message with format string FORMAT and argument ARG.
4522 Signaling an error, e.g. when an image cannot be loaded, is not a
4523 good idea because this would interrupt redisplay, and the error
4524 message display would lead to another redisplay. This function
4525 therefore simply displays a message. */
4528 image_error (format
, arg1
, arg2
)
4530 Lisp_Object arg1
, arg2
;
4532 add_to_log (format
, arg1
, arg2
);
4537 /***********************************************************************
4538 Image specifications
4539 ***********************************************************************/
4541 enum image_value_type
4543 IMAGE_DONT_CHECK_VALUE_TYPE
,
4545 IMAGE_STRING_OR_NIL_VALUE
,
4547 IMAGE_POSITIVE_INTEGER_VALUE
,
4548 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
4549 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
4551 IMAGE_INTEGER_VALUE
,
4552 IMAGE_FUNCTION_VALUE
,
4557 /* Structure used when parsing image specifications. */
4559 struct image_keyword
4561 /* Name of keyword. */
4564 /* The type of value allowed. */
4565 enum image_value_type type
;
4567 /* Non-zero means key must be present. */
4570 /* Used to recognize duplicate keywords in a property list. */
4573 /* The value that was found. */
4578 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
4580 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
4583 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
4584 has the format (image KEYWORD VALUE ...). One of the keyword/
4585 value pairs must be `:type TYPE'. KEYWORDS is a vector of
4586 image_keywords structures of size NKEYWORDS describing other
4587 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
4590 parse_image_spec (spec
, keywords
, nkeywords
, type
)
4592 struct image_keyword
*keywords
;
4602 plist
= XCDR (spec
);
4603 while (CONSP (plist
))
4605 Lisp_Object key
, value
;
4607 /* First element of a pair must be a symbol. */
4609 plist
= XCDR (plist
);
4613 /* There must follow a value. */
4616 value
= XCAR (plist
);
4617 plist
= XCDR (plist
);
4619 /* Find key in KEYWORDS. Error if not found. */
4620 for (i
= 0; i
< nkeywords
; ++i
)
4621 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
4627 /* Record that we recognized the keyword. If a keywords
4628 was found more than once, it's an error. */
4629 keywords
[i
].value
= value
;
4630 ++keywords
[i
].count
;
4632 if (keywords
[i
].count
> 1)
4635 /* Check type of value against allowed type. */
4636 switch (keywords
[i
].type
)
4638 case IMAGE_STRING_VALUE
:
4639 if (!STRINGP (value
))
4643 case IMAGE_STRING_OR_NIL_VALUE
:
4644 if (!STRINGP (value
) && !NILP (value
))
4648 case IMAGE_SYMBOL_VALUE
:
4649 if (!SYMBOLP (value
))
4653 case IMAGE_POSITIVE_INTEGER_VALUE
:
4654 if (!INTEGERP (value
) || XINT (value
) <= 0)
4658 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
4659 if (INTEGERP (value
) && XINT (value
) >= 0)
4662 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
4663 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
4667 case IMAGE_ASCENT_VALUE
:
4668 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
4670 else if (INTEGERP (value
)
4671 && XINT (value
) >= 0
4672 && XINT (value
) <= 100)
4676 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
4677 if (!INTEGERP (value
) || XINT (value
) < 0)
4681 case IMAGE_DONT_CHECK_VALUE_TYPE
:
4684 case IMAGE_FUNCTION_VALUE
:
4685 value
= indirect_function (value
);
4687 || COMPILEDP (value
)
4688 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
4692 case IMAGE_NUMBER_VALUE
:
4693 if (!INTEGERP (value
) && !FLOATP (value
))
4697 case IMAGE_INTEGER_VALUE
:
4698 if (!INTEGERP (value
))
4702 case IMAGE_BOOL_VALUE
:
4703 if (!NILP (value
) && !EQ (value
, Qt
))
4712 if (EQ (key
, QCtype
) && !EQ (type
, value
))
4716 /* Check that all mandatory fields are present. */
4717 for (i
= 0; i
< nkeywords
; ++i
)
4718 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
4721 return NILP (plist
);
4725 /* Return the value of KEY in image specification SPEC. Value is nil
4726 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
4727 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
4730 image_spec_value (spec
, key
, found
)
4731 Lisp_Object spec
, key
;
4736 xassert (valid_image_p (spec
));
4738 for (tail
= XCDR (spec
);
4739 CONSP (tail
) && CONSP (XCDR (tail
));
4740 tail
= XCDR (XCDR (tail
)))
4742 if (EQ (XCAR (tail
), key
))
4746 return XCAR (XCDR (tail
));
4756 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
4757 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
4758 PIXELS non-nil means return the size in pixels, otherwise return the
4759 size in canonical character units.
4760 FRAME is the frame on which the image will be displayed. FRAME nil
4761 or omitted means use the selected frame. */)
4762 (spec
, pixels
, frame
)
4763 Lisp_Object spec
, pixels
, frame
;
4768 if (valid_image_p (spec
))
4770 struct frame
*f
= check_x_frame (frame
);
4771 int id
= lookup_image (f
, spec
);
4772 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4773 int width
= img
->width
+ 2 * img
->hmargin
;
4774 int height
= img
->height
+ 2 * img
->vmargin
;
4777 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
4778 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
4780 size
= Fcons (make_number (width
), make_number (height
));
4783 error ("Invalid image specification");
4789 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
4790 doc
: /* Return t if image SPEC has a mask bitmap.
4791 FRAME is the frame on which the image will be displayed. FRAME nil
4792 or omitted means use the selected frame. */)
4794 Lisp_Object spec
, frame
;
4799 if (valid_image_p (spec
))
4801 struct frame
*f
= check_x_frame (frame
);
4802 int id
= lookup_image (f
, spec
);
4803 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4808 error ("Invalid image specification");
4815 /***********************************************************************
4816 Image type independent image structures
4817 ***********************************************************************/
4819 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
4820 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
4823 /* Allocate and return a new image structure for image specification
4824 SPEC. SPEC has a hash value of HASH. */
4826 static struct image
*
4827 make_image (spec
, hash
)
4831 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
4833 xassert (valid_image_p (spec
));
4834 bzero (img
, sizeof *img
);
4835 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
4836 xassert (img
->type
!= NULL
);
4838 img
->data
.lisp_val
= Qnil
;
4839 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
4845 /* Free image IMG which was used on frame F, including its resources. */
4854 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4856 /* Remove IMG from the hash table of its cache. */
4858 img
->prev
->next
= img
->next
;
4860 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
4863 img
->next
->prev
= img
->prev
;
4865 c
->images
[img
->id
] = NULL
;
4867 /* Free resources, then free IMG. */
4868 img
->type
->free (f
, img
);
4874 /* Prepare image IMG for display on frame F. Must be called before
4875 drawing an image. */
4878 prepare_image_for_display (f
, img
)
4884 /* We're about to display IMG, so set its timestamp to `now'. */
4886 img
->timestamp
= EMACS_SECS (t
);
4888 /* If IMG doesn't have a pixmap yet, load it now, using the image
4889 type dependent loader function. */
4890 if (img
->pixmap
== None
&& !img
->load_failed_p
)
4891 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
4895 /* Value is the number of pixels for the ascent of image IMG when
4896 drawn in face FACE. */
4899 image_ascent (img
, face
)
4903 int height
= img
->height
+ img
->vmargin
;
4906 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
4909 /* This expression is arranged so that if the image can't be
4910 exactly centered, it will be moved slightly up. This is
4911 because a typical font is `top-heavy' (due to the presence
4912 uppercase letters), so the image placement should err towards
4913 being top-heavy too. It also just generally looks better. */
4914 ascent
= (height
+ face
->font
->ascent
- face
->font
->descent
+ 1) / 2;
4916 ascent
= height
/ 2;
4919 ascent
= height
* img
->ascent
/ 100.0;
4925 /* Image background colors. */
4927 static unsigned long
4928 four_corners_best (ximg
, width
, height
)
4930 unsigned long width
, height
;
4932 unsigned long corners
[4], best
;
4935 /* Get the colors at the corners of ximg. */
4936 corners
[0] = XGetPixel (ximg
, 0, 0);
4937 corners
[1] = XGetPixel (ximg
, width
- 1, 0);
4938 corners
[2] = XGetPixel (ximg
, width
- 1, height
- 1);
4939 corners
[3] = XGetPixel (ximg
, 0, height
- 1);
4941 /* Choose the most frequently found color as background. */
4942 for (i
= best_count
= 0; i
< 4; ++i
)
4946 for (j
= n
= 0; j
< 4; ++j
)
4947 if (corners
[i
] == corners
[j
])
4951 best
= corners
[i
], best_count
= n
;
4957 /* Return the `background' field of IMG. If IMG doesn't have one yet,
4958 it is guessed heuristically. If non-zero, XIMG is an existing XImage
4959 object to use for the heuristic. */
4962 image_background (img
, f
, ximg
)
4967 if (! img
->background_valid
)
4968 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4970 int free_ximg
= !ximg
;
4973 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4974 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4976 img
->background
= four_corners_best (ximg
, img
->width
, img
->height
);
4979 XDestroyImage (ximg
);
4981 img
->background_valid
= 1;
4984 return img
->background
;
4987 /* Return the `background_transparent' field of IMG. If IMG doesn't
4988 have one yet, it is guessed heuristically. If non-zero, MASK is an
4989 existing XImage object to use for the heuristic. */
4992 image_background_transparent (img
, f
, mask
)
4997 if (! img
->background_transparent_valid
)
4998 /* IMG doesn't have a background yet, try to guess a reasonable value. */
5002 int free_mask
= !mask
;
5005 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
5006 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
5008 img
->background_transparent
5009 = !four_corners_best (mask
, img
->width
, img
->height
);
5012 XDestroyImage (mask
);
5015 img
->background_transparent
= 0;
5017 img
->background_transparent_valid
= 1;
5020 return img
->background_transparent
;
5024 /***********************************************************************
5025 Helper functions for X image types
5026 ***********************************************************************/
5028 static void x_clear_image_1
P_ ((struct frame
*, struct image
*, int,
5030 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
5031 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
5033 Lisp_Object color_name
,
5034 unsigned long dflt
));
5037 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
5038 free the pixmap if any. MASK_P non-zero means clear the mask
5039 pixmap if any. COLORS_P non-zero means free colors allocated for
5040 the image, if any. */
5043 x_clear_image_1 (f
, img
, pixmap_p
, mask_p
, colors_p
)
5046 int pixmap_p
, mask_p
, colors_p
;
5048 if (pixmap_p
&& img
->pixmap
)
5050 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
5052 img
->background_valid
= 0;
5055 if (mask_p
&& img
->mask
)
5057 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
5059 img
->background_transparent_valid
= 0;
5062 if (colors_p
&& img
->ncolors
)
5064 x_free_colors (f
, img
->colors
, img
->ncolors
);
5065 xfree (img
->colors
);
5071 /* Free X resources of image IMG which is used on frame F. */
5074 x_clear_image (f
, img
)
5079 x_clear_image_1 (f
, img
, 1, 1, 1);
5084 /* Allocate color COLOR_NAME for image IMG on frame F. If color
5085 cannot be allocated, use DFLT. Add a newly allocated color to
5086 IMG->colors, so that it can be freed again. Value is the pixel
5089 static unsigned long
5090 x_alloc_image_color (f
, img
, color_name
, dflt
)
5093 Lisp_Object color_name
;
5097 unsigned long result
;
5099 xassert (STRINGP (color_name
));
5101 if (x_defined_color (f
, SDATA (color_name
), &color
, 1))
5103 /* This isn't called frequently so we get away with simply
5104 reallocating the color vector to the needed size, here. */
5107 (unsigned long *) xrealloc (img
->colors
,
5108 img
->ncolors
* sizeof *img
->colors
);
5109 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
5110 result
= color
.pixel
;
5120 /***********************************************************************
5122 ***********************************************************************/
5124 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
5125 static void postprocess_image
P_ ((struct frame
*, struct image
*));
5128 /* Return a new, initialized image cache that is allocated from the
5129 heap. Call free_image_cache to free an image cache. */
5131 struct image_cache
*
5134 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
5137 bzero (c
, sizeof *c
);
5139 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
5140 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
5141 c
->buckets
= (struct image
**) xmalloc (size
);
5142 bzero (c
->buckets
, size
);
5147 /* Free image cache of frame F. Be aware that X frames share images
5151 free_image_cache (f
)
5154 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5159 /* Cache should not be referenced by any frame when freed. */
5160 xassert (c
->refcount
== 0);
5162 for (i
= 0; i
< c
->used
; ++i
)
5163 free_image (f
, c
->images
[i
]);
5167 FRAME_X_IMAGE_CACHE (f
) = NULL
;
5172 /* Clear image cache of frame F. FORCE_P non-zero means free all
5173 images. FORCE_P zero means clear only images that haven't been
5174 displayed for some time. Should be called from time to time to
5175 reduce the number of loaded images. If image-eviction-seconds is
5176 non-nil, this frees images in the cache which weren't displayed for
5177 at least that many seconds. */
5180 clear_image_cache (f
, force_p
)
5184 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5186 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
5193 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
5195 /* Block input so that we won't be interrupted by a SIGIO
5196 while being in an inconsistent state. */
5199 for (i
= nfreed
= 0; i
< c
->used
; ++i
)
5201 struct image
*img
= c
->images
[i
];
5203 && (force_p
|| img
->timestamp
< old
))
5205 free_image (f
, img
);
5210 /* We may be clearing the image cache because, for example,
5211 Emacs was iconified for a longer period of time. In that
5212 case, current matrices may still contain references to
5213 images freed above. So, clear these matrices. */
5216 Lisp_Object tail
, frame
;
5218 FOR_EACH_FRAME (tail
, frame
)
5220 struct frame
*f
= XFRAME (frame
);
5222 && FRAME_X_IMAGE_CACHE (f
) == c
)
5223 clear_current_matrices (f
);
5226 ++windows_or_buffers_changed
;
5234 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
5236 doc
: /* Clear the image cache of FRAME.
5237 FRAME nil or omitted means use the selected frame.
5238 FRAME t means clear the image caches of all frames. */)
5246 FOR_EACH_FRAME (tail
, frame
)
5247 if (FRAME_X_P (XFRAME (frame
)))
5248 clear_image_cache (XFRAME (frame
), 1);
5251 clear_image_cache (check_x_frame (frame
), 1);
5257 /* Compute masks and transform image IMG on frame F, as specified
5258 by the image's specification, */
5261 postprocess_image (f
, img
)
5265 /* Manipulation of the image's mask. */
5268 Lisp_Object conversion
, spec
;
5273 /* `:heuristic-mask t'
5275 means build a mask heuristically.
5276 `:heuristic-mask (R G B)'
5277 `:mask (heuristic (R G B))'
5278 means build a mask from color (R G B) in the
5281 means remove a mask, if any. */
5283 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
5285 x_build_heuristic_mask (f
, img
, mask
);
5290 mask
= image_spec_value (spec
, QCmask
, &found_p
);
5292 if (EQ (mask
, Qheuristic
))
5293 x_build_heuristic_mask (f
, img
, Qt
);
5294 else if (CONSP (mask
)
5295 && EQ (XCAR (mask
), Qheuristic
))
5297 if (CONSP (XCDR (mask
)))
5298 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
5300 x_build_heuristic_mask (f
, img
, XCDR (mask
));
5302 else if (NILP (mask
) && found_p
&& img
->mask
)
5304 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
5310 /* Should we apply an image transformation algorithm? */
5311 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
5312 if (EQ (conversion
, Qdisabled
))
5313 x_disable_image (f
, img
);
5314 else if (EQ (conversion
, Qlaplace
))
5316 else if (EQ (conversion
, Qemboss
))
5318 else if (CONSP (conversion
)
5319 && EQ (XCAR (conversion
), Qedge_detection
))
5322 tem
= XCDR (conversion
);
5324 x_edge_detection (f
, img
,
5325 Fplist_get (tem
, QCmatrix
),
5326 Fplist_get (tem
, QCcolor_adjustment
));
5332 /* Return the id of image with Lisp specification SPEC on frame F.
5333 SPEC must be a valid Lisp image specification (see valid_image_p). */
5336 lookup_image (f
, spec
)
5340 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5344 struct gcpro gcpro1
;
5347 /* F must be a window-system frame, and SPEC must be a valid image
5349 xassert (FRAME_WINDOW_P (f
));
5350 xassert (valid_image_p (spec
));
5354 /* Look up SPEC in the hash table of the image cache. */
5355 hash
= sxhash (spec
, 0);
5356 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5358 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
5359 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
5362 /* If not found, create a new image and cache it. */
5365 extern Lisp_Object Qpostscript
;
5368 img
= make_image (spec
, hash
);
5369 cache_image (f
, img
);
5370 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5372 /* If we can't load the image, and we don't have a width and
5373 height, use some arbitrary width and height so that we can
5374 draw a rectangle for it. */
5375 if (img
->load_failed_p
)
5379 value
= image_spec_value (spec
, QCwidth
, NULL
);
5380 img
->width
= (INTEGERP (value
)
5381 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
5382 value
= image_spec_value (spec
, QCheight
, NULL
);
5383 img
->height
= (INTEGERP (value
)
5384 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
5388 /* Handle image type independent image attributes
5389 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
5390 `:background COLOR'. */
5391 Lisp_Object ascent
, margin
, relief
, bg
;
5393 ascent
= image_spec_value (spec
, QCascent
, NULL
);
5394 if (INTEGERP (ascent
))
5395 img
->ascent
= XFASTINT (ascent
);
5396 else if (EQ (ascent
, Qcenter
))
5397 img
->ascent
= CENTERED_IMAGE_ASCENT
;
5399 margin
= image_spec_value (spec
, QCmargin
, NULL
);
5400 if (INTEGERP (margin
) && XINT (margin
) >= 0)
5401 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
5402 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
5403 && INTEGERP (XCDR (margin
)))
5405 if (XINT (XCAR (margin
)) > 0)
5406 img
->hmargin
= XFASTINT (XCAR (margin
));
5407 if (XINT (XCDR (margin
)) > 0)
5408 img
->vmargin
= XFASTINT (XCDR (margin
));
5411 relief
= image_spec_value (spec
, QCrelief
, NULL
);
5412 if (INTEGERP (relief
))
5414 img
->relief
= XINT (relief
);
5415 img
->hmargin
+= abs (img
->relief
);
5416 img
->vmargin
+= abs (img
->relief
);
5419 if (! img
->background_valid
)
5421 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
5425 = x_alloc_image_color (f
, img
, bg
,
5426 FRAME_BACKGROUND_PIXEL (f
));
5427 img
->background_valid
= 1;
5431 /* Do image transformations and compute masks, unless we
5432 don't have the image yet. */
5433 if (!EQ (*img
->type
->type
, Qpostscript
))
5434 postprocess_image (f
, img
);
5438 xassert (!interrupt_input_blocked
);
5441 /* We're using IMG, so set its timestamp to `now'. */
5442 EMACS_GET_TIME (now
);
5443 img
->timestamp
= EMACS_SECS (now
);
5447 /* Value is the image id. */
5452 /* Cache image IMG in the image cache of frame F. */
5455 cache_image (f
, img
)
5459 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5462 /* Find a free slot in c->images. */
5463 for (i
= 0; i
< c
->used
; ++i
)
5464 if (c
->images
[i
] == NULL
)
5467 /* If no free slot found, maybe enlarge c->images. */
5468 if (i
== c
->used
&& c
->used
== c
->size
)
5471 c
->images
= (struct image
**) xrealloc (c
->images
,
5472 c
->size
* sizeof *c
->images
);
5475 /* Add IMG to c->images, and assign IMG an id. */
5481 /* Add IMG to the cache's hash table. */
5482 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5483 img
->next
= c
->buckets
[i
];
5485 img
->next
->prev
= img
;
5487 c
->buckets
[i
] = img
;
5491 /* Call FN on every image in the image cache of frame F. Used to mark
5492 Lisp Objects in the image cache. */
5495 forall_images_in_image_cache (f
, fn
)
5497 void (*fn
) P_ ((struct image
*img
));
5499 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
))
5501 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5505 for (i
= 0; i
< c
->used
; ++i
)
5514 /***********************************************************************
5516 ***********************************************************************/
5518 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
5519 XImage
**, Pixmap
*));
5520 static void x_destroy_x_image
P_ ((XImage
*));
5521 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
5524 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
5525 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
5526 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
5527 via xmalloc. Print error messages via image_error if an error
5528 occurs. Value is non-zero if successful. */
5531 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
5533 int width
, height
, depth
;
5537 Display
*display
= FRAME_X_DISPLAY (f
);
5538 Screen
*screen
= FRAME_X_SCREEN (f
);
5539 Window window
= FRAME_X_WINDOW (f
);
5541 xassert (interrupt_input_blocked
);
5544 depth
= DefaultDepthOfScreen (screen
);
5545 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
5546 depth
, ZPixmap
, 0, NULL
, width
, height
,
5547 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
5550 image_error ("Unable to allocate X image", Qnil
, Qnil
);
5554 /* Allocate image raster. */
5555 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
5557 /* Allocate a pixmap of the same size. */
5558 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
5559 if (*pixmap
== None
)
5561 x_destroy_x_image (*ximg
);
5563 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
5571 /* Destroy XImage XIMG. Free XIMG->data. */
5574 x_destroy_x_image (ximg
)
5577 xassert (interrupt_input_blocked
);
5582 XDestroyImage (ximg
);
5587 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
5588 are width and height of both the image and pixmap. */
5591 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
5599 xassert (interrupt_input_blocked
);
5600 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
5601 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
5602 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5607 /***********************************************************************
5609 ***********************************************************************/
5611 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
5612 static char *slurp_file
P_ ((char *, int *));
5615 /* Find image file FILE. Look in data-directory, then
5616 x-bitmap-file-path. Value is the full name of the file found, or
5617 nil if not found. */
5620 x_find_image_file (file
)
5623 Lisp_Object file_found
, search_path
;
5624 struct gcpro gcpro1
, gcpro2
;
5628 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
5629 GCPRO2 (file_found
, search_path
);
5631 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
5632 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
5644 /* Read FILE into memory. Value is a pointer to a buffer allocated
5645 with xmalloc holding FILE's contents. Value is null if an error
5646 occurred. *SIZE is set to the size of the file. */
5649 slurp_file (file
, size
)
5657 if (stat (file
, &st
) == 0
5658 && (fp
= fopen (file
, "r")) != NULL
5659 && (buf
= (char *) xmalloc (st
.st_size
),
5660 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5681 /***********************************************************************
5683 ***********************************************************************/
5685 static int xbm_scan
P_ ((char **, char *, char *, int *));
5686 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
5687 static int xbm_load_image
P_ ((struct frame
*f
, struct image
*img
,
5689 static int xbm_image_p
P_ ((Lisp_Object object
));
5690 static int xbm_read_bitmap_data
P_ ((char *, char *, int *, int *,
5692 static int xbm_file_p
P_ ((Lisp_Object
));
5695 /* Indices of image specification fields in xbm_format, below. */
5697 enum xbm_keyword_index
5715 /* Vector of image_keyword structures describing the format
5716 of valid XBM image specifications. */
5718 static struct image_keyword xbm_format
[XBM_LAST
] =
5720 {":type", IMAGE_SYMBOL_VALUE
, 1},
5721 {":file", IMAGE_STRING_VALUE
, 0},
5722 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5723 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5724 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5725 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
5726 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
5727 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5728 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5729 {":relief", IMAGE_INTEGER_VALUE
, 0},
5730 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5731 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5732 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5735 /* Structure describing the image type XBM. */
5737 static struct image_type xbm_type
=
5746 /* Tokens returned from xbm_scan. */
5755 /* Return non-zero if OBJECT is a valid XBM-type image specification.
5756 A valid specification is a list starting with the symbol `image'
5757 The rest of the list is a property list which must contain an
5760 If the specification specifies a file to load, it must contain
5761 an entry `:file FILENAME' where FILENAME is a string.
5763 If the specification is for a bitmap loaded from memory it must
5764 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
5765 WIDTH and HEIGHT are integers > 0. DATA may be:
5767 1. a string large enough to hold the bitmap data, i.e. it must
5768 have a size >= (WIDTH + 7) / 8 * HEIGHT
5770 2. a bool-vector of size >= WIDTH * HEIGHT
5772 3. a vector of strings or bool-vectors, one for each line of the
5775 4. A string containing an in-memory XBM file. WIDTH and HEIGHT
5776 may not be specified in this case because they are defined in the
5779 Both the file and data forms may contain the additional entries
5780 `:background COLOR' and `:foreground COLOR'. If not present,
5781 foreground and background of the frame on which the image is
5782 displayed is used. */
5785 xbm_image_p (object
)
5788 struct image_keyword kw
[XBM_LAST
];
5790 bcopy (xbm_format
, kw
, sizeof kw
);
5791 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
5794 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
5796 if (kw
[XBM_FILE
].count
)
5798 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
5801 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
5803 /* In-memory XBM file. */
5804 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
5812 /* Entries for `:width', `:height' and `:data' must be present. */
5813 if (!kw
[XBM_WIDTH
].count
5814 || !kw
[XBM_HEIGHT
].count
5815 || !kw
[XBM_DATA
].count
)
5818 data
= kw
[XBM_DATA
].value
;
5819 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
5820 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
5822 /* Check type of data, and width and height against contents of
5828 /* Number of elements of the vector must be >= height. */
5829 if (XVECTOR (data
)->size
< height
)
5832 /* Each string or bool-vector in data must be large enough
5833 for one line of the image. */
5834 for (i
= 0; i
< height
; ++i
)
5836 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
5841 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
5844 else if (BOOL_VECTOR_P (elt
))
5846 if (XBOOL_VECTOR (elt
)->size
< width
)
5853 else if (STRINGP (data
))
5856 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
5859 else if (BOOL_VECTOR_P (data
))
5861 if (XBOOL_VECTOR (data
)->size
< width
* height
)
5872 /* Scan a bitmap file. FP is the stream to read from. Value is
5873 either an enumerator from enum xbm_token, or a character for a
5874 single-character token, or 0 at end of file. If scanning an
5875 identifier, store the lexeme of the identifier in SVAL. If
5876 scanning a number, store its value in *IVAL. */
5879 xbm_scan (s
, end
, sval
, ival
)
5888 /* Skip white space. */
5889 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5894 else if (isdigit (c
))
5896 int value
= 0, digit
;
5898 if (c
== '0' && *s
< end
)
5901 if (c
== 'x' || c
== 'X')
5908 else if (c
>= 'a' && c
<= 'f')
5909 digit
= c
- 'a' + 10;
5910 else if (c
>= 'A' && c
<= 'F')
5911 digit
= c
- 'A' + 10;
5914 value
= 16 * value
+ digit
;
5917 else if (isdigit (c
))
5921 && (c
= *(*s
)++, isdigit (c
)))
5922 value
= 8 * value
+ c
- '0';
5929 && (c
= *(*s
)++, isdigit (c
)))
5930 value
= 10 * value
+ c
- '0';
5938 else if (isalpha (c
) || c
== '_')
5942 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
5949 else if (c
== '/' && **s
== '*')
5951 /* C-style comment. */
5953 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
5966 /* Replacement for XReadBitmapFileData which isn't available under old
5967 X versions. CONTENTS is a pointer to a buffer to parse; END is the
5968 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
5969 the image. Return in *DATA the bitmap data allocated with xmalloc.
5970 Value is non-zero if successful. DATA null means just test if
5971 CONTENTS looks like an in-memory XBM file. */
5974 xbm_read_bitmap_data (contents
, end
, width
, height
, data
)
5975 char *contents
, *end
;
5976 int *width
, *height
;
5977 unsigned char **data
;
5980 char buffer
[BUFSIZ
];
5983 int bytes_per_line
, i
, nbytes
;
5989 LA1 = xbm_scan (&s, end, buffer, &value)
5991 #define expect(TOKEN) \
5992 if (LA1 != (TOKEN)) \
5997 #define expect_ident(IDENT) \
5998 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
6003 *width
= *height
= -1;
6006 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
6008 /* Parse defines for width, height and hot-spots. */
6012 expect_ident ("define");
6013 expect (XBM_TK_IDENT
);
6015 if (LA1
== XBM_TK_NUMBER
);
6017 char *p
= strrchr (buffer
, '_');
6018 p
= p
? p
+ 1 : buffer
;
6019 if (strcmp (p
, "width") == 0)
6021 else if (strcmp (p
, "height") == 0)
6024 expect (XBM_TK_NUMBER
);
6027 if (*width
< 0 || *height
< 0)
6029 else if (data
== NULL
)
6032 /* Parse bits. Must start with `static'. */
6033 expect_ident ("static");
6034 if (LA1
== XBM_TK_IDENT
)
6036 if (strcmp (buffer
, "unsigned") == 0)
6039 expect_ident ("char");
6041 else if (strcmp (buffer
, "short") == 0)
6045 if (*width
% 16 && *width
% 16 < 9)
6048 else if (strcmp (buffer
, "char") == 0)
6056 expect (XBM_TK_IDENT
);
6062 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
6063 nbytes
= bytes_per_line
* *height
;
6064 p
= *data
= (char *) xmalloc (nbytes
);
6068 for (i
= 0; i
< nbytes
; i
+= 2)
6071 expect (XBM_TK_NUMBER
);
6074 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
6077 if (LA1
== ',' || LA1
== '}')
6085 for (i
= 0; i
< nbytes
; ++i
)
6088 expect (XBM_TK_NUMBER
);
6092 if (LA1
== ',' || LA1
== '}')
6117 /* Load XBM image IMG which will be displayed on frame F from buffer
6118 CONTENTS. END is the end of the buffer. Value is non-zero if
6122 xbm_load_image (f
, img
, contents
, end
)
6125 char *contents
, *end
;
6128 unsigned char *data
;
6131 rc
= xbm_read_bitmap_data (contents
, end
, &img
->width
, &img
->height
, &data
);
6134 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6135 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6136 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6139 xassert (img
->width
> 0 && img
->height
> 0);
6141 /* Get foreground and background colors, maybe allocate colors. */
6142 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
6144 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
6145 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
6148 background
= x_alloc_image_color (f
, img
, value
, background
);
6149 img
->background
= background
;
6150 img
->background_valid
= 1;
6154 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
6157 img
->width
, img
->height
,
6158 foreground
, background
,
6162 if (img
->pixmap
== None
)
6164 x_clear_image (f
, img
);
6165 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
6171 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6177 /* Value is non-zero if DATA looks like an in-memory XBM file. */
6184 return (STRINGP (data
)
6185 && xbm_read_bitmap_data (SDATA (data
),
6192 /* Fill image IMG which is used on frame F with pixmap data. Value is
6193 non-zero if successful. */
6201 Lisp_Object file_name
;
6203 xassert (xbm_image_p (img
->spec
));
6205 /* If IMG->spec specifies a file name, create a non-file spec from it. */
6206 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
6207 if (STRINGP (file_name
))
6212 struct gcpro gcpro1
;
6214 file
= x_find_image_file (file_name
);
6216 if (!STRINGP (file
))
6218 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
6223 contents
= slurp_file (SDATA (file
), &size
);
6224 if (contents
== NULL
)
6226 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6231 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
6236 struct image_keyword fmt
[XBM_LAST
];
6239 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6240 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6243 int in_memory_file_p
= 0;
6245 /* See if data looks like an in-memory XBM file. */
6246 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6247 in_memory_file_p
= xbm_file_p (data
);
6249 /* Parse the image specification. */
6250 bcopy (xbm_format
, fmt
, sizeof fmt
);
6251 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
6254 /* Get specified width, and height. */
6255 if (!in_memory_file_p
)
6257 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
6258 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
6259 xassert (img
->width
> 0 && img
->height
> 0);
6262 /* Get foreground and background colors, maybe allocate colors. */
6263 if (fmt
[XBM_FOREGROUND
].count
6264 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
6265 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
6267 if (fmt
[XBM_BACKGROUND
].count
6268 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
6269 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
6272 if (in_memory_file_p
)
6273 success_p
= xbm_load_image (f
, img
, SDATA (data
),
6282 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
6284 p
= bits
= (char *) alloca (nbytes
* img
->height
);
6285 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
6287 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
6289 bcopy (SDATA (line
), p
, nbytes
);
6291 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
6294 else if (STRINGP (data
))
6295 bits
= SDATA (data
);
6297 bits
= XBOOL_VECTOR (data
)->data
;
6299 /* Create the pixmap. */
6300 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6302 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
6305 img
->width
, img
->height
,
6306 foreground
, background
,
6312 image_error ("Unable to create pixmap for XBM image `%s'",
6314 x_clear_image (f
, img
);
6324 /***********************************************************************
6326 ***********************************************************************/
6330 static int xpm_image_p
P_ ((Lisp_Object object
));
6331 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
6332 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
6334 #include "X11/xpm.h"
6336 /* The symbol `xpm' identifying XPM-format images. */
6340 /* Indices of image specification fields in xpm_format, below. */
6342 enum xpm_keyword_index
6358 /* Vector of image_keyword structures describing the format
6359 of valid XPM image specifications. */
6361 static struct image_keyword xpm_format
[XPM_LAST
] =
6363 {":type", IMAGE_SYMBOL_VALUE
, 1},
6364 {":file", IMAGE_STRING_VALUE
, 0},
6365 {":data", IMAGE_STRING_VALUE
, 0},
6366 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6367 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6368 {":relief", IMAGE_INTEGER_VALUE
, 0},
6369 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6370 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6371 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6372 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6373 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6376 /* Structure describing the image type XBM. */
6378 static struct image_type xpm_type
=
6388 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
6389 functions for allocating image colors. Our own functions handle
6390 color allocation failures more gracefully than the ones on the XPM
6393 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
6394 #define ALLOC_XPM_COLORS
6397 #ifdef ALLOC_XPM_COLORS
6399 static void xpm_init_color_cache
P_ ((struct frame
*, XpmAttributes
*));
6400 static void xpm_free_color_cache
P_ ((void));
6401 static int xpm_lookup_color
P_ ((struct frame
*, char *, XColor
*));
6402 static int xpm_color_bucket
P_ ((char *));
6403 static struct xpm_cached_color
*xpm_cache_color
P_ ((struct frame
*, char *,
6406 /* An entry in a hash table used to cache color definitions of named
6407 colors. This cache is necessary to speed up XPM image loading in
6408 case we do color allocations ourselves. Without it, we would need
6409 a call to XParseColor per pixel in the image. */
6411 struct xpm_cached_color
6413 /* Next in collision chain. */
6414 struct xpm_cached_color
*next
;
6416 /* Color definition (RGB and pixel color). */
6423 /* The hash table used for the color cache, and its bucket vector
6426 #define XPM_COLOR_CACHE_BUCKETS 1001
6427 struct xpm_cached_color
**xpm_color_cache
;
6429 /* Initialize the color cache. */
6432 xpm_init_color_cache (f
, attrs
)
6434 XpmAttributes
*attrs
;
6436 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
6437 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
6438 memset (xpm_color_cache
, 0, nbytes
);
6439 init_color_table ();
6441 if (attrs
->valuemask
& XpmColorSymbols
)
6446 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
6447 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6448 attrs
->colorsymbols
[i
].value
, &color
))
6450 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
6452 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
6458 /* Free the color cache. */
6461 xpm_free_color_cache ()
6463 struct xpm_cached_color
*p
, *next
;
6466 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
6467 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
6473 xfree (xpm_color_cache
);
6474 xpm_color_cache
= NULL
;
6475 free_color_table ();
6479 /* Return the bucket index for color named COLOR_NAME in the color
6483 xpm_color_bucket (color_name
)
6489 for (s
= color_name
; *s
; ++s
)
6491 return h
%= XPM_COLOR_CACHE_BUCKETS
;
6495 /* On frame F, cache values COLOR for color with name COLOR_NAME.
6496 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
6499 static struct xpm_cached_color
*
6500 xpm_cache_color (f
, color_name
, color
, bucket
)
6507 struct xpm_cached_color
*p
;
6510 bucket
= xpm_color_bucket (color_name
);
6512 nbytes
= sizeof *p
+ strlen (color_name
);
6513 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
6514 strcpy (p
->name
, color_name
);
6516 p
->next
= xpm_color_cache
[bucket
];
6517 xpm_color_cache
[bucket
] = p
;
6522 /* Look up color COLOR_NAME for frame F in the color cache. If found,
6523 return the cached definition in *COLOR. Otherwise, make a new
6524 entry in the cache and allocate the color. Value is zero if color
6525 allocation failed. */
6528 xpm_lookup_color (f
, color_name
, color
)
6533 struct xpm_cached_color
*p
;
6534 int h
= xpm_color_bucket (color_name
);
6536 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
6537 if (strcmp (p
->name
, color_name
) == 0)
6542 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6545 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
6547 p
= xpm_cache_color (f
, color_name
, color
, h
);
6549 /* You get `opaque' at least from ImageMagick converting pbm to xpm
6550 with transparency, and it's useful. */
6551 else if (strcmp ("opaque", color_name
) == 0)
6553 bzero (color
, sizeof (XColor
)); /* Is this necessary/correct? */
6554 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
6555 p
= xpm_cache_color (f
, color_name
, color
, h
);
6562 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
6563 CLOSURE is a pointer to the frame on which we allocate the
6564 color. Return in *COLOR the allocated color. Value is non-zero
6568 xpm_alloc_color (dpy
, cmap
, color_name
, color
, closure
)
6575 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
6579 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
6580 is a pointer to the frame on which we allocate the color. Value is
6581 non-zero if successful. */
6584 xpm_free_colors (dpy
, cmap
, pixels
, npixels
, closure
)
6594 #endif /* ALLOC_XPM_COLORS */
6597 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
6598 for XPM images. Such a list must consist of conses whose car and
6602 xpm_valid_color_symbols_p (color_symbols
)
6603 Lisp_Object color_symbols
;
6605 while (CONSP (color_symbols
))
6607 Lisp_Object sym
= XCAR (color_symbols
);
6609 || !STRINGP (XCAR (sym
))
6610 || !STRINGP (XCDR (sym
)))
6612 color_symbols
= XCDR (color_symbols
);
6615 return NILP (color_symbols
);
6619 /* Value is non-zero if OBJECT is a valid XPM image specification. */
6622 xpm_image_p (object
)
6625 struct image_keyword fmt
[XPM_LAST
];
6626 bcopy (xpm_format
, fmt
, sizeof fmt
);
6627 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
6628 /* Either `:file' or `:data' must be present. */
6629 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
6630 /* Either no `:color-symbols' or it's a list of conses
6631 whose car and cdr are strings. */
6632 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
6633 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
6637 /* Load image IMG which will be displayed on frame F. Value is
6638 non-zero if successful. */
6646 XpmAttributes attrs
;
6647 Lisp_Object specified_file
, color_symbols
;
6649 /* Configure the XPM lib. Use the visual of frame F. Allocate
6650 close colors. Return colors allocated. */
6651 bzero (&attrs
, sizeof attrs
);
6652 attrs
.visual
= FRAME_X_VISUAL (f
);
6653 attrs
.colormap
= FRAME_X_COLORMAP (f
);
6654 attrs
.valuemask
|= XpmVisual
;
6655 attrs
.valuemask
|= XpmColormap
;
6657 #ifdef ALLOC_XPM_COLORS
6658 /* Allocate colors with our own functions which handle
6659 failing color allocation more gracefully. */
6660 attrs
.color_closure
= f
;
6661 attrs
.alloc_color
= xpm_alloc_color
;
6662 attrs
.free_colors
= xpm_free_colors
;
6663 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
6664 #else /* not ALLOC_XPM_COLORS */
6665 /* Let the XPM lib allocate colors. */
6666 attrs
.valuemask
|= XpmReturnAllocPixels
;
6667 #ifdef XpmAllocCloseColors
6668 attrs
.alloc_close_colors
= 1;
6669 attrs
.valuemask
|= XpmAllocCloseColors
;
6670 #else /* not XpmAllocCloseColors */
6671 attrs
.closeness
= 600;
6672 attrs
.valuemask
|= XpmCloseness
;
6673 #endif /* not XpmAllocCloseColors */
6674 #endif /* ALLOC_XPM_COLORS */
6676 /* If image specification contains symbolic color definitions, add
6677 these to `attrs'. */
6678 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
6679 if (CONSP (color_symbols
))
6682 XpmColorSymbol
*xpm_syms
;
6685 attrs
.valuemask
|= XpmColorSymbols
;
6687 /* Count number of symbols. */
6688 attrs
.numsymbols
= 0;
6689 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
6692 /* Allocate an XpmColorSymbol array. */
6693 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
6694 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
6695 bzero (xpm_syms
, size
);
6696 attrs
.colorsymbols
= xpm_syms
;
6698 /* Fill the color symbol array. */
6699 for (tail
= color_symbols
, i
= 0;
6701 ++i
, tail
= XCDR (tail
))
6703 Lisp_Object name
= XCAR (XCAR (tail
));
6704 Lisp_Object color
= XCDR (XCAR (tail
));
6705 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
6706 strcpy (xpm_syms
[i
].name
, SDATA (name
));
6707 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
6708 strcpy (xpm_syms
[i
].value
, SDATA (color
));
6712 /* Create a pixmap for the image, either from a file, or from a
6713 string buffer containing data in the same format as an XPM file. */
6714 #ifdef ALLOC_XPM_COLORS
6715 xpm_init_color_cache (f
, &attrs
);
6718 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6719 if (STRINGP (specified_file
))
6721 Lisp_Object file
= x_find_image_file (specified_file
);
6722 if (!STRINGP (file
))
6724 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6728 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6729 SDATA (file
), &img
->pixmap
, &img
->mask
,
6734 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
6735 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6737 &img
->pixmap
, &img
->mask
,
6741 if (rc
== XpmSuccess
)
6743 #ifdef ALLOC_XPM_COLORS
6744 img
->colors
= colors_in_color_table (&img
->ncolors
);
6745 #else /* not ALLOC_XPM_COLORS */
6748 img
->ncolors
= attrs
.nalloc_pixels
;
6749 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
6750 * sizeof *img
->colors
);
6751 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
6753 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
6754 #ifdef DEBUG_X_COLORS
6755 register_color (img
->colors
[i
]);
6758 #endif /* not ALLOC_XPM_COLORS */
6760 img
->width
= attrs
.width
;
6761 img
->height
= attrs
.height
;
6762 xassert (img
->width
> 0 && img
->height
> 0);
6764 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
6765 XpmFreeAttributes (&attrs
);
6772 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
6775 case XpmFileInvalid
:
6776 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
6780 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
6783 case XpmColorFailed
:
6784 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
6788 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
6793 #ifdef ALLOC_XPM_COLORS
6794 xpm_free_color_cache ();
6796 return rc
== XpmSuccess
;
6799 #endif /* HAVE_XPM != 0 */
6802 /***********************************************************************
6804 ***********************************************************************/
6806 /* An entry in the color table mapping an RGB color to a pixel color. */
6811 unsigned long pixel
;
6813 /* Next in color table collision list. */
6814 struct ct_color
*next
;
6817 /* The bucket vector size to use. Must be prime. */
6821 /* Value is a hash of the RGB color given by R, G, and B. */
6823 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
6825 /* The color hash table. */
6827 struct ct_color
**ct_table
;
6829 /* Number of entries in the color table. */
6831 int ct_colors_allocated
;
6833 /* Initialize the color table. */
6838 int size
= CT_SIZE
* sizeof (*ct_table
);
6839 ct_table
= (struct ct_color
**) xmalloc (size
);
6840 bzero (ct_table
, size
);
6841 ct_colors_allocated
= 0;
6845 /* Free memory associated with the color table. */
6851 struct ct_color
*p
, *next
;
6853 for (i
= 0; i
< CT_SIZE
; ++i
)
6854 for (p
= ct_table
[i
]; p
; p
= next
)
6865 /* Value is a pixel color for RGB color R, G, B on frame F. If an
6866 entry for that color already is in the color table, return the
6867 pixel color of that entry. Otherwise, allocate a new color for R,
6868 G, B, and make an entry in the color table. */
6870 static unsigned long
6871 lookup_rgb_color (f
, r
, g
, b
)
6875 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
6876 int i
= hash
% CT_SIZE
;
6878 struct x_display_info
*dpyinfo
;
6880 /* Handle TrueColor visuals specially, which improves performance by
6881 two orders of magnitude. Freeing colors on TrueColor visuals is
6882 a nop, and pixel colors specify RGB values directly. See also
6883 the Xlib spec, chapter 3.1. */
6884 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6885 if (dpyinfo
->red_bits
> 0)
6887 unsigned long pr
, pg
, pb
;
6889 /* Apply gamma-correction like normal color allocation does. */
6893 color
.red
= r
, color
.green
= g
, color
.blue
= b
;
6894 gamma_correct (f
, &color
);
6895 r
= color
.red
, g
= color
.green
, b
= color
.blue
;
6898 /* Scale down RGB values to the visual's bits per RGB, and shift
6899 them to the right position in the pixel color. Note that the
6900 original RGB values are 16-bit values, as usual in X. */
6901 pr
= (r
>> (16 - dpyinfo
->red_bits
)) << dpyinfo
->red_offset
;
6902 pg
= (g
>> (16 - dpyinfo
->green_bits
)) << dpyinfo
->green_offset
;
6903 pb
= (b
>> (16 - dpyinfo
->blue_bits
)) << dpyinfo
->blue_offset
;
6905 /* Assemble the pixel color. */
6906 return pr
| pg
| pb
;
6909 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6910 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
6923 cmap
= FRAME_X_COLORMAP (f
);
6924 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6928 ++ct_colors_allocated
;
6930 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6934 p
->pixel
= color
.pixel
;
6935 p
->next
= ct_table
[i
];
6939 return FRAME_FOREGROUND_PIXEL (f
);
6946 /* Look up pixel color PIXEL which is used on frame F in the color
6947 table. If not already present, allocate it. Value is PIXEL. */
6949 static unsigned long
6950 lookup_pixel_color (f
, pixel
)
6952 unsigned long pixel
;
6954 int i
= pixel
% CT_SIZE
;
6957 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6958 if (p
->pixel
== pixel
)
6967 cmap
= FRAME_X_COLORMAP (f
);
6968 color
.pixel
= pixel
;
6969 x_query_color (f
, &color
);
6970 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6974 ++ct_colors_allocated
;
6976 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6981 p
->next
= ct_table
[i
];
6985 return FRAME_FOREGROUND_PIXEL (f
);
6992 /* Value is a vector of all pixel colors contained in the color table,
6993 allocated via xmalloc. Set *N to the number of colors. */
6995 static unsigned long *
6996 colors_in_color_table (n
)
7001 unsigned long *colors
;
7003 if (ct_colors_allocated
== 0)
7010 colors
= (unsigned long *) xmalloc (ct_colors_allocated
7012 *n
= ct_colors_allocated
;
7014 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
7015 for (p
= ct_table
[i
]; p
; p
= p
->next
)
7016 colors
[j
++] = p
->pixel
;
7024 /***********************************************************************
7026 ***********************************************************************/
7028 static XColor
*x_to_xcolors
P_ ((struct frame
*, struct image
*, int));
7029 static void x_from_xcolors
P_ ((struct frame
*, struct image
*, XColor
*));
7030 static void x_detect_edges
P_ ((struct frame
*, struct image
*, int[9], int));
7032 /* Non-zero means draw a cross on images having `:conversion
7035 int cross_disabled_images
;
7037 /* Edge detection matrices for different edge-detection
7040 static int emboss_matrix
[9] = {
7042 2, -1, 0, /* y - 1 */
7044 0, 1, -2 /* y + 1 */
7047 static int laplace_matrix
[9] = {
7049 1, 0, 0, /* y - 1 */
7051 0, 0, -1 /* y + 1 */
7054 /* Value is the intensity of the color whose red/green/blue values
7057 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
7060 /* On frame F, return an array of XColor structures describing image
7061 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
7062 non-zero means also fill the red/green/blue members of the XColor
7063 structures. Value is a pointer to the array of XColors structures,
7064 allocated with xmalloc; it must be freed by the caller. */
7067 x_to_xcolors (f
, img
, rgb_p
)
7076 colors
= (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *colors
);
7078 /* Get the X image IMG->pixmap. */
7079 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
7080 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
7082 /* Fill the `pixel' members of the XColor array. I wished there
7083 were an easy and portable way to circumvent XGetPixel. */
7085 for (y
= 0; y
< img
->height
; ++y
)
7089 for (x
= 0; x
< img
->width
; ++x
, ++p
)
7090 p
->pixel
= XGetPixel (ximg
, x
, y
);
7093 x_query_colors (f
, row
, img
->width
);
7096 XDestroyImage (ximg
);
7101 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
7102 RGB members are set. F is the frame on which this all happens.
7103 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
7106 x_from_xcolors (f
, img
, colors
)
7116 init_color_table ();
7118 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
7121 for (y
= 0; y
< img
->height
; ++y
)
7122 for (x
= 0; x
< img
->width
; ++x
, ++p
)
7124 unsigned long pixel
;
7125 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
7126 XPutPixel (oimg
, x
, y
, pixel
);
7130 x_clear_image_1 (f
, img
, 1, 0, 1);
7132 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
7133 x_destroy_x_image (oimg
);
7134 img
->pixmap
= pixmap
;
7135 img
->colors
= colors_in_color_table (&img
->ncolors
);
7136 free_color_table ();
7140 /* On frame F, perform edge-detection on image IMG.
7142 MATRIX is a nine-element array specifying the transformation
7143 matrix. See emboss_matrix for an example.
7145 COLOR_ADJUST is a color adjustment added to each pixel of the
7149 x_detect_edges (f
, img
, matrix
, color_adjust
)
7152 int matrix
[9], color_adjust
;
7154 XColor
*colors
= x_to_xcolors (f
, img
, 1);
7158 for (i
= sum
= 0; i
< 9; ++i
)
7159 sum
+= abs (matrix
[i
]);
7161 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
7163 new = (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *new);
7165 for (y
= 0; y
< img
->height
; ++y
)
7167 p
= COLOR (new, 0, y
);
7168 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7169 p
= COLOR (new, img
->width
- 1, y
);
7170 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7173 for (x
= 1; x
< img
->width
- 1; ++x
)
7175 p
= COLOR (new, x
, 0);
7176 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7177 p
= COLOR (new, x
, img
->height
- 1);
7178 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7181 for (y
= 1; y
< img
->height
- 1; ++y
)
7183 p
= COLOR (new, 1, y
);
7185 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
7187 int r
, g
, b
, y1
, x1
;
7190 for (y1
= y
- 1; y1
< y
+ 2; ++y1
)
7191 for (x1
= x
- 1; x1
< x
+ 2; ++x1
, ++i
)
7194 XColor
*t
= COLOR (colors
, x1
, y1
);
7195 r
+= matrix
[i
] * t
->red
;
7196 g
+= matrix
[i
] * t
->green
;
7197 b
+= matrix
[i
] * t
->blue
;
7200 r
= (r
/ sum
+ color_adjust
) & 0xffff;
7201 g
= (g
/ sum
+ color_adjust
) & 0xffff;
7202 b
= (b
/ sum
+ color_adjust
) & 0xffff;
7203 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
7208 x_from_xcolors (f
, img
, new);
7214 /* Perform the pre-defined `emboss' edge-detection on image IMG
7222 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
7226 /* Perform the pre-defined `laplace' edge-detection on image IMG
7234 x_detect_edges (f
, img
, laplace_matrix
, 45000);
7238 /* Perform edge-detection on image IMG on frame F, with specified
7239 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
7241 MATRIX must be either
7243 - a list of at least 9 numbers in row-major form
7244 - a vector of at least 9 numbers
7246 COLOR_ADJUST nil means use a default; otherwise it must be a
7250 x_edge_detection (f
, img
, matrix
, color_adjust
)
7253 Lisp_Object matrix
, color_adjust
;
7261 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
7262 ++i
, matrix
= XCDR (matrix
))
7263 trans
[i
] = XFLOATINT (XCAR (matrix
));
7265 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
7267 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
7268 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
7271 if (NILP (color_adjust
))
7272 color_adjust
= make_number (0xffff / 2);
7274 if (i
== 9 && NUMBERP (color_adjust
))
7275 x_detect_edges (f
, img
, trans
, (int) XFLOATINT (color_adjust
));
7279 /* Transform image IMG on frame F so that it looks disabled. */
7282 x_disable_image (f
, img
)
7286 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7288 if (dpyinfo
->n_planes
>= 2)
7290 /* Color (or grayscale). Convert to gray, and equalize. Just
7291 drawing such images with a stipple can look very odd, so
7292 we're using this method instead. */
7293 XColor
*colors
= x_to_xcolors (f
, img
, 1);
7295 const int h
= 15000;
7296 const int l
= 30000;
7298 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
7302 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
7303 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
7304 p
->red
= p
->green
= p
->blue
= i2
;
7307 x_from_xcolors (f
, img
, colors
);
7310 /* Draw a cross over the disabled image, if we must or if we
7312 if (dpyinfo
->n_planes
< 2 || cross_disabled_images
)
7314 Display
*dpy
= FRAME_X_DISPLAY (f
);
7317 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
7318 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
7319 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
7320 img
->width
- 1, img
->height
- 1);
7321 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
7327 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
7328 XSetForeground (dpy
, gc
, WHITE_PIX_DEFAULT (f
));
7329 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
7330 img
->width
- 1, img
->height
- 1);
7331 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
7339 /* Build a mask for image IMG which is used on frame F. FILE is the
7340 name of an image file, for error messages. HOW determines how to
7341 determine the background color of IMG. If it is a list '(R G B)',
7342 with R, G, and B being integers >= 0, take that as the color of the
7343 background. Otherwise, determine the background color of IMG
7344 heuristically. Value is non-zero if successful. */
7347 x_build_heuristic_mask (f
, img
, how
)
7352 Display
*dpy
= FRAME_X_DISPLAY (f
);
7353 XImage
*ximg
, *mask_img
;
7354 int x
, y
, rc
, use_img_background
;
7355 unsigned long bg
= 0;
7359 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
7361 img
->background_transparent_valid
= 0;
7364 /* Create an image and pixmap serving as mask. */
7365 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
7366 &mask_img
, &img
->mask
);
7370 /* Get the X image of IMG->pixmap. */
7371 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
7374 /* Determine the background color of ximg. If HOW is `(R G B)'
7375 take that as color. Otherwise, use the image's background color. */
7376 use_img_background
= 1;
7382 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
7384 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
7388 if (i
== 3 && NILP (how
))
7390 char color_name
[30];
7391 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
7392 bg
= x_alloc_image_color (f
, img
, build_string (color_name
), 0);
7393 use_img_background
= 0;
7397 if (use_img_background
)
7398 bg
= four_corners_best (ximg
, img
->width
, img
->height
);
7400 /* Set all bits in mask_img to 1 whose color in ximg is different
7401 from the background color bg. */
7402 for (y
= 0; y
< img
->height
; ++y
)
7403 for (x
= 0; x
< img
->width
; ++x
)
7404 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
7406 /* Fill in the background_transparent field while we have the mask handy. */
7407 image_background_transparent (img
, f
, mask_img
);
7409 /* Put mask_img into img->mask. */
7410 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
7411 x_destroy_x_image (mask_img
);
7412 XDestroyImage (ximg
);
7419 /***********************************************************************
7420 PBM (mono, gray, color)
7421 ***********************************************************************/
7423 static int pbm_image_p
P_ ((Lisp_Object object
));
7424 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
7425 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
7427 /* The symbol `pbm' identifying images of this type. */
7431 /* Indices of image specification fields in gs_format, below. */
7433 enum pbm_keyword_index
7449 /* Vector of image_keyword structures describing the format
7450 of valid user-defined image specifications. */
7452 static struct image_keyword pbm_format
[PBM_LAST
] =
7454 {":type", IMAGE_SYMBOL_VALUE
, 1},
7455 {":file", IMAGE_STRING_VALUE
, 0},
7456 {":data", IMAGE_STRING_VALUE
, 0},
7457 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7458 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7459 {":relief", IMAGE_INTEGER_VALUE
, 0},
7460 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7461 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7462 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7463 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
7464 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7467 /* Structure describing the image type `pbm'. */
7469 static struct image_type pbm_type
=
7479 /* Return non-zero if OBJECT is a valid PBM image specification. */
7482 pbm_image_p (object
)
7485 struct image_keyword fmt
[PBM_LAST
];
7487 bcopy (pbm_format
, fmt
, sizeof fmt
);
7489 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
7492 /* Must specify either :data or :file. */
7493 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
7497 /* Scan a decimal number from *S and return it. Advance *S while
7498 reading the number. END is the end of the string. Value is -1 at
7502 pbm_scan_number (s
, end
)
7503 unsigned char **s
, *end
;
7505 int c
= 0, val
= -1;
7509 /* Skip white-space. */
7510 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
7515 /* Skip comment to end of line. */
7516 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
7519 else if (isdigit (c
))
7521 /* Read decimal number. */
7523 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
7524 val
= 10 * val
+ c
- '0';
7535 /* Load PBM image IMG for use on frame F. */
7543 int width
, height
, max_color_idx
= 0;
7545 Lisp_Object file
, specified_file
;
7546 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
7547 struct gcpro gcpro1
;
7548 unsigned char *contents
= NULL
;
7549 unsigned char *end
, *p
;
7552 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7556 if (STRINGP (specified_file
))
7558 file
= x_find_image_file (specified_file
);
7559 if (!STRINGP (file
))
7561 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7566 contents
= slurp_file (SDATA (file
), &size
);
7567 if (contents
== NULL
)
7569 image_error ("Error reading `%s'", file
, Qnil
);
7575 end
= contents
+ size
;
7580 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7582 end
= p
+ SBYTES (data
);
7585 /* Check magic number. */
7586 if (end
- p
< 2 || *p
++ != 'P')
7588 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7598 raw_p
= 0, type
= PBM_MONO
;
7602 raw_p
= 0, type
= PBM_GRAY
;
7606 raw_p
= 0, type
= PBM_COLOR
;
7610 raw_p
= 1, type
= PBM_MONO
;
7614 raw_p
= 1, type
= PBM_GRAY
;
7618 raw_p
= 1, type
= PBM_COLOR
;
7622 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7626 /* Read width, height, maximum color-component. Characters
7627 starting with `#' up to the end of a line are ignored. */
7628 width
= pbm_scan_number (&p
, end
);
7629 height
= pbm_scan_number (&p
, end
);
7631 if (type
!= PBM_MONO
)
7633 max_color_idx
= pbm_scan_number (&p
, end
);
7634 if (raw_p
&& max_color_idx
> 255)
7635 max_color_idx
= 255;
7640 || (type
!= PBM_MONO
&& max_color_idx
< 0))
7643 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7644 &ximg
, &img
->pixmap
))
7647 /* Initialize the color hash table. */
7648 init_color_table ();
7650 if (type
== PBM_MONO
)
7653 struct image_keyword fmt
[PBM_LAST
];
7654 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
7655 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
7657 /* Parse the image specification. */
7658 bcopy (pbm_format
, fmt
, sizeof fmt
);
7659 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
7661 /* Get foreground and background colors, maybe allocate colors. */
7662 if (fmt
[PBM_FOREGROUND
].count
7663 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
7664 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
7665 if (fmt
[PBM_BACKGROUND
].count
7666 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
7668 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
7669 img
->background
= bg
;
7670 img
->background_valid
= 1;
7673 for (y
= 0; y
< height
; ++y
)
7674 for (x
= 0; x
< width
; ++x
)
7684 g
= pbm_scan_number (&p
, end
);
7686 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
7691 for (y
= 0; y
< height
; ++y
)
7692 for (x
= 0; x
< width
; ++x
)
7696 if (type
== PBM_GRAY
)
7697 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
7706 r
= pbm_scan_number (&p
, end
);
7707 g
= pbm_scan_number (&p
, end
);
7708 b
= pbm_scan_number (&p
, end
);
7711 if (r
< 0 || g
< 0 || b
< 0)
7715 XDestroyImage (ximg
);
7716 image_error ("Invalid pixel value in image `%s'",
7721 /* RGB values are now in the range 0..max_color_idx.
7722 Scale this to the range 0..0xffff supported by X. */
7723 r
= (double) r
* 65535 / max_color_idx
;
7724 g
= (double) g
* 65535 / max_color_idx
;
7725 b
= (double) b
* 65535 / max_color_idx
;
7726 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7730 /* Store in IMG->colors the colors allocated for the image, and
7731 free the color table. */
7732 img
->colors
= colors_in_color_table (&img
->ncolors
);
7733 free_color_table ();
7735 /* Maybe fill in the background field while we have ximg handy. */
7736 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7737 IMAGE_BACKGROUND (img
, f
, ximg
);
7739 /* Put the image into a pixmap. */
7740 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7741 x_destroy_x_image (ximg
);
7744 img
->height
= height
;
7753 /***********************************************************************
7755 ***********************************************************************/
7759 #if defined HAVE_LIBPNG_PNG_H
7760 # include <libpng/png.h>
7765 /* Function prototypes. */
7767 static int png_image_p
P_ ((Lisp_Object object
));
7768 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
7770 /* The symbol `png' identifying images of this type. */
7774 /* Indices of image specification fields in png_format, below. */
7776 enum png_keyword_index
7791 /* Vector of image_keyword structures describing the format
7792 of valid user-defined image specifications. */
7794 static struct image_keyword png_format
[PNG_LAST
] =
7796 {":type", IMAGE_SYMBOL_VALUE
, 1},
7797 {":data", IMAGE_STRING_VALUE
, 0},
7798 {":file", IMAGE_STRING_VALUE
, 0},
7799 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7800 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7801 {":relief", IMAGE_INTEGER_VALUE
, 0},
7802 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7803 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7804 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7805 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7808 /* Structure describing the image type `png'. */
7810 static struct image_type png_type
=
7820 /* Return non-zero if OBJECT is a valid PNG image specification. */
7823 png_image_p (object
)
7826 struct image_keyword fmt
[PNG_LAST
];
7827 bcopy (png_format
, fmt
, sizeof fmt
);
7829 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
7832 /* Must specify either the :data or :file keyword. */
7833 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
7837 /* Error and warning handlers installed when the PNG library
7841 my_png_error (png_ptr
, msg
)
7842 png_struct
*png_ptr
;
7845 xassert (png_ptr
!= NULL
);
7846 image_error ("PNG error: %s", build_string (msg
), Qnil
);
7847 longjmp (png_ptr
->jmpbuf
, 1);
7852 my_png_warning (png_ptr
, msg
)
7853 png_struct
*png_ptr
;
7856 xassert (png_ptr
!= NULL
);
7857 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
7860 /* Memory source for PNG decoding. */
7862 struct png_memory_storage
7864 unsigned char *bytes
; /* The data */
7865 size_t len
; /* How big is it? */
7866 int index
; /* Where are we? */
7870 /* Function set as reader function when reading PNG image from memory.
7871 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
7872 bytes from the input to DATA. */
7875 png_read_from_memory (png_ptr
, data
, length
)
7876 png_structp png_ptr
;
7880 struct png_memory_storage
*tbr
7881 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
7883 if (length
> tbr
->len
- tbr
->index
)
7884 png_error (png_ptr
, "Read error");
7886 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
7887 tbr
->index
= tbr
->index
+ length
;
7890 /* Load PNG image IMG for use on frame F. Value is non-zero if
7898 Lisp_Object file
, specified_file
;
7899 Lisp_Object specified_data
;
7901 XImage
*ximg
, *mask_img
= NULL
;
7902 struct gcpro gcpro1
;
7903 png_struct
*png_ptr
= NULL
;
7904 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
7905 FILE *volatile fp
= NULL
;
7907 png_byte
* volatile pixels
= NULL
;
7908 png_byte
** volatile rows
= NULL
;
7909 png_uint_32 width
, height
;
7910 int bit_depth
, color_type
, interlace_type
;
7912 png_uint_32 row_bytes
;
7914 double screen_gamma
;
7915 struct png_memory_storage tbr
; /* Data to be read */
7917 /* Find out what file to load. */
7918 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7919 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7923 if (NILP (specified_data
))
7925 file
= x_find_image_file (specified_file
);
7926 if (!STRINGP (file
))
7928 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7933 /* Open the image file. */
7934 fp
= fopen (SDATA (file
), "rb");
7937 image_error ("Cannot open image file `%s'", file
, Qnil
);
7943 /* Check PNG signature. */
7944 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
7945 || !png_check_sig (sig
, sizeof sig
))
7947 image_error ("Not a PNG file: `%s'", file
, Qnil
);
7955 /* Read from memory. */
7956 tbr
.bytes
= SDATA (specified_data
);
7957 tbr
.len
= SBYTES (specified_data
);
7960 /* Check PNG signature. */
7961 if (tbr
.len
< sizeof sig
7962 || !png_check_sig (tbr
.bytes
, sizeof sig
))
7964 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
7969 /* Need to skip past the signature. */
7970 tbr
.bytes
+= sizeof (sig
);
7973 /* Initialize read and info structs for PNG lib. */
7974 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
7975 my_png_error
, my_png_warning
);
7978 if (fp
) fclose (fp
);
7983 info_ptr
= png_create_info_struct (png_ptr
);
7986 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
7987 if (fp
) fclose (fp
);
7992 end_info
= png_create_info_struct (png_ptr
);
7995 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
7996 if (fp
) fclose (fp
);
8001 /* Set error jump-back. We come back here when the PNG library
8002 detects an error. */
8003 if (setjmp (png_ptr
->jmpbuf
))
8007 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
8010 if (fp
) fclose (fp
);
8015 /* Read image info. */
8016 if (!NILP (specified_data
))
8017 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
8019 png_init_io (png_ptr
, fp
);
8021 png_set_sig_bytes (png_ptr
, sizeof sig
);
8022 png_read_info (png_ptr
, info_ptr
);
8023 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
8024 &interlace_type
, NULL
, NULL
);
8026 /* If image contains simply transparency data, we prefer to
8027 construct a clipping mask. */
8028 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
8033 /* This function is easier to write if we only have to handle
8034 one data format: RGB or RGBA with 8 bits per channel. Let's
8035 transform other formats into that format. */
8037 /* Strip more than 8 bits per channel. */
8038 if (bit_depth
== 16)
8039 png_set_strip_16 (png_ptr
);
8041 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
8043 png_set_expand (png_ptr
);
8045 /* Convert grayscale images to RGB. */
8046 if (color_type
== PNG_COLOR_TYPE_GRAY
8047 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
8048 png_set_gray_to_rgb (png_ptr
);
8050 screen_gamma
= (f
->gamma
? 1 / f
->gamma
/ 0.45455 : 2.2);
8052 #if 0 /* Avoid double gamma correction for PNG images. */
8053 { /* Tell the PNG lib to handle gamma correction for us. */
8056 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
8057 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
8058 /* The libpng documentation says this is right in this case. */
8059 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
8062 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
8063 /* Image contains gamma information. */
8064 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
8066 /* Use the standard default for the image gamma. */
8067 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
8071 /* Handle alpha channel by combining the image with a background
8072 color. Do this only if a real alpha channel is supplied. For
8073 simple transparency, we prefer a clipping mask. */
8076 png_color_16
*image_bg
;
8077 Lisp_Object specified_bg
8078 = image_spec_value (img
->spec
, QCbackground
, NULL
);
8080 if (STRINGP (specified_bg
))
8081 /* The user specified `:background', use that. */
8084 if (x_defined_color (f
, SDATA (specified_bg
), &color
, 0))
8086 png_color_16 user_bg
;
8088 bzero (&user_bg
, sizeof user_bg
);
8089 user_bg
.red
= color
.red
;
8090 user_bg
.green
= color
.green
;
8091 user_bg
.blue
= color
.blue
;
8093 png_set_background (png_ptr
, &user_bg
,
8094 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
8097 else if (png_get_bKGD (png_ptr
, info_ptr
, &image_bg
))
8098 /* Image contains a background color with which to
8099 combine the image. */
8100 png_set_background (png_ptr
, image_bg
,
8101 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
8104 /* Image does not contain a background color with which
8105 to combine the image data via an alpha channel. Use
8106 the frame's background instead. */
8109 png_color_16 frame_background
;
8111 cmap
= FRAME_X_COLORMAP (f
);
8112 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
8113 x_query_color (f
, &color
);
8115 bzero (&frame_background
, sizeof frame_background
);
8116 frame_background
.red
= color
.red
;
8117 frame_background
.green
= color
.green
;
8118 frame_background
.blue
= color
.blue
;
8120 png_set_background (png_ptr
, &frame_background
,
8121 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
8125 /* Update info structure. */
8126 png_read_update_info (png_ptr
, info_ptr
);
8128 /* Get number of channels. Valid values are 1 for grayscale images
8129 and images with a palette, 2 for grayscale images with transparency
8130 information (alpha channel), 3 for RGB images, and 4 for RGB
8131 images with alpha channel, i.e. RGBA. If conversions above were
8132 sufficient we should only have 3 or 4 channels here. */
8133 channels
= png_get_channels (png_ptr
, info_ptr
);
8134 xassert (channels
== 3 || channels
== 4);
8136 /* Number of bytes needed for one row of the image. */
8137 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
8139 /* Allocate memory for the image. */
8140 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
8141 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
8142 for (i
= 0; i
< height
; ++i
)
8143 rows
[i
] = pixels
+ i
* row_bytes
;
8145 /* Read the entire image. */
8146 png_read_image (png_ptr
, rows
);
8147 png_read_end (png_ptr
, info_ptr
);
8154 /* Create the X image and pixmap. */
8155 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
8159 /* Create an image and pixmap serving as mask if the PNG image
8160 contains an alpha channel. */
8163 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
8164 &mask_img
, &img
->mask
))
8166 x_destroy_x_image (ximg
);
8167 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
8172 /* Fill the X image and mask from PNG data. */
8173 init_color_table ();
8175 for (y
= 0; y
< height
; ++y
)
8177 png_byte
*p
= rows
[y
];
8179 for (x
= 0; x
< width
; ++x
)
8186 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
8188 /* An alpha channel, aka mask channel, associates variable
8189 transparency with an image. Where other image formats
8190 support binary transparency---fully transparent or fully
8191 opaque---PNG allows up to 254 levels of partial transparency.
8192 The PNG library implements partial transparency by combining
8193 the image with a specified background color.
8195 I'm not sure how to handle this here nicely: because the
8196 background on which the image is displayed may change, for
8197 real alpha channel support, it would be necessary to create
8198 a new image for each possible background.
8200 What I'm doing now is that a mask is created if we have
8201 boolean transparency information. Otherwise I'm using
8202 the frame's background color to combine the image with. */
8207 XPutPixel (mask_img
, x
, y
, *p
> 0);
8213 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8214 /* Set IMG's background color from the PNG image, unless the user
8218 if (png_get_bKGD (png_ptr
, info_ptr
, &bg
))
8220 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
8221 img
->background_valid
= 1;
8225 /* Remember colors allocated for this image. */
8226 img
->colors
= colors_in_color_table (&img
->ncolors
);
8227 free_color_table ();
8230 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
8235 img
->height
= height
;
8237 /* Maybe fill in the background field while we have ximg handy. */
8238 IMAGE_BACKGROUND (img
, f
, ximg
);
8240 /* Put the image into the pixmap, then free the X image and its buffer. */
8241 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8242 x_destroy_x_image (ximg
);
8244 /* Same for the mask. */
8247 /* Fill in the background_transparent field while we have the mask
8249 image_background_transparent (img
, f
, mask_img
);
8251 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
8252 x_destroy_x_image (mask_img
);
8259 #endif /* HAVE_PNG != 0 */
8263 /***********************************************************************
8265 ***********************************************************************/
8269 /* Work around a warning about HAVE_STDLIB_H being redefined in
8271 #ifdef HAVE_STDLIB_H
8272 #define HAVE_STDLIB_H_1
8273 #undef HAVE_STDLIB_H
8274 #endif /* HAVE_STLIB_H */
8276 #include <jpeglib.h>
8280 #ifdef HAVE_STLIB_H_1
8281 #define HAVE_STDLIB_H 1
8284 static int jpeg_image_p
P_ ((Lisp_Object object
));
8285 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
8287 /* The symbol `jpeg' identifying images of this type. */
8291 /* Indices of image specification fields in gs_format, below. */
8293 enum jpeg_keyword_index
8302 JPEG_HEURISTIC_MASK
,
8308 /* Vector of image_keyword structures describing the format
8309 of valid user-defined image specifications. */
8311 static struct image_keyword jpeg_format
[JPEG_LAST
] =
8313 {":type", IMAGE_SYMBOL_VALUE
, 1},
8314 {":data", IMAGE_STRING_VALUE
, 0},
8315 {":file", IMAGE_STRING_VALUE
, 0},
8316 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8317 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8318 {":relief", IMAGE_INTEGER_VALUE
, 0},
8319 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8320 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8321 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8322 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8325 /* Structure describing the image type `jpeg'. */
8327 static struct image_type jpeg_type
=
8337 /* Return non-zero if OBJECT is a valid JPEG image specification. */
8340 jpeg_image_p (object
)
8343 struct image_keyword fmt
[JPEG_LAST
];
8345 bcopy (jpeg_format
, fmt
, sizeof fmt
);
8347 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
8350 /* Must specify either the :data or :file keyword. */
8351 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
8355 struct my_jpeg_error_mgr
8357 struct jpeg_error_mgr pub
;
8358 jmp_buf setjmp_buffer
;
8363 my_error_exit (cinfo
)
8366 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
8367 longjmp (mgr
->setjmp_buffer
, 1);
8371 /* Init source method for JPEG data source manager. Called by
8372 jpeg_read_header() before any data is actually read. See
8373 libjpeg.doc from the JPEG lib distribution. */
8376 our_init_source (cinfo
)
8377 j_decompress_ptr cinfo
;
8382 /* Fill input buffer method for JPEG data source manager. Called
8383 whenever more data is needed. We read the whole image in one step,
8384 so this only adds a fake end of input marker at the end. */
8387 our_fill_input_buffer (cinfo
)
8388 j_decompress_ptr cinfo
;
8390 /* Insert a fake EOI marker. */
8391 struct jpeg_source_mgr
*src
= cinfo
->src
;
8392 static JOCTET buffer
[2];
8394 buffer
[0] = (JOCTET
) 0xFF;
8395 buffer
[1] = (JOCTET
) JPEG_EOI
;
8397 src
->next_input_byte
= buffer
;
8398 src
->bytes_in_buffer
= 2;
8403 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
8404 is the JPEG data source manager. */
8407 our_skip_input_data (cinfo
, num_bytes
)
8408 j_decompress_ptr cinfo
;
8411 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8415 if (num_bytes
> src
->bytes_in_buffer
)
8416 ERREXIT (cinfo
, JERR_INPUT_EOF
);
8418 src
->bytes_in_buffer
-= num_bytes
;
8419 src
->next_input_byte
+= num_bytes
;
8424 /* Method to terminate data source. Called by
8425 jpeg_finish_decompress() after all data has been processed. */
8428 our_term_source (cinfo
)
8429 j_decompress_ptr cinfo
;
8434 /* Set up the JPEG lib for reading an image from DATA which contains
8435 LEN bytes. CINFO is the decompression info structure created for
8436 reading the image. */
8439 jpeg_memory_src (cinfo
, data
, len
)
8440 j_decompress_ptr cinfo
;
8444 struct jpeg_source_mgr
*src
;
8446 if (cinfo
->src
== NULL
)
8448 /* First time for this JPEG object? */
8449 cinfo
->src
= (struct jpeg_source_mgr
*)
8450 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
8451 sizeof (struct jpeg_source_mgr
));
8452 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8453 src
->next_input_byte
= data
;
8456 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8457 src
->init_source
= our_init_source
;
8458 src
->fill_input_buffer
= our_fill_input_buffer
;
8459 src
->skip_input_data
= our_skip_input_data
;
8460 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
8461 src
->term_source
= our_term_source
;
8462 src
->bytes_in_buffer
= len
;
8463 src
->next_input_byte
= data
;
8467 /* Load image IMG for use on frame F. Patterned after example.c
8468 from the JPEG lib. */
8475 struct jpeg_decompress_struct cinfo
;
8476 struct my_jpeg_error_mgr mgr
;
8477 Lisp_Object file
, specified_file
;
8478 Lisp_Object specified_data
;
8479 FILE * volatile fp
= NULL
;
8481 int row_stride
, x
, y
;
8482 XImage
*ximg
= NULL
;
8484 unsigned long *colors
;
8486 struct gcpro gcpro1
;
8488 /* Open the JPEG file. */
8489 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8490 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8494 if (NILP (specified_data
))
8496 file
= x_find_image_file (specified_file
);
8497 if (!STRINGP (file
))
8499 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8504 fp
= fopen (SDATA (file
), "r");
8507 image_error ("Cannot open `%s'", file
, Qnil
);
8513 /* Customize libjpeg's error handling to call my_error_exit when an
8514 error is detected. This function will perform a longjmp. */
8515 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
8516 mgr
.pub
.error_exit
= my_error_exit
;
8518 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
8522 /* Called from my_error_exit. Display a JPEG error. */
8523 char buffer
[JMSG_LENGTH_MAX
];
8524 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
8525 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
8526 build_string (buffer
));
8529 /* Close the input file and destroy the JPEG object. */
8531 fclose ((FILE *) fp
);
8532 jpeg_destroy_decompress (&cinfo
);
8534 /* If we already have an XImage, free that. */
8535 x_destroy_x_image (ximg
);
8537 /* Free pixmap and colors. */
8538 x_clear_image (f
, img
);
8544 /* Create the JPEG decompression object. Let it read from fp.
8545 Read the JPEG image header. */
8546 jpeg_create_decompress (&cinfo
);
8548 if (NILP (specified_data
))
8549 jpeg_stdio_src (&cinfo
, (FILE *) fp
);
8551 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
8552 SBYTES (specified_data
));
8554 jpeg_read_header (&cinfo
, TRUE
);
8556 /* Customize decompression so that color quantization will be used.
8557 Start decompression. */
8558 cinfo
.quantize_colors
= TRUE
;
8559 jpeg_start_decompress (&cinfo
);
8560 width
= img
->width
= cinfo
.output_width
;
8561 height
= img
->height
= cinfo
.output_height
;
8563 /* Create X image and pixmap. */
8564 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8565 longjmp (mgr
.setjmp_buffer
, 2);
8567 /* Allocate colors. When color quantization is used,
8568 cinfo.actual_number_of_colors has been set with the number of
8569 colors generated, and cinfo.colormap is a two-dimensional array
8570 of color indices in the range 0..cinfo.actual_number_of_colors.
8571 No more than 255 colors will be generated. */
8575 if (cinfo
.out_color_components
> 2)
8576 ir
= 0, ig
= 1, ib
= 2;
8577 else if (cinfo
.out_color_components
> 1)
8578 ir
= 0, ig
= 1, ib
= 0;
8580 ir
= 0, ig
= 0, ib
= 0;
8582 /* Use the color table mechanism because it handles colors that
8583 cannot be allocated nicely. Such colors will be replaced with
8584 a default color, and we don't have to care about which colors
8585 can be freed safely, and which can't. */
8586 init_color_table ();
8587 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
8590 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
8592 /* Multiply RGB values with 255 because X expects RGB values
8593 in the range 0..0xffff. */
8594 int r
= cinfo
.colormap
[ir
][i
] << 8;
8595 int g
= cinfo
.colormap
[ig
][i
] << 8;
8596 int b
= cinfo
.colormap
[ib
][i
] << 8;
8597 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8600 /* Remember those colors actually allocated. */
8601 img
->colors
= colors_in_color_table (&img
->ncolors
);
8602 free_color_table ();
8606 row_stride
= width
* cinfo
.output_components
;
8607 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
8609 for (y
= 0; y
< height
; ++y
)
8611 jpeg_read_scanlines (&cinfo
, buffer
, 1);
8612 for (x
= 0; x
< cinfo
.output_width
; ++x
)
8613 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
8617 jpeg_finish_decompress (&cinfo
);
8618 jpeg_destroy_decompress (&cinfo
);
8620 fclose ((FILE *) fp
);
8622 /* Maybe fill in the background field while we have ximg handy. */
8623 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8624 IMAGE_BACKGROUND (img
, f
, ximg
);
8626 /* Put the image into the pixmap. */
8627 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8628 x_destroy_x_image (ximg
);
8633 #endif /* HAVE_JPEG */
8637 /***********************************************************************
8639 ***********************************************************************/
8645 static int tiff_image_p
P_ ((Lisp_Object object
));
8646 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
8648 /* The symbol `tiff' identifying images of this type. */
8652 /* Indices of image specification fields in tiff_format, below. */
8654 enum tiff_keyword_index
8663 TIFF_HEURISTIC_MASK
,
8669 /* Vector of image_keyword structures describing the format
8670 of valid user-defined image specifications. */
8672 static struct image_keyword tiff_format
[TIFF_LAST
] =
8674 {":type", IMAGE_SYMBOL_VALUE
, 1},
8675 {":data", IMAGE_STRING_VALUE
, 0},
8676 {":file", IMAGE_STRING_VALUE
, 0},
8677 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8678 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8679 {":relief", IMAGE_INTEGER_VALUE
, 0},
8680 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8681 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8682 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8683 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8686 /* Structure describing the image type `tiff'. */
8688 static struct image_type tiff_type
=
8698 /* Return non-zero if OBJECT is a valid TIFF image specification. */
8701 tiff_image_p (object
)
8704 struct image_keyword fmt
[TIFF_LAST
];
8705 bcopy (tiff_format
, fmt
, sizeof fmt
);
8707 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
8710 /* Must specify either the :data or :file keyword. */
8711 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
8715 /* Reading from a memory buffer for TIFF images Based on the PNG
8716 memory source, but we have to provide a lot of extra functions.
8719 We really only need to implement read and seek, but I am not
8720 convinced that the TIFF library is smart enough not to destroy
8721 itself if we only hand it the function pointers we need to
8726 unsigned char *bytes
;
8734 tiff_read_from_memory (data
, buf
, size
)
8739 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8741 if (size
> src
->len
- src
->index
)
8743 bcopy (src
->bytes
+ src
->index
, buf
, size
);
8750 tiff_write_from_memory (data
, buf
, size
)
8760 tiff_seek_in_memory (data
, off
, whence
)
8765 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8770 case SEEK_SET
: /* Go from beginning of source. */
8774 case SEEK_END
: /* Go from end of source. */
8775 idx
= src
->len
+ off
;
8778 case SEEK_CUR
: /* Go from current position. */
8779 idx
= src
->index
+ off
;
8782 default: /* Invalid `whence'. */
8786 if (idx
> src
->len
|| idx
< 0)
8795 tiff_close_memory (data
)
8804 tiff_mmap_memory (data
, pbase
, psize
)
8809 /* It is already _IN_ memory. */
8815 tiff_unmap_memory (data
, base
, size
)
8820 /* We don't need to do this. */
8825 tiff_size_of_memory (data
)
8828 return ((tiff_memory_source
*) data
)->len
;
8833 tiff_error_handler (title
, format
, ap
)
8834 const char *title
, *format
;
8840 len
= sprintf (buf
, "TIFF error: %s ", title
);
8841 vsprintf (buf
+ len
, format
, ap
);
8842 add_to_log (buf
, Qnil
, Qnil
);
8847 tiff_warning_handler (title
, format
, ap
)
8848 const char *title
, *format
;
8854 len
= sprintf (buf
, "TIFF warning: %s ", title
);
8855 vsprintf (buf
+ len
, format
, ap
);
8856 add_to_log (buf
, Qnil
, Qnil
);
8860 /* Load TIFF image IMG for use on frame F. Value is non-zero if
8868 Lisp_Object file
, specified_file
;
8869 Lisp_Object specified_data
;
8871 int width
, height
, x
, y
;
8875 struct gcpro gcpro1
;
8876 tiff_memory_source memsrc
;
8878 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8879 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8883 TIFFSetErrorHandler (tiff_error_handler
);
8884 TIFFSetWarningHandler (tiff_warning_handler
);
8886 if (NILP (specified_data
))
8888 /* Read from a file */
8889 file
= x_find_image_file (specified_file
);
8890 if (!STRINGP (file
))
8892 image_error ("Cannot find image file `%s'", file
, Qnil
);
8897 /* Try to open the image file. */
8898 tiff
= TIFFOpen (SDATA (file
), "r");
8901 image_error ("Cannot open `%s'", file
, Qnil
);
8908 /* Memory source! */
8909 memsrc
.bytes
= SDATA (specified_data
);
8910 memsrc
.len
= SBYTES (specified_data
);
8913 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
8914 (TIFFReadWriteProc
) tiff_read_from_memory
,
8915 (TIFFReadWriteProc
) tiff_write_from_memory
,
8916 tiff_seek_in_memory
,
8918 tiff_size_of_memory
,
8924 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
8930 /* Get width and height of the image, and allocate a raster buffer
8931 of width x height 32-bit values. */
8932 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
8933 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
8934 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
8936 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
8940 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
8946 /* Create the X image and pixmap. */
8947 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8954 /* Initialize the color table. */
8955 init_color_table ();
8957 /* Process the pixel raster. Origin is in the lower-left corner. */
8958 for (y
= 0; y
< height
; ++y
)
8960 uint32
*row
= buf
+ y
* width
;
8962 for (x
= 0; x
< width
; ++x
)
8964 uint32 abgr
= row
[x
];
8965 int r
= TIFFGetR (abgr
) << 8;
8966 int g
= TIFFGetG (abgr
) << 8;
8967 int b
= TIFFGetB (abgr
) << 8;
8968 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
8972 /* Remember the colors allocated for the image. Free the color table. */
8973 img
->colors
= colors_in_color_table (&img
->ncolors
);
8974 free_color_table ();
8977 img
->height
= height
;
8979 /* Maybe fill in the background field while we have ximg handy. */
8980 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8981 IMAGE_BACKGROUND (img
, f
, ximg
);
8983 /* Put the image into the pixmap, then free the X image and its buffer. */
8984 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8985 x_destroy_x_image (ximg
);
8992 #endif /* HAVE_TIFF != 0 */
8996 /***********************************************************************
8998 ***********************************************************************/
9002 #include <gif_lib.h>
9004 static int gif_image_p
P_ ((Lisp_Object object
));
9005 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
9007 /* The symbol `gif' identifying images of this type. */
9011 /* Indices of image specification fields in gif_format, below. */
9013 enum gif_keyword_index
9029 /* Vector of image_keyword structures describing the format
9030 of valid user-defined image specifications. */
9032 static struct image_keyword gif_format
[GIF_LAST
] =
9034 {":type", IMAGE_SYMBOL_VALUE
, 1},
9035 {":data", IMAGE_STRING_VALUE
, 0},
9036 {":file", IMAGE_STRING_VALUE
, 0},
9037 {":ascent", IMAGE_ASCENT_VALUE
, 0},
9038 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
9039 {":relief", IMAGE_INTEGER_VALUE
, 0},
9040 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9041 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9042 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9043 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
9044 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
9047 /* Structure describing the image type `gif'. */
9049 static struct image_type gif_type
=
9059 /* Return non-zero if OBJECT is a valid GIF image specification. */
9062 gif_image_p (object
)
9065 struct image_keyword fmt
[GIF_LAST
];
9066 bcopy (gif_format
, fmt
, sizeof fmt
);
9068 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
9071 /* Must specify either the :data or :file keyword. */
9072 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
9076 /* Reading a GIF image from memory
9077 Based on the PNG memory stuff to a certain extent. */
9081 unsigned char *bytes
;
9088 /* Make the current memory source available to gif_read_from_memory.
9089 It's done this way because not all versions of libungif support
9090 a UserData field in the GifFileType structure. */
9091 static gif_memory_source
*current_gif_memory_src
;
9094 gif_read_from_memory (file
, buf
, len
)
9099 gif_memory_source
*src
= current_gif_memory_src
;
9101 if (len
> src
->len
- src
->index
)
9104 bcopy (src
->bytes
+ src
->index
, buf
, len
);
9110 /* Load GIF image IMG for use on frame F. Value is non-zero if
9118 Lisp_Object file
, specified_file
;
9119 Lisp_Object specified_data
;
9120 int rc
, width
, height
, x
, y
, i
;
9122 ColorMapObject
*gif_color_map
;
9123 unsigned long pixel_colors
[256];
9125 struct gcpro gcpro1
;
9127 int ino
, image_left
, image_top
, image_width
, image_height
;
9128 gif_memory_source memsrc
;
9129 unsigned char *raster
;
9131 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
9132 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
9136 if (NILP (specified_data
))
9138 file
= x_find_image_file (specified_file
);
9139 if (!STRINGP (file
))
9141 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
9146 /* Open the GIF file. */
9147 gif
= DGifOpenFileName (SDATA (file
));
9150 image_error ("Cannot open `%s'", file
, Qnil
);
9157 /* Read from memory! */
9158 current_gif_memory_src
= &memsrc
;
9159 memsrc
.bytes
= SDATA (specified_data
);
9160 memsrc
.len
= SBYTES (specified_data
);
9163 gif
= DGifOpen (&memsrc
, gif_read_from_memory
);
9166 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
9172 /* Read entire contents. */
9173 rc
= DGifSlurp (gif
);
9174 if (rc
== GIF_ERROR
)
9176 image_error ("Error reading `%s'", img
->spec
, Qnil
);
9177 DGifCloseFile (gif
);
9182 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
9183 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
9184 if (ino
>= gif
->ImageCount
)
9186 image_error ("Invalid image number `%s' in image `%s'",
9188 DGifCloseFile (gif
);
9193 width
= img
->width
= max (gif
->SWidth
, gif
->Image
.Left
+ gif
->Image
.Width
);
9194 height
= img
->height
= max (gif
->SHeight
, gif
->Image
.Top
+ gif
->Image
.Height
);
9196 /* Create the X image and pixmap. */
9197 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
9199 DGifCloseFile (gif
);
9204 /* Allocate colors. */
9205 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
9207 gif_color_map
= gif
->SColorMap
;
9208 init_color_table ();
9209 bzero (pixel_colors
, sizeof pixel_colors
);
9211 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
9213 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
9214 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
9215 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
9216 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
9219 img
->colors
= colors_in_color_table (&img
->ncolors
);
9220 free_color_table ();
9222 /* Clear the part of the screen image that are not covered by
9223 the image from the GIF file. Full animated GIF support
9224 requires more than can be done here (see the gif89 spec,
9225 disposal methods). Let's simply assume that the part
9226 not covered by a sub-image is in the frame's background color. */
9227 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
9228 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
9229 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
9230 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
9232 for (y
= 0; y
< image_top
; ++y
)
9233 for (x
= 0; x
< width
; ++x
)
9234 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9236 for (y
= image_top
+ image_height
; y
< height
; ++y
)
9237 for (x
= 0; x
< width
; ++x
)
9238 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9240 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
9242 for (x
= 0; x
< image_left
; ++x
)
9243 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9244 for (x
= image_left
+ image_width
; x
< width
; ++x
)
9245 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9248 /* Read the GIF image into the X image. We use a local variable
9249 `raster' here because RasterBits below is a char *, and invites
9250 problems with bytes >= 0x80. */
9251 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
9253 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
9255 static int interlace_start
[] = {0, 4, 2, 1};
9256 static int interlace_increment
[] = {8, 8, 4, 2};
9258 int row
= interlace_start
[0];
9262 for (y
= 0; y
< image_height
; y
++)
9264 if (row
>= image_height
)
9266 row
= interlace_start
[++pass
];
9267 while (row
>= image_height
)
9268 row
= interlace_start
[++pass
];
9271 for (x
= 0; x
< image_width
; x
++)
9273 int i
= raster
[(y
* image_width
) + x
];
9274 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
9278 row
+= interlace_increment
[pass
];
9283 for (y
= 0; y
< image_height
; ++y
)
9284 for (x
= 0; x
< image_width
; ++x
)
9286 int i
= raster
[y
* image_width
+ x
];
9287 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
9291 DGifCloseFile (gif
);
9293 /* Maybe fill in the background field while we have ximg handy. */
9294 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
9295 IMAGE_BACKGROUND (img
, f
, ximg
);
9297 /* Put the image into the pixmap, then free the X image and its buffer. */
9298 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
9299 x_destroy_x_image (ximg
);
9305 #endif /* HAVE_GIF != 0 */
9309 /***********************************************************************
9311 ***********************************************************************/
9313 static int gs_image_p
P_ ((Lisp_Object object
));
9314 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
9315 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
9317 /* The symbol `postscript' identifying images of this type. */
9319 Lisp_Object Qpostscript
;
9321 /* Keyword symbols. */
9323 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
9325 /* Indices of image specification fields in gs_format, below. */
9327 enum gs_keyword_index
9345 /* Vector of image_keyword structures describing the format
9346 of valid user-defined image specifications. */
9348 static struct image_keyword gs_format
[GS_LAST
] =
9350 {":type", IMAGE_SYMBOL_VALUE
, 1},
9351 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9352 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9353 {":file", IMAGE_STRING_VALUE
, 1},
9354 {":loader", IMAGE_FUNCTION_VALUE
, 0},
9355 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
9356 {":ascent", IMAGE_ASCENT_VALUE
, 0},
9357 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
9358 {":relief", IMAGE_INTEGER_VALUE
, 0},
9359 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9360 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9361 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9362 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
9365 /* Structure describing the image type `ghostscript'. */
9367 static struct image_type gs_type
=
9377 /* Free X resources of Ghostscript image IMG which is used on frame F. */
9380 gs_clear_image (f
, img
)
9384 /* IMG->data.ptr_val may contain a recorded colormap. */
9385 xfree (img
->data
.ptr_val
);
9386 x_clear_image (f
, img
);
9390 /* Return non-zero if OBJECT is a valid Ghostscript image
9397 struct image_keyword fmt
[GS_LAST
];
9401 bcopy (gs_format
, fmt
, sizeof fmt
);
9403 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
9406 /* Bounding box must be a list or vector containing 4 integers. */
9407 tem
= fmt
[GS_BOUNDING_BOX
].value
;
9410 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
9411 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
9416 else if (VECTORP (tem
))
9418 if (XVECTOR (tem
)->size
!= 4)
9420 for (i
= 0; i
< 4; ++i
)
9421 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
9431 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
9440 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
9441 struct gcpro gcpro1
, gcpro2
;
9443 double in_width
, in_height
;
9444 Lisp_Object pixel_colors
= Qnil
;
9446 /* Compute pixel size of pixmap needed from the given size in the
9447 image specification. Sizes in the specification are in pt. 1 pt
9448 = 1/72 in, xdpi and ydpi are stored in the frame's X display
9450 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
9451 in_width
= XFASTINT (pt_width
) / 72.0;
9452 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
9453 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
9454 in_height
= XFASTINT (pt_height
) / 72.0;
9455 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
9457 /* Create the pixmap. */
9458 xassert (img
->pixmap
== None
);
9459 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9460 img
->width
, img
->height
,
9461 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
9465 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
9469 /* Call the loader to fill the pixmap. It returns a process object
9470 if successful. We do not record_unwind_protect here because
9471 other places in redisplay like calling window scroll functions
9472 don't either. Let the Lisp loader use `unwind-protect' instead. */
9473 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
9475 sprintf (buffer
, "%lu %lu",
9476 (unsigned long) FRAME_X_WINDOW (f
),
9477 (unsigned long) img
->pixmap
);
9478 window_and_pixmap_id
= build_string (buffer
);
9480 sprintf (buffer
, "%lu %lu",
9481 FRAME_FOREGROUND_PIXEL (f
),
9482 FRAME_BACKGROUND_PIXEL (f
));
9483 pixel_colors
= build_string (buffer
);
9485 XSETFRAME (frame
, f
);
9486 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
9488 loader
= intern ("gs-load-image");
9490 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
9491 make_number (img
->width
),
9492 make_number (img
->height
),
9493 window_and_pixmap_id
,
9496 return PROCESSP (img
->data
.lisp_val
);
9500 /* Kill the Ghostscript process that was started to fill PIXMAP on
9501 frame F. Called from XTread_socket when receiving an event
9502 telling Emacs that Ghostscript has finished drawing. */
9505 x_kill_gs_process (pixmap
, f
)
9509 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
9513 /* Find the image containing PIXMAP. */
9514 for (i
= 0; i
< c
->used
; ++i
)
9515 if (c
->images
[i
]->pixmap
== pixmap
)
9518 /* Should someone in between have cleared the image cache, for
9519 instance, give up. */
9523 /* Kill the GS process. We should have found PIXMAP in the image
9524 cache and its image should contain a process object. */
9526 xassert (PROCESSP (img
->data
.lisp_val
));
9527 Fkill_process (img
->data
.lisp_val
, Qnil
);
9528 img
->data
.lisp_val
= Qnil
;
9530 /* On displays with a mutable colormap, figure out the colors
9531 allocated for the image by looking at the pixels of an XImage for
9533 class = FRAME_X_VISUAL (f
)->class;
9534 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
9540 /* Try to get an XImage for img->pixmep. */
9541 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
9542 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
9547 /* Initialize the color table. */
9548 init_color_table ();
9550 /* For each pixel of the image, look its color up in the
9551 color table. After having done so, the color table will
9552 contain an entry for each color used by the image. */
9553 for (y
= 0; y
< img
->height
; ++y
)
9554 for (x
= 0; x
< img
->width
; ++x
)
9556 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
9557 lookup_pixel_color (f
, pixel
);
9560 /* Record colors in the image. Free color table and XImage. */
9561 img
->colors
= colors_in_color_table (&img
->ncolors
);
9562 free_color_table ();
9563 XDestroyImage (ximg
);
9565 #if 0 /* This doesn't seem to be the case. If we free the colors
9566 here, we get a BadAccess later in x_clear_image when
9567 freeing the colors. */
9568 /* We have allocated colors once, but Ghostscript has also
9569 allocated colors on behalf of us. So, to get the
9570 reference counts right, free them once. */
9572 x_free_colors (f
, img
->colors
, img
->ncolors
);
9576 image_error ("Cannot get X image of `%s'; colors will not be freed",
9582 /* Now that we have the pixmap, compute mask and transform the
9583 image if requested. */
9585 postprocess_image (f
, img
);
9591 /***********************************************************************
9593 ***********************************************************************/
9595 DEFUN ("x-change-window-property", Fx_change_window_property
,
9596 Sx_change_window_property
, 2, 3, 0,
9597 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
9598 PROP and VALUE must be strings. FRAME nil or omitted means use the
9599 selected frame. Value is VALUE. */)
9600 (prop
, value
, frame
)
9601 Lisp_Object frame
, prop
, value
;
9603 struct frame
*f
= check_x_frame (frame
);
9606 CHECK_STRING (prop
);
9607 CHECK_STRING (value
);
9610 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9611 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9612 prop_atom
, XA_STRING
, 8, PropModeReplace
,
9613 SDATA (value
), SCHARS (value
));
9615 /* Make sure the property is set when we return. */
9616 XFlush (FRAME_X_DISPLAY (f
));
9623 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
9624 Sx_delete_window_property
, 1, 2, 0,
9625 doc
: /* Remove window property PROP from X window of FRAME.
9626 FRAME nil or omitted means use the selected frame. Value is PROP. */)
9628 Lisp_Object prop
, frame
;
9630 struct frame
*f
= check_x_frame (frame
);
9633 CHECK_STRING (prop
);
9635 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9636 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
9638 /* Make sure the property is removed when we return. */
9639 XFlush (FRAME_X_DISPLAY (f
));
9646 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
9648 doc
: /* Value is the value of window property PROP on FRAME.
9649 If FRAME is nil or omitted, use the selected frame. Value is nil
9650 if FRAME hasn't a property with name PROP or if PROP has no string
9653 Lisp_Object prop
, frame
;
9655 struct frame
*f
= check_x_frame (frame
);
9658 Lisp_Object prop_value
= Qnil
;
9659 char *tmp_data
= NULL
;
9662 unsigned long actual_size
, bytes_remaining
;
9664 CHECK_STRING (prop
);
9666 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9667 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9668 prop_atom
, 0, 0, False
, XA_STRING
,
9669 &actual_type
, &actual_format
, &actual_size
,
9670 &bytes_remaining
, (unsigned char **) &tmp_data
);
9673 int size
= bytes_remaining
;
9678 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9679 prop_atom
, 0, bytes_remaining
,
9681 &actual_type
, &actual_format
,
9682 &actual_size
, &bytes_remaining
,
9683 (unsigned char **) &tmp_data
);
9684 if (rc
== Success
&& tmp_data
)
9685 prop_value
= make_string (tmp_data
, size
);
9696 /***********************************************************************
9698 ***********************************************************************/
9700 /* If non-null, an asynchronous timer that, when it expires, displays
9701 an hourglass cursor on all frames. */
9703 static struct atimer
*hourglass_atimer
;
9705 /* Non-zero means an hourglass cursor is currently shown. */
9707 static int hourglass_shown_p
;
9709 /* Number of seconds to wait before displaying an hourglass cursor. */
9711 static Lisp_Object Vhourglass_delay
;
9713 /* Default number of seconds to wait before displaying an hourglass
9716 #define DEFAULT_HOURGLASS_DELAY 1
9718 /* Function prototypes. */
9720 static void show_hourglass
P_ ((struct atimer
*));
9721 static void hide_hourglass
P_ ((void));
9724 /* Cancel a currently active hourglass timer, and start a new one. */
9730 int secs
, usecs
= 0;
9732 cancel_hourglass ();
9734 if (INTEGERP (Vhourglass_delay
)
9735 && XINT (Vhourglass_delay
) > 0)
9736 secs
= XFASTINT (Vhourglass_delay
);
9737 else if (FLOATP (Vhourglass_delay
)
9738 && XFLOAT_DATA (Vhourglass_delay
) > 0)
9741 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
9742 secs
= XFASTINT (tem
);
9743 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
9746 secs
= DEFAULT_HOURGLASS_DELAY
;
9748 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
9749 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
9750 show_hourglass
, NULL
);
9754 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
9760 if (hourglass_atimer
)
9762 cancel_atimer (hourglass_atimer
);
9763 hourglass_atimer
= NULL
;
9766 if (hourglass_shown_p
)
9771 /* Timer function of hourglass_atimer. TIMER is equal to
9774 Display an hourglass pointer on all frames by mapping the frames'
9775 hourglass_window. Set the hourglass_p flag in the frames'
9776 output_data.x structure to indicate that an hourglass cursor is
9777 shown on the frames. */
9780 show_hourglass (timer
)
9781 struct atimer
*timer
;
9783 /* The timer implementation will cancel this timer automatically
9784 after this function has run. Set hourglass_atimer to null
9785 so that we know the timer doesn't have to be canceled. */
9786 hourglass_atimer
= NULL
;
9788 if (!hourglass_shown_p
)
9790 Lisp_Object rest
, frame
;
9794 FOR_EACH_FRAME (rest
, frame
)
9796 struct frame
*f
= XFRAME (frame
);
9798 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
9800 Display
*dpy
= FRAME_X_DISPLAY (f
);
9802 #ifdef USE_X_TOOLKIT
9803 if (f
->output_data
.x
->widget
)
9805 if (FRAME_OUTER_WINDOW (f
))
9808 f
->output_data
.x
->hourglass_p
= 1;
9810 if (!f
->output_data
.x
->hourglass_window
)
9812 unsigned long mask
= CWCursor
;
9813 XSetWindowAttributes attrs
;
9815 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
9817 f
->output_data
.x
->hourglass_window
9818 = XCreateWindow (dpy
, FRAME_OUTER_WINDOW (f
),
9819 0, 0, 32000, 32000, 0, 0,
9825 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
9831 hourglass_shown_p
= 1;
9837 /* Hide the hourglass pointer on all frames, if it is currently
9843 if (hourglass_shown_p
)
9845 Lisp_Object rest
, frame
;
9848 FOR_EACH_FRAME (rest
, frame
)
9850 struct frame
*f
= XFRAME (frame
);
9853 /* Watch out for newly created frames. */
9854 && f
->output_data
.x
->hourglass_window
)
9856 XUnmapWindow (FRAME_X_DISPLAY (f
),
9857 f
->output_data
.x
->hourglass_window
);
9858 /* Sync here because XTread_socket looks at the
9859 hourglass_p flag that is reset to zero below. */
9860 XSync (FRAME_X_DISPLAY (f
), False
);
9861 f
->output_data
.x
->hourglass_p
= 0;
9865 hourglass_shown_p
= 0;
9872 /***********************************************************************
9874 ***********************************************************************/
9876 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
9877 Lisp_Object
, Lisp_Object
));
9878 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
9879 Lisp_Object
, int, int, int *, int *));
9881 /* The frame of a currently visible tooltip. */
9883 Lisp_Object tip_frame
;
9885 /* If non-nil, a timer started that hides the last tooltip when it
9888 Lisp_Object tip_timer
;
9891 /* If non-nil, a vector of 3 elements containing the last args
9892 with which x-show-tip was called. See there. */
9894 Lisp_Object last_show_tip_args
;
9896 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
9898 Lisp_Object Vx_max_tooltip_size
;
9902 unwind_create_tip_frame (frame
)
9905 Lisp_Object deleted
;
9907 deleted
= unwind_create_frame (frame
);
9908 if (EQ (deleted
, Qt
))
9918 /* Create a frame for a tooltip on the display described by DPYINFO.
9919 PARMS is a list of frame parameters. TEXT is the string to
9920 display in the tip frame. Value is the frame.
9922 Note that functions called here, esp. x_default_parameter can
9923 signal errors, for instance when a specified color name is
9924 undefined. We have to make sure that we're in a consistent state
9925 when this happens. */
9928 x_create_tip_frame (dpyinfo
, parms
, text
)
9929 struct x_display_info
*dpyinfo
;
9930 Lisp_Object parms
, text
;
9933 Lisp_Object frame
, tem
;
9935 long window_prompting
= 0;
9937 int count
= SPECPDL_INDEX ();
9938 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9940 int face_change_count_before
= face_change_count
;
9942 struct buffer
*old_buffer
;
9946 /* Use this general default value to start with until we know if
9947 this frame has a specified name. */
9948 Vx_resource_name
= Vinvocation_name
;
9951 kb
= dpyinfo
->kboard
;
9953 kb
= &the_only_kboard
;
9956 /* Get the name of the frame to use for resource lookup. */
9957 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
9959 && !EQ (name
, Qunbound
)
9961 error ("Invalid frame name--not a string or nil");
9962 Vx_resource_name
= name
;
9965 GCPRO3 (parms
, name
, frame
);
9967 XSETFRAME (frame
, f
);
9969 buffer
= Fget_buffer_create (build_string (" *tip*"));
9970 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
9971 old_buffer
= current_buffer
;
9972 set_buffer_internal_1 (XBUFFER (buffer
));
9973 current_buffer
->truncate_lines
= Qnil
;
9976 set_buffer_internal_1 (old_buffer
);
9978 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
9979 record_unwind_protect (unwind_create_tip_frame
, frame
);
9981 /* By setting the output method, we're essentially saying that
9982 the frame is live, as per FRAME_LIVE_P. If we get a signal
9983 from this point on, x_destroy_window might screw up reference
9985 f
->output_method
= output_x_window
;
9986 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
9987 bzero (f
->output_data
.x
, sizeof (struct x_output
));
9988 f
->output_data
.x
->icon_bitmap
= -1;
9989 FRAME_FONTSET (f
) = -1;
9990 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
9991 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
9992 #ifdef USE_TOOLKIT_SCROLL_BARS
9993 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
9994 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
9995 #endif /* USE_TOOLKIT_SCROLL_BARS */
9996 f
->icon_name
= Qnil
;
9997 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
9999 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
10000 dpyinfo_refcount
= dpyinfo
->reference_count
;
10001 #endif /* GLYPH_DEBUG */
10002 #ifdef MULTI_KBOARD
10003 FRAME_KBOARD (f
) = kb
;
10005 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
10006 f
->output_data
.x
->explicit_parent
= 0;
10008 /* These colors will be set anyway later, but it's important
10009 to get the color reference counts right, so initialize them! */
10012 struct gcpro gcpro1
;
10014 black
= build_string ("black");
10016 f
->output_data
.x
->foreground_pixel
10017 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
10018 f
->output_data
.x
->background_pixel
10019 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
10020 f
->output_data
.x
->cursor_pixel
10021 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
10022 f
->output_data
.x
->cursor_foreground_pixel
10023 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
10024 f
->output_data
.x
->border_pixel
10025 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
10026 f
->output_data
.x
->mouse_pixel
10027 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
10031 /* Set the name; the functions to which we pass f expect the name to
10033 if (EQ (name
, Qunbound
) || NILP (name
))
10035 f
->name
= build_string (dpyinfo
->x_id_name
);
10036 f
->explicit_name
= 0;
10041 f
->explicit_name
= 1;
10042 /* use the frame's title when getting resources for this frame. */
10043 specbind (Qx_resource_name
, name
);
10046 /* Extract the window parameters from the supplied values that are
10047 needed to determine window geometry. */
10051 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
10054 /* First, try whatever font the caller has specified. */
10055 if (STRINGP (font
))
10057 tem
= Fquery_fontset (font
, Qnil
);
10059 font
= x_new_fontset (f
, SDATA (tem
));
10061 font
= x_new_font (f
, SDATA (font
));
10064 /* Try out a font which we hope has bold and italic variations. */
10065 if (!STRINGP (font
))
10066 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
10067 if (!STRINGP (font
))
10068 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
10069 if (! STRINGP (font
))
10070 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
10071 if (! STRINGP (font
))
10072 /* This was formerly the first thing tried, but it finds too many fonts
10073 and takes too long. */
10074 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
10075 /* If those didn't work, look for something which will at least work. */
10076 if (! STRINGP (font
))
10077 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
10079 if (! STRINGP (font
))
10080 font
= build_string ("fixed");
10082 x_default_parameter (f
, parms
, Qfont
, font
,
10083 "font", "Font", RES_TYPE_STRING
);
10086 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
10087 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
10089 /* This defaults to 2 in order to match xterm. We recognize either
10090 internalBorderWidth or internalBorder (which is what xterm calls
10092 if (NILP (Fassq (Qinternal_border_width
, parms
)))
10096 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
10097 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
10098 if (! EQ (value
, Qunbound
))
10099 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
10103 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
10104 "internalBorderWidth", "internalBorderWidth",
10107 /* Also do the stuff which must be set before the window exists. */
10108 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
10109 "foreground", "Foreground", RES_TYPE_STRING
);
10110 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
10111 "background", "Background", RES_TYPE_STRING
);
10112 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
10113 "pointerColor", "Foreground", RES_TYPE_STRING
);
10114 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
10115 "cursorColor", "Foreground", RES_TYPE_STRING
);
10116 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
10117 "borderColor", "BorderColor", RES_TYPE_STRING
);
10119 /* Init faces before x_default_parameter is called for scroll-bar
10120 parameters because that function calls x_set_scroll_bar_width,
10121 which calls change_frame_size, which calls Fset_window_buffer,
10122 which runs hooks, which call Fvertical_motion. At the end, we
10123 end up in init_iterator with a null face cache, which should not
10125 init_frame_faces (f
);
10127 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
10129 window_prompting
= x_figure_window_size (f
, parms
, 0);
10132 XSetWindowAttributes attrs
;
10133 unsigned long mask
;
10136 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
10137 if (DoesSaveUnders (dpyinfo
->screen
))
10138 mask
|= CWSaveUnder
;
10140 /* Window managers look at the override-redirect flag to determine
10141 whether or net to give windows a decoration (Xlib spec, chapter
10143 attrs
.override_redirect
= True
;
10144 attrs
.save_under
= True
;
10145 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
10146 /* Arrange for getting MapNotify and UnmapNotify events. */
10147 attrs
.event_mask
= StructureNotifyMask
;
10149 = FRAME_X_WINDOW (f
)
10150 = XCreateWindow (FRAME_X_DISPLAY (f
),
10151 FRAME_X_DISPLAY_INFO (f
)->root_window
,
10152 /* x, y, width, height */
10156 CopyFromParent
, InputOutput
, CopyFromParent
,
10163 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
10164 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
10165 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
10166 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
10167 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
10168 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
10170 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
10171 Change will not be effected unless different from the current
10172 FRAME_LINES (f). */
10173 width
= FRAME_COLS (f
);
10174 height
= FRAME_LINES (f
);
10175 SET_FRAME_COLS (f
, 0);
10176 FRAME_LINES (f
) = 0;
10177 change_frame_size (f
, height
, width
, 1, 0, 0);
10179 /* Add `tooltip' frame parameter's default value. */
10180 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
10181 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
10184 /* Set up faces after all frame parameters are known. This call
10185 also merges in face attributes specified for new frames.
10187 Frame parameters may be changed if .Xdefaults contains
10188 specifications for the default font. For example, if there is an
10189 `Emacs.default.attributeBackground: pink', the `background-color'
10190 attribute of the frame get's set, which let's the internal border
10191 of the tooltip frame appear in pink. Prevent this. */
10193 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
10195 /* Set tip_frame here, so that */
10197 call1 (Qface_set_after_frame_default
, frame
);
10199 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
10200 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
10208 /* It is now ok to make the frame official even if we get an error
10209 below. And the frame needs to be on Vframe_list or making it
10210 visible won't work. */
10211 Vframe_list
= Fcons (frame
, Vframe_list
);
10213 /* Now that the frame is official, it counts as a reference to
10215 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
10217 /* Setting attributes of faces of the tooltip frame from resources
10218 and similar will increment face_change_count, which leads to the
10219 clearing of all current matrices. Since this isn't necessary
10220 here, avoid it by resetting face_change_count to the value it
10221 had before we created the tip frame. */
10222 face_change_count
= face_change_count_before
;
10224 /* Discard the unwind_protect. */
10225 return unbind_to (count
, frame
);
10229 /* Compute where to display tip frame F. PARMS is the list of frame
10230 parameters for F. DX and DY are specified offsets from the current
10231 location of the mouse. WIDTH and HEIGHT are the width and height
10232 of the tooltip. Return coordinates relative to the root window of
10233 the display in *ROOT_X, and *ROOT_Y. */
10236 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
10238 Lisp_Object parms
, dx
, dy
;
10240 int *root_x
, *root_y
;
10242 Lisp_Object left
, top
;
10244 Window root
, child
;
10247 /* User-specified position? */
10248 left
= Fcdr (Fassq (Qleft
, parms
));
10249 top
= Fcdr (Fassq (Qtop
, parms
));
10251 /* Move the tooltip window where the mouse pointer is. Resize and
10253 if (!INTEGERP (left
) || !INTEGERP (top
))
10256 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
10257 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
10261 if (INTEGERP (top
))
10262 *root_y
= XINT (top
);
10263 else if (*root_y
+ XINT (dy
) - height
< 0)
10264 *root_y
-= XINT (dy
);
10268 *root_y
+= XINT (dy
);
10271 if (INTEGERP (left
))
10272 *root_x
= XINT (left
);
10273 else if (*root_x
+ XINT (dx
) + width
<= FRAME_X_DISPLAY_INFO (f
)->width
)
10274 /* It fits to the right of the pointer. */
10275 *root_x
+= XINT (dx
);
10276 else if (width
+ XINT (dx
) <= *root_x
)
10277 /* It fits to the left of the pointer. */
10278 *root_x
-= width
+ XINT (dx
);
10280 /* Put it left-justified on the screen--it ought to fit that way. */
10285 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
10286 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
10287 A tooltip window is a small X window displaying a string.
10289 FRAME nil or omitted means use the selected frame.
10291 PARMS is an optional list of frame parameters which can be used to
10292 change the tooltip's appearance.
10294 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
10295 means use the default timeout of 5 seconds.
10297 If the list of frame parameters PARAMS contains a `left' parameters,
10298 the tooltip is displayed at that x-position. Otherwise it is
10299 displayed at the mouse position, with offset DX added (default is 5 if
10300 DX isn't specified). Likewise for the y-position; if a `top' frame
10301 parameter is specified, it determines the y-position of the tooltip
10302 window, otherwise it is displayed at the mouse position, with offset
10303 DY added (default is -10).
10305 A tooltip's maximum size is specified by `x-max-tooltip-size'.
10306 Text larger than the specified size is clipped. */)
10307 (string
, frame
, parms
, timeout
, dx
, dy
)
10308 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
10312 int root_x
, root_y
;
10313 struct buffer
*old_buffer
;
10314 struct text_pos pos
;
10315 int i
, width
, height
;
10316 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
10317 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
10318 int count
= SPECPDL_INDEX ();
10320 specbind (Qinhibit_redisplay
, Qt
);
10322 GCPRO4 (string
, parms
, frame
, timeout
);
10324 CHECK_STRING (string
);
10325 f
= check_x_frame (frame
);
10326 if (NILP (timeout
))
10327 timeout
= make_number (5);
10329 CHECK_NATNUM (timeout
);
10332 dx
= make_number (5);
10337 dy
= make_number (-10);
10341 if (NILP (last_show_tip_args
))
10342 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
10344 if (!NILP (tip_frame
))
10346 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
10347 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
10348 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
10350 if (EQ (frame
, last_frame
)
10351 && !NILP (Fequal (last_string
, string
))
10352 && !NILP (Fequal (last_parms
, parms
)))
10354 struct frame
*f
= XFRAME (tip_frame
);
10356 /* Only DX and DY have changed. */
10357 if (!NILP (tip_timer
))
10359 Lisp_Object timer
= tip_timer
;
10361 call1 (Qcancel_timer
, timer
);
10365 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
10366 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
10367 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10374 /* Hide a previous tip, if any. */
10377 ASET (last_show_tip_args
, 0, string
);
10378 ASET (last_show_tip_args
, 1, frame
);
10379 ASET (last_show_tip_args
, 2, parms
);
10381 /* Add default values to frame parameters. */
10382 if (NILP (Fassq (Qname
, parms
)))
10383 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
10384 if (NILP (Fassq (Qinternal_border_width
, parms
)))
10385 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
10386 if (NILP (Fassq (Qborder_width
, parms
)))
10387 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
10388 if (NILP (Fassq (Qborder_color
, parms
)))
10389 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
10390 if (NILP (Fassq (Qbackground_color
, parms
)))
10391 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
10394 /* Create a frame for the tooltip, and record it in the global
10395 variable tip_frame. */
10396 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
10397 f
= XFRAME (frame
);
10399 /* Set up the frame's root window. */
10400 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
10401 w
->left_col
= w
->top_line
= make_number (0);
10403 if (CONSP (Vx_max_tooltip_size
)
10404 && INTEGERP (XCAR (Vx_max_tooltip_size
))
10405 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
10406 && INTEGERP (XCDR (Vx_max_tooltip_size
))
10407 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
10409 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
10410 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
10414 w
->total_cols
= make_number (80);
10415 w
->total_lines
= make_number (40);
10418 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
10420 w
->pseudo_window_p
= 1;
10422 /* Display the tooltip text in a temporary buffer. */
10423 old_buffer
= current_buffer
;
10424 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
10425 current_buffer
->truncate_lines
= Qnil
;
10426 clear_glyph_matrix (w
->desired_matrix
);
10427 clear_glyph_matrix (w
->current_matrix
);
10428 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
10429 try_window (FRAME_ROOT_WINDOW (f
), pos
);
10431 /* Compute width and height of the tooltip. */
10432 width
= height
= 0;
10433 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
10435 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
10436 struct glyph
*last
;
10439 /* Stop at the first empty row at the end. */
10440 if (!row
->enabled_p
|| !row
->displays_text_p
)
10443 /* Let the row go over the full width of the frame. */
10444 row
->full_width_p
= 1;
10446 /* There's a glyph at the end of rows that is used to place
10447 the cursor there. Don't include the width of this glyph. */
10448 if (row
->used
[TEXT_AREA
])
10450 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
10451 row_width
= row
->pixel_width
- last
->pixel_width
;
10454 row_width
= row
->pixel_width
;
10456 height
+= row
->height
;
10457 width
= max (width
, row_width
);
10460 /* Add the frame's internal border to the width and height the X
10461 window should have. */
10462 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10463 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10465 /* Move the tooltip window where the mouse pointer is. Resize and
10467 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
10470 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10471 root_x
, root_y
, width
, height
);
10472 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
10475 /* Draw into the window. */
10476 w
->must_be_updated_p
= 1;
10477 update_single_window (w
, 1);
10479 /* Restore original current buffer. */
10480 set_buffer_internal_1 (old_buffer
);
10481 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
10484 /* Let the tip disappear after timeout seconds. */
10485 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
10486 intern ("x-hide-tip"));
10489 return unbind_to (count
, Qnil
);
10493 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
10494 doc
: /* Hide the current tooltip window, if there is any.
10495 Value is t if tooltip was open, nil otherwise. */)
10499 Lisp_Object deleted
, frame
, timer
;
10500 struct gcpro gcpro1
, gcpro2
;
10502 /* Return quickly if nothing to do. */
10503 if (NILP (tip_timer
) && NILP (tip_frame
))
10508 GCPRO2 (frame
, timer
);
10509 tip_frame
= tip_timer
= deleted
= Qnil
;
10511 count
= SPECPDL_INDEX ();
10512 specbind (Qinhibit_redisplay
, Qt
);
10513 specbind (Qinhibit_quit
, Qt
);
10516 call1 (Qcancel_timer
, timer
);
10518 if (FRAMEP (frame
))
10520 Fdelete_frame (frame
, Qnil
);
10524 /* Bloodcurdling hack alert: The Lucid menu bar widget's
10525 redisplay procedure is not called when a tip frame over menu
10526 items is unmapped. Redisplay the menu manually... */
10528 struct frame
*f
= SELECTED_FRAME ();
10529 Widget w
= f
->output_data
.x
->menubar_widget
;
10530 extern void xlwmenu_redisplay
P_ ((Widget
));
10532 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
10536 xlwmenu_redisplay (w
);
10540 #endif /* USE_LUCID */
10544 return unbind_to (count
, deleted
);
10549 /***********************************************************************
10550 File selection dialog
10551 ***********************************************************************/
10555 /* Callback for "OK" and "Cancel" on file selection dialog. */
10558 file_dialog_cb (widget
, client_data
, call_data
)
10560 XtPointer call_data
, client_data
;
10562 int *result
= (int *) client_data
;
10563 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
10564 *result
= cb
->reason
;
10568 /* Callback for unmapping a file selection dialog. This is used to
10569 capture the case where a dialog is closed via a window manager's
10570 closer button, for example. Using a XmNdestroyCallback didn't work
10574 file_dialog_unmap_cb (widget
, client_data
, call_data
)
10576 XtPointer call_data
, client_data
;
10578 int *result
= (int *) client_data
;
10579 *result
= XmCR_CANCEL
;
10583 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10584 doc
: /* Read file name, prompting with PROMPT in directory DIR.
10585 Use a file selection dialog.
10586 Select DEFAULT-FILENAME in the dialog's file selection box, if
10587 specified. Don't let the user enter a file name in the file
10588 selection dialog's entry field, if MUSTMATCH is non-nil. */)
10589 (prompt
, dir
, default_filename
, mustmatch
)
10590 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10593 struct frame
*f
= SELECTED_FRAME ();
10594 Lisp_Object file
= Qnil
;
10595 Widget dialog
, text
, list
, help
;
10598 extern XtAppContext Xt_app_con
;
10599 XmString dir_xmstring
, pattern_xmstring
;
10600 int count
= SPECPDL_INDEX ();
10601 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10603 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10604 CHECK_STRING (prompt
);
10605 CHECK_STRING (dir
);
10607 /* Prevent redisplay. */
10608 specbind (Qinhibit_redisplay
, Qt
);
10612 /* Create the dialog with PROMPT as title, using DIR as initial
10613 directory and using "*" as pattern. */
10614 dir
= Fexpand_file_name (dir
, Qnil
);
10615 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
10616 pattern_xmstring
= XmStringCreateLocalized ("*");
10618 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
10619 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
10620 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
10621 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
10622 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
10623 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
10625 XmStringFree (dir_xmstring
);
10626 XmStringFree (pattern_xmstring
);
10628 /* Add callbacks for OK and Cancel. */
10629 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
10630 (XtPointer
) &result
);
10631 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
10632 (XtPointer
) &result
);
10633 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
10634 (XtPointer
) &result
);
10636 /* Disable the help button since we can't display help. */
10637 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
10638 XtSetSensitive (help
, False
);
10640 /* Mark OK button as default. */
10641 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
10642 XmNshowAsDefault
, True
, NULL
);
10644 /* If MUSTMATCH is non-nil, disable the file entry field of the
10645 dialog, so that the user must select a file from the files list
10646 box. We can't remove it because we wouldn't have a way to get at
10647 the result file name, then. */
10648 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
10649 if (!NILP (mustmatch
))
10652 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
10653 XtSetSensitive (text
, False
);
10654 XtSetSensitive (label
, False
);
10657 /* Manage the dialog, so that list boxes get filled. */
10658 XtManageChild (dialog
);
10660 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
10661 must include the path for this to work. */
10662 list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
10663 if (STRINGP (default_filename
))
10665 XmString default_xmstring
;
10669 = XmStringCreateLocalized (SDATA (default_filename
));
10671 if (!XmListItemExists (list
, default_xmstring
))
10673 /* Add a new item if DEFAULT_FILENAME is not in the list. */
10674 XmListAddItem (list
, default_xmstring
, 0);
10678 item_pos
= XmListItemPos (list
, default_xmstring
);
10679 XmStringFree (default_xmstring
);
10681 /* Select the item and scroll it into view. */
10682 XmListSelectPos (list
, item_pos
, True
);
10683 XmListSetPos (list
, item_pos
);
10686 /* Process events until the user presses Cancel or OK. */
10688 while (result
== 0)
10691 XtAppNextEvent (Xt_app_con
, &event
);
10692 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
) );
10695 /* Get the result. */
10696 if (result
== XmCR_OK
)
10701 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
10702 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
10703 XmStringFree (text
);
10704 file
= build_string (data
);
10711 XtUnmanageChild (dialog
);
10712 XtDestroyWidget (dialog
);
10716 /* Make "Cancel" equivalent to C-g. */
10718 Fsignal (Qquit
, Qnil
);
10720 return unbind_to (count
, file
);
10723 #endif /* USE_MOTIF */
10727 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10728 "Read file name, prompting with PROMPT in directory DIR.\n\
10729 Use a file selection dialog.\n\
10730 Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
10731 specified. Don't let the user enter a file name in the file\n\
10732 selection dialog's entry field, if MUSTMATCH is non-nil.")
10733 (prompt
, dir
, default_filename
, mustmatch
)
10734 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10736 FRAME_PTR f
= SELECTED_FRAME ();
10738 Lisp_Object file
= Qnil
;
10739 int count
= specpdl_ptr
- specpdl
;
10740 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10744 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10745 CHECK_STRING (prompt
);
10746 CHECK_STRING (dir
);
10748 /* Prevent redisplay. */
10749 specbind (Qinhibit_redisplay
, Qt
);
10753 if (STRINGP (default_filename
))
10754 cdef_file
= SDATA (default_filename
);
10756 cdef_file
= SDATA (dir
);
10758 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
, ! NILP (mustmatch
));
10762 file
= build_string (fn
);
10769 /* Make "Cancel" equivalent to C-g. */
10771 Fsignal (Qquit
, Qnil
);
10773 return unbind_to (count
, file
);
10776 #endif /* USE_GTK */
10779 /***********************************************************************
10781 ***********************************************************************/
10783 #ifdef HAVE_XKBGETKEYBOARD
10784 #include <X11/XKBlib.h>
10785 #include <X11/keysym.h>
10788 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
10789 Sx_backspace_delete_keys_p
, 0, 1, 0,
10790 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
10791 FRAME nil means use the selected frame.
10792 Value is t if we know that both keys are present, and are mapped to the
10793 usual X keysyms. */)
10797 #ifdef HAVE_XKBGETKEYBOARD
10799 struct frame
*f
= check_x_frame (frame
);
10800 Display
*dpy
= FRAME_X_DISPLAY (f
);
10801 Lisp_Object have_keys
;
10802 int major
, minor
, op
, event
, error
;
10806 /* Check library version in case we're dynamically linked. */
10807 major
= XkbMajorVersion
;
10808 minor
= XkbMinorVersion
;
10809 if (!XkbLibraryVersion (&major
, &minor
))
10815 /* Check that the server supports XKB. */
10816 major
= XkbMajorVersion
;
10817 minor
= XkbMinorVersion
;
10818 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
10825 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
10828 int delete_keycode
= 0, backspace_keycode
= 0, i
;
10830 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
10832 for (i
= kb
->min_key_code
;
10833 (i
< kb
->max_key_code
10834 && (delete_keycode
== 0 || backspace_keycode
== 0));
10837 /* The XKB symbolic key names can be seen most easily in
10838 the PS file generated by `xkbprint -label name
10840 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
10841 delete_keycode
= i
;
10842 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
10843 backspace_keycode
= i
;
10846 XkbFreeNames (kb
, 0, True
);
10849 XkbFreeClientMap (kb
, 0, True
);
10852 && backspace_keycode
10853 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
10854 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
10859 #else /* not HAVE_XKBGETKEYBOARD */
10861 #endif /* not HAVE_XKBGETKEYBOARD */
10866 /***********************************************************************
10868 ***********************************************************************/
10870 /* Keep this list in the same order as frame_parms in frame.c.
10871 Use 0 for unsupported frame parameters. */
10873 frame_parm_handler x_frame_parm_handlers
[] =
10877 x_set_background_color
,
10878 x_set_border_color
,
10879 x_set_border_width
,
10880 x_set_cursor_color
,
10883 x_set_foreground_color
,
10886 x_set_internal_border_width
,
10887 x_set_menu_bar_lines
,
10889 x_explicitly_set_name
,
10890 x_set_scroll_bar_width
,
10892 x_set_unsplittable
,
10893 x_set_vertical_scroll_bars
,
10895 x_set_tool_bar_lines
,
10896 x_set_scroll_bar_foreground
,
10897 x_set_scroll_bar_background
,
10898 x_set_screen_gamma
,
10899 x_set_line_spacing
,
10900 x_set_fringe_width
,
10901 x_set_fringe_width
,
10909 /* This is zero if not using X windows. */
10912 /* The section below is built by the lisp expression at the top of the file,
10913 just above where these variables are declared. */
10914 /*&&& init symbols here &&&*/
10915 Qnone
= intern ("none");
10916 staticpro (&Qnone
);
10917 Qsuppress_icon
= intern ("suppress-icon");
10918 staticpro (&Qsuppress_icon
);
10919 Qundefined_color
= intern ("undefined-color");
10920 staticpro (&Qundefined_color
);
10921 Qcenter
= intern ("center");
10922 staticpro (&Qcenter
);
10923 Qcompound_text
= intern ("compound-text");
10924 staticpro (&Qcompound_text
);
10925 Qcancel_timer
= intern ("cancel-timer");
10926 staticpro (&Qcancel_timer
);
10927 /* This is the end of symbol initialization. */
10929 /* Text property `display' should be nonsticky by default. */
10930 Vtext_property_default_nonsticky
10931 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
10934 Qlaplace
= intern ("laplace");
10935 staticpro (&Qlaplace
);
10936 Qemboss
= intern ("emboss");
10937 staticpro (&Qemboss
);
10938 Qedge_detection
= intern ("edge-detection");
10939 staticpro (&Qedge_detection
);
10940 Qheuristic
= intern ("heuristic");
10941 staticpro (&Qheuristic
);
10942 QCmatrix
= intern (":matrix");
10943 staticpro (&QCmatrix
);
10944 QCcolor_adjustment
= intern (":color-adjustment");
10945 staticpro (&QCcolor_adjustment
);
10946 QCmask
= intern (":mask");
10947 staticpro (&QCmask
);
10949 Fput (Qundefined_color
, Qerror_conditions
,
10950 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
10951 Fput (Qundefined_color
, Qerror_message
,
10952 build_string ("Undefined color"));
10954 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images
,
10955 doc
: /* Non-nil means always draw a cross over disabled images.
10956 Disabled images are those having an `:conversion disabled' property.
10957 A cross is always drawn on black & white displays. */);
10958 cross_disabled_images
= 0;
10960 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
10961 doc
: /* List of directories to search for window system bitmap files. */);
10962 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
10964 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
10965 doc
: /* The shape of the pointer when over text.
10966 Changing the value does not affect existing frames
10967 unless you set the mouse color. */);
10968 Vx_pointer_shape
= Qnil
;
10970 #if 0 /* This doesn't really do anything. */
10971 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
10972 doc
: /* The shape of the pointer when not over text.
10973 This variable takes effect when you create a new frame
10974 or when you set the mouse color. */);
10976 Vx_nontext_pointer_shape
= Qnil
;
10978 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
10979 doc
: /* The shape of the pointer when Emacs is busy.
10980 This variable takes effect when you create a new frame
10981 or when you set the mouse color. */);
10982 Vx_hourglass_pointer_shape
= Qnil
;
10984 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
10985 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
10986 display_hourglass_p
= 1;
10988 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
10989 doc
: /* *Seconds to wait before displaying an hourglass pointer.
10990 Value must be an integer or float. */);
10991 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
10993 #if 0 /* This doesn't really do anything. */
10994 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
10995 doc
: /* The shape of the pointer when over the mode line.
10996 This variable takes effect when you create a new frame
10997 or when you set the mouse color. */);
10999 Vx_mode_pointer_shape
= Qnil
;
11001 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
11002 &Vx_sensitive_text_pointer_shape
,
11003 doc
: /* The shape of the pointer when over mouse-sensitive text.
11004 This variable takes effect when you create a new frame
11005 or when you set the mouse color. */);
11006 Vx_sensitive_text_pointer_shape
= Qnil
;
11008 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
11009 &Vx_window_horizontal_drag_shape
,
11010 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
11011 This variable takes effect when you create a new frame
11012 or when you set the mouse color. */);
11013 Vx_window_horizontal_drag_shape
= Qnil
;
11015 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
11016 doc
: /* A string indicating the foreground color of the cursor box. */);
11017 Vx_cursor_fore_pixel
= Qnil
;
11019 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
11020 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
11021 Text larger than this is clipped. */);
11022 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
11024 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
11025 doc
: /* Non-nil if no X window manager is in use.
11026 Emacs doesn't try to figure this out; this is always nil
11027 unless you set it to something else. */);
11028 /* We don't have any way to find this out, so set it to nil
11029 and maybe the user would like to set it to t. */
11030 Vx_no_window_manager
= Qnil
;
11032 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
11033 &Vx_pixel_size_width_font_regexp
,
11034 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
11036 Since Emacs gets width of a font matching with this regexp from
11037 PIXEL_SIZE field of the name, font finding mechanism gets faster for
11038 such a font. This is especially effective for such large fonts as
11039 Chinese, Japanese, and Korean. */);
11040 Vx_pixel_size_width_font_regexp
= Qnil
;
11042 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
11043 doc
: /* Time after which cached images are removed from the cache.
11044 When an image has not been displayed this many seconds, remove it
11045 from the image cache. Value must be an integer or nil with nil
11046 meaning don't clear the cache. */);
11047 Vimage_cache_eviction_delay
= make_number (30 * 60);
11049 #ifdef USE_X_TOOLKIT
11050 Fprovide (intern ("x-toolkit"), Qnil
);
11052 Fprovide (intern ("motif"), Qnil
);
11054 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
11055 doc
: /* Version info for LessTif/Motif. */);
11056 Vmotif_version_string
= build_string (XmVERSION_STRING
);
11057 #endif /* USE_MOTIF */
11058 #endif /* USE_X_TOOLKIT */
11061 Fprovide (intern ("gtk"), Qnil
);
11063 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string
,
11064 doc
: /* Version info for GTK+. */);
11066 char gtk_version
[40];
11067 g_snprintf (gtk_version
, sizeof (gtk_version
), "%u.%u.%u",
11068 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
11069 Vgtk_version_string
= build_string (gtk_version
);
11071 #endif /* USE_GTK */
11073 /* X window properties. */
11074 defsubr (&Sx_change_window_property
);
11075 defsubr (&Sx_delete_window_property
);
11076 defsubr (&Sx_window_property
);
11078 defsubr (&Sxw_display_color_p
);
11079 defsubr (&Sx_display_grayscale_p
);
11080 defsubr (&Sxw_color_defined_p
);
11081 defsubr (&Sxw_color_values
);
11082 defsubr (&Sx_server_max_request_size
);
11083 defsubr (&Sx_server_vendor
);
11084 defsubr (&Sx_server_version
);
11085 defsubr (&Sx_display_pixel_width
);
11086 defsubr (&Sx_display_pixel_height
);
11087 defsubr (&Sx_display_mm_width
);
11088 defsubr (&Sx_display_mm_height
);
11089 defsubr (&Sx_display_screens
);
11090 defsubr (&Sx_display_planes
);
11091 defsubr (&Sx_display_color_cells
);
11092 defsubr (&Sx_display_visual_class
);
11093 defsubr (&Sx_display_backing_store
);
11094 defsubr (&Sx_display_save_under
);
11095 defsubr (&Sx_create_frame
);
11096 defsubr (&Sx_open_connection
);
11097 defsubr (&Sx_close_connection
);
11098 defsubr (&Sx_display_list
);
11099 defsubr (&Sx_synchronize
);
11100 defsubr (&Sx_send_client_message
);
11101 defsubr (&Sx_focus_frame
);
11102 defsubr (&Sx_backspace_delete_keys_p
);
11104 /* Setting callback functions for fontset handler. */
11105 get_font_info_func
= x_get_font_info
;
11107 #if 0 /* This function pointer doesn't seem to be used anywhere.
11108 And the pointer assigned has the wrong type, anyway. */
11109 list_fonts_func
= x_list_fonts
;
11112 load_font_func
= x_load_font
;
11113 find_ccl_program_func
= x_find_ccl_program
;
11114 query_font_func
= x_query_font
;
11115 set_frame_fontset_func
= x_set_font
;
11116 check_window_system_func
= check_x
;
11119 Qxbm
= intern ("xbm");
11121 QCconversion
= intern (":conversion");
11122 staticpro (&QCconversion
);
11123 QCheuristic_mask
= intern (":heuristic-mask");
11124 staticpro (&QCheuristic_mask
);
11125 QCcolor_symbols
= intern (":color-symbols");
11126 staticpro (&QCcolor_symbols
);
11127 QCascent
= intern (":ascent");
11128 staticpro (&QCascent
);
11129 QCmargin
= intern (":margin");
11130 staticpro (&QCmargin
);
11131 QCrelief
= intern (":relief");
11132 staticpro (&QCrelief
);
11133 Qpostscript
= intern ("postscript");
11134 staticpro (&Qpostscript
);
11135 QCloader
= intern (":loader");
11136 staticpro (&QCloader
);
11137 QCbounding_box
= intern (":bounding-box");
11138 staticpro (&QCbounding_box
);
11139 QCpt_width
= intern (":pt-width");
11140 staticpro (&QCpt_width
);
11141 QCpt_height
= intern (":pt-height");
11142 staticpro (&QCpt_height
);
11143 QCindex
= intern (":index");
11144 staticpro (&QCindex
);
11145 Qpbm
= intern ("pbm");
11149 Qxpm
= intern ("xpm");
11154 Qjpeg
= intern ("jpeg");
11155 staticpro (&Qjpeg
);
11159 Qtiff
= intern ("tiff");
11160 staticpro (&Qtiff
);
11164 Qgif
= intern ("gif");
11169 Qpng
= intern ("png");
11173 defsubr (&Sclear_image_cache
);
11174 defsubr (&Simage_size
);
11175 defsubr (&Simage_mask_p
);
11177 hourglass_atimer
= NULL
;
11178 hourglass_shown_p
= 0;
11180 defsubr (&Sx_show_tip
);
11181 defsubr (&Sx_hide_tip
);
11183 staticpro (&tip_timer
);
11185 staticpro (&tip_frame
);
11187 last_show_tip_args
= Qnil
;
11188 staticpro (&last_show_tip_args
);
11191 defsubr (&Sx_file_dialog
);
11199 image_types
= NULL
;
11200 Vimage_types
= Qnil
;
11202 define_image_type (&xbm_type
);
11203 define_image_type (&gs_type
);
11204 define_image_type (&pbm_type
);
11207 define_image_type (&xpm_type
);
11211 define_image_type (&jpeg_type
);
11215 define_image_type (&tiff_type
);
11219 define_image_type (&gif_type
);
11223 define_image_type (&png_type
);
11227 #endif /* HAVE_X_WINDOWS */
11229 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
11230 (do not change this comment) */