1 /* Functions for the X window system.
2 Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 99, 2000,01,02,03,04
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"
56 #include <sys/types.h>
60 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
61 #include "bitmaps/gray.xbm"
63 #include <X11/bitmaps/gray>
66 #include "[.bitmaps]gray.xbm"
74 #include <X11/Shell.h>
77 #include <X11/Xaw/Paned.h>
78 #include <X11/Xaw/Label.h>
79 #endif /* USE_MOTIF */
82 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
91 #include "../lwlib/lwlib.h"
95 #include <Xm/DialogS.h>
96 #include <Xm/FileSB.h>
99 /* Do the EDITRES protocol if running X11R5
100 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
102 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
104 extern void _XEditResCheckMessages ();
105 #endif /* R5 + Athena */
107 /* Unique id counter for widgets created by the Lucid Widget Library. */
109 extern LWLIB_ID widget_id_tick
;
112 /* This is part of a kludge--see lwlib/xlwmenu.c. */
113 extern XFontStruct
*xlwmenu_default_font
;
116 extern void free_frame_menubar ();
117 extern double atof ();
121 /* LessTif/Motif version info. */
123 static Lisp_Object Vmotif_version_string
;
125 #endif /* USE_MOTIF */
127 #endif /* USE_X_TOOLKIT */
131 /* GTK+ version info */
133 static Lisp_Object Vgtk_version_string
;
138 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
140 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
143 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
144 it, and including `bitmaps/gray' more than once is a problem when
145 config.h defines `static' as an empty replacement string. */
147 int gray_bitmap_width
= gray_width
;
148 int gray_bitmap_height
= gray_height
;
149 char *gray_bitmap_bits
= gray_bits
;
151 /* Non-zero means we're allowed to display an hourglass cursor. */
153 int display_hourglass_p
;
155 /* The background and shape of the mouse pointer, and shape when not
156 over text or in the modeline. */
158 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
159 Lisp_Object Vx_hourglass_pointer_shape
;
161 /* The shape when over mouse-sensitive text. */
163 Lisp_Object Vx_sensitive_text_pointer_shape
;
165 /* If non-nil, the pointer shape to indicate that windows can be
166 dragged horizontally. */
168 Lisp_Object Vx_window_horizontal_drag_shape
;
170 /* Color of chars displayed in cursor box. */
172 Lisp_Object Vx_cursor_fore_pixel
;
174 /* Nonzero if using X. */
178 /* Non nil if no window manager is in use. */
180 Lisp_Object Vx_no_window_manager
;
182 /* Search path for bitmap files. */
184 Lisp_Object Vx_bitmap_file_path
;
186 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
188 Lisp_Object Vx_pixel_size_width_font_regexp
;
191 Lisp_Object Qsuppress_icon
;
192 Lisp_Object Qundefined_color
;
194 Lisp_Object Qcompound_text
, Qcancel_timer
;
198 extern Lisp_Object Vwindow_system_version
;
200 /* The below are defined in frame.c. */
203 int image_cache_refcount
, dpyinfo_refcount
;
208 /* Error if we are not connected to X. */
214 error ("X windows are not in use or not initialized");
217 /* Nonzero if we can use mouse menus.
218 You should not call this unless HAVE_MENUS is defined. */
226 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
227 and checking validity for X. */
230 check_x_frame (frame
)
236 frame
= selected_frame
;
237 CHECK_LIVE_FRAME (frame
);
240 error ("Non-X frame used");
244 /* Let the user specify an X display with a frame.
245 nil stands for the selected frame--or, if that is not an X frame,
246 the first X display on the list. */
248 struct x_display_info
*
249 check_x_display_info (frame
)
252 struct x_display_info
*dpyinfo
= NULL
;
256 struct frame
*sf
= XFRAME (selected_frame
);
258 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
259 dpyinfo
= FRAME_X_DISPLAY_INFO (sf
);
260 else if (x_display_list
!= 0)
261 dpyinfo
= x_display_list
;
263 error ("X windows are not in use or not initialized");
265 else if (STRINGP (frame
))
266 dpyinfo
= x_display_info_for_name (frame
);
269 FRAME_PTR f
= check_x_frame (frame
);
270 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
277 /* Return the Emacs frame-object corresponding to an X window.
278 It could be the frame's main window or an icon window. */
280 /* This function can be called during GC, so use GC_xxx type test macros. */
283 x_window_to_frame (dpyinfo
, wdesc
)
284 struct x_display_info
*dpyinfo
;
287 Lisp_Object tail
, frame
;
290 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
293 if (!GC_FRAMEP (frame
))
296 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
298 if (f
->output_data
.x
->hourglass_window
== wdesc
)
301 if ((f
->output_data
.x
->edit_widget
302 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
303 /* A tooltip frame? */
304 || (!f
->output_data
.x
->edit_widget
305 && FRAME_X_WINDOW (f
) == wdesc
)
306 || f
->output_data
.x
->icon_desc
== wdesc
)
308 #else /* not USE_X_TOOLKIT */
310 if (f
->output_data
.x
->edit_widget
)
312 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
313 struct x_output
*x
= f
->output_data
.x
;
314 if (gwdesc
!= 0 && gwdesc
== x
->edit_widget
)
318 if (FRAME_X_WINDOW (f
) == wdesc
319 || f
->output_data
.x
->icon_desc
== wdesc
)
321 #endif /* not USE_X_TOOLKIT */
326 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
327 /* Like x_window_to_frame but also compares the window with the widget's
331 x_any_window_to_frame (dpyinfo
, wdesc
)
332 struct x_display_info
*dpyinfo
;
335 Lisp_Object tail
, frame
;
336 struct frame
*f
, *found
;
340 for (tail
= Vframe_list
; GC_CONSP (tail
) && !found
; tail
= XCDR (tail
))
343 if (!GC_FRAMEP (frame
))
347 if (FRAME_X_P (f
) && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
349 /* This frame matches if the window is any of its widgets. */
350 x
= f
->output_data
.x
;
351 if (x
->hourglass_window
== wdesc
)
356 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
358 && (gwdesc
== x
->widget
359 || gwdesc
== x
->edit_widget
360 || gwdesc
== x
->vbox_widget
361 || gwdesc
== x
->menubar_widget
))
364 if (wdesc
== XtWindow (x
->widget
)
365 || wdesc
== XtWindow (x
->column_widget
)
366 || wdesc
== XtWindow (x
->edit_widget
))
368 /* Match if the window is this frame's menubar. */
369 else if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
373 else if (FRAME_X_WINDOW (f
) == wdesc
)
374 /* A tooltip frame. */
382 /* Likewise, but exclude the menu bar widget. */
385 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
386 struct x_display_info
*dpyinfo
;
389 Lisp_Object tail
, frame
;
393 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
396 if (!GC_FRAMEP (frame
))
399 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
401 x
= f
->output_data
.x
;
402 /* This frame matches if the window is any of its widgets. */
403 if (x
->hourglass_window
== wdesc
)
408 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
410 && (gwdesc
== x
->widget
411 || gwdesc
== x
->edit_widget
412 || gwdesc
== x
->vbox_widget
))
415 if (wdesc
== XtWindow (x
->widget
)
416 || wdesc
== XtWindow (x
->column_widget
)
417 || wdesc
== XtWindow (x
->edit_widget
))
421 else if (FRAME_X_WINDOW (f
) == wdesc
)
422 /* A tooltip frame. */
428 /* Likewise, but consider only the menu bar widget. */
431 x_menubar_window_to_frame (dpyinfo
, wdesc
)
432 struct x_display_info
*dpyinfo
;
435 Lisp_Object tail
, frame
;
439 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
442 if (!GC_FRAMEP (frame
))
445 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
447 x
= f
->output_data
.x
;
448 /* Match if the window is this frame's menubar. */
450 if (x
->menubar_widget
)
452 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
457 && (gwdesc
== x
->menubar_widget
458 || gtk_widget_get_parent (gwdesc
) == x
->menubar_widget
))
464 if (x
->menubar_widget
465 && lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
472 /* Return the frame whose principal (outermost) window is WDESC.
473 If WDESC is some other (smaller) window, we return 0. */
476 x_top_window_to_frame (dpyinfo
, wdesc
)
477 struct x_display_info
*dpyinfo
;
480 Lisp_Object tail
, frame
;
484 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
487 if (!GC_FRAMEP (frame
))
490 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
492 x
= f
->output_data
.x
;
496 /* This frame matches if the window is its topmost widget. */
498 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
499 if (gwdesc
== x
->widget
)
502 if (wdesc
== XtWindow (x
->widget
))
504 #if 0 /* I don't know why it did this,
505 but it seems logically wrong,
506 and it causes trouble for MapNotify events. */
507 /* Match if the window is this frame's menubar. */
508 if (x
->menubar_widget
509 && wdesc
== XtWindow (x
->menubar_widget
))
514 else if (FRAME_X_WINDOW (f
) == wdesc
)
520 #endif /* USE_X_TOOLKIT || USE_GTK */
524 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
525 id, which is just an int that this section returns. Bitmaps are
526 reference counted so they can be shared among frames.
528 Bitmap indices are guaranteed to be > 0, so a negative number can
529 be used to indicate no bitmap.
531 If you use x_create_bitmap_from_data, then you must keep track of
532 the bitmaps yourself. That is, creating a bitmap from the same
533 data more than once will not be caught. */
536 /* Functions to access the contents of a bitmap, given an id. */
539 x_bitmap_height (f
, id
)
543 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
547 x_bitmap_width (f
, id
)
551 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
555 x_bitmap_pixmap (f
, id
)
559 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
563 x_bitmap_mask (f
, id
)
567 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].mask
;
571 /* Allocate a new bitmap record. Returns index of new record. */
574 x_allocate_bitmap_record (f
)
577 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
580 if (dpyinfo
->bitmaps
== NULL
)
582 dpyinfo
->bitmaps_size
= 10;
584 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
585 dpyinfo
->bitmaps_last
= 1;
589 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
590 return ++dpyinfo
->bitmaps_last
;
592 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
593 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
596 dpyinfo
->bitmaps_size
*= 2;
598 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
599 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
600 return ++dpyinfo
->bitmaps_last
;
603 /* Add one reference to the reference count of the bitmap with id ID. */
606 x_reference_bitmap (f
, id
)
610 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
613 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
616 x_create_bitmap_from_data (f
, bits
, width
, height
)
619 unsigned int width
, height
;
621 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
625 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
626 bits
, width
, height
);
633 id
= x_allocate_bitmap_record (f
);
634 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
635 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
636 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
637 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
638 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
639 dpyinfo
->bitmaps
[id
- 1].height
= height
;
640 dpyinfo
->bitmaps
[id
- 1].width
= width
;
645 /* Create bitmap from file FILE for frame F. */
648 x_create_bitmap_from_file (f
, file
)
652 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
653 unsigned int width
, height
;
655 int xhot
, yhot
, result
, id
;
660 /* Look for an existing bitmap with the same name. */
661 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
663 if (dpyinfo
->bitmaps
[id
].refcount
664 && dpyinfo
->bitmaps
[id
].file
665 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) SDATA (file
)))
667 ++dpyinfo
->bitmaps
[id
].refcount
;
672 /* Search bitmap-file-path for the file, if appropriate. */
673 fd
= openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, Qnil
);
678 filename
= (char *) SDATA (found
);
680 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
681 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
682 if (result
!= BitmapSuccess
)
685 id
= x_allocate_bitmap_record (f
);
686 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
687 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
688 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
689 dpyinfo
->bitmaps
[id
- 1].file
690 = (char *) xmalloc (SBYTES (file
) + 1);
691 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
692 dpyinfo
->bitmaps
[id
- 1].height
= height
;
693 dpyinfo
->bitmaps
[id
- 1].width
= width
;
694 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
699 /* Remove reference to bitmap with id number ID. */
702 x_destroy_bitmap (f
, id
)
706 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
710 --dpyinfo
->bitmaps
[id
- 1].refcount
;
711 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
714 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
715 if (dpyinfo
->bitmaps
[id
- 1].have_mask
)
716 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].mask
);
717 if (dpyinfo
->bitmaps
[id
- 1].file
)
719 xfree (dpyinfo
->bitmaps
[id
- 1].file
);
720 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
727 /* Free all the bitmaps for the display specified by DPYINFO. */
730 x_destroy_all_bitmaps (dpyinfo
)
731 struct x_display_info
*dpyinfo
;
734 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
735 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
737 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
738 if (dpyinfo
->bitmaps
[i
].have_mask
)
739 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].mask
);
740 if (dpyinfo
->bitmaps
[i
].file
)
741 xfree (dpyinfo
->bitmaps
[i
].file
);
743 dpyinfo
->bitmaps_last
= 0;
749 /* Useful functions defined in the section
750 `Image type independent image structures' below. */
752 static unsigned long four_corners_best
P_ ((XImage
*ximg
, unsigned long width
,
753 unsigned long height
));
755 static int x_create_x_image_and_pixmap
P_ ((struct frame
*f
, int width
, int height
,
756 int depth
, XImage
**ximg
,
759 static void x_destroy_x_image
P_ ((XImage
*ximg
));
762 /* Create a mask of a bitmap. Note is this not a perfect mask.
763 It's nicer with some borders in this context */
766 x_create_bitmap_mask (f
, id
)
771 XImage
*ximg
, *mask_img
;
772 unsigned long width
, height
;
775 unsigned long x
, y
, xp
, xm
, yp
, ym
;
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 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
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 (FRAME_DISPLAY (f
)->condemn_scroll_bars_hook
)
1764 (*FRAME_DISPLAY (f
)->condemn_scroll_bars_hook
) (f
);
1765 if (FRAME_DISPLAY (f
)->judge_scroll_bars_hook
)
1766 (*FRAME_DISPLAY (f
)->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 (FRAME_DISPLAY (f
)->condemn_scroll_bars_hook
)
1813 (*FRAME_DISPLAY (f
)->condemn_scroll_bars_hook
) (f
);
1814 if (FRAME_DISPLAY (f
)->judge_scroll_bars_hook
)
1815 (*FRAME_DISPLAY (f
)->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
;
3190 /* Use this general default value to start with
3191 until we know if this frame has a specified name. */
3192 Vx_resource_name
= Vinvocation_name
;
3194 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3195 if (EQ (display
, Qunbound
))
3197 dpyinfo
= check_x_display_info (display
);
3199 kb
= dpyinfo
->kboard
;
3201 kb
= &the_only_kboard
;
3204 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3206 && ! EQ (name
, Qunbound
)
3208 error ("Invalid frame name--not a string or nil");
3211 Vx_resource_name
= name
;
3213 /* See if parent window is specified. */
3214 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3215 if (EQ (parent
, Qunbound
))
3217 if (! NILP (parent
))
3218 CHECK_NUMBER (parent
);
3220 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3221 /* No need to protect DISPLAY because that's not used after passing
3222 it to make_frame_without_minibuffer. */
3224 GCPRO4 (parms
, parent
, name
, frame
);
3225 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3227 if (EQ (tem
, Qnone
) || NILP (tem
))
3228 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3229 else if (EQ (tem
, Qonly
))
3231 f
= make_minibuffer_frame ();
3232 minibuffer_only
= 1;
3234 else if (WINDOWP (tem
))
3235 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3239 XSETFRAME (frame
, f
);
3241 /* Note that X Windows does support scroll bars. */
3242 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3244 f
->display
= dpyinfo
->frame_display
;
3245 f
->display
->reference_count
++;
3247 f
->output_method
= output_x_window
;
3248 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3249 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3250 f
->output_data
.x
->icon_bitmap
= -1;
3251 FRAME_FONTSET (f
) = -1;
3252 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3253 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3254 #ifdef USE_TOOLKIT_SCROLL_BARS
3255 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3256 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3257 #endif /* USE_TOOLKIT_SCROLL_BARS */
3258 record_unwind_protect (unwind_create_frame
, frame
);
3261 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3263 if (! STRINGP (f
->icon_name
))
3264 f
->icon_name
= Qnil
;
3266 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3268 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
3269 dpyinfo_refcount
= dpyinfo
->reference_count
;
3270 #endif /* GLYPH_DEBUG */
3272 FRAME_KBOARD (f
) = kb
;
3275 /* These colors will be set anyway later, but it's important
3276 to get the color reference counts right, so initialize them! */
3279 struct gcpro gcpro1
;
3281 /* Function x_decode_color can signal an error. Make
3282 sure to initialize color slots so that we won't try
3283 to free colors we haven't allocated. */
3284 f
->output_data
.x
->foreground_pixel
= -1;
3285 f
->output_data
.x
->background_pixel
= -1;
3286 f
->output_data
.x
->cursor_pixel
= -1;
3287 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3288 f
->output_data
.x
->border_pixel
= -1;
3289 f
->output_data
.x
->mouse_pixel
= -1;
3291 black
= build_string ("black");
3293 f
->output_data
.x
->foreground_pixel
3294 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3295 f
->output_data
.x
->background_pixel
3296 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3297 f
->output_data
.x
->cursor_pixel
3298 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3299 f
->output_data
.x
->cursor_foreground_pixel
3300 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3301 f
->output_data
.x
->border_pixel
3302 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3303 f
->output_data
.x
->mouse_pixel
3304 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3308 /* Specify the parent under which to make this X window. */
3312 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3313 f
->output_data
.x
->explicit_parent
= 1;
3317 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3318 f
->output_data
.x
->explicit_parent
= 0;
3321 /* Set the name; the functions to which we pass f expect the name to
3323 if (EQ (name
, Qunbound
) || NILP (name
))
3325 f
->name
= build_string (dpyinfo
->x_id_name
);
3326 f
->explicit_name
= 0;
3331 f
->explicit_name
= 1;
3332 /* use the frame's title when getting resources for this frame. */
3333 specbind (Qx_resource_name
, name
);
3336 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qwindow_system
, Qx
), Qnil
));
3338 /* Extract the window parameters from the supplied values
3339 that are needed to determine window geometry. */
3343 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3346 /* First, try whatever font the caller has specified. */
3349 tem
= Fquery_fontset (font
, Qnil
);
3351 font
= x_new_fontset (f
, SDATA (tem
));
3353 font
= x_new_font (f
, SDATA (font
));
3356 /* Try out a font which we hope has bold and italic variations. */
3357 if (!STRINGP (font
))
3358 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
3359 if (!STRINGP (font
))
3360 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3361 if (! STRINGP (font
))
3362 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3363 if (! STRINGP (font
))
3364 /* This was formerly the first thing tried, but it finds too many fonts
3365 and takes too long. */
3366 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3367 /* If those didn't work, look for something which will at least work. */
3368 if (! STRINGP (font
))
3369 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3371 if (! STRINGP (font
))
3372 font
= build_string ("fixed");
3374 x_default_parameter (f
, parms
, Qfont
, font
,
3375 "font", "Font", RES_TYPE_STRING
);
3379 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3380 whereby it fails to get any font. */
3381 xlwmenu_default_font
= FRAME_FONT (f
);
3384 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3385 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3387 /* This defaults to 1 in order to match xterm. We recognize either
3388 internalBorderWidth or internalBorder (which is what xterm calls
3390 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3394 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3395 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3396 if (! EQ (value
, Qunbound
))
3397 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3400 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3401 "internalBorderWidth", "internalBorderWidth",
3403 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3404 "verticalScrollBars", "ScrollBars",
3407 /* Also do the stuff which must be set before the window exists. */
3408 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3409 "foreground", "Foreground", RES_TYPE_STRING
);
3410 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3411 "background", "Background", RES_TYPE_STRING
);
3412 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3413 "pointerColor", "Foreground", RES_TYPE_STRING
);
3414 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3415 "cursorColor", "Foreground", RES_TYPE_STRING
);
3416 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3417 "borderColor", "BorderColor", RES_TYPE_STRING
);
3418 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3419 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3420 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3421 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3422 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3423 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3424 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3425 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3427 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3428 "scrollBarForeground",
3429 "ScrollBarForeground", 1);
3430 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3431 "scrollBarBackground",
3432 "ScrollBarBackground", 0);
3434 /* Init faces before x_default_parameter is called for scroll-bar
3435 parameters because that function calls x_set_scroll_bar_width,
3436 which calls change_frame_size, which calls Fset_window_buffer,
3437 which runs hooks, which call Fvertical_motion. At the end, we
3438 end up in init_iterator with a null face cache, which should not
3440 init_frame_faces (f
);
3442 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3443 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3444 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (1),
3445 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3446 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3447 "bufferPredicate", "BufferPredicate",
3449 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3450 "title", "Title", RES_TYPE_STRING
);
3451 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3452 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3453 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3454 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3456 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3458 /* Compute the size of the X window. */
3459 window_prompting
= x_figure_window_size (f
, parms
, 1);
3461 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3462 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3464 /* Create the X widget or window. */
3465 #ifdef USE_X_TOOLKIT
3466 x_window (f
, window_prompting
, minibuffer_only
);
3474 /* Now consider the frame official. */
3475 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3476 Vframe_list
= Fcons (frame
, Vframe_list
);
3478 /* We need to do this after creating the X window, so that the
3479 icon-creation functions can say whose icon they're describing. */
3480 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3481 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
3483 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3484 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3485 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3486 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3487 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3488 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3489 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3490 "scrollBarWidth", "ScrollBarWidth",
3493 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3494 Change will not be effected unless different from the current
3496 width
= FRAME_COLS (f
);
3497 height
= FRAME_LINES (f
);
3499 SET_FRAME_COLS (f
, 0);
3500 FRAME_LINES (f
) = 0;
3501 change_frame_size (f
, height
, width
, 1, 0, 0);
3503 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3504 /* Create the menu bar. */
3505 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3507 /* If this signals an error, we haven't set size hints for the
3508 frame and we didn't make it visible. */
3509 initialize_frame_menubar (f
);
3512 /* This is a no-op, except under Motif where it arranges the
3513 main window for the widgets on it. */
3514 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3515 f
->output_data
.x
->menubar_widget
,
3516 f
->output_data
.x
->edit_widget
);
3517 #endif /* not USE_GTK */
3519 #endif /* USE_X_TOOLKIT || USE_GTK */
3521 /* Tell the server what size and position, etc, we want, and how
3522 badly we want them. This should be done after we have the menu
3523 bar so that its size can be taken into account. */
3525 x_wm_set_size_hint (f
, window_prompting
, 0);
3528 /* Make the window appear on the frame and enable display, unless
3529 the caller says not to. However, with explicit parent, Emacs
3530 cannot control visibility, so don't try. */
3531 if (! f
->output_data
.x
->explicit_parent
)
3533 Lisp_Object visibility
;
3535 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3537 if (EQ (visibility
, Qunbound
))
3540 if (EQ (visibility
, Qicon
))
3541 x_iconify_frame (f
);
3542 else if (! NILP (visibility
))
3543 x_make_frame_visible (f
);
3545 /* Must have been Qnil. */
3549 /* Set the WM leader property. GTK does this itself, so this is not
3550 needed when using GTK. */
3551 if (dpyinfo
->client_leader_window
!= 0)
3554 XChangeProperty (FRAME_X_DISPLAY (f
),
3555 FRAME_OUTER_WINDOW (f
),
3556 dpyinfo
->Xatom_wm_client_leader
,
3557 XA_WINDOW
, 32, PropModeReplace
,
3558 (char *) &dpyinfo
->client_leader_window
, 1);
3564 /* Make sure windows on this frame appear in calls to next-window
3565 and similar functions. */
3566 Vwindow_list
= Qnil
;
3568 return unbind_to (count
, frame
);
3572 /* FRAME is used only to get a handle on the X display. We don't pass the
3573 display info directly because we're called from frame.c, which doesn't
3574 know about that structure. */
3577 x_get_focus_frame (frame
)
3578 struct frame
*frame
;
3580 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3582 if (! dpyinfo
->x_focus_frame
)
3585 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3590 /* In certain situations, when the window manager follows a
3591 click-to-focus policy, there seems to be no way around calling
3592 XSetInputFocus to give another frame the input focus .
3594 In an ideal world, XSetInputFocus should generally be avoided so
3595 that applications don't interfere with the window manager's focus
3596 policy. But I think it's okay to use when it's clearly done
3597 following a user-command. */
3599 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
3600 doc
: /* Set the input focus to FRAME.
3601 FRAME nil means use the selected frame. */)
3605 struct frame
*f
= check_x_frame (frame
);
3606 Display
*dpy
= FRAME_X_DISPLAY (f
);
3610 count
= x_catch_errors (dpy
);
3611 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3612 RevertToParent
, CurrentTime
);
3613 x_uncatch_errors (dpy
, count
);
3620 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3621 doc
: /* Internal function called by `color-defined-p', which see. */)
3623 Lisp_Object color
, frame
;
3626 FRAME_PTR f
= check_x_frame (frame
);
3628 CHECK_STRING (color
);
3630 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3636 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3637 doc
: /* Internal function called by `color-values', which see. */)
3639 Lisp_Object color
, frame
;
3642 FRAME_PTR f
= check_x_frame (frame
);
3644 CHECK_STRING (color
);
3646 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3650 rgb
[0] = make_number (foo
.red
);
3651 rgb
[1] = make_number (foo
.green
);
3652 rgb
[2] = make_number (foo
.blue
);
3653 return Flist (3, rgb
);
3659 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3660 doc
: /* Internal function called by `display-color-p', which see. */)
3662 Lisp_Object display
;
3664 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3666 if (dpyinfo
->n_planes
<= 2)
3669 switch (dpyinfo
->visual
->class)
3682 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3684 doc
: /* Return t if the X display supports shades of gray.
3685 Note that color displays do support shades of gray.
3686 The optional argument DISPLAY specifies which display to ask about.
3687 DISPLAY should be either a frame or a display name (a string).
3688 If omitted or nil, that stands for the selected frame's display. */)
3690 Lisp_Object display
;
3692 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3694 if (dpyinfo
->n_planes
<= 1)
3697 switch (dpyinfo
->visual
->class)
3712 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3714 doc
: /* Returns the width in pixels of the X display DISPLAY.
3715 The optional argument DISPLAY specifies which display to ask about.
3716 DISPLAY should be either a frame or a display name (a string).
3717 If omitted or nil, that stands for the selected frame's display. */)
3719 Lisp_Object display
;
3721 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3723 return make_number (dpyinfo
->width
);
3726 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3727 Sx_display_pixel_height
, 0, 1, 0,
3728 doc
: /* Returns the height in pixels of the X display DISPLAY.
3729 The optional argument DISPLAY specifies which display to ask about.
3730 DISPLAY should be either a frame or a display name (a string).
3731 If omitted or nil, that stands for the selected frame's display. */)
3733 Lisp_Object display
;
3735 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3737 return make_number (dpyinfo
->height
);
3740 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3742 doc
: /* Returns the number of bitplanes of the X display DISPLAY.
3743 The optional argument DISPLAY specifies which display to ask about.
3744 DISPLAY should be either a frame or a display name (a string).
3745 If omitted or nil, that stands for the selected frame's display. */)
3747 Lisp_Object display
;
3749 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3751 return make_number (dpyinfo
->n_planes
);
3754 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3756 doc
: /* Returns the number of color cells of the X display DISPLAY.
3757 The optional argument DISPLAY specifies which display to ask about.
3758 DISPLAY should be either a frame or a display name (a string).
3759 If omitted or nil, that stands for the selected frame's display. */)
3761 Lisp_Object display
;
3763 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3765 int nr_planes
= DisplayPlanes (dpyinfo
->display
,
3766 XScreenNumberOfScreen (dpyinfo
->screen
));
3768 /* Truncate nr_planes to 24 to avoid integer overflow.
3769 Some displays says 32, but only 24 bits are actually significant.
3770 There are only very few and rare video cards that have more than
3771 24 significant bits. Also 24 bits is more than 16 million colors,
3772 it "should be enough for everyone". */
3773 if (nr_planes
> 24) nr_planes
= 24;
3775 return make_number (1 << nr_planes
);
3778 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3779 Sx_server_max_request_size
,
3781 doc
: /* Returns the maximum request size of the X server of display DISPLAY.
3782 The optional argument DISPLAY specifies which display to ask about.
3783 DISPLAY should be either a frame or a display name (a string).
3784 If omitted or nil, that stands for the selected frame's display. */)
3786 Lisp_Object display
;
3788 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3790 return make_number (MAXREQUEST (dpyinfo
->display
));
3793 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3794 doc
: /* Returns the vendor ID string of the X server of display DISPLAY.
3795 The optional argument DISPLAY specifies which display to ask about.
3796 DISPLAY should be either a frame or a display name (a string).
3797 If omitted or nil, that stands for the selected frame's display. */)
3799 Lisp_Object display
;
3801 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3802 char *vendor
= ServerVendor (dpyinfo
->display
);
3804 if (! vendor
) vendor
= "";
3805 return build_string (vendor
);
3808 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3809 doc
: /* Returns the version numbers of the X server of display DISPLAY.
3810 The value is a list of three integers: the major and minor
3811 version numbers of the X Protocol in use, and the vendor-specific release
3812 number. See also the function `x-server-vendor'.
3814 The optional argument DISPLAY specifies which display to ask about.
3815 DISPLAY should be either a frame or a display name (a string).
3816 If omitted or nil, that stands for the selected frame's display. */)
3818 Lisp_Object display
;
3820 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3821 Display
*dpy
= dpyinfo
->display
;
3823 return Fcons (make_number (ProtocolVersion (dpy
)),
3824 Fcons (make_number (ProtocolRevision (dpy
)),
3825 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3828 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3829 doc
: /* Return the number of screens on the X server of display DISPLAY.
3830 The optional argument DISPLAY specifies which display to ask about.
3831 DISPLAY should be either a frame or a display name (a string).
3832 If omitted or nil, that stands for the selected frame's display. */)
3834 Lisp_Object display
;
3836 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3838 return make_number (ScreenCount (dpyinfo
->display
));
3841 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3842 doc
: /* Return the height in millimeters of the X display DISPLAY.
3843 The optional argument DISPLAY specifies which display to ask about.
3844 DISPLAY should be either a frame or a display name (a string).
3845 If omitted or nil, that stands for the selected frame's display. */)
3847 Lisp_Object display
;
3849 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3851 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3854 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3855 doc
: /* Return the width in millimeters of the X display DISPLAY.
3856 The optional argument DISPLAY specifies which display to ask about.
3857 DISPLAY should be either a frame or a display name (a string).
3858 If omitted or nil, that stands for the selected frame's display. */)
3860 Lisp_Object display
;
3862 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3864 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3867 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3868 Sx_display_backing_store
, 0, 1, 0,
3869 doc
: /* Returns an indication of whether X display DISPLAY does backing store.
3870 The value may be `always', `when-mapped', or `not-useful'.
3871 The optional argument DISPLAY specifies which display to ask about.
3872 DISPLAY should be either a frame or a display name (a string).
3873 If omitted or nil, that stands for the selected frame's display. */)
3875 Lisp_Object display
;
3877 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3880 switch (DoesBackingStore (dpyinfo
->screen
))
3883 result
= intern ("always");
3887 result
= intern ("when-mapped");
3891 result
= intern ("not-useful");
3895 error ("Strange value for BackingStore parameter of screen");
3902 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3903 Sx_display_visual_class
, 0, 1, 0,
3904 doc
: /* Return the visual class of the X display DISPLAY.
3905 The value is one of the symbols `static-gray', `gray-scale',
3906 `static-color', `pseudo-color', `true-color', or `direct-color'.
3908 The optional argument DISPLAY specifies which display to ask about.
3909 DISPLAY should be either a frame or a display name (a string).
3910 If omitted or nil, that stands for the selected frame's display. */)
3912 Lisp_Object display
;
3914 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3917 switch (dpyinfo
->visual
->class)
3920 result
= intern ("static-gray");
3923 result
= intern ("gray-scale");
3926 result
= intern ("static-color");
3929 result
= intern ("pseudo-color");
3932 result
= intern ("true-color");
3935 result
= intern ("direct-color");
3938 error ("Display has an unknown visual class");
3945 DEFUN ("x-display-save-under", Fx_display_save_under
,
3946 Sx_display_save_under
, 0, 1, 0,
3947 doc
: /* Returns t if the X display DISPLAY supports the save-under feature.
3948 The optional argument DISPLAY specifies which display to ask about.
3949 DISPLAY should be either a frame or a display name (a string).
3950 If omitted or nil, that stands for the selected frame's display. */)
3952 Lisp_Object display
;
3954 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3956 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3964 register struct frame
*f
;
3966 return FRAME_PIXEL_WIDTH (f
);
3971 register struct frame
*f
;
3973 return FRAME_PIXEL_HEIGHT (f
);
3978 register struct frame
*f
;
3980 return FRAME_COLUMN_WIDTH (f
);
3985 register struct frame
*f
;
3987 return FRAME_LINE_HEIGHT (f
);
3992 register struct frame
*f
;
3994 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
3999 /************************************************************************
4001 ************************************************************************/
4004 /* Mapping visual names to visuals. */
4006 static struct visual_class
4013 {"StaticGray", StaticGray
},
4014 {"GrayScale", GrayScale
},
4015 {"StaticColor", StaticColor
},
4016 {"PseudoColor", PseudoColor
},
4017 {"TrueColor", TrueColor
},
4018 {"DirectColor", DirectColor
},
4023 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4025 /* Value is the screen number of screen SCR. This is a substitute for
4026 the X function with the same name when that doesn't exist. */
4029 XScreenNumberOfScreen (scr
)
4030 register Screen
*scr
;
4032 Display
*dpy
= scr
->display
;
4035 for (i
= 0; i
< dpy
->nscreens
; ++i
)
4036 if (scr
== dpy
->screens
+ i
)
4042 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4045 /* Select the visual that should be used on display DPYINFO. Set
4046 members of DPYINFO appropriately. Called from x_term_init. */
4049 select_visual (dpyinfo
)
4050 struct x_display_info
*dpyinfo
;
4052 Display
*dpy
= dpyinfo
->display
;
4053 Screen
*screen
= dpyinfo
->screen
;
4056 /* See if a visual is specified. */
4057 value
= display_x_get_resource (dpyinfo
,
4058 build_string ("visualClass"),
4059 build_string ("VisualClass"),
4061 if (STRINGP (value
))
4063 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4064 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4065 depth, a decimal number. NAME is compared with case ignored. */
4066 char *s
= (char *) alloca (SBYTES (value
) + 1);
4071 strcpy (s
, SDATA (value
));
4072 dash
= index (s
, '-');
4075 dpyinfo
->n_planes
= atoi (dash
+ 1);
4079 /* We won't find a matching visual with depth 0, so that
4080 an error will be printed below. */
4081 dpyinfo
->n_planes
= 0;
4083 /* Determine the visual class. */
4084 for (i
= 0; visual_classes
[i
].name
; ++i
)
4085 if (xstricmp (s
, visual_classes
[i
].name
) == 0)
4087 class = visual_classes
[i
].class;
4091 /* Look up a matching visual for the specified class. */
4093 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4094 dpyinfo
->n_planes
, class, &vinfo
))
4095 fatal ("Invalid visual specification `%s'", SDATA (value
));
4097 dpyinfo
->visual
= vinfo
.visual
;
4102 XVisualInfo
*vinfo
, vinfo_template
;
4104 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4107 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4109 vinfo_template
.visualid
= dpyinfo
->visual
->visualid
;
4111 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4112 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4113 &vinfo_template
, &n_visuals
);
4115 fatal ("Can't get proper X visual info");
4117 dpyinfo
->n_planes
= vinfo
->depth
;
4118 XFree ((char *) vinfo
);
4123 /* Return the X display structure for the display named NAME.
4124 Open a new connection if necessary. */
4126 struct x_display_info
*
4127 x_display_info_for_name (name
)
4131 struct x_display_info
*dpyinfo
;
4133 CHECK_STRING (name
);
4136 if (! EQ (Vinitial_window_system
, intern ("x")))
4137 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4140 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4142 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4145 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4150 /* Use this general default value to start with. */
4151 Vx_resource_name
= Vinvocation_name
;
4153 validate_x_resource_name ();
4155 dpyinfo
= x_term_init (name
, (char *)0,
4156 (char *) SDATA (Vx_resource_name
));
4159 error ("Cannot connect to X server %s", SDATA (name
));
4162 XSETFASTINT (Vwindow_system_version
, 11);
4168 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4170 doc
: /* Open a connection to an X server.
4171 DISPLAY is the name of the display to connect to.
4172 Optional second arg XRM-STRING is a string of resources in xrdb format.
4173 If the optional third arg MUST-SUCCEED is non-nil,
4174 terminate Emacs if we can't open the connection. */)
4175 (display
, xrm_string
, must_succeed
)
4176 Lisp_Object display
, xrm_string
, must_succeed
;
4178 unsigned char *xrm_option
;
4179 struct x_display_info
*dpyinfo
;
4181 CHECK_STRING (display
);
4182 if (! NILP (xrm_string
))
4183 CHECK_STRING (xrm_string
);
4186 if (! EQ (Vinitial_window_system
, intern ("x")))
4187 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4190 if (! NILP (xrm_string
))
4191 xrm_option
= (unsigned char *) SDATA (xrm_string
);
4193 xrm_option
= (unsigned char *) 0;
4195 validate_x_resource_name ();
4197 /* This is what opens the connection and sets x_current_display.
4198 This also initializes many symbols, such as those used for input. */
4199 dpyinfo
= x_term_init (display
, xrm_option
,
4200 (char *) SDATA (Vx_resource_name
));
4204 if (!NILP (must_succeed
))
4205 fatal ("Cannot connect to X server %s.\n\
4206 Check the DISPLAY environment variable or use `-d'.\n\
4207 Also use the `xauth' program to verify that you have the proper\n\
4208 authorization information needed to connect the X server.\n\
4209 An insecure way to solve the problem may be to use `xhost'.\n",
4212 error ("Cannot connect to X server %s", SDATA (display
));
4217 XSETFASTINT (Vwindow_system_version
, 11);
4221 DEFUN ("x-close-connection", Fx_close_connection
,
4222 Sx_close_connection
, 1, 1, 0,
4223 doc
: /* Close the connection to DISPLAY's X server.
4224 For DISPLAY, specify either a frame or a display name (a string).
4225 If DISPLAY is nil, that stands for the selected frame's display. */)
4227 Lisp_Object display
;
4229 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4232 if (dpyinfo
->reference_count
> 0)
4233 error ("Display still has frames on it");
4236 /* Free the fonts in the font table. */
4237 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4238 if (dpyinfo
->font_table
[i
].name
)
4240 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4243 x_destroy_all_bitmaps (dpyinfo
);
4244 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4246 #ifdef USE_X_TOOLKIT
4247 XtCloseDisplay (dpyinfo
->display
);
4249 XCloseDisplay (dpyinfo
->display
);
4252 x_delete_display (dpyinfo
);
4258 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4259 doc
: /* Return the list of display names that Emacs has connections to. */)
4262 Lisp_Object tail
, result
;
4265 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
4266 result
= Fcons (XCAR (XCAR (tail
)), result
);
4271 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4272 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4273 If ON is nil, allow buffering of requests.
4274 Turning on synchronization prohibits the Xlib routines from buffering
4275 requests and seriously degrades performance, but makes debugging much
4277 The optional second argument DISPLAY specifies which display to act on.
4278 DISPLAY should be either a frame or a display name (a string).
4279 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4281 Lisp_Object display
, on
;
4283 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4285 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4290 /* Wait for responses to all X commands issued so far for frame F. */
4297 XSync (FRAME_X_DISPLAY (f
), False
);
4302 /***********************************************************************
4304 ***********************************************************************/
4306 /* Value is the number of elements of vector VECTOR. */
4308 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
4310 /* List of supported image types. Use define_image_type to add new
4311 types. Use lookup_image_type to find a type for a given symbol. */
4313 static struct image_type
*image_types
;
4315 /* The symbol `xbm' which is used as the type symbol for XBM images. */
4321 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
4322 extern Lisp_Object QCdata
, QCtype
;
4323 Lisp_Object QCascent
, QCmargin
, QCrelief
;
4324 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
4325 Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
;
4327 /* Other symbols. */
4329 Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
4331 /* Time in seconds after which images should be removed from the cache
4332 if not displayed. */
4334 Lisp_Object Vimage_cache_eviction_delay
;
4336 /* Function prototypes. */
4338 static void define_image_type
P_ ((struct image_type
*type
));
4339 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
4340 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
4341 static void x_laplace
P_ ((struct frame
*, struct image
*));
4342 static void x_emboss
P_ ((struct frame
*, struct image
*));
4343 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
4347 /* Define a new image type from TYPE. This adds a copy of TYPE to
4348 image_types and adds the symbol *TYPE->type to Vimage_types. */
4351 define_image_type (type
)
4352 struct image_type
*type
;
4354 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
4355 The initialized data segment is read-only. */
4356 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
4357 bcopy (type
, p
, sizeof *p
);
4358 p
->next
= image_types
;
4360 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
4364 /* Look up image type SYMBOL, and return a pointer to its image_type
4365 structure. Value is null if SYMBOL is not a known image type. */
4367 static INLINE
struct image_type
*
4368 lookup_image_type (symbol
)
4371 struct image_type
*type
;
4373 for (type
= image_types
; type
; type
= type
->next
)
4374 if (EQ (symbol
, *type
->type
))
4381 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
4382 valid image specification is a list whose car is the symbol
4383 `image', and whose rest is a property list. The property list must
4384 contain a value for key `:type'. That value must be the name of a
4385 supported image type. The rest of the property list depends on the
4389 valid_image_p (object
)
4394 if (IMAGEP (object
))
4398 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
4399 if (EQ (XCAR (tem
), QCtype
))
4402 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
4404 struct image_type
*type
;
4405 type
= lookup_image_type (XCAR (tem
));
4407 valid_p
= type
->valid_p (object
);
4418 /* Log error message with format string FORMAT and argument ARG.
4419 Signaling an error, e.g. when an image cannot be loaded, is not a
4420 good idea because this would interrupt redisplay, and the error
4421 message display would lead to another redisplay. This function
4422 therefore simply displays a message. */
4425 image_error (format
, arg1
, arg2
)
4427 Lisp_Object arg1
, arg2
;
4429 add_to_log (format
, arg1
, arg2
);
4434 /***********************************************************************
4435 Image specifications
4436 ***********************************************************************/
4438 enum image_value_type
4440 IMAGE_DONT_CHECK_VALUE_TYPE
,
4442 IMAGE_STRING_OR_NIL_VALUE
,
4444 IMAGE_POSITIVE_INTEGER_VALUE
,
4445 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
4446 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
4448 IMAGE_INTEGER_VALUE
,
4449 IMAGE_FUNCTION_VALUE
,
4454 /* Structure used when parsing image specifications. */
4456 struct image_keyword
4458 /* Name of keyword. */
4461 /* The type of value allowed. */
4462 enum image_value_type type
;
4464 /* Non-zero means key must be present. */
4467 /* Used to recognize duplicate keywords in a property list. */
4470 /* The value that was found. */
4475 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
4477 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
4480 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
4481 has the format (image KEYWORD VALUE ...). One of the keyword/
4482 value pairs must be `:type TYPE'. KEYWORDS is a vector of
4483 image_keywords structures of size NKEYWORDS describing other
4484 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
4487 parse_image_spec (spec
, keywords
, nkeywords
, type
)
4489 struct image_keyword
*keywords
;
4499 plist
= XCDR (spec
);
4500 while (CONSP (plist
))
4502 Lisp_Object key
, value
;
4504 /* First element of a pair must be a symbol. */
4506 plist
= XCDR (plist
);
4510 /* There must follow a value. */
4513 value
= XCAR (plist
);
4514 plist
= XCDR (plist
);
4516 /* Find key in KEYWORDS. Error if not found. */
4517 for (i
= 0; i
< nkeywords
; ++i
)
4518 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
4524 /* Record that we recognized the keyword. If a keywords
4525 was found more than once, it's an error. */
4526 keywords
[i
].value
= value
;
4527 ++keywords
[i
].count
;
4529 if (keywords
[i
].count
> 1)
4532 /* Check type of value against allowed type. */
4533 switch (keywords
[i
].type
)
4535 case IMAGE_STRING_VALUE
:
4536 if (!STRINGP (value
))
4540 case IMAGE_STRING_OR_NIL_VALUE
:
4541 if (!STRINGP (value
) && !NILP (value
))
4545 case IMAGE_SYMBOL_VALUE
:
4546 if (!SYMBOLP (value
))
4550 case IMAGE_POSITIVE_INTEGER_VALUE
:
4551 if (!INTEGERP (value
) || XINT (value
) <= 0)
4555 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
4556 if (INTEGERP (value
) && XINT (value
) >= 0)
4559 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
4560 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
4564 case IMAGE_ASCENT_VALUE
:
4565 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
4567 else if (INTEGERP (value
)
4568 && XINT (value
) >= 0
4569 && XINT (value
) <= 100)
4573 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
4574 if (!INTEGERP (value
) || XINT (value
) < 0)
4578 case IMAGE_DONT_CHECK_VALUE_TYPE
:
4581 case IMAGE_FUNCTION_VALUE
:
4582 value
= indirect_function (value
);
4584 || COMPILEDP (value
)
4585 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
4589 case IMAGE_NUMBER_VALUE
:
4590 if (!INTEGERP (value
) && !FLOATP (value
))
4594 case IMAGE_INTEGER_VALUE
:
4595 if (!INTEGERP (value
))
4599 case IMAGE_BOOL_VALUE
:
4600 if (!NILP (value
) && !EQ (value
, Qt
))
4609 if (EQ (key
, QCtype
) && !EQ (type
, value
))
4613 /* Check that all mandatory fields are present. */
4614 for (i
= 0; i
< nkeywords
; ++i
)
4615 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
4618 return NILP (plist
);
4622 /* Return the value of KEY in image specification SPEC. Value is nil
4623 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
4624 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
4627 image_spec_value (spec
, key
, found
)
4628 Lisp_Object spec
, key
;
4633 xassert (valid_image_p (spec
));
4635 for (tail
= XCDR (spec
);
4636 CONSP (tail
) && CONSP (XCDR (tail
));
4637 tail
= XCDR (XCDR (tail
)))
4639 if (EQ (XCAR (tail
), key
))
4643 return XCAR (XCDR (tail
));
4653 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
4654 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
4655 PIXELS non-nil means return the size in pixels, otherwise return the
4656 size in canonical character units.
4657 FRAME is the frame on which the image will be displayed. FRAME nil
4658 or omitted means use the selected frame. */)
4659 (spec
, pixels
, frame
)
4660 Lisp_Object spec
, pixels
, frame
;
4665 if (valid_image_p (spec
))
4667 struct frame
*f
= check_x_frame (frame
);
4668 int id
= lookup_image (f
, spec
);
4669 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4670 int width
= img
->width
+ 2 * img
->hmargin
;
4671 int height
= img
->height
+ 2 * img
->vmargin
;
4674 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
4675 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
4677 size
= Fcons (make_number (width
), make_number (height
));
4680 error ("Invalid image specification");
4686 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
4687 doc
: /* Return t if image SPEC has a mask bitmap.
4688 FRAME is the frame on which the image will be displayed. FRAME nil
4689 or omitted means use the selected frame. */)
4691 Lisp_Object spec
, frame
;
4696 if (valid_image_p (spec
))
4698 struct frame
*f
= check_x_frame (frame
);
4699 int id
= lookup_image (f
, spec
);
4700 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4705 error ("Invalid image specification");
4712 /***********************************************************************
4713 Image type independent image structures
4714 ***********************************************************************/
4716 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
4717 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
4720 /* Allocate and return a new image structure for image specification
4721 SPEC. SPEC has a hash value of HASH. */
4723 static struct image
*
4724 make_image (spec
, hash
)
4728 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
4730 xassert (valid_image_p (spec
));
4731 bzero (img
, sizeof *img
);
4732 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
4733 xassert (img
->type
!= NULL
);
4735 img
->data
.lisp_val
= Qnil
;
4736 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
4742 /* Free image IMG which was used on frame F, including its resources. */
4751 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4753 /* Remove IMG from the hash table of its cache. */
4755 img
->prev
->next
= img
->next
;
4757 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
4760 img
->next
->prev
= img
->prev
;
4762 c
->images
[img
->id
] = NULL
;
4764 /* Free resources, then free IMG. */
4765 img
->type
->free (f
, img
);
4771 /* Prepare image IMG for display on frame F. Must be called before
4772 drawing an image. */
4775 prepare_image_for_display (f
, img
)
4781 /* We're about to display IMG, so set its timestamp to `now'. */
4783 img
->timestamp
= EMACS_SECS (t
);
4785 /* If IMG doesn't have a pixmap yet, load it now, using the image
4786 type dependent loader function. */
4787 if (img
->pixmap
== None
&& !img
->load_failed_p
)
4788 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
4792 /* Value is the number of pixels for the ascent of image IMG when
4793 drawn in face FACE. */
4796 image_ascent (img
, face
)
4800 int height
= img
->height
+ img
->vmargin
;
4803 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
4806 /* This expression is arranged so that if the image can't be
4807 exactly centered, it will be moved slightly up. This is
4808 because a typical font is `top-heavy' (due to the presence
4809 uppercase letters), so the image placement should err towards
4810 being top-heavy too. It also just generally looks better. */
4811 ascent
= (height
+ face
->font
->ascent
- face
->font
->descent
+ 1) / 2;
4813 ascent
= height
/ 2;
4816 ascent
= height
* img
->ascent
/ 100.0;
4822 /* Image background colors. */
4824 static unsigned long
4825 four_corners_best (ximg
, width
, height
)
4827 unsigned long width
, height
;
4829 unsigned long corners
[4], best
;
4832 /* Get the colors at the corners of ximg. */
4833 corners
[0] = XGetPixel (ximg
, 0, 0);
4834 corners
[1] = XGetPixel (ximg
, width
- 1, 0);
4835 corners
[2] = XGetPixel (ximg
, width
- 1, height
- 1);
4836 corners
[3] = XGetPixel (ximg
, 0, height
- 1);
4838 /* Choose the most frequently found color as background. */
4839 for (i
= best_count
= 0; i
< 4; ++i
)
4843 for (j
= n
= 0; j
< 4; ++j
)
4844 if (corners
[i
] == corners
[j
])
4848 best
= corners
[i
], best_count
= n
;
4854 /* Return the `background' field of IMG. If IMG doesn't have one yet,
4855 it is guessed heuristically. If non-zero, XIMG is an existing XImage
4856 object to use for the heuristic. */
4859 image_background (img
, f
, ximg
)
4864 if (! img
->background_valid
)
4865 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4867 int free_ximg
= !ximg
;
4870 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4871 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4873 img
->background
= four_corners_best (ximg
, img
->width
, img
->height
);
4876 XDestroyImage (ximg
);
4878 img
->background_valid
= 1;
4881 return img
->background
;
4884 /* Return the `background_transparent' field of IMG. If IMG doesn't
4885 have one yet, it is guessed heuristically. If non-zero, MASK is an
4886 existing XImage object to use for the heuristic. */
4889 image_background_transparent (img
, f
, mask
)
4894 if (! img
->background_transparent_valid
)
4895 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4899 int free_mask
= !mask
;
4902 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
4903 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4905 img
->background_transparent
4906 = !four_corners_best (mask
, img
->width
, img
->height
);
4909 XDestroyImage (mask
);
4912 img
->background_transparent
= 0;
4914 img
->background_transparent_valid
= 1;
4917 return img
->background_transparent
;
4921 /***********************************************************************
4922 Helper functions for X image types
4923 ***********************************************************************/
4925 static void x_clear_image_1
P_ ((struct frame
*, struct image
*, int,
4927 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
4928 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
4930 Lisp_Object color_name
,
4931 unsigned long dflt
));
4934 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
4935 free the pixmap if any. MASK_P non-zero means clear the mask
4936 pixmap if any. COLORS_P non-zero means free colors allocated for
4937 the image, if any. */
4940 x_clear_image_1 (f
, img
, pixmap_p
, mask_p
, colors_p
)
4943 int pixmap_p
, mask_p
, colors_p
;
4945 if (pixmap_p
&& img
->pixmap
)
4947 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
4949 img
->background_valid
= 0;
4952 if (mask_p
&& img
->mask
)
4954 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4956 img
->background_transparent_valid
= 0;
4959 if (colors_p
&& img
->ncolors
)
4961 x_free_colors (f
, img
->colors
, img
->ncolors
);
4962 xfree (img
->colors
);
4968 /* Free X resources of image IMG which is used on frame F. */
4971 x_clear_image (f
, img
)
4976 x_clear_image_1 (f
, img
, 1, 1, 1);
4981 /* Allocate color COLOR_NAME for image IMG on frame F. If color
4982 cannot be allocated, use DFLT. Add a newly allocated color to
4983 IMG->colors, so that it can be freed again. Value is the pixel
4986 static unsigned long
4987 x_alloc_image_color (f
, img
, color_name
, dflt
)
4990 Lisp_Object color_name
;
4994 unsigned long result
;
4996 xassert (STRINGP (color_name
));
4998 if (x_defined_color (f
, SDATA (color_name
), &color
, 1))
5000 /* This isn't called frequently so we get away with simply
5001 reallocating the color vector to the needed size, here. */
5004 (unsigned long *) xrealloc (img
->colors
,
5005 img
->ncolors
* sizeof *img
->colors
);
5006 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
5007 result
= color
.pixel
;
5017 /***********************************************************************
5019 ***********************************************************************/
5021 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
5022 static void postprocess_image
P_ ((struct frame
*, struct image
*));
5025 /* Return a new, initialized image cache that is allocated from the
5026 heap. Call free_image_cache to free an image cache. */
5028 struct image_cache
*
5031 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
5034 bzero (c
, sizeof *c
);
5036 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
5037 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
5038 c
->buckets
= (struct image
**) xmalloc (size
);
5039 bzero (c
->buckets
, size
);
5044 /* Free image cache of frame F. Be aware that X frames share images
5048 free_image_cache (f
)
5051 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5056 /* Cache should not be referenced by any frame when freed. */
5057 xassert (c
->refcount
== 0);
5059 for (i
= 0; i
< c
->used
; ++i
)
5060 free_image (f
, c
->images
[i
]);
5064 FRAME_X_IMAGE_CACHE (f
) = NULL
;
5069 /* Clear image cache of frame F. FORCE_P non-zero means free all
5070 images. FORCE_P zero means clear only images that haven't been
5071 displayed for some time. Should be called from time to time to
5072 reduce the number of loaded images. If image-eviction-seconds is
5073 non-nil, this frees images in the cache which weren't displayed for
5074 at least that many seconds. */
5077 clear_image_cache (f
, force_p
)
5081 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5083 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
5090 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
5092 /* Block input so that we won't be interrupted by a SIGIO
5093 while being in an inconsistent state. */
5096 for (i
= nfreed
= 0; i
< c
->used
; ++i
)
5098 struct image
*img
= c
->images
[i
];
5100 && (force_p
|| img
->timestamp
< old
))
5102 free_image (f
, img
);
5107 /* We may be clearing the image cache because, for example,
5108 Emacs was iconified for a longer period of time. In that
5109 case, current matrices may still contain references to
5110 images freed above. So, clear these matrices. */
5113 Lisp_Object tail
, frame
;
5115 FOR_EACH_FRAME (tail
, frame
)
5117 struct frame
*f
= XFRAME (frame
);
5119 && FRAME_X_IMAGE_CACHE (f
) == c
)
5120 clear_current_matrices (f
);
5123 ++windows_or_buffers_changed
;
5131 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
5133 doc
: /* Clear the image cache of FRAME.
5134 FRAME nil or omitted means use the selected frame.
5135 FRAME t means clear the image caches of all frames. */)
5143 FOR_EACH_FRAME (tail
, frame
)
5144 if (FRAME_X_P (XFRAME (frame
)))
5145 clear_image_cache (XFRAME (frame
), 1);
5148 clear_image_cache (check_x_frame (frame
), 1);
5154 /* Compute masks and transform image IMG on frame F, as specified
5155 by the image's specification, */
5158 postprocess_image (f
, img
)
5162 /* Manipulation of the image's mask. */
5165 Lisp_Object conversion
, spec
;
5170 /* `:heuristic-mask t'
5172 means build a mask heuristically.
5173 `:heuristic-mask (R G B)'
5174 `:mask (heuristic (R G B))'
5175 means build a mask from color (R G B) in the
5178 means remove a mask, if any. */
5180 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
5182 x_build_heuristic_mask (f
, img
, mask
);
5187 mask
= image_spec_value (spec
, QCmask
, &found_p
);
5189 if (EQ (mask
, Qheuristic
))
5190 x_build_heuristic_mask (f
, img
, Qt
);
5191 else if (CONSP (mask
)
5192 && EQ (XCAR (mask
), Qheuristic
))
5194 if (CONSP (XCDR (mask
)))
5195 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
5197 x_build_heuristic_mask (f
, img
, XCDR (mask
));
5199 else if (NILP (mask
) && found_p
&& img
->mask
)
5201 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
5207 /* Should we apply an image transformation algorithm? */
5208 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
5209 if (EQ (conversion
, Qdisabled
))
5210 x_disable_image (f
, img
);
5211 else if (EQ (conversion
, Qlaplace
))
5213 else if (EQ (conversion
, Qemboss
))
5215 else if (CONSP (conversion
)
5216 && EQ (XCAR (conversion
), Qedge_detection
))
5219 tem
= XCDR (conversion
);
5221 x_edge_detection (f
, img
,
5222 Fplist_get (tem
, QCmatrix
),
5223 Fplist_get (tem
, QCcolor_adjustment
));
5229 /* Return the id of image with Lisp specification SPEC on frame F.
5230 SPEC must be a valid Lisp image specification (see valid_image_p). */
5233 lookup_image (f
, spec
)
5237 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5241 struct gcpro gcpro1
;
5244 /* F must be a window-system frame, and SPEC must be a valid image
5246 xassert (FRAME_WINDOW_P (f
));
5247 xassert (valid_image_p (spec
));
5251 /* Look up SPEC in the hash table of the image cache. */
5252 hash
= sxhash (spec
, 0);
5253 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5255 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
5256 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
5259 /* If not found, create a new image and cache it. */
5262 extern Lisp_Object Qpostscript
;
5265 img
= make_image (spec
, hash
);
5266 cache_image (f
, img
);
5267 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5269 /* If we can't load the image, and we don't have a width and
5270 height, use some arbitrary width and height so that we can
5271 draw a rectangle for it. */
5272 if (img
->load_failed_p
)
5276 value
= image_spec_value (spec
, QCwidth
, NULL
);
5277 img
->width
= (INTEGERP (value
)
5278 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
5279 value
= image_spec_value (spec
, QCheight
, NULL
);
5280 img
->height
= (INTEGERP (value
)
5281 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
5285 /* Handle image type independent image attributes
5286 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
5287 `:background COLOR'. */
5288 Lisp_Object ascent
, margin
, relief
, bg
;
5290 ascent
= image_spec_value (spec
, QCascent
, NULL
);
5291 if (INTEGERP (ascent
))
5292 img
->ascent
= XFASTINT (ascent
);
5293 else if (EQ (ascent
, Qcenter
))
5294 img
->ascent
= CENTERED_IMAGE_ASCENT
;
5296 margin
= image_spec_value (spec
, QCmargin
, NULL
);
5297 if (INTEGERP (margin
) && XINT (margin
) >= 0)
5298 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
5299 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
5300 && INTEGERP (XCDR (margin
)))
5302 if (XINT (XCAR (margin
)) > 0)
5303 img
->hmargin
= XFASTINT (XCAR (margin
));
5304 if (XINT (XCDR (margin
)) > 0)
5305 img
->vmargin
= XFASTINT (XCDR (margin
));
5308 relief
= image_spec_value (spec
, QCrelief
, NULL
);
5309 if (INTEGERP (relief
))
5311 img
->relief
= XINT (relief
);
5312 img
->hmargin
+= abs (img
->relief
);
5313 img
->vmargin
+= abs (img
->relief
);
5316 if (! img
->background_valid
)
5318 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
5322 = x_alloc_image_color (f
, img
, bg
,
5323 FRAME_BACKGROUND_PIXEL (f
));
5324 img
->background_valid
= 1;
5328 /* Do image transformations and compute masks, unless we
5329 don't have the image yet. */
5330 if (!EQ (*img
->type
->type
, Qpostscript
))
5331 postprocess_image (f
, img
);
5337 /* We're using IMG, so set its timestamp to `now'. */
5338 EMACS_GET_TIME (now
);
5339 img
->timestamp
= EMACS_SECS (now
);
5343 /* Value is the image id. */
5348 /* Cache image IMG in the image cache of frame F. */
5351 cache_image (f
, img
)
5355 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5358 /* Find a free slot in c->images. */
5359 for (i
= 0; i
< c
->used
; ++i
)
5360 if (c
->images
[i
] == NULL
)
5363 /* If no free slot found, maybe enlarge c->images. */
5364 if (i
== c
->used
&& c
->used
== c
->size
)
5367 c
->images
= (struct image
**) xrealloc (c
->images
,
5368 c
->size
* sizeof *c
->images
);
5371 /* Add IMG to c->images, and assign IMG an id. */
5377 /* Add IMG to the cache's hash table. */
5378 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5379 img
->next
= c
->buckets
[i
];
5381 img
->next
->prev
= img
;
5383 c
->buckets
[i
] = img
;
5387 /* Call FN on every image in the image cache of frame F. Used to mark
5388 Lisp Objects in the image cache. */
5391 forall_images_in_image_cache (f
, fn
)
5393 void (*fn
) P_ ((struct image
*img
));
5395 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
))
5397 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5401 for (i
= 0; i
< c
->used
; ++i
)
5410 /***********************************************************************
5412 ***********************************************************************/
5414 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
5415 XImage
**, Pixmap
*));
5416 static void x_destroy_x_image
P_ ((XImage
*));
5417 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
5420 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
5421 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
5422 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
5423 via xmalloc. Print error messages via image_error if an error
5424 occurs. Value is non-zero if successful. */
5427 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
5429 int width
, height
, depth
;
5433 Display
*display
= FRAME_X_DISPLAY (f
);
5434 Screen
*screen
= FRAME_X_SCREEN (f
);
5435 Window window
= FRAME_X_WINDOW (f
);
5437 xassert (interrupt_input_blocked
);
5440 depth
= DefaultDepthOfScreen (screen
);
5441 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
5442 depth
, ZPixmap
, 0, NULL
, width
, height
,
5443 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
5446 image_error ("Unable to allocate X image", Qnil
, Qnil
);
5450 /* Allocate image raster. */
5451 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
5453 /* Allocate a pixmap of the same size. */
5454 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
5455 if (*pixmap
== None
)
5457 x_destroy_x_image (*ximg
);
5459 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
5467 /* Destroy XImage XIMG. Free XIMG->data. */
5470 x_destroy_x_image (ximg
)
5473 xassert (interrupt_input_blocked
);
5478 XDestroyImage (ximg
);
5483 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
5484 are width and height of both the image and pixmap. */
5487 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
5495 xassert (interrupt_input_blocked
);
5496 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
5497 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
5498 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5503 /***********************************************************************
5505 ***********************************************************************/
5507 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
5508 static char *slurp_file
P_ ((char *, int *));
5511 /* Find image file FILE. Look in data-directory, then
5512 x-bitmap-file-path. Value is the full name of the file found, or
5513 nil if not found. */
5516 x_find_image_file (file
)
5519 Lisp_Object file_found
, search_path
;
5520 struct gcpro gcpro1
, gcpro2
;
5524 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
5525 GCPRO2 (file_found
, search_path
);
5527 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
5528 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
5540 /* Read FILE into memory. Value is a pointer to a buffer allocated
5541 with xmalloc holding FILE's contents. Value is null if an error
5542 occurred. *SIZE is set to the size of the file. */
5545 slurp_file (file
, size
)
5553 if (stat (file
, &st
) == 0
5554 && (fp
= fopen (file
, "r")) != NULL
5555 && (buf
= (char *) xmalloc (st
.st_size
),
5556 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5577 /***********************************************************************
5579 ***********************************************************************/
5581 static int xbm_scan
P_ ((char **, char *, char *, int *));
5582 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
5583 static int xbm_load_image
P_ ((struct frame
*f
, struct image
*img
,
5585 static int xbm_image_p
P_ ((Lisp_Object object
));
5586 static int xbm_read_bitmap_data
P_ ((char *, char *, int *, int *,
5588 static int xbm_file_p
P_ ((Lisp_Object
));
5591 /* Indices of image specification fields in xbm_format, below. */
5593 enum xbm_keyword_index
5611 /* Vector of image_keyword structures describing the format
5612 of valid XBM image specifications. */
5614 static struct image_keyword xbm_format
[XBM_LAST
] =
5616 {":type", IMAGE_SYMBOL_VALUE
, 1},
5617 {":file", IMAGE_STRING_VALUE
, 0},
5618 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5619 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5620 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5621 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
5622 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
5623 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5624 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5625 {":relief", IMAGE_INTEGER_VALUE
, 0},
5626 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5627 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5628 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5631 /* Structure describing the image type XBM. */
5633 static struct image_type xbm_type
=
5642 /* Tokens returned from xbm_scan. */
5651 /* Return non-zero if OBJECT is a valid XBM-type image specification.
5652 A valid specification is a list starting with the symbol `image'
5653 The rest of the list is a property list which must contain an
5656 If the specification specifies a file to load, it must contain
5657 an entry `:file FILENAME' where FILENAME is a string.
5659 If the specification is for a bitmap loaded from memory it must
5660 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
5661 WIDTH and HEIGHT are integers > 0. DATA may be:
5663 1. a string large enough to hold the bitmap data, i.e. it must
5664 have a size >= (WIDTH + 7) / 8 * HEIGHT
5666 2. a bool-vector of size >= WIDTH * HEIGHT
5668 3. a vector of strings or bool-vectors, one for each line of the
5671 4. A string containing an in-memory XBM file. WIDTH and HEIGHT
5672 may not be specified in this case because they are defined in the
5675 Both the file and data forms may contain the additional entries
5676 `:background COLOR' and `:foreground COLOR'. If not present,
5677 foreground and background of the frame on which the image is
5678 displayed is used. */
5681 xbm_image_p (object
)
5684 struct image_keyword kw
[XBM_LAST
];
5686 bcopy (xbm_format
, kw
, sizeof kw
);
5687 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
5690 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
5692 if (kw
[XBM_FILE
].count
)
5694 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
5697 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
5699 /* In-memory XBM file. */
5700 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
5708 /* Entries for `:width', `:height' and `:data' must be present. */
5709 if (!kw
[XBM_WIDTH
].count
5710 || !kw
[XBM_HEIGHT
].count
5711 || !kw
[XBM_DATA
].count
)
5714 data
= kw
[XBM_DATA
].value
;
5715 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
5716 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
5718 /* Check type of data, and width and height against contents of
5724 /* Number of elements of the vector must be >= height. */
5725 if (XVECTOR (data
)->size
< height
)
5728 /* Each string or bool-vector in data must be large enough
5729 for one line of the image. */
5730 for (i
= 0; i
< height
; ++i
)
5732 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
5737 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
5740 else if (BOOL_VECTOR_P (elt
))
5742 if (XBOOL_VECTOR (elt
)->size
< width
)
5749 else if (STRINGP (data
))
5752 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
5755 else if (BOOL_VECTOR_P (data
))
5757 if (XBOOL_VECTOR (data
)->size
< width
* height
)
5768 /* Scan a bitmap file. FP is the stream to read from. Value is
5769 either an enumerator from enum xbm_token, or a character for a
5770 single-character token, or 0 at end of file. If scanning an
5771 identifier, store the lexeme of the identifier in SVAL. If
5772 scanning a number, store its value in *IVAL. */
5775 xbm_scan (s
, end
, sval
, ival
)
5784 /* Skip white space. */
5785 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5790 else if (isdigit (c
))
5792 int value
= 0, digit
;
5794 if (c
== '0' && *s
< end
)
5797 if (c
== 'x' || c
== 'X')
5804 else if (c
>= 'a' && c
<= 'f')
5805 digit
= c
- 'a' + 10;
5806 else if (c
>= 'A' && c
<= 'F')
5807 digit
= c
- 'A' + 10;
5810 value
= 16 * value
+ digit
;
5813 else if (isdigit (c
))
5817 && (c
= *(*s
)++, isdigit (c
)))
5818 value
= 8 * value
+ c
- '0';
5825 && (c
= *(*s
)++, isdigit (c
)))
5826 value
= 10 * value
+ c
- '0';
5834 else if (isalpha (c
) || c
== '_')
5838 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
5845 else if (c
== '/' && **s
== '*')
5847 /* C-style comment. */
5849 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
5862 /* Replacement for XReadBitmapFileData which isn't available under old
5863 X versions. CONTENTS is a pointer to a buffer to parse; END is the
5864 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
5865 the image. Return in *DATA the bitmap data allocated with xmalloc.
5866 Value is non-zero if successful. DATA null means just test if
5867 CONTENTS looks like an in-memory XBM file. */
5870 xbm_read_bitmap_data (contents
, end
, width
, height
, data
)
5871 char *contents
, *end
;
5872 int *width
, *height
;
5873 unsigned char **data
;
5876 char buffer
[BUFSIZ
];
5879 int bytes_per_line
, i
, nbytes
;
5885 LA1 = xbm_scan (&s, end, buffer, &value)
5887 #define expect(TOKEN) \
5888 if (LA1 != (TOKEN)) \
5893 #define expect_ident(IDENT) \
5894 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
5899 *width
= *height
= -1;
5902 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
5904 /* Parse defines for width, height and hot-spots. */
5908 expect_ident ("define");
5909 expect (XBM_TK_IDENT
);
5911 if (LA1
== XBM_TK_NUMBER
);
5913 char *p
= strrchr (buffer
, '_');
5914 p
= p
? p
+ 1 : buffer
;
5915 if (strcmp (p
, "width") == 0)
5917 else if (strcmp (p
, "height") == 0)
5920 expect (XBM_TK_NUMBER
);
5923 if (*width
< 0 || *height
< 0)
5925 else if (data
== NULL
)
5928 /* Parse bits. Must start with `static'. */
5929 expect_ident ("static");
5930 if (LA1
== XBM_TK_IDENT
)
5932 if (strcmp (buffer
, "unsigned") == 0)
5935 expect_ident ("char");
5937 else if (strcmp (buffer
, "short") == 0)
5941 if (*width
% 16 && *width
% 16 < 9)
5944 else if (strcmp (buffer
, "char") == 0)
5952 expect (XBM_TK_IDENT
);
5958 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
5959 nbytes
= bytes_per_line
* *height
;
5960 p
= *data
= (char *) xmalloc (nbytes
);
5964 for (i
= 0; i
< nbytes
; i
+= 2)
5967 expect (XBM_TK_NUMBER
);
5970 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
5973 if (LA1
== ',' || LA1
== '}')
5981 for (i
= 0; i
< nbytes
; ++i
)
5984 expect (XBM_TK_NUMBER
);
5988 if (LA1
== ',' || LA1
== '}')
6013 /* Load XBM image IMG which will be displayed on frame F from buffer
6014 CONTENTS. END is the end of the buffer. Value is non-zero if
6018 xbm_load_image (f
, img
, contents
, end
)
6021 char *contents
, *end
;
6024 unsigned char *data
;
6027 rc
= xbm_read_bitmap_data (contents
, end
, &img
->width
, &img
->height
, &data
);
6030 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6031 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6032 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6035 xassert (img
->width
> 0 && img
->height
> 0);
6037 /* Get foreground and background colors, maybe allocate colors. */
6038 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
6040 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
6041 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
6044 background
= x_alloc_image_color (f
, img
, value
, background
);
6045 img
->background
= background
;
6046 img
->background_valid
= 1;
6050 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
6053 img
->width
, img
->height
,
6054 foreground
, background
,
6058 if (img
->pixmap
== None
)
6060 x_clear_image (f
, img
);
6061 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
6067 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6073 /* Value is non-zero if DATA looks like an in-memory XBM file. */
6080 return (STRINGP (data
)
6081 && xbm_read_bitmap_data (SDATA (data
),
6088 /* Fill image IMG which is used on frame F with pixmap data. Value is
6089 non-zero if successful. */
6097 Lisp_Object file_name
;
6099 xassert (xbm_image_p (img
->spec
));
6101 /* If IMG->spec specifies a file name, create a non-file spec from it. */
6102 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
6103 if (STRINGP (file_name
))
6108 struct gcpro gcpro1
;
6110 file
= x_find_image_file (file_name
);
6112 if (!STRINGP (file
))
6114 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
6119 contents
= slurp_file (SDATA (file
), &size
);
6120 if (contents
== NULL
)
6122 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6127 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
6132 struct image_keyword fmt
[XBM_LAST
];
6135 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6136 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6139 int in_memory_file_p
= 0;
6141 /* See if data looks like an in-memory XBM file. */
6142 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6143 in_memory_file_p
= xbm_file_p (data
);
6145 /* Parse the image specification. */
6146 bcopy (xbm_format
, fmt
, sizeof fmt
);
6147 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
6150 /* Get specified width, and height. */
6151 if (!in_memory_file_p
)
6153 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
6154 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
6155 xassert (img
->width
> 0 && img
->height
> 0);
6158 /* Get foreground and background colors, maybe allocate colors. */
6159 if (fmt
[XBM_FOREGROUND
].count
6160 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
6161 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
6163 if (fmt
[XBM_BACKGROUND
].count
6164 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
6165 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
6168 if (in_memory_file_p
)
6169 success_p
= xbm_load_image (f
, img
, SDATA (data
),
6178 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
6180 p
= bits
= (char *) alloca (nbytes
* img
->height
);
6181 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
6183 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
6185 bcopy (SDATA (line
), p
, nbytes
);
6187 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
6190 else if (STRINGP (data
))
6191 bits
= SDATA (data
);
6193 bits
= XBOOL_VECTOR (data
)->data
;
6195 /* Create the pixmap. */
6196 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6198 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
6201 img
->width
, img
->height
,
6202 foreground
, background
,
6208 image_error ("Unable to create pixmap for XBM image `%s'",
6210 x_clear_image (f
, img
);
6220 /***********************************************************************
6222 ***********************************************************************/
6226 static int xpm_image_p
P_ ((Lisp_Object object
));
6227 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
6228 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
6230 #include "X11/xpm.h"
6232 /* The symbol `xpm' identifying XPM-format images. */
6236 /* Indices of image specification fields in xpm_format, below. */
6238 enum xpm_keyword_index
6254 /* Vector of image_keyword structures describing the format
6255 of valid XPM image specifications. */
6257 static struct image_keyword xpm_format
[XPM_LAST
] =
6259 {":type", IMAGE_SYMBOL_VALUE
, 1},
6260 {":file", IMAGE_STRING_VALUE
, 0},
6261 {":data", IMAGE_STRING_VALUE
, 0},
6262 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6263 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6264 {":relief", IMAGE_INTEGER_VALUE
, 0},
6265 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6266 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6267 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6268 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6269 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6272 /* Structure describing the image type XBM. */
6274 static struct image_type xpm_type
=
6284 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
6285 functions for allocating image colors. Our own functions handle
6286 color allocation failures more gracefully than the ones on the XPM
6289 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
6290 #define ALLOC_XPM_COLORS
6293 #ifdef ALLOC_XPM_COLORS
6295 static void xpm_init_color_cache
P_ ((struct frame
*, XpmAttributes
*));
6296 static void xpm_free_color_cache
P_ ((void));
6297 static int xpm_lookup_color
P_ ((struct frame
*, char *, XColor
*));
6298 static int xpm_color_bucket
P_ ((char *));
6299 static struct xpm_cached_color
*xpm_cache_color
P_ ((struct frame
*, char *,
6302 /* An entry in a hash table used to cache color definitions of named
6303 colors. This cache is necessary to speed up XPM image loading in
6304 case we do color allocations ourselves. Without it, we would need
6305 a call to XParseColor per pixel in the image. */
6307 struct xpm_cached_color
6309 /* Next in collision chain. */
6310 struct xpm_cached_color
*next
;
6312 /* Color definition (RGB and pixel color). */
6319 /* The hash table used for the color cache, and its bucket vector
6322 #define XPM_COLOR_CACHE_BUCKETS 1001
6323 struct xpm_cached_color
**xpm_color_cache
;
6325 /* Initialize the color cache. */
6328 xpm_init_color_cache (f
, attrs
)
6330 XpmAttributes
*attrs
;
6332 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
6333 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
6334 memset (xpm_color_cache
, 0, nbytes
);
6335 init_color_table ();
6337 if (attrs
->valuemask
& XpmColorSymbols
)
6342 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
6343 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6344 attrs
->colorsymbols
[i
].value
, &color
))
6346 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
6348 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
6354 /* Free the color cache. */
6357 xpm_free_color_cache ()
6359 struct xpm_cached_color
*p
, *next
;
6362 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
6363 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
6369 xfree (xpm_color_cache
);
6370 xpm_color_cache
= NULL
;
6371 free_color_table ();
6375 /* Return the bucket index for color named COLOR_NAME in the color
6379 xpm_color_bucket (color_name
)
6385 for (s
= color_name
; *s
; ++s
)
6387 return h
%= XPM_COLOR_CACHE_BUCKETS
;
6391 /* On frame F, cache values COLOR for color with name COLOR_NAME.
6392 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
6395 static struct xpm_cached_color
*
6396 xpm_cache_color (f
, color_name
, color
, bucket
)
6403 struct xpm_cached_color
*p
;
6406 bucket
= xpm_color_bucket (color_name
);
6408 nbytes
= sizeof *p
+ strlen (color_name
);
6409 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
6410 strcpy (p
->name
, color_name
);
6412 p
->next
= xpm_color_cache
[bucket
];
6413 xpm_color_cache
[bucket
] = p
;
6418 /* Look up color COLOR_NAME for frame F in the color cache. If found,
6419 return the cached definition in *COLOR. Otherwise, make a new
6420 entry in the cache and allocate the color. Value is zero if color
6421 allocation failed. */
6424 xpm_lookup_color (f
, color_name
, color
)
6429 struct xpm_cached_color
*p
;
6430 int h
= xpm_color_bucket (color_name
);
6432 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
6433 if (strcmp (p
->name
, color_name
) == 0)
6438 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6441 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
6443 p
= xpm_cache_color (f
, color_name
, color
, h
);
6445 /* You get `opaque' at least from ImageMagick converting pbm to xpm
6446 with transparency, and it's useful. */
6447 else if (strcmp ("opaque", color_name
) == 0)
6449 bzero (color
, sizeof (XColor
)); /* Is this necessary/correct? */
6450 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
6451 p
= xpm_cache_color (f
, color_name
, color
, h
);
6458 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
6459 CLOSURE is a pointer to the frame on which we allocate the
6460 color. Return in *COLOR the allocated color. Value is non-zero
6464 xpm_alloc_color (dpy
, cmap
, color_name
, color
, closure
)
6471 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
6475 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
6476 is a pointer to the frame on which we allocate the color. Value is
6477 non-zero if successful. */
6480 xpm_free_colors (dpy
, cmap
, pixels
, npixels
, closure
)
6490 #endif /* ALLOC_XPM_COLORS */
6493 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
6494 for XPM images. Such a list must consist of conses whose car and
6498 xpm_valid_color_symbols_p (color_symbols
)
6499 Lisp_Object color_symbols
;
6501 while (CONSP (color_symbols
))
6503 Lisp_Object sym
= XCAR (color_symbols
);
6505 || !STRINGP (XCAR (sym
))
6506 || !STRINGP (XCDR (sym
)))
6508 color_symbols
= XCDR (color_symbols
);
6511 return NILP (color_symbols
);
6515 /* Value is non-zero if OBJECT is a valid XPM image specification. */
6518 xpm_image_p (object
)
6521 struct image_keyword fmt
[XPM_LAST
];
6522 bcopy (xpm_format
, fmt
, sizeof fmt
);
6523 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
6524 /* Either `:file' or `:data' must be present. */
6525 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
6526 /* Either no `:color-symbols' or it's a list of conses
6527 whose car and cdr are strings. */
6528 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
6529 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
6533 /* Load image IMG which will be displayed on frame F. Value is
6534 non-zero if successful. */
6542 XpmAttributes attrs
;
6543 Lisp_Object specified_file
, color_symbols
;
6545 /* Configure the XPM lib. Use the visual of frame F. Allocate
6546 close colors. Return colors allocated. */
6547 bzero (&attrs
, sizeof attrs
);
6548 attrs
.visual
= FRAME_X_VISUAL (f
);
6549 attrs
.colormap
= FRAME_X_COLORMAP (f
);
6550 attrs
.valuemask
|= XpmVisual
;
6551 attrs
.valuemask
|= XpmColormap
;
6553 #ifdef ALLOC_XPM_COLORS
6554 /* Allocate colors with our own functions which handle
6555 failing color allocation more gracefully. */
6556 attrs
.color_closure
= f
;
6557 attrs
.alloc_color
= xpm_alloc_color
;
6558 attrs
.free_colors
= xpm_free_colors
;
6559 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
6560 #else /* not ALLOC_XPM_COLORS */
6561 /* Let the XPM lib allocate colors. */
6562 attrs
.valuemask
|= XpmReturnAllocPixels
;
6563 #ifdef XpmAllocCloseColors
6564 attrs
.alloc_close_colors
= 1;
6565 attrs
.valuemask
|= XpmAllocCloseColors
;
6566 #else /* not XpmAllocCloseColors */
6567 attrs
.closeness
= 600;
6568 attrs
.valuemask
|= XpmCloseness
;
6569 #endif /* not XpmAllocCloseColors */
6570 #endif /* ALLOC_XPM_COLORS */
6572 /* If image specification contains symbolic color definitions, add
6573 these to `attrs'. */
6574 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
6575 if (CONSP (color_symbols
))
6578 XpmColorSymbol
*xpm_syms
;
6581 attrs
.valuemask
|= XpmColorSymbols
;
6583 /* Count number of symbols. */
6584 attrs
.numsymbols
= 0;
6585 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
6588 /* Allocate an XpmColorSymbol array. */
6589 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
6590 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
6591 bzero (xpm_syms
, size
);
6592 attrs
.colorsymbols
= xpm_syms
;
6594 /* Fill the color symbol array. */
6595 for (tail
= color_symbols
, i
= 0;
6597 ++i
, tail
= XCDR (tail
))
6599 Lisp_Object name
= XCAR (XCAR (tail
));
6600 Lisp_Object color
= XCDR (XCAR (tail
));
6601 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
6602 strcpy (xpm_syms
[i
].name
, SDATA (name
));
6603 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
6604 strcpy (xpm_syms
[i
].value
, SDATA (color
));
6608 /* Create a pixmap for the image, either from a file, or from a
6609 string buffer containing data in the same format as an XPM file. */
6610 #ifdef ALLOC_XPM_COLORS
6611 xpm_init_color_cache (f
, &attrs
);
6614 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6615 if (STRINGP (specified_file
))
6617 Lisp_Object file
= x_find_image_file (specified_file
);
6618 if (!STRINGP (file
))
6620 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6624 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6625 SDATA (file
), &img
->pixmap
, &img
->mask
,
6630 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
6631 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6633 &img
->pixmap
, &img
->mask
,
6637 if (rc
== XpmSuccess
)
6639 #ifdef ALLOC_XPM_COLORS
6640 img
->colors
= colors_in_color_table (&img
->ncolors
);
6641 #else /* not ALLOC_XPM_COLORS */
6644 img
->ncolors
= attrs
.nalloc_pixels
;
6645 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
6646 * sizeof *img
->colors
);
6647 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
6649 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
6650 #ifdef DEBUG_X_COLORS
6651 register_color (img
->colors
[i
]);
6654 #endif /* not ALLOC_XPM_COLORS */
6656 img
->width
= attrs
.width
;
6657 img
->height
= attrs
.height
;
6658 xassert (img
->width
> 0 && img
->height
> 0);
6660 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
6661 XpmFreeAttributes (&attrs
);
6668 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
6671 case XpmFileInvalid
:
6672 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
6676 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
6679 case XpmColorFailed
:
6680 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
6684 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
6689 #ifdef ALLOC_XPM_COLORS
6690 xpm_free_color_cache ();
6692 return rc
== XpmSuccess
;
6695 #endif /* HAVE_XPM != 0 */
6698 /***********************************************************************
6700 ***********************************************************************/
6702 /* An entry in the color table mapping an RGB color to a pixel color. */
6707 unsigned long pixel
;
6709 /* Next in color table collision list. */
6710 struct ct_color
*next
;
6713 /* The bucket vector size to use. Must be prime. */
6717 /* Value is a hash of the RGB color given by R, G, and B. */
6719 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
6721 /* The color hash table. */
6723 struct ct_color
**ct_table
;
6725 /* Number of entries in the color table. */
6727 int ct_colors_allocated
;
6729 /* Initialize the color table. */
6734 int size
= CT_SIZE
* sizeof (*ct_table
);
6735 ct_table
= (struct ct_color
**) xmalloc (size
);
6736 bzero (ct_table
, size
);
6737 ct_colors_allocated
= 0;
6741 /* Free memory associated with the color table. */
6747 struct ct_color
*p
, *next
;
6749 for (i
= 0; i
< CT_SIZE
; ++i
)
6750 for (p
= ct_table
[i
]; p
; p
= next
)
6761 /* Value is a pixel color for RGB color R, G, B on frame F. If an
6762 entry for that color already is in the color table, return the
6763 pixel color of that entry. Otherwise, allocate a new color for R,
6764 G, B, and make an entry in the color table. */
6766 static unsigned long
6767 lookup_rgb_color (f
, r
, g
, b
)
6771 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
6772 int i
= hash
% CT_SIZE
;
6774 struct x_display_info
*dpyinfo
;
6776 /* Handle TrueColor visuals specially, which improves performance by
6777 two orders of magnitude. Freeing colors on TrueColor visuals is
6778 a nop, and pixel colors specify RGB values directly. See also
6779 the Xlib spec, chapter 3.1. */
6780 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6781 if (dpyinfo
->red_bits
> 0)
6783 unsigned long pr
, pg
, pb
;
6785 /* Apply gamma-correction like normal color allocation does. */
6789 color
.red
= r
, color
.green
= g
, color
.blue
= b
;
6790 gamma_correct (f
, &color
);
6791 r
= color
.red
, g
= color
.green
, b
= color
.blue
;
6794 /* Scale down RGB values to the visual's bits per RGB, and shift
6795 them to the right position in the pixel color. Note that the
6796 original RGB values are 16-bit values, as usual in X. */
6797 pr
= (r
>> (16 - dpyinfo
->red_bits
)) << dpyinfo
->red_offset
;
6798 pg
= (g
>> (16 - dpyinfo
->green_bits
)) << dpyinfo
->green_offset
;
6799 pb
= (b
>> (16 - dpyinfo
->blue_bits
)) << dpyinfo
->blue_offset
;
6801 /* Assemble the pixel color. */
6802 return pr
| pg
| pb
;
6805 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6806 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
6819 cmap
= FRAME_X_COLORMAP (f
);
6820 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6824 ++ct_colors_allocated
;
6826 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6830 p
->pixel
= color
.pixel
;
6831 p
->next
= ct_table
[i
];
6835 return FRAME_FOREGROUND_PIXEL (f
);
6842 /* Look up pixel color PIXEL which is used on frame F in the color
6843 table. If not already present, allocate it. Value is PIXEL. */
6845 static unsigned long
6846 lookup_pixel_color (f
, pixel
)
6848 unsigned long pixel
;
6850 int i
= pixel
% CT_SIZE
;
6853 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6854 if (p
->pixel
== pixel
)
6863 cmap
= FRAME_X_COLORMAP (f
);
6864 color
.pixel
= pixel
;
6865 x_query_color (f
, &color
);
6866 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6870 ++ct_colors_allocated
;
6872 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6877 p
->next
= ct_table
[i
];
6881 return FRAME_FOREGROUND_PIXEL (f
);
6888 /* Value is a vector of all pixel colors contained in the color table,
6889 allocated via xmalloc. Set *N to the number of colors. */
6891 static unsigned long *
6892 colors_in_color_table (n
)
6897 unsigned long *colors
;
6899 if (ct_colors_allocated
== 0)
6906 colors
= (unsigned long *) xmalloc (ct_colors_allocated
6908 *n
= ct_colors_allocated
;
6910 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
6911 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6912 colors
[j
++] = p
->pixel
;
6920 /***********************************************************************
6922 ***********************************************************************/
6924 static XColor
*x_to_xcolors
P_ ((struct frame
*, struct image
*, int));
6925 static void x_from_xcolors
P_ ((struct frame
*, struct image
*, XColor
*));
6926 static void x_detect_edges
P_ ((struct frame
*, struct image
*, int[9], int));
6928 /* Non-zero means draw a cross on images having `:conversion
6931 int cross_disabled_images
;
6933 /* Edge detection matrices for different edge-detection
6936 static int emboss_matrix
[9] = {
6938 2, -1, 0, /* y - 1 */
6940 0, 1, -2 /* y + 1 */
6943 static int laplace_matrix
[9] = {
6945 1, 0, 0, /* y - 1 */
6947 0, 0, -1 /* y + 1 */
6950 /* Value is the intensity of the color whose red/green/blue values
6953 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
6956 /* On frame F, return an array of XColor structures describing image
6957 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
6958 non-zero means also fill the red/green/blue members of the XColor
6959 structures. Value is a pointer to the array of XColors structures,
6960 allocated with xmalloc; it must be freed by the caller. */
6963 x_to_xcolors (f
, img
, rgb_p
)
6972 colors
= (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *colors
);
6974 /* Get the X image IMG->pixmap. */
6975 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
6976 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
6978 /* Fill the `pixel' members of the XColor array. I wished there
6979 were an easy and portable way to circumvent XGetPixel. */
6981 for (y
= 0; y
< img
->height
; ++y
)
6985 for (x
= 0; x
< img
->width
; ++x
, ++p
)
6986 p
->pixel
= XGetPixel (ximg
, x
, y
);
6989 x_query_colors (f
, row
, img
->width
);
6992 XDestroyImage (ximg
);
6997 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
6998 RGB members are set. F is the frame on which this all happens.
6999 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
7002 x_from_xcolors (f
, img
, colors
)
7012 init_color_table ();
7014 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
7017 for (y
= 0; y
< img
->height
; ++y
)
7018 for (x
= 0; x
< img
->width
; ++x
, ++p
)
7020 unsigned long pixel
;
7021 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
7022 XPutPixel (oimg
, x
, y
, pixel
);
7026 x_clear_image_1 (f
, img
, 1, 0, 1);
7028 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
7029 x_destroy_x_image (oimg
);
7030 img
->pixmap
= pixmap
;
7031 img
->colors
= colors_in_color_table (&img
->ncolors
);
7032 free_color_table ();
7036 /* On frame F, perform edge-detection on image IMG.
7038 MATRIX is a nine-element array specifying the transformation
7039 matrix. See emboss_matrix for an example.
7041 COLOR_ADJUST is a color adjustment added to each pixel of the
7045 x_detect_edges (f
, img
, matrix
, color_adjust
)
7048 int matrix
[9], color_adjust
;
7050 XColor
*colors
= x_to_xcolors (f
, img
, 1);
7054 for (i
= sum
= 0; i
< 9; ++i
)
7055 sum
+= abs (matrix
[i
]);
7057 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
7059 new = (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *new);
7061 for (y
= 0; y
< img
->height
; ++y
)
7063 p
= COLOR (new, 0, y
);
7064 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7065 p
= COLOR (new, img
->width
- 1, y
);
7066 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7069 for (x
= 1; x
< img
->width
- 1; ++x
)
7071 p
= COLOR (new, x
, 0);
7072 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7073 p
= COLOR (new, x
, img
->height
- 1);
7074 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7077 for (y
= 1; y
< img
->height
- 1; ++y
)
7079 p
= COLOR (new, 1, y
);
7081 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
7083 int r
, g
, b
, y1
, x1
;
7086 for (y1
= y
- 1; y1
< y
+ 2; ++y1
)
7087 for (x1
= x
- 1; x1
< x
+ 2; ++x1
, ++i
)
7090 XColor
*t
= COLOR (colors
, x1
, y1
);
7091 r
+= matrix
[i
] * t
->red
;
7092 g
+= matrix
[i
] * t
->green
;
7093 b
+= matrix
[i
] * t
->blue
;
7096 r
= (r
/ sum
+ color_adjust
) & 0xffff;
7097 g
= (g
/ sum
+ color_adjust
) & 0xffff;
7098 b
= (b
/ sum
+ color_adjust
) & 0xffff;
7099 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
7104 x_from_xcolors (f
, img
, new);
7110 /* Perform the pre-defined `emboss' edge-detection on image IMG
7118 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
7122 /* Perform the pre-defined `laplace' edge-detection on image IMG
7130 x_detect_edges (f
, img
, laplace_matrix
, 45000);
7134 /* Perform edge-detection on image IMG on frame F, with specified
7135 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
7137 MATRIX must be either
7139 - a list of at least 9 numbers in row-major form
7140 - a vector of at least 9 numbers
7142 COLOR_ADJUST nil means use a default; otherwise it must be a
7146 x_edge_detection (f
, img
, matrix
, color_adjust
)
7149 Lisp_Object matrix
, color_adjust
;
7157 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
7158 ++i
, matrix
= XCDR (matrix
))
7159 trans
[i
] = XFLOATINT (XCAR (matrix
));
7161 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
7163 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
7164 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
7167 if (NILP (color_adjust
))
7168 color_adjust
= make_number (0xffff / 2);
7170 if (i
== 9 && NUMBERP (color_adjust
))
7171 x_detect_edges (f
, img
, trans
, (int) XFLOATINT (color_adjust
));
7175 /* Transform image IMG on frame F so that it looks disabled. */
7178 x_disable_image (f
, img
)
7182 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7184 if (dpyinfo
->n_planes
>= 2)
7186 /* Color (or grayscale). Convert to gray, and equalize. Just
7187 drawing such images with a stipple can look very odd, so
7188 we're using this method instead. */
7189 XColor
*colors
= x_to_xcolors (f
, img
, 1);
7191 const int h
= 15000;
7192 const int l
= 30000;
7194 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
7198 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
7199 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
7200 p
->red
= p
->green
= p
->blue
= i2
;
7203 x_from_xcolors (f
, img
, colors
);
7206 /* Draw a cross over the disabled image, if we must or if we
7208 if (dpyinfo
->n_planes
< 2 || cross_disabled_images
)
7210 Display
*dpy
= FRAME_X_DISPLAY (f
);
7213 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
7214 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
7215 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
7216 img
->width
- 1, img
->height
- 1);
7217 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
7223 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
7224 XSetForeground (dpy
, gc
, WHITE_PIX_DEFAULT (f
));
7225 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
7226 img
->width
- 1, img
->height
- 1);
7227 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
7235 /* Build a mask for image IMG which is used on frame F. FILE is the
7236 name of an image file, for error messages. HOW determines how to
7237 determine the background color of IMG. If it is a list '(R G B)',
7238 with R, G, and B being integers >= 0, take that as the color of the
7239 background. Otherwise, determine the background color of IMG
7240 heuristically. Value is non-zero if successful. */
7243 x_build_heuristic_mask (f
, img
, how
)
7248 Display
*dpy
= FRAME_X_DISPLAY (f
);
7249 XImage
*ximg
, *mask_img
;
7250 int x
, y
, rc
, use_img_background
;
7251 unsigned long bg
= 0;
7255 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
7257 img
->background_transparent_valid
= 0;
7260 /* Create an image and pixmap serving as mask. */
7261 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
7262 &mask_img
, &img
->mask
);
7266 /* Get the X image of IMG->pixmap. */
7267 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
7270 /* Determine the background color of ximg. If HOW is `(R G B)'
7271 take that as color. Otherwise, use the image's background color. */
7272 use_img_background
= 1;
7278 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
7280 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
7284 if (i
== 3 && NILP (how
))
7286 char color_name
[30];
7287 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
7288 bg
= x_alloc_image_color (f
, img
, build_string (color_name
), 0);
7289 use_img_background
= 0;
7293 if (use_img_background
)
7294 bg
= four_corners_best (ximg
, img
->width
, img
->height
);
7296 /* Set all bits in mask_img to 1 whose color in ximg is different
7297 from the background color bg. */
7298 for (y
= 0; y
< img
->height
; ++y
)
7299 for (x
= 0; x
< img
->width
; ++x
)
7300 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
7302 /* Fill in the background_transparent field while we have the mask handy. */
7303 image_background_transparent (img
, f
, mask_img
);
7305 /* Put mask_img into img->mask. */
7306 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
7307 x_destroy_x_image (mask_img
);
7308 XDestroyImage (ximg
);
7315 /***********************************************************************
7316 PBM (mono, gray, color)
7317 ***********************************************************************/
7319 static int pbm_image_p
P_ ((Lisp_Object object
));
7320 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
7321 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
7323 /* The symbol `pbm' identifying images of this type. */
7327 /* Indices of image specification fields in gs_format, below. */
7329 enum pbm_keyword_index
7345 /* Vector of image_keyword structures describing the format
7346 of valid user-defined image specifications. */
7348 static struct image_keyword pbm_format
[PBM_LAST
] =
7350 {":type", IMAGE_SYMBOL_VALUE
, 1},
7351 {":file", IMAGE_STRING_VALUE
, 0},
7352 {":data", IMAGE_STRING_VALUE
, 0},
7353 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7354 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7355 {":relief", IMAGE_INTEGER_VALUE
, 0},
7356 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7357 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7358 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7359 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
7360 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7363 /* Structure describing the image type `pbm'. */
7365 static struct image_type pbm_type
=
7375 /* Return non-zero if OBJECT is a valid PBM image specification. */
7378 pbm_image_p (object
)
7381 struct image_keyword fmt
[PBM_LAST
];
7383 bcopy (pbm_format
, fmt
, sizeof fmt
);
7385 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
7388 /* Must specify either :data or :file. */
7389 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
7393 /* Scan a decimal number from *S and return it. Advance *S while
7394 reading the number. END is the end of the string. Value is -1 at
7398 pbm_scan_number (s
, end
)
7399 unsigned char **s
, *end
;
7401 int c
= 0, val
= -1;
7405 /* Skip white-space. */
7406 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
7411 /* Skip comment to end of line. */
7412 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
7415 else if (isdigit (c
))
7417 /* Read decimal number. */
7419 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
7420 val
= 10 * val
+ c
- '0';
7431 /* Load PBM image IMG for use on frame F. */
7439 int width
, height
, max_color_idx
= 0;
7441 Lisp_Object file
, specified_file
;
7442 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
7443 struct gcpro gcpro1
;
7444 unsigned char *contents
= NULL
;
7445 unsigned char *end
, *p
;
7448 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7452 if (STRINGP (specified_file
))
7454 file
= x_find_image_file (specified_file
);
7455 if (!STRINGP (file
))
7457 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7462 contents
= slurp_file (SDATA (file
), &size
);
7463 if (contents
== NULL
)
7465 image_error ("Error reading `%s'", file
, Qnil
);
7471 end
= contents
+ size
;
7476 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7478 end
= p
+ SBYTES (data
);
7481 /* Check magic number. */
7482 if (end
- p
< 2 || *p
++ != 'P')
7484 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7494 raw_p
= 0, type
= PBM_MONO
;
7498 raw_p
= 0, type
= PBM_GRAY
;
7502 raw_p
= 0, type
= PBM_COLOR
;
7506 raw_p
= 1, type
= PBM_MONO
;
7510 raw_p
= 1, type
= PBM_GRAY
;
7514 raw_p
= 1, type
= PBM_COLOR
;
7518 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7522 /* Read width, height, maximum color-component. Characters
7523 starting with `#' up to the end of a line are ignored. */
7524 width
= pbm_scan_number (&p
, end
);
7525 height
= pbm_scan_number (&p
, end
);
7527 if (type
!= PBM_MONO
)
7529 max_color_idx
= pbm_scan_number (&p
, end
);
7530 if (raw_p
&& max_color_idx
> 255)
7531 max_color_idx
= 255;
7536 || (type
!= PBM_MONO
&& max_color_idx
< 0))
7539 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7540 &ximg
, &img
->pixmap
))
7543 /* Initialize the color hash table. */
7544 init_color_table ();
7546 if (type
== PBM_MONO
)
7549 struct image_keyword fmt
[PBM_LAST
];
7550 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
7551 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
7553 /* Parse the image specification. */
7554 bcopy (pbm_format
, fmt
, sizeof fmt
);
7555 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
7557 /* Get foreground and background colors, maybe allocate colors. */
7558 if (fmt
[PBM_FOREGROUND
].count
7559 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
7560 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
7561 if (fmt
[PBM_BACKGROUND
].count
7562 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
7564 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
7565 img
->background
= bg
;
7566 img
->background_valid
= 1;
7569 for (y
= 0; y
< height
; ++y
)
7570 for (x
= 0; x
< width
; ++x
)
7580 g
= pbm_scan_number (&p
, end
);
7582 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
7587 for (y
= 0; y
< height
; ++y
)
7588 for (x
= 0; x
< width
; ++x
)
7592 if (type
== PBM_GRAY
)
7593 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
7602 r
= pbm_scan_number (&p
, end
);
7603 g
= pbm_scan_number (&p
, end
);
7604 b
= pbm_scan_number (&p
, end
);
7607 if (r
< 0 || g
< 0 || b
< 0)
7611 XDestroyImage (ximg
);
7612 image_error ("Invalid pixel value in image `%s'",
7617 /* RGB values are now in the range 0..max_color_idx.
7618 Scale this to the range 0..0xffff supported by X. */
7619 r
= (double) r
* 65535 / max_color_idx
;
7620 g
= (double) g
* 65535 / max_color_idx
;
7621 b
= (double) b
* 65535 / max_color_idx
;
7622 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7626 /* Store in IMG->colors the colors allocated for the image, and
7627 free the color table. */
7628 img
->colors
= colors_in_color_table (&img
->ncolors
);
7629 free_color_table ();
7631 /* Maybe fill in the background field while we have ximg handy. */
7632 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7633 IMAGE_BACKGROUND (img
, f
, ximg
);
7635 /* Put the image into a pixmap. */
7636 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7637 x_destroy_x_image (ximg
);
7640 img
->height
= height
;
7649 /***********************************************************************
7651 ***********************************************************************/
7655 #if defined HAVE_LIBPNG_PNG_H
7656 # include <libpng/png.h>
7661 /* Function prototypes. */
7663 static int png_image_p
P_ ((Lisp_Object object
));
7664 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
7666 /* The symbol `png' identifying images of this type. */
7670 /* Indices of image specification fields in png_format, below. */
7672 enum png_keyword_index
7687 /* Vector of image_keyword structures describing the format
7688 of valid user-defined image specifications. */
7690 static struct image_keyword png_format
[PNG_LAST
] =
7692 {":type", IMAGE_SYMBOL_VALUE
, 1},
7693 {":data", IMAGE_STRING_VALUE
, 0},
7694 {":file", IMAGE_STRING_VALUE
, 0},
7695 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7696 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7697 {":relief", IMAGE_INTEGER_VALUE
, 0},
7698 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7699 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7700 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7701 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7704 /* Structure describing the image type `png'. */
7706 static struct image_type png_type
=
7716 /* Return non-zero if OBJECT is a valid PNG image specification. */
7719 png_image_p (object
)
7722 struct image_keyword fmt
[PNG_LAST
];
7723 bcopy (png_format
, fmt
, sizeof fmt
);
7725 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
7728 /* Must specify either the :data or :file keyword. */
7729 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
7733 /* Error and warning handlers installed when the PNG library
7737 my_png_error (png_ptr
, msg
)
7738 png_struct
*png_ptr
;
7741 xassert (png_ptr
!= NULL
);
7742 image_error ("PNG error: %s", build_string (msg
), Qnil
);
7743 longjmp (png_ptr
->jmpbuf
, 1);
7748 my_png_warning (png_ptr
, msg
)
7749 png_struct
*png_ptr
;
7752 xassert (png_ptr
!= NULL
);
7753 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
7756 /* Memory source for PNG decoding. */
7758 struct png_memory_storage
7760 unsigned char *bytes
; /* The data */
7761 size_t len
; /* How big is it? */
7762 int index
; /* Where are we? */
7766 /* Function set as reader function when reading PNG image from memory.
7767 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
7768 bytes from the input to DATA. */
7771 png_read_from_memory (png_ptr
, data
, length
)
7772 png_structp png_ptr
;
7776 struct png_memory_storage
*tbr
7777 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
7779 if (length
> tbr
->len
- tbr
->index
)
7780 png_error (png_ptr
, "Read error");
7782 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
7783 tbr
->index
= tbr
->index
+ length
;
7786 /* Load PNG image IMG for use on frame F. Value is non-zero if
7794 Lisp_Object file
, specified_file
;
7795 Lisp_Object specified_data
;
7797 XImage
*ximg
, *mask_img
= NULL
;
7798 struct gcpro gcpro1
;
7799 png_struct
*png_ptr
= NULL
;
7800 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
7801 FILE *volatile fp
= NULL
;
7803 png_byte
* volatile pixels
= NULL
;
7804 png_byte
** volatile rows
= NULL
;
7805 png_uint_32 width
, height
;
7806 int bit_depth
, color_type
, interlace_type
;
7808 png_uint_32 row_bytes
;
7810 double screen_gamma
;
7811 struct png_memory_storage tbr
; /* Data to be read */
7813 /* Find out what file to load. */
7814 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7815 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7819 if (NILP (specified_data
))
7821 file
= x_find_image_file (specified_file
);
7822 if (!STRINGP (file
))
7824 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7829 /* Open the image file. */
7830 fp
= fopen (SDATA (file
), "rb");
7833 image_error ("Cannot open image file `%s'", file
, Qnil
);
7839 /* Check PNG signature. */
7840 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
7841 || !png_check_sig (sig
, sizeof sig
))
7843 image_error ("Not a PNG file: `%s'", file
, Qnil
);
7851 /* Read from memory. */
7852 tbr
.bytes
= SDATA (specified_data
);
7853 tbr
.len
= SBYTES (specified_data
);
7856 /* Check PNG signature. */
7857 if (tbr
.len
< sizeof sig
7858 || !png_check_sig (tbr
.bytes
, sizeof sig
))
7860 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
7865 /* Need to skip past the signature. */
7866 tbr
.bytes
+= sizeof (sig
);
7869 /* Initialize read and info structs for PNG lib. */
7870 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
7871 my_png_error
, my_png_warning
);
7874 if (fp
) fclose (fp
);
7879 info_ptr
= png_create_info_struct (png_ptr
);
7882 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
7883 if (fp
) fclose (fp
);
7888 end_info
= png_create_info_struct (png_ptr
);
7891 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
7892 if (fp
) fclose (fp
);
7897 /* Set error jump-back. We come back here when the PNG library
7898 detects an error. */
7899 if (setjmp (png_ptr
->jmpbuf
))
7903 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7906 if (fp
) fclose (fp
);
7911 /* Read image info. */
7912 if (!NILP (specified_data
))
7913 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
7915 png_init_io (png_ptr
, fp
);
7917 png_set_sig_bytes (png_ptr
, sizeof sig
);
7918 png_read_info (png_ptr
, info_ptr
);
7919 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
7920 &interlace_type
, NULL
, NULL
);
7922 /* If image contains simply transparency data, we prefer to
7923 construct a clipping mask. */
7924 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
7929 /* This function is easier to write if we only have to handle
7930 one data format: RGB or RGBA with 8 bits per channel. Let's
7931 transform other formats into that format. */
7933 /* Strip more than 8 bits per channel. */
7934 if (bit_depth
== 16)
7935 png_set_strip_16 (png_ptr
);
7937 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
7939 png_set_expand (png_ptr
);
7941 /* Convert grayscale images to RGB. */
7942 if (color_type
== PNG_COLOR_TYPE_GRAY
7943 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
7944 png_set_gray_to_rgb (png_ptr
);
7946 screen_gamma
= (f
->gamma
? 1 / f
->gamma
/ 0.45455 : 2.2);
7948 #if 0 /* Avoid double gamma correction for PNG images. */
7949 { /* Tell the PNG lib to handle gamma correction for us. */
7952 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
7953 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
7954 /* The libpng documentation says this is right in this case. */
7955 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7958 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
7959 /* Image contains gamma information. */
7960 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
7962 /* Use the standard default for the image gamma. */
7963 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7967 /* Handle alpha channel by combining the image with a background
7968 color. Do this only if a real alpha channel is supplied. For
7969 simple transparency, we prefer a clipping mask. */
7972 png_color_16
*image_bg
;
7973 Lisp_Object specified_bg
7974 = image_spec_value (img
->spec
, QCbackground
, NULL
);
7976 if (STRINGP (specified_bg
))
7977 /* The user specified `:background', use that. */
7980 if (x_defined_color (f
, SDATA (specified_bg
), &color
, 0))
7982 png_color_16 user_bg
;
7984 bzero (&user_bg
, sizeof user_bg
);
7985 user_bg
.red
= color
.red
;
7986 user_bg
.green
= color
.green
;
7987 user_bg
.blue
= color
.blue
;
7989 png_set_background (png_ptr
, &user_bg
,
7990 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7993 else if (png_get_bKGD (png_ptr
, info_ptr
, &image_bg
))
7994 /* Image contains a background color with which to
7995 combine the image. */
7996 png_set_background (png_ptr
, image_bg
,
7997 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
8000 /* Image does not contain a background color with which
8001 to combine the image data via an alpha channel. Use
8002 the frame's background instead. */
8005 png_color_16 frame_background
;
8007 cmap
= FRAME_X_COLORMAP (f
);
8008 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
8009 x_query_color (f
, &color
);
8011 bzero (&frame_background
, sizeof frame_background
);
8012 frame_background
.red
= color
.red
;
8013 frame_background
.green
= color
.green
;
8014 frame_background
.blue
= color
.blue
;
8016 png_set_background (png_ptr
, &frame_background
,
8017 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
8021 /* Update info structure. */
8022 png_read_update_info (png_ptr
, info_ptr
);
8024 /* Get number of channels. Valid values are 1 for grayscale images
8025 and images with a palette, 2 for grayscale images with transparency
8026 information (alpha channel), 3 for RGB images, and 4 for RGB
8027 images with alpha channel, i.e. RGBA. If conversions above were
8028 sufficient we should only have 3 or 4 channels here. */
8029 channels
= png_get_channels (png_ptr
, info_ptr
);
8030 xassert (channels
== 3 || channels
== 4);
8032 /* Number of bytes needed for one row of the image. */
8033 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
8035 /* Allocate memory for the image. */
8036 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
8037 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
8038 for (i
= 0; i
< height
; ++i
)
8039 rows
[i
] = pixels
+ i
* row_bytes
;
8041 /* Read the entire image. */
8042 png_read_image (png_ptr
, rows
);
8043 png_read_end (png_ptr
, info_ptr
);
8050 /* Create the X image and pixmap. */
8051 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
8055 /* Create an image and pixmap serving as mask if the PNG image
8056 contains an alpha channel. */
8059 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
8060 &mask_img
, &img
->mask
))
8062 x_destroy_x_image (ximg
);
8063 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
8068 /* Fill the X image and mask from PNG data. */
8069 init_color_table ();
8071 for (y
= 0; y
< height
; ++y
)
8073 png_byte
*p
= rows
[y
];
8075 for (x
= 0; x
< width
; ++x
)
8082 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
8084 /* An alpha channel, aka mask channel, associates variable
8085 transparency with an image. Where other image formats
8086 support binary transparency---fully transparent or fully
8087 opaque---PNG allows up to 254 levels of partial transparency.
8088 The PNG library implements partial transparency by combining
8089 the image with a specified background color.
8091 I'm not sure how to handle this here nicely: because the
8092 background on which the image is displayed may change, for
8093 real alpha channel support, it would be necessary to create
8094 a new image for each possible background.
8096 What I'm doing now is that a mask is created if we have
8097 boolean transparency information. Otherwise I'm using
8098 the frame's background color to combine the image with. */
8103 XPutPixel (mask_img
, x
, y
, *p
> 0);
8109 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8110 /* Set IMG's background color from the PNG image, unless the user
8114 if (png_get_bKGD (png_ptr
, info_ptr
, &bg
))
8116 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
8117 img
->background_valid
= 1;
8121 /* Remember colors allocated for this image. */
8122 img
->colors
= colors_in_color_table (&img
->ncolors
);
8123 free_color_table ();
8126 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
8131 img
->height
= height
;
8133 /* Maybe fill in the background field while we have ximg handy. */
8134 IMAGE_BACKGROUND (img
, f
, ximg
);
8136 /* Put the image into the pixmap, then free the X image and its buffer. */
8137 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8138 x_destroy_x_image (ximg
);
8140 /* Same for the mask. */
8143 /* Fill in the background_transparent field while we have the mask
8145 image_background_transparent (img
, f
, mask_img
);
8147 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
8148 x_destroy_x_image (mask_img
);
8155 #endif /* HAVE_PNG != 0 */
8159 /***********************************************************************
8161 ***********************************************************************/
8165 /* Work around a warning about HAVE_STDLIB_H being redefined in
8167 #ifdef HAVE_STDLIB_H
8168 #define HAVE_STDLIB_H_1
8169 #undef HAVE_STDLIB_H
8170 #endif /* HAVE_STLIB_H */
8172 #include <jpeglib.h>
8176 #ifdef HAVE_STLIB_H_1
8177 #define HAVE_STDLIB_H 1
8180 static int jpeg_image_p
P_ ((Lisp_Object object
));
8181 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
8183 /* The symbol `jpeg' identifying images of this type. */
8187 /* Indices of image specification fields in gs_format, below. */
8189 enum jpeg_keyword_index
8198 JPEG_HEURISTIC_MASK
,
8204 /* Vector of image_keyword structures describing the format
8205 of valid user-defined image specifications. */
8207 static struct image_keyword jpeg_format
[JPEG_LAST
] =
8209 {":type", IMAGE_SYMBOL_VALUE
, 1},
8210 {":data", IMAGE_STRING_VALUE
, 0},
8211 {":file", IMAGE_STRING_VALUE
, 0},
8212 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8213 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8214 {":relief", IMAGE_INTEGER_VALUE
, 0},
8215 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8216 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8217 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8218 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8221 /* Structure describing the image type `jpeg'. */
8223 static struct image_type jpeg_type
=
8233 /* Return non-zero if OBJECT is a valid JPEG image specification. */
8236 jpeg_image_p (object
)
8239 struct image_keyword fmt
[JPEG_LAST
];
8241 bcopy (jpeg_format
, fmt
, sizeof fmt
);
8243 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
8246 /* Must specify either the :data or :file keyword. */
8247 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
8251 struct my_jpeg_error_mgr
8253 struct jpeg_error_mgr pub
;
8254 jmp_buf setjmp_buffer
;
8259 my_error_exit (cinfo
)
8262 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
8263 longjmp (mgr
->setjmp_buffer
, 1);
8267 /* Init source method for JPEG data source manager. Called by
8268 jpeg_read_header() before any data is actually read. See
8269 libjpeg.doc from the JPEG lib distribution. */
8272 our_init_source (cinfo
)
8273 j_decompress_ptr cinfo
;
8278 /* Fill input buffer method for JPEG data source manager. Called
8279 whenever more data is needed. We read the whole image in one step,
8280 so this only adds a fake end of input marker at the end. */
8283 our_fill_input_buffer (cinfo
)
8284 j_decompress_ptr cinfo
;
8286 /* Insert a fake EOI marker. */
8287 struct jpeg_source_mgr
*src
= cinfo
->src
;
8288 static JOCTET buffer
[2];
8290 buffer
[0] = (JOCTET
) 0xFF;
8291 buffer
[1] = (JOCTET
) JPEG_EOI
;
8293 src
->next_input_byte
= buffer
;
8294 src
->bytes_in_buffer
= 2;
8299 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
8300 is the JPEG data source manager. */
8303 our_skip_input_data (cinfo
, num_bytes
)
8304 j_decompress_ptr cinfo
;
8307 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8311 if (num_bytes
> src
->bytes_in_buffer
)
8312 ERREXIT (cinfo
, JERR_INPUT_EOF
);
8314 src
->bytes_in_buffer
-= num_bytes
;
8315 src
->next_input_byte
+= num_bytes
;
8320 /* Method to terminate data source. Called by
8321 jpeg_finish_decompress() after all data has been processed. */
8324 our_term_source (cinfo
)
8325 j_decompress_ptr cinfo
;
8330 /* Set up the JPEG lib for reading an image from DATA which contains
8331 LEN bytes. CINFO is the decompression info structure created for
8332 reading the image. */
8335 jpeg_memory_src (cinfo
, data
, len
)
8336 j_decompress_ptr cinfo
;
8340 struct jpeg_source_mgr
*src
;
8342 if (cinfo
->src
== NULL
)
8344 /* First time for this JPEG object? */
8345 cinfo
->src
= (struct jpeg_source_mgr
*)
8346 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
8347 sizeof (struct jpeg_source_mgr
));
8348 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8349 src
->next_input_byte
= data
;
8352 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8353 src
->init_source
= our_init_source
;
8354 src
->fill_input_buffer
= our_fill_input_buffer
;
8355 src
->skip_input_data
= our_skip_input_data
;
8356 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
8357 src
->term_source
= our_term_source
;
8358 src
->bytes_in_buffer
= len
;
8359 src
->next_input_byte
= data
;
8363 /* Load image IMG for use on frame F. Patterned after example.c
8364 from the JPEG lib. */
8371 struct jpeg_decompress_struct cinfo
;
8372 struct my_jpeg_error_mgr mgr
;
8373 Lisp_Object file
, specified_file
;
8374 Lisp_Object specified_data
;
8375 FILE * volatile fp
= NULL
;
8377 int row_stride
, x
, y
;
8378 XImage
*ximg
= NULL
;
8380 unsigned long *colors
;
8382 struct gcpro gcpro1
;
8384 /* Open the JPEG file. */
8385 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8386 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8390 if (NILP (specified_data
))
8392 file
= x_find_image_file (specified_file
);
8393 if (!STRINGP (file
))
8395 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8400 fp
= fopen (SDATA (file
), "r");
8403 image_error ("Cannot open `%s'", file
, Qnil
);
8409 /* Customize libjpeg's error handling to call my_error_exit when an
8410 error is detected. This function will perform a longjmp. */
8411 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
8412 mgr
.pub
.error_exit
= my_error_exit
;
8414 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
8418 /* Called from my_error_exit. Display a JPEG error. */
8419 char buffer
[JMSG_LENGTH_MAX
];
8420 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
8421 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
8422 build_string (buffer
));
8425 /* Close the input file and destroy the JPEG object. */
8427 fclose ((FILE *) fp
);
8428 jpeg_destroy_decompress (&cinfo
);
8430 /* If we already have an XImage, free that. */
8431 x_destroy_x_image (ximg
);
8433 /* Free pixmap and colors. */
8434 x_clear_image (f
, img
);
8440 /* Create the JPEG decompression object. Let it read from fp.
8441 Read the JPEG image header. */
8442 jpeg_create_decompress (&cinfo
);
8444 if (NILP (specified_data
))
8445 jpeg_stdio_src (&cinfo
, (FILE *) fp
);
8447 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
8448 SBYTES (specified_data
));
8450 jpeg_read_header (&cinfo
, TRUE
);
8452 /* Customize decompression so that color quantization will be used.
8453 Start decompression. */
8454 cinfo
.quantize_colors
= TRUE
;
8455 jpeg_start_decompress (&cinfo
);
8456 width
= img
->width
= cinfo
.output_width
;
8457 height
= img
->height
= cinfo
.output_height
;
8459 /* Create X image and pixmap. */
8460 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8461 longjmp (mgr
.setjmp_buffer
, 2);
8463 /* Allocate colors. When color quantization is used,
8464 cinfo.actual_number_of_colors has been set with the number of
8465 colors generated, and cinfo.colormap is a two-dimensional array
8466 of color indices in the range 0..cinfo.actual_number_of_colors.
8467 No more than 255 colors will be generated. */
8471 if (cinfo
.out_color_components
> 2)
8472 ir
= 0, ig
= 1, ib
= 2;
8473 else if (cinfo
.out_color_components
> 1)
8474 ir
= 0, ig
= 1, ib
= 0;
8476 ir
= 0, ig
= 0, ib
= 0;
8478 /* Use the color table mechanism because it handles colors that
8479 cannot be allocated nicely. Such colors will be replaced with
8480 a default color, and we don't have to care about which colors
8481 can be freed safely, and which can't. */
8482 init_color_table ();
8483 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
8486 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
8488 /* Multiply RGB values with 255 because X expects RGB values
8489 in the range 0..0xffff. */
8490 int r
= cinfo
.colormap
[ir
][i
] << 8;
8491 int g
= cinfo
.colormap
[ig
][i
] << 8;
8492 int b
= cinfo
.colormap
[ib
][i
] << 8;
8493 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8496 /* Remember those colors actually allocated. */
8497 img
->colors
= colors_in_color_table (&img
->ncolors
);
8498 free_color_table ();
8502 row_stride
= width
* cinfo
.output_components
;
8503 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
8505 for (y
= 0; y
< height
; ++y
)
8507 jpeg_read_scanlines (&cinfo
, buffer
, 1);
8508 for (x
= 0; x
< cinfo
.output_width
; ++x
)
8509 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
8513 jpeg_finish_decompress (&cinfo
);
8514 jpeg_destroy_decompress (&cinfo
);
8516 fclose ((FILE *) fp
);
8518 /* Maybe fill in the background field while we have ximg handy. */
8519 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8520 IMAGE_BACKGROUND (img
, f
, ximg
);
8522 /* Put the image into the pixmap. */
8523 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8524 x_destroy_x_image (ximg
);
8529 #endif /* HAVE_JPEG */
8533 /***********************************************************************
8535 ***********************************************************************/
8541 static int tiff_image_p
P_ ((Lisp_Object object
));
8542 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
8544 /* The symbol `tiff' identifying images of this type. */
8548 /* Indices of image specification fields in tiff_format, below. */
8550 enum tiff_keyword_index
8559 TIFF_HEURISTIC_MASK
,
8565 /* Vector of image_keyword structures describing the format
8566 of valid user-defined image specifications. */
8568 static struct image_keyword tiff_format
[TIFF_LAST
] =
8570 {":type", IMAGE_SYMBOL_VALUE
, 1},
8571 {":data", IMAGE_STRING_VALUE
, 0},
8572 {":file", IMAGE_STRING_VALUE
, 0},
8573 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8574 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8575 {":relief", IMAGE_INTEGER_VALUE
, 0},
8576 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8577 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8578 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8579 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8582 /* Structure describing the image type `tiff'. */
8584 static struct image_type tiff_type
=
8594 /* Return non-zero if OBJECT is a valid TIFF image specification. */
8597 tiff_image_p (object
)
8600 struct image_keyword fmt
[TIFF_LAST
];
8601 bcopy (tiff_format
, fmt
, sizeof fmt
);
8603 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
8606 /* Must specify either the :data or :file keyword. */
8607 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
8611 /* Reading from a memory buffer for TIFF images Based on the PNG
8612 memory source, but we have to provide a lot of extra functions.
8615 We really only need to implement read and seek, but I am not
8616 convinced that the TIFF library is smart enough not to destroy
8617 itself if we only hand it the function pointers we need to
8622 unsigned char *bytes
;
8630 tiff_read_from_memory (data
, buf
, size
)
8635 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8637 if (size
> src
->len
- src
->index
)
8639 bcopy (src
->bytes
+ src
->index
, buf
, size
);
8646 tiff_write_from_memory (data
, buf
, size
)
8656 tiff_seek_in_memory (data
, off
, whence
)
8661 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8666 case SEEK_SET
: /* Go from beginning of source. */
8670 case SEEK_END
: /* Go from end of source. */
8671 idx
= src
->len
+ off
;
8674 case SEEK_CUR
: /* Go from current position. */
8675 idx
= src
->index
+ off
;
8678 default: /* Invalid `whence'. */
8682 if (idx
> src
->len
|| idx
< 0)
8691 tiff_close_memory (data
)
8700 tiff_mmap_memory (data
, pbase
, psize
)
8705 /* It is already _IN_ memory. */
8711 tiff_unmap_memory (data
, base
, size
)
8716 /* We don't need to do this. */
8721 tiff_size_of_memory (data
)
8724 return ((tiff_memory_source
*) data
)->len
;
8729 tiff_error_handler (title
, format
, ap
)
8730 const char *title
, *format
;
8736 len
= sprintf (buf
, "TIFF error: %s ", title
);
8737 vsprintf (buf
+ len
, format
, ap
);
8738 add_to_log (buf
, Qnil
, Qnil
);
8743 tiff_warning_handler (title
, format
, ap
)
8744 const char *title
, *format
;
8750 len
= sprintf (buf
, "TIFF warning: %s ", title
);
8751 vsprintf (buf
+ len
, format
, ap
);
8752 add_to_log (buf
, Qnil
, Qnil
);
8756 /* Load TIFF image IMG for use on frame F. Value is non-zero if
8764 Lisp_Object file
, specified_file
;
8765 Lisp_Object specified_data
;
8767 int width
, height
, x
, y
;
8771 struct gcpro gcpro1
;
8772 tiff_memory_source memsrc
;
8774 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8775 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8779 TIFFSetErrorHandler (tiff_error_handler
);
8780 TIFFSetWarningHandler (tiff_warning_handler
);
8782 if (NILP (specified_data
))
8784 /* Read from a file */
8785 file
= x_find_image_file (specified_file
);
8786 if (!STRINGP (file
))
8788 image_error ("Cannot find image file `%s'", file
, Qnil
);
8793 /* Try to open the image file. */
8794 tiff
= TIFFOpen (SDATA (file
), "r");
8797 image_error ("Cannot open `%s'", file
, Qnil
);
8804 /* Memory source! */
8805 memsrc
.bytes
= SDATA (specified_data
);
8806 memsrc
.len
= SBYTES (specified_data
);
8809 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
8810 (TIFFReadWriteProc
) tiff_read_from_memory
,
8811 (TIFFReadWriteProc
) tiff_write_from_memory
,
8812 tiff_seek_in_memory
,
8814 tiff_size_of_memory
,
8820 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
8826 /* Get width and height of the image, and allocate a raster buffer
8827 of width x height 32-bit values. */
8828 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
8829 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
8830 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
8832 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
8836 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
8842 /* Create the X image and pixmap. */
8843 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8850 /* Initialize the color table. */
8851 init_color_table ();
8853 /* Process the pixel raster. Origin is in the lower-left corner. */
8854 for (y
= 0; y
< height
; ++y
)
8856 uint32
*row
= buf
+ y
* width
;
8858 for (x
= 0; x
< width
; ++x
)
8860 uint32 abgr
= row
[x
];
8861 int r
= TIFFGetR (abgr
) << 8;
8862 int g
= TIFFGetG (abgr
) << 8;
8863 int b
= TIFFGetB (abgr
) << 8;
8864 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
8868 /* Remember the colors allocated for the image. Free the color table. */
8869 img
->colors
= colors_in_color_table (&img
->ncolors
);
8870 free_color_table ();
8873 img
->height
= height
;
8875 /* Maybe fill in the background field while we have ximg handy. */
8876 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8877 IMAGE_BACKGROUND (img
, f
, ximg
);
8879 /* Put the image into the pixmap, then free the X image and its buffer. */
8880 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8881 x_destroy_x_image (ximg
);
8888 #endif /* HAVE_TIFF != 0 */
8892 /***********************************************************************
8894 ***********************************************************************/
8898 #include <gif_lib.h>
8900 static int gif_image_p
P_ ((Lisp_Object object
));
8901 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
8903 /* The symbol `gif' identifying images of this type. */
8907 /* Indices of image specification fields in gif_format, below. */
8909 enum gif_keyword_index
8925 /* Vector of image_keyword structures describing the format
8926 of valid user-defined image specifications. */
8928 static struct image_keyword gif_format
[GIF_LAST
] =
8930 {":type", IMAGE_SYMBOL_VALUE
, 1},
8931 {":data", IMAGE_STRING_VALUE
, 0},
8932 {":file", IMAGE_STRING_VALUE
, 0},
8933 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8934 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8935 {":relief", IMAGE_INTEGER_VALUE
, 0},
8936 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8937 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8938 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8939 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8940 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8943 /* Structure describing the image type `gif'. */
8945 static struct image_type gif_type
=
8955 /* Return non-zero if OBJECT is a valid GIF image specification. */
8958 gif_image_p (object
)
8961 struct image_keyword fmt
[GIF_LAST
];
8962 bcopy (gif_format
, fmt
, sizeof fmt
);
8964 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
8967 /* Must specify either the :data or :file keyword. */
8968 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
8972 /* Reading a GIF image from memory
8973 Based on the PNG memory stuff to a certain extent. */
8977 unsigned char *bytes
;
8984 /* Make the current memory source available to gif_read_from_memory.
8985 It's done this way because not all versions of libungif support
8986 a UserData field in the GifFileType structure. */
8987 static gif_memory_source
*current_gif_memory_src
;
8990 gif_read_from_memory (file
, buf
, len
)
8995 gif_memory_source
*src
= current_gif_memory_src
;
8997 if (len
> src
->len
- src
->index
)
9000 bcopy (src
->bytes
+ src
->index
, buf
, len
);
9006 /* Load GIF image IMG for use on frame F. Value is non-zero if
9014 Lisp_Object file
, specified_file
;
9015 Lisp_Object specified_data
;
9016 int rc
, width
, height
, x
, y
, i
;
9018 ColorMapObject
*gif_color_map
;
9019 unsigned long pixel_colors
[256];
9021 struct gcpro gcpro1
;
9023 int ino
, image_left
, image_top
, image_width
, image_height
;
9024 gif_memory_source memsrc
;
9025 unsigned char *raster
;
9027 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
9028 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
9032 if (NILP (specified_data
))
9034 file
= x_find_image_file (specified_file
);
9035 if (!STRINGP (file
))
9037 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
9042 /* Open the GIF file. */
9043 gif
= DGifOpenFileName (SDATA (file
));
9046 image_error ("Cannot open `%s'", file
, Qnil
);
9053 /* Read from memory! */
9054 current_gif_memory_src
= &memsrc
;
9055 memsrc
.bytes
= SDATA (specified_data
);
9056 memsrc
.len
= SBYTES (specified_data
);
9059 gif
= DGifOpen (&memsrc
, gif_read_from_memory
);
9062 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
9068 /* Read entire contents. */
9069 rc
= DGifSlurp (gif
);
9070 if (rc
== GIF_ERROR
)
9072 image_error ("Error reading `%s'", img
->spec
, Qnil
);
9073 DGifCloseFile (gif
);
9078 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
9079 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
9080 if (ino
>= gif
->ImageCount
)
9082 image_error ("Invalid image number `%s' in image `%s'",
9084 DGifCloseFile (gif
);
9089 width
= img
->width
= max (gif
->SWidth
, gif
->Image
.Left
+ gif
->Image
.Width
);
9090 height
= img
->height
= max (gif
->SHeight
, gif
->Image
.Top
+ gif
->Image
.Height
);
9092 /* Create the X image and pixmap. */
9093 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
9095 DGifCloseFile (gif
);
9100 /* Allocate colors. */
9101 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
9103 gif_color_map
= gif
->SColorMap
;
9104 init_color_table ();
9105 bzero (pixel_colors
, sizeof pixel_colors
);
9107 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
9109 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
9110 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
9111 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
9112 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
9115 img
->colors
= colors_in_color_table (&img
->ncolors
);
9116 free_color_table ();
9118 /* Clear the part of the screen image that are not covered by
9119 the image from the GIF file. Full animated GIF support
9120 requires more than can be done here (see the gif89 spec,
9121 disposal methods). Let's simply assume that the part
9122 not covered by a sub-image is in the frame's background color. */
9123 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
9124 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
9125 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
9126 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
9128 for (y
= 0; y
< image_top
; ++y
)
9129 for (x
= 0; x
< width
; ++x
)
9130 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9132 for (y
= image_top
+ image_height
; y
< height
; ++y
)
9133 for (x
= 0; x
< width
; ++x
)
9134 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9136 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
9138 for (x
= 0; x
< image_left
; ++x
)
9139 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9140 for (x
= image_left
+ image_width
; x
< width
; ++x
)
9141 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9144 /* Read the GIF image into the X image. We use a local variable
9145 `raster' here because RasterBits below is a char *, and invites
9146 problems with bytes >= 0x80. */
9147 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
9149 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
9151 static int interlace_start
[] = {0, 4, 2, 1};
9152 static int interlace_increment
[] = {8, 8, 4, 2};
9154 int row
= interlace_start
[0];
9158 for (y
= 0; y
< image_height
; y
++)
9160 if (row
>= image_height
)
9162 row
= interlace_start
[++pass
];
9163 while (row
>= image_height
)
9164 row
= interlace_start
[++pass
];
9167 for (x
= 0; x
< image_width
; x
++)
9169 int i
= raster
[(y
* image_width
) + x
];
9170 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
9174 row
+= interlace_increment
[pass
];
9179 for (y
= 0; y
< image_height
; ++y
)
9180 for (x
= 0; x
< image_width
; ++x
)
9182 int i
= raster
[y
* image_width
+ x
];
9183 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
9187 DGifCloseFile (gif
);
9189 /* Maybe fill in the background field while we have ximg handy. */
9190 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
9191 IMAGE_BACKGROUND (img
, f
, ximg
);
9193 /* Put the image into the pixmap, then free the X image and its buffer. */
9194 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
9195 x_destroy_x_image (ximg
);
9201 #endif /* HAVE_GIF != 0 */
9205 /***********************************************************************
9207 ***********************************************************************/
9209 static int gs_image_p
P_ ((Lisp_Object object
));
9210 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
9211 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
9213 /* The symbol `postscript' identifying images of this type. */
9215 Lisp_Object Qpostscript
;
9217 /* Keyword symbols. */
9219 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
9221 /* Indices of image specification fields in gs_format, below. */
9223 enum gs_keyword_index
9241 /* Vector of image_keyword structures describing the format
9242 of valid user-defined image specifications. */
9244 static struct image_keyword gs_format
[GS_LAST
] =
9246 {":type", IMAGE_SYMBOL_VALUE
, 1},
9247 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9248 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9249 {":file", IMAGE_STRING_VALUE
, 1},
9250 {":loader", IMAGE_FUNCTION_VALUE
, 0},
9251 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
9252 {":ascent", IMAGE_ASCENT_VALUE
, 0},
9253 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
9254 {":relief", IMAGE_INTEGER_VALUE
, 0},
9255 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9256 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9257 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9258 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
9261 /* Structure describing the image type `ghostscript'. */
9263 static struct image_type gs_type
=
9273 /* Free X resources of Ghostscript image IMG which is used on frame F. */
9276 gs_clear_image (f
, img
)
9280 /* IMG->data.ptr_val may contain a recorded colormap. */
9281 xfree (img
->data
.ptr_val
);
9282 x_clear_image (f
, img
);
9286 /* Return non-zero if OBJECT is a valid Ghostscript image
9293 struct image_keyword fmt
[GS_LAST
];
9297 bcopy (gs_format
, fmt
, sizeof fmt
);
9299 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
9302 /* Bounding box must be a list or vector containing 4 integers. */
9303 tem
= fmt
[GS_BOUNDING_BOX
].value
;
9306 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
9307 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
9312 else if (VECTORP (tem
))
9314 if (XVECTOR (tem
)->size
!= 4)
9316 for (i
= 0; i
< 4; ++i
)
9317 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
9327 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
9336 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
9337 struct gcpro gcpro1
, gcpro2
;
9339 double in_width
, in_height
;
9340 Lisp_Object pixel_colors
= Qnil
;
9342 /* Compute pixel size of pixmap needed from the given size in the
9343 image specification. Sizes in the specification are in pt. 1 pt
9344 = 1/72 in, xdpi and ydpi are stored in the frame's X display
9346 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
9347 in_width
= XFASTINT (pt_width
) / 72.0;
9348 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
9349 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
9350 in_height
= XFASTINT (pt_height
) / 72.0;
9351 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
9353 /* Create the pixmap. */
9354 xassert (img
->pixmap
== None
);
9355 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9356 img
->width
, img
->height
,
9357 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
9361 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
9365 /* Call the loader to fill the pixmap. It returns a process object
9366 if successful. We do not record_unwind_protect here because
9367 other places in redisplay like calling window scroll functions
9368 don't either. Let the Lisp loader use `unwind-protect' instead. */
9369 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
9371 sprintf (buffer
, "%lu %lu",
9372 (unsigned long) FRAME_X_WINDOW (f
),
9373 (unsigned long) img
->pixmap
);
9374 window_and_pixmap_id
= build_string (buffer
);
9376 sprintf (buffer
, "%lu %lu",
9377 FRAME_FOREGROUND_PIXEL (f
),
9378 FRAME_BACKGROUND_PIXEL (f
));
9379 pixel_colors
= build_string (buffer
);
9381 XSETFRAME (frame
, f
);
9382 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
9384 loader
= intern ("gs-load-image");
9386 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
9387 make_number (img
->width
),
9388 make_number (img
->height
),
9389 window_and_pixmap_id
,
9392 return PROCESSP (img
->data
.lisp_val
);
9396 /* Kill the Ghostscript process that was started to fill PIXMAP on
9397 frame F. Called from XTread_socket when receiving an event
9398 telling Emacs that Ghostscript has finished drawing. */
9401 x_kill_gs_process (pixmap
, f
)
9405 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
9409 /* Find the image containing PIXMAP. */
9410 for (i
= 0; i
< c
->used
; ++i
)
9411 if (c
->images
[i
]->pixmap
== pixmap
)
9414 /* Should someone in between have cleared the image cache, for
9415 instance, give up. */
9419 /* Kill the GS process. We should have found PIXMAP in the image
9420 cache and its image should contain a process object. */
9422 xassert (PROCESSP (img
->data
.lisp_val
));
9423 Fkill_process (img
->data
.lisp_val
, Qnil
);
9424 img
->data
.lisp_val
= Qnil
;
9426 /* On displays with a mutable colormap, figure out the colors
9427 allocated for the image by looking at the pixels of an XImage for
9429 class = FRAME_X_VISUAL (f
)->class;
9430 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
9436 /* Try to get an XImage for img->pixmep. */
9437 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
9438 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
9443 /* Initialize the color table. */
9444 init_color_table ();
9446 /* For each pixel of the image, look its color up in the
9447 color table. After having done so, the color table will
9448 contain an entry for each color used by the image. */
9449 for (y
= 0; y
< img
->height
; ++y
)
9450 for (x
= 0; x
< img
->width
; ++x
)
9452 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
9453 lookup_pixel_color (f
, pixel
);
9456 /* Record colors in the image. Free color table and XImage. */
9457 img
->colors
= colors_in_color_table (&img
->ncolors
);
9458 free_color_table ();
9459 XDestroyImage (ximg
);
9461 #if 0 /* This doesn't seem to be the case. If we free the colors
9462 here, we get a BadAccess later in x_clear_image when
9463 freeing the colors. */
9464 /* We have allocated colors once, but Ghostscript has also
9465 allocated colors on behalf of us. So, to get the
9466 reference counts right, free them once. */
9468 x_free_colors (f
, img
->colors
, img
->ncolors
);
9472 image_error ("Cannot get X image of `%s'; colors will not be freed",
9478 /* Now that we have the pixmap, compute mask and transform the
9479 image if requested. */
9481 postprocess_image (f
, img
);
9487 /***********************************************************************
9489 ***********************************************************************/
9491 DEFUN ("x-change-window-property", Fx_change_window_property
,
9492 Sx_change_window_property
, 2, 6, 0,
9493 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
9494 PROP must be a string.
9495 VALUE may be a string or a list of conses, numbers and/or strings.
9496 If an element in the list is a string, it is converted to
9497 an Atom and the value of the Atom is used. If an element is a cons,
9498 it is converted to a 32 bit number where the car is the 16 top bits and the
9499 cdr is the lower 16 bits.
9500 FRAME nil or omitted means use the selected frame.
9501 If TYPE is given and non-nil, it is the name of the type of VALUE.
9502 If TYPE is not given or nil, the type is STRING.
9503 FORMAT gives the size in bits of each element if VALUE is a list.
9504 It must be one of 8, 16 or 32.
9505 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
9506 If OUTER_P is non-nil, the property is changed for the outer X window of
9507 FRAME. Default is to change on the edit X window.
9510 (prop
, value
, frame
, type
, format
, outer_p
)
9511 Lisp_Object prop
, value
, frame
, type
, format
, outer_p
;
9513 struct frame
*f
= check_x_frame (frame
);
9515 Atom target_type
= XA_STRING
;
9516 int element_format
= 8;
9517 unsigned char *data
;
9521 CHECK_STRING (prop
);
9523 if (! NILP (format
))
9525 CHECK_NUMBER (format
);
9526 element_format
= XFASTINT (format
);
9528 if (element_format
!= 8 && element_format
!= 16
9529 && element_format
!= 32)
9530 error ("FORMAT must be one of 8, 16 or 32");
9535 nelements
= x_check_property_data (value
);
9536 if (nelements
== -1)
9537 error ("Bad data in VALUE, must be number, string or cons");
9539 if (element_format
== 8)
9540 data
= (unsigned char *) xmalloc (nelements
);
9541 else if (element_format
== 16)
9542 data
= (unsigned char *) xmalloc (nelements
*2);
9544 data
= (unsigned char *) xmalloc (nelements
*4);
9546 x_fill_property_data (FRAME_X_DISPLAY (f
), value
, data
, element_format
);
9550 CHECK_STRING (value
);
9551 data
= SDATA (value
);
9552 nelements
= SCHARS (value
);
9556 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9559 CHECK_STRING (type
);
9560 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (type
), False
);
9563 if (! NILP (outer_p
)) w
= FRAME_OUTER_WINDOW (f
);
9564 else w
= FRAME_X_WINDOW (f
);
9566 XChangeProperty (FRAME_X_DISPLAY (f
), w
,
9567 prop_atom
, target_type
, element_format
, PropModeReplace
,
9570 if (CONSP (value
)) xfree (data
);
9572 /* Make sure the property is set when we return. */
9573 XFlush (FRAME_X_DISPLAY (f
));
9580 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
9581 Sx_delete_window_property
, 1, 2, 0,
9582 doc
: /* Remove window property PROP from X window of FRAME.
9583 FRAME nil or omitted means use the selected frame. Value is PROP. */)
9585 Lisp_Object prop
, frame
;
9587 struct frame
*f
= check_x_frame (frame
);
9590 CHECK_STRING (prop
);
9592 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9593 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
9595 /* Make sure the property is removed when we return. */
9596 XFlush (FRAME_X_DISPLAY (f
));
9603 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
9605 doc
: /* Value is the value of window property PROP on FRAME.
9606 If FRAME is nil or omitted, use the selected frame.
9607 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
9608 is the name of the Atom that denotes the type expected.
9609 If SOURCE is non-nil, get the property on that window instead of from
9610 FRAME. The number 0 denotes the root window.
9611 If DELETE_P is non-nil, delete the property after retreiving it.
9612 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
9614 Value is nil if FRAME hasn't a property with name PROP or if PROP has
9615 no value of TYPE. */)
9616 (prop
, frame
, type
, source
, delete_p
, vector_ret_p
)
9617 Lisp_Object prop
, frame
, type
, source
, delete_p
, vector_ret_p
;
9619 struct frame
*f
= check_x_frame (frame
);
9622 Lisp_Object prop_value
= Qnil
;
9623 char *tmp_data
= NULL
;
9625 Atom target_type
= XA_STRING
;
9627 unsigned long actual_size
, bytes_remaining
;
9628 Window target_window
= FRAME_X_WINDOW (f
);
9629 struct gcpro gcpro1
;
9631 GCPRO1 (prop_value
);
9632 CHECK_STRING (prop
);
9634 if (! NILP (source
))
9636 if (NUMBERP (source
))
9638 if (FLOATP (source
))
9639 target_window
= (Window
) XFLOAT (source
);
9641 target_window
= XFASTINT (source
);
9643 if (target_window
== 0)
9644 target_window
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
9646 else if (CONSP (source
))
9647 target_window
= cons_to_long (source
);
9653 if (strcmp ("AnyPropertyType", SDATA (type
)) == 0)
9654 target_type
= AnyPropertyType
;
9656 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (type
), False
);
9659 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9660 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
9661 prop_atom
, 0, 0, False
, target_type
,
9662 &actual_type
, &actual_format
, &actual_size
,
9663 &bytes_remaining
, (unsigned char **) &tmp_data
);
9666 int size
= bytes_remaining
;
9671 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
9672 prop_atom
, 0, bytes_remaining
,
9673 ! NILP (delete_p
), target_type
,
9674 &actual_type
, &actual_format
,
9675 &actual_size
, &bytes_remaining
,
9676 (unsigned char **) &tmp_data
);
9677 if (rc
== Success
&& tmp_data
)
9679 if (NILP (vector_ret_p
))
9680 prop_value
= make_string (tmp_data
, size
);
9682 prop_value
= x_property_data_to_lisp (f
,
9683 (unsigned char *) tmp_data
,
9689 if (tmp_data
) XFree (tmp_data
);
9699 /***********************************************************************
9701 ***********************************************************************/
9703 /* If non-null, an asynchronous timer that, when it expires, displays
9704 an hourglass cursor on all frames. */
9706 static struct atimer
*hourglass_atimer
;
9708 /* Non-zero means an hourglass cursor is currently shown. */
9710 static int hourglass_shown_p
;
9712 /* Number of seconds to wait before displaying an hourglass cursor. */
9714 static Lisp_Object Vhourglass_delay
;
9716 /* Default number of seconds to wait before displaying an hourglass
9719 #define DEFAULT_HOURGLASS_DELAY 1
9721 /* Function prototypes. */
9723 static void show_hourglass
P_ ((struct atimer
*));
9724 static void hide_hourglass
P_ ((void));
9727 /* Cancel a currently active hourglass timer, and start a new one. */
9733 int secs
, usecs
= 0;
9735 cancel_hourglass ();
9737 if (INTEGERP (Vhourglass_delay
)
9738 && XINT (Vhourglass_delay
) > 0)
9739 secs
= XFASTINT (Vhourglass_delay
);
9740 else if (FLOATP (Vhourglass_delay
)
9741 && XFLOAT_DATA (Vhourglass_delay
) > 0)
9744 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
9745 secs
= XFASTINT (tem
);
9746 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
9749 secs
= DEFAULT_HOURGLASS_DELAY
;
9751 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
9752 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
9753 show_hourglass
, NULL
);
9757 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
9763 if (hourglass_atimer
)
9765 cancel_atimer (hourglass_atimer
);
9766 hourglass_atimer
= NULL
;
9769 if (hourglass_shown_p
)
9774 /* Timer function of hourglass_atimer. TIMER is equal to
9777 Display an hourglass pointer on all frames by mapping the frames'
9778 hourglass_window. Set the hourglass_p flag in the frames'
9779 output_data.x structure to indicate that an hourglass cursor is
9780 shown on the frames. */
9783 show_hourglass (timer
)
9784 struct atimer
*timer
;
9786 /* The timer implementation will cancel this timer automatically
9787 after this function has run. Set hourglass_atimer to null
9788 so that we know the timer doesn't have to be canceled. */
9789 hourglass_atimer
= NULL
;
9791 if (!hourglass_shown_p
)
9793 Lisp_Object rest
, frame
;
9797 FOR_EACH_FRAME (rest
, frame
)
9799 struct frame
*f
= XFRAME (frame
);
9801 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
9803 Display
*dpy
= FRAME_X_DISPLAY (f
);
9805 #ifdef USE_X_TOOLKIT
9806 if (f
->output_data
.x
->widget
)
9808 if (FRAME_OUTER_WINDOW (f
))
9811 f
->output_data
.x
->hourglass_p
= 1;
9813 if (!f
->output_data
.x
->hourglass_window
)
9815 unsigned long mask
= CWCursor
;
9816 XSetWindowAttributes attrs
;
9818 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
9820 f
->output_data
.x
->hourglass_window
9821 = XCreateWindow (dpy
, FRAME_OUTER_WINDOW (f
),
9822 0, 0, 32000, 32000, 0, 0,
9828 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
9834 hourglass_shown_p
= 1;
9840 /* Hide the hourglass pointer on all frames, if it is currently
9846 if (hourglass_shown_p
)
9848 Lisp_Object rest
, frame
;
9851 FOR_EACH_FRAME (rest
, frame
)
9853 struct frame
*f
= XFRAME (frame
);
9856 /* Watch out for newly created frames. */
9857 && f
->output_data
.x
->hourglass_window
)
9859 XUnmapWindow (FRAME_X_DISPLAY (f
),
9860 f
->output_data
.x
->hourglass_window
);
9861 /* Sync here because XTread_socket looks at the
9862 hourglass_p flag that is reset to zero below. */
9863 XSync (FRAME_X_DISPLAY (f
), False
);
9864 f
->output_data
.x
->hourglass_p
= 0;
9868 hourglass_shown_p
= 0;
9875 /***********************************************************************
9877 ***********************************************************************/
9879 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
9880 Lisp_Object
, Lisp_Object
));
9881 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
9882 Lisp_Object
, int, int, int *, int *));
9884 /* The frame of a currently visible tooltip. */
9886 Lisp_Object tip_frame
;
9888 /* If non-nil, a timer started that hides the last tooltip when it
9891 Lisp_Object tip_timer
;
9894 /* If non-nil, a vector of 3 elements containing the last args
9895 with which x-show-tip was called. See there. */
9897 Lisp_Object last_show_tip_args
;
9899 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
9901 Lisp_Object Vx_max_tooltip_size
;
9905 unwind_create_tip_frame (frame
)
9908 Lisp_Object deleted
;
9910 deleted
= unwind_create_frame (frame
);
9911 if (EQ (deleted
, Qt
))
9921 /* Create a frame for a tooltip on the display described by DPYINFO.
9922 PARMS is a list of frame parameters. TEXT is the string to
9923 display in the tip frame. Value is the frame.
9925 Note that functions called here, esp. x_default_parameter can
9926 signal errors, for instance when a specified color name is
9927 undefined. We have to make sure that we're in a consistent state
9928 when this happens. */
9931 x_create_tip_frame (dpyinfo
, parms
, text
)
9932 struct x_display_info
*dpyinfo
;
9933 Lisp_Object parms
, text
;
9936 Lisp_Object frame
, tem
;
9938 long window_prompting
= 0;
9940 int count
= SPECPDL_INDEX ();
9941 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9943 int face_change_count_before
= face_change_count
;
9945 struct buffer
*old_buffer
;
9949 /* Use this general default value to start with until we know if
9950 this frame has a specified name. */
9951 Vx_resource_name
= Vinvocation_name
;
9954 kb
= dpyinfo
->kboard
;
9956 kb
= &the_only_kboard
;
9959 /* Get the name of the frame to use for resource lookup. */
9960 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
9962 && !EQ (name
, Qunbound
)
9964 error ("Invalid frame name--not a string or nil");
9965 Vx_resource_name
= name
;
9968 GCPRO3 (parms
, name
, frame
);
9970 XSETFRAME (frame
, f
);
9972 buffer
= Fget_buffer_create (build_string (" *tip*"));
9973 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
9974 old_buffer
= current_buffer
;
9975 set_buffer_internal_1 (XBUFFER (buffer
));
9976 current_buffer
->truncate_lines
= Qnil
;
9979 set_buffer_internal_1 (old_buffer
);
9981 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
9982 record_unwind_protect (unwind_create_tip_frame
, frame
);
9984 f
->display
= dpyinfo
->frame_display
;
9985 f
->display
->reference_count
++;
9987 /* By setting the output method, we're essentially saying that
9988 the frame is live, as per FRAME_LIVE_P. If we get a signal
9989 from this point on, x_destroy_window might screw up reference
9991 f
->output_method
= output_x_window
;
9992 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
9993 bzero (f
->output_data
.x
, sizeof (struct x_output
));
9994 f
->output_data
.x
->icon_bitmap
= -1;
9995 FRAME_FONTSET (f
) = -1;
9996 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
9997 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
9998 #ifdef USE_TOOLKIT_SCROLL_BARS
9999 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
10000 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
10001 #endif /* USE_TOOLKIT_SCROLL_BARS */
10002 f
->icon_name
= Qnil
;
10003 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
10005 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
10006 dpyinfo_refcount
= dpyinfo
->reference_count
;
10007 #endif /* GLYPH_DEBUG */
10008 #ifdef MULTI_KBOARD
10009 FRAME_KBOARD (f
) = kb
;
10011 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
10012 f
->output_data
.x
->explicit_parent
= 0;
10014 /* These colors will be set anyway later, but it's important
10015 to get the color reference counts right, so initialize them! */
10018 struct gcpro gcpro1
;
10020 black
= build_string ("black");
10022 f
->output_data
.x
->foreground_pixel
10023 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
10024 f
->output_data
.x
->background_pixel
10025 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
10026 f
->output_data
.x
->cursor_pixel
10027 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
10028 f
->output_data
.x
->cursor_foreground_pixel
10029 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
10030 f
->output_data
.x
->border_pixel
10031 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
10032 f
->output_data
.x
->mouse_pixel
10033 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
10037 /* Set the name; the functions to which we pass f expect the name to
10039 if (EQ (name
, Qunbound
) || NILP (name
))
10041 f
->name
= build_string (dpyinfo
->x_id_name
);
10042 f
->explicit_name
= 0;
10047 f
->explicit_name
= 1;
10048 /* use the frame's title when getting resources for this frame. */
10049 specbind (Qx_resource_name
, name
);
10052 /* Extract the window parameters from the supplied values that are
10053 needed to determine window geometry. */
10057 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
10060 /* First, try whatever font the caller has specified. */
10061 if (STRINGP (font
))
10063 tem
= Fquery_fontset (font
, Qnil
);
10065 font
= x_new_fontset (f
, SDATA (tem
));
10067 font
= x_new_font (f
, SDATA (font
));
10070 /* Try out a font which we hope has bold and italic variations. */
10071 if (!STRINGP (font
))
10072 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
10073 if (!STRINGP (font
))
10074 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
10075 if (! STRINGP (font
))
10076 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
10077 if (! STRINGP (font
))
10078 /* This was formerly the first thing tried, but it finds too many fonts
10079 and takes too long. */
10080 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
10081 /* If those didn't work, look for something which will at least work. */
10082 if (! STRINGP (font
))
10083 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
10085 if (! STRINGP (font
))
10086 font
= build_string ("fixed");
10088 x_default_parameter (f
, parms
, Qfont
, font
,
10089 "font", "Font", RES_TYPE_STRING
);
10092 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
10093 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
10095 /* This defaults to 2 in order to match xterm. We recognize either
10096 internalBorderWidth or internalBorder (which is what xterm calls
10098 if (NILP (Fassq (Qinternal_border_width
, parms
)))
10102 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
10103 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
10104 if (! EQ (value
, Qunbound
))
10105 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
10109 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
10110 "internalBorderWidth", "internalBorderWidth",
10113 /* Also do the stuff which must be set before the window exists. */
10114 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
10115 "foreground", "Foreground", RES_TYPE_STRING
);
10116 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
10117 "background", "Background", RES_TYPE_STRING
);
10118 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
10119 "pointerColor", "Foreground", RES_TYPE_STRING
);
10120 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
10121 "cursorColor", "Foreground", RES_TYPE_STRING
);
10122 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
10123 "borderColor", "BorderColor", RES_TYPE_STRING
);
10125 /* Init faces before x_default_parameter is called for scroll-bar
10126 parameters because that function calls x_set_scroll_bar_width,
10127 which calls change_frame_size, which calls Fset_window_buffer,
10128 which runs hooks, which call Fvertical_motion. At the end, we
10129 end up in init_iterator with a null face cache, which should not
10131 init_frame_faces (f
);
10133 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
10135 window_prompting
= x_figure_window_size (f
, parms
, 0);
10138 XSetWindowAttributes attrs
;
10139 unsigned long mask
;
10142 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
10143 if (DoesSaveUnders (dpyinfo
->screen
))
10144 mask
|= CWSaveUnder
;
10146 /* Window managers look at the override-redirect flag to determine
10147 whether or net to give windows a decoration (Xlib spec, chapter
10149 attrs
.override_redirect
= True
;
10150 attrs
.save_under
= True
;
10151 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
10152 /* Arrange for getting MapNotify and UnmapNotify events. */
10153 attrs
.event_mask
= StructureNotifyMask
;
10155 = FRAME_X_WINDOW (f
)
10156 = XCreateWindow (FRAME_X_DISPLAY (f
),
10157 FRAME_X_DISPLAY_INFO (f
)->root_window
,
10158 /* x, y, width, height */
10162 CopyFromParent
, InputOutput
, CopyFromParent
,
10169 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
10170 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
10171 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
10172 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
10173 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
10174 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
10176 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
10177 Change will not be effected unless different from the current
10178 FRAME_LINES (f). */
10179 width
= FRAME_COLS (f
);
10180 height
= FRAME_LINES (f
);
10181 SET_FRAME_COLS (f
, 0);
10182 FRAME_LINES (f
) = 0;
10183 change_frame_size (f
, height
, width
, 1, 0, 0);
10185 /* Add `tooltip' frame parameter's default value. */
10186 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
10187 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
10190 /* Set up faces after all frame parameters are known. This call
10191 also merges in face attributes specified for new frames.
10193 Frame parameters may be changed if .Xdefaults contains
10194 specifications for the default font. For example, if there is an
10195 `Emacs.default.attributeBackground: pink', the `background-color'
10196 attribute of the frame get's set, which let's the internal border
10197 of the tooltip frame appear in pink. Prevent this. */
10199 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
10201 /* Set tip_frame here, so that */
10203 call1 (Qface_set_after_frame_default
, frame
);
10205 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
10206 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
10210 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qwindow_system
, Qx
), Qnil
));
10216 /* It is now ok to make the frame official even if we get an error
10217 below. And the frame needs to be on Vframe_list or making it
10218 visible won't work. */
10219 Vframe_list
= Fcons (frame
, Vframe_list
);
10221 /* Now that the frame is official, it counts as a reference to
10223 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
10225 /* Setting attributes of faces of the tooltip frame from resources
10226 and similar will increment face_change_count, which leads to the
10227 clearing of all current matrices. Since this isn't necessary
10228 here, avoid it by resetting face_change_count to the value it
10229 had before we created the tip frame. */
10230 face_change_count
= face_change_count_before
;
10232 /* Discard the unwind_protect. */
10233 return unbind_to (count
, frame
);
10237 /* Compute where to display tip frame F. PARMS is the list of frame
10238 parameters for F. DX and DY are specified offsets from the current
10239 location of the mouse. WIDTH and HEIGHT are the width and height
10240 of the tooltip. Return coordinates relative to the root window of
10241 the display in *ROOT_X, and *ROOT_Y. */
10244 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
10246 Lisp_Object parms
, dx
, dy
;
10248 int *root_x
, *root_y
;
10250 Lisp_Object left
, top
;
10252 Window root
, child
;
10255 /* User-specified position? */
10256 left
= Fcdr (Fassq (Qleft
, parms
));
10257 top
= Fcdr (Fassq (Qtop
, parms
));
10259 /* Move the tooltip window where the mouse pointer is. Resize and
10261 if (!INTEGERP (left
) || !INTEGERP (top
))
10264 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
10265 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
10269 if (INTEGERP (top
))
10270 *root_y
= XINT (top
);
10271 else if (*root_y
+ XINT (dy
) - height
< 0)
10272 *root_y
-= XINT (dy
);
10276 *root_y
+= XINT (dy
);
10279 if (INTEGERP (left
))
10280 *root_x
= XINT (left
);
10281 else if (*root_x
+ XINT (dx
) + width
<= FRAME_X_DISPLAY_INFO (f
)->width
)
10282 /* It fits to the right of the pointer. */
10283 *root_x
+= XINT (dx
);
10284 else if (width
+ XINT (dx
) <= *root_x
)
10285 /* It fits to the left of the pointer. */
10286 *root_x
-= width
+ XINT (dx
);
10288 /* Put it left-justified on the screen--it ought to fit that way. */
10293 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
10294 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
10295 A tooltip window is a small X window displaying a string.
10297 FRAME nil or omitted means use the selected frame.
10299 PARMS is an optional list of frame parameters which can be used to
10300 change the tooltip's appearance.
10302 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
10303 means use the default timeout of 5 seconds.
10305 If the list of frame parameters PARAMS contains a `left' parameters,
10306 the tooltip is displayed at that x-position. Otherwise it is
10307 displayed at the mouse position, with offset DX added (default is 5 if
10308 DX isn't specified). Likewise for the y-position; if a `top' frame
10309 parameter is specified, it determines the y-position of the tooltip
10310 window, otherwise it is displayed at the mouse position, with offset
10311 DY added (default is -10).
10313 A tooltip's maximum size is specified by `x-max-tooltip-size'.
10314 Text larger than the specified size is clipped. */)
10315 (string
, frame
, parms
, timeout
, dx
, dy
)
10316 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
10320 int root_x
, root_y
;
10321 struct buffer
*old_buffer
;
10322 struct text_pos pos
;
10323 int i
, width
, height
;
10324 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
10325 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
10326 int count
= SPECPDL_INDEX ();
10328 specbind (Qinhibit_redisplay
, Qt
);
10330 GCPRO4 (string
, parms
, frame
, timeout
);
10332 CHECK_STRING (string
);
10333 f
= check_x_frame (frame
);
10334 if (NILP (timeout
))
10335 timeout
= make_number (5);
10337 CHECK_NATNUM (timeout
);
10340 dx
= make_number (5);
10345 dy
= make_number (-10);
10349 if (NILP (last_show_tip_args
))
10350 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
10352 if (!NILP (tip_frame
))
10354 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
10355 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
10356 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
10358 if (EQ (frame
, last_frame
)
10359 && !NILP (Fequal (last_string
, string
))
10360 && !NILP (Fequal (last_parms
, parms
)))
10362 struct frame
*f
= XFRAME (tip_frame
);
10364 /* Only DX and DY have changed. */
10365 if (!NILP (tip_timer
))
10367 Lisp_Object timer
= tip_timer
;
10369 call1 (Qcancel_timer
, timer
);
10373 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
10374 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
10375 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10382 /* Hide a previous tip, if any. */
10385 ASET (last_show_tip_args
, 0, string
);
10386 ASET (last_show_tip_args
, 1, frame
);
10387 ASET (last_show_tip_args
, 2, parms
);
10389 /* Add default values to frame parameters. */
10390 if (NILP (Fassq (Qname
, parms
)))
10391 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
10392 if (NILP (Fassq (Qinternal_border_width
, parms
)))
10393 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
10394 if (NILP (Fassq (Qborder_width
, parms
)))
10395 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
10396 if (NILP (Fassq (Qborder_color
, parms
)))
10397 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
10398 if (NILP (Fassq (Qbackground_color
, parms
)))
10399 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
10402 /* Create a frame for the tooltip, and record it in the global
10403 variable tip_frame. */
10404 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
10405 f
= XFRAME (frame
);
10407 /* Set up the frame's root window. */
10408 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
10409 w
->left_col
= w
->top_line
= make_number (0);
10411 if (CONSP (Vx_max_tooltip_size
)
10412 && INTEGERP (XCAR (Vx_max_tooltip_size
))
10413 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
10414 && INTEGERP (XCDR (Vx_max_tooltip_size
))
10415 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
10417 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
10418 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
10422 w
->total_cols
= make_number (80);
10423 w
->total_lines
= make_number (40);
10426 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
10428 w
->pseudo_window_p
= 1;
10430 /* Display the tooltip text in a temporary buffer. */
10431 old_buffer
= current_buffer
;
10432 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
10433 current_buffer
->truncate_lines
= Qnil
;
10434 clear_glyph_matrix (w
->desired_matrix
);
10435 clear_glyph_matrix (w
->current_matrix
);
10436 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
10437 try_window (FRAME_ROOT_WINDOW (f
), pos
);
10439 /* Compute width and height of the tooltip. */
10440 width
= height
= 0;
10441 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
10443 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
10444 struct glyph
*last
;
10447 /* Stop at the first empty row at the end. */
10448 if (!row
->enabled_p
|| !row
->displays_text_p
)
10451 /* Let the row go over the full width of the frame. */
10452 row
->full_width_p
= 1;
10454 /* There's a glyph at the end of rows that is used to place
10455 the cursor there. Don't include the width of this glyph. */
10456 if (row
->used
[TEXT_AREA
])
10458 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
10459 row_width
= row
->pixel_width
- last
->pixel_width
;
10462 row_width
= row
->pixel_width
;
10464 height
+= row
->height
;
10465 width
= max (width
, row_width
);
10468 /* Add the frame's internal border to the width and height the X
10469 window should have. */
10470 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10471 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10473 /* Move the tooltip window where the mouse pointer is. Resize and
10475 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
10478 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10479 root_x
, root_y
, width
, height
);
10480 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
10483 /* Draw into the window. */
10484 w
->must_be_updated_p
= 1;
10485 update_single_window (w
, 1);
10487 /* Restore original current buffer. */
10488 set_buffer_internal_1 (old_buffer
);
10489 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
10492 /* Let the tip disappear after timeout seconds. */
10493 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
10494 intern ("x-hide-tip"));
10497 return unbind_to (count
, Qnil
);
10501 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
10502 doc
: /* Hide the current tooltip window, if there is any.
10503 Value is t if tooltip was open, nil otherwise. */)
10507 Lisp_Object deleted
, frame
, timer
;
10508 struct gcpro gcpro1
, gcpro2
;
10510 /* Return quickly if nothing to do. */
10511 if (NILP (tip_timer
) && NILP (tip_frame
))
10516 GCPRO2 (frame
, timer
);
10517 tip_frame
= tip_timer
= deleted
= Qnil
;
10519 count
= SPECPDL_INDEX ();
10520 specbind (Qinhibit_redisplay
, Qt
);
10521 specbind (Qinhibit_quit
, Qt
);
10524 call1 (Qcancel_timer
, timer
);
10526 if (FRAMEP (frame
))
10528 Fdelete_frame (frame
, Qnil
);
10532 /* Bloodcurdling hack alert: The Lucid menu bar widget's
10533 redisplay procedure is not called when a tip frame over menu
10534 items is unmapped. Redisplay the menu manually... */
10536 struct frame
*f
= SELECTED_FRAME ();
10537 Widget w
= f
->output_data
.x
->menubar_widget
;
10538 extern void xlwmenu_redisplay
P_ ((Widget
));
10540 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
10544 xlwmenu_redisplay (w
);
10548 #endif /* USE_LUCID */
10552 return unbind_to (count
, deleted
);
10557 /***********************************************************************
10558 File selection dialog
10559 ***********************************************************************/
10563 /* Callback for "OK" and "Cancel" on file selection dialog. */
10566 file_dialog_cb (widget
, client_data
, call_data
)
10568 XtPointer call_data
, client_data
;
10570 int *result
= (int *) client_data
;
10571 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
10572 *result
= cb
->reason
;
10576 /* Callback for unmapping a file selection dialog. This is used to
10577 capture the case where a dialog is closed via a window manager's
10578 closer button, for example. Using a XmNdestroyCallback didn't work
10582 file_dialog_unmap_cb (widget
, client_data
, call_data
)
10584 XtPointer call_data
, client_data
;
10586 int *result
= (int *) client_data
;
10587 *result
= XmCR_CANCEL
;
10591 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10592 doc
: /* Read file name, prompting with PROMPT in directory DIR.
10593 Use a file selection dialog.
10594 Select DEFAULT-FILENAME in the dialog's file selection box, if
10595 specified. Don't let the user enter a file name in the file
10596 selection dialog's entry field, if MUSTMATCH is non-nil. */)
10597 (prompt
, dir
, default_filename
, mustmatch
)
10598 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10601 struct frame
*f
= SELECTED_FRAME ();
10602 Lisp_Object file
= Qnil
;
10603 Widget dialog
, text
, list
, help
;
10606 extern XtAppContext Xt_app_con
;
10607 XmString dir_xmstring
, pattern_xmstring
;
10608 int count
= SPECPDL_INDEX ();
10609 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10611 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10612 CHECK_STRING (prompt
);
10613 CHECK_STRING (dir
);
10615 /* Prevent redisplay. */
10616 specbind (Qinhibit_redisplay
, Qt
);
10620 /* Create the dialog with PROMPT as title, using DIR as initial
10621 directory and using "*" as pattern. */
10622 dir
= Fexpand_file_name (dir
, Qnil
);
10623 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
10624 pattern_xmstring
= XmStringCreateLocalized ("*");
10626 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
10627 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
10628 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
10629 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
10630 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
10631 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
10633 XmStringFree (dir_xmstring
);
10634 XmStringFree (pattern_xmstring
);
10636 /* Add callbacks for OK and Cancel. */
10637 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
10638 (XtPointer
) &result
);
10639 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
10640 (XtPointer
) &result
);
10641 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
10642 (XtPointer
) &result
);
10644 /* Disable the help button since we can't display help. */
10645 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
10646 XtSetSensitive (help
, False
);
10648 /* Mark OK button as default. */
10649 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
10650 XmNshowAsDefault
, True
, NULL
);
10652 /* If MUSTMATCH is non-nil, disable the file entry field of the
10653 dialog, so that the user must select a file from the files list
10654 box. We can't remove it because we wouldn't have a way to get at
10655 the result file name, then. */
10656 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
10657 if (!NILP (mustmatch
))
10660 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
10661 XtSetSensitive (text
, False
);
10662 XtSetSensitive (label
, False
);
10665 /* Manage the dialog, so that list boxes get filled. */
10666 XtManageChild (dialog
);
10668 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
10669 must include the path for this to work. */
10670 list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
10671 if (STRINGP (default_filename
))
10673 XmString default_xmstring
;
10677 = XmStringCreateLocalized (SDATA (default_filename
));
10679 if (!XmListItemExists (list
, default_xmstring
))
10681 /* Add a new item if DEFAULT_FILENAME is not in the list. */
10682 XmListAddItem (list
, default_xmstring
, 0);
10686 item_pos
= XmListItemPos (list
, default_xmstring
);
10687 XmStringFree (default_xmstring
);
10689 /* Select the item and scroll it into view. */
10690 XmListSelectPos (list
, item_pos
, True
);
10691 XmListSetPos (list
, item_pos
);
10694 /* Process events until the user presses Cancel or OK. */
10696 while (result
== 0)
10699 XtAppNextEvent (Xt_app_con
, &event
);
10700 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
) );
10703 /* Get the result. */
10704 if (result
== XmCR_OK
)
10709 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
10710 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
10711 XmStringFree (text
);
10712 file
= build_string (data
);
10719 XtUnmanageChild (dialog
);
10720 XtDestroyWidget (dialog
);
10724 /* Make "Cancel" equivalent to C-g. */
10726 Fsignal (Qquit
, Qnil
);
10728 return unbind_to (count
, file
);
10731 #endif /* USE_MOTIF */
10735 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10736 "Read file name, prompting with PROMPT in directory DIR.\n\
10737 Use a file selection dialog.\n\
10738 Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
10739 specified. Don't let the user enter a file name in the file\n\
10740 selection dialog's entry field, if MUSTMATCH is non-nil.")
10741 (prompt
, dir
, default_filename
, mustmatch
)
10742 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10744 FRAME_PTR f
= SELECTED_FRAME ();
10746 Lisp_Object file
= Qnil
;
10747 int count
= specpdl_ptr
- specpdl
;
10748 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10751 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10752 CHECK_STRING (prompt
);
10753 CHECK_STRING (dir
);
10755 /* Prevent redisplay. */
10756 specbind (Qinhibit_redisplay
, Qt
);
10760 if (STRINGP (default_filename
))
10761 cdef_file
= SDATA (default_filename
);
10763 cdef_file
= SDATA (dir
);
10765 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
, ! NILP (mustmatch
));
10769 file
= build_string (fn
);
10776 /* Make "Cancel" equivalent to C-g. */
10778 Fsignal (Qquit
, Qnil
);
10780 return unbind_to (count
, file
);
10783 #endif /* USE_GTK */
10786 /***********************************************************************
10788 ***********************************************************************/
10790 #ifdef HAVE_XKBGETKEYBOARD
10791 #include <X11/XKBlib.h>
10792 #include <X11/keysym.h>
10795 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
10796 Sx_backspace_delete_keys_p
, 0, 1, 0,
10797 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
10798 FRAME nil means use the selected frame.
10799 Value is t if we know that both keys are present, and are mapped to the
10800 usual X keysyms. */)
10804 #ifdef HAVE_XKBGETKEYBOARD
10806 struct frame
*f
= check_x_frame (frame
);
10807 Display
*dpy
= FRAME_X_DISPLAY (f
);
10808 Lisp_Object have_keys
;
10809 int major
, minor
, op
, event
, error
;
10813 /* Check library version in case we're dynamically linked. */
10814 major
= XkbMajorVersion
;
10815 minor
= XkbMinorVersion
;
10816 if (!XkbLibraryVersion (&major
, &minor
))
10822 /* Check that the server supports XKB. */
10823 major
= XkbMajorVersion
;
10824 minor
= XkbMinorVersion
;
10825 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
10832 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
10835 int delete_keycode
= 0, backspace_keycode
= 0, i
;
10837 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
10839 for (i
= kb
->min_key_code
;
10840 (i
< kb
->max_key_code
10841 && (delete_keycode
== 0 || backspace_keycode
== 0));
10844 /* The XKB symbolic key names can be seen most easily in
10845 the PS file generated by `xkbprint -label name
10847 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
10848 delete_keycode
= i
;
10849 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
10850 backspace_keycode
= i
;
10853 XkbFreeNames (kb
, 0, True
);
10856 XkbFreeClientMap (kb
, 0, True
);
10859 && backspace_keycode
10860 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
10861 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
10866 #else /* not HAVE_XKBGETKEYBOARD */
10868 #endif /* not HAVE_XKBGETKEYBOARD */
10873 /***********************************************************************
10875 ***********************************************************************/
10877 /* Keep this list in the same order as frame_parms in frame.c.
10878 Use 0 for unsupported frame parameters. */
10880 frame_parm_handler x_frame_parm_handlers
[] =
10884 x_set_background_color
,
10885 x_set_border_color
,
10886 x_set_border_width
,
10887 x_set_cursor_color
,
10890 x_set_foreground_color
,
10893 x_set_internal_border_width
,
10894 x_set_menu_bar_lines
,
10896 x_explicitly_set_name
,
10897 x_set_scroll_bar_width
,
10899 x_set_unsplittable
,
10900 x_set_vertical_scroll_bars
,
10902 x_set_tool_bar_lines
,
10903 x_set_scroll_bar_foreground
,
10904 x_set_scroll_bar_background
,
10905 x_set_screen_gamma
,
10906 x_set_line_spacing
,
10907 x_set_fringe_width
,
10908 x_set_fringe_width
,
10916 /* This is zero if not using X windows. */
10919 /* The section below is built by the lisp expression at the top of the file,
10920 just above where these variables are declared. */
10921 /*&&& init symbols here &&&*/
10922 Qnone
= intern ("none");
10923 staticpro (&Qnone
);
10924 Qsuppress_icon
= intern ("suppress-icon");
10925 staticpro (&Qsuppress_icon
);
10926 Qundefined_color
= intern ("undefined-color");
10927 staticpro (&Qundefined_color
);
10928 Qcenter
= intern ("center");
10929 staticpro (&Qcenter
);
10930 Qcompound_text
= intern ("compound-text");
10931 staticpro (&Qcompound_text
);
10932 Qcancel_timer
= intern ("cancel-timer");
10933 staticpro (&Qcancel_timer
);
10934 /* This is the end of symbol initialization. */
10936 /* Text property `display' should be nonsticky by default. */
10937 Vtext_property_default_nonsticky
10938 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
10941 Qlaplace
= intern ("laplace");
10942 staticpro (&Qlaplace
);
10943 Qemboss
= intern ("emboss");
10944 staticpro (&Qemboss
);
10945 Qedge_detection
= intern ("edge-detection");
10946 staticpro (&Qedge_detection
);
10947 Qheuristic
= intern ("heuristic");
10948 staticpro (&Qheuristic
);
10949 QCmatrix
= intern (":matrix");
10950 staticpro (&QCmatrix
);
10951 QCcolor_adjustment
= intern (":color-adjustment");
10952 staticpro (&QCcolor_adjustment
);
10953 QCmask
= intern (":mask");
10954 staticpro (&QCmask
);
10956 Fput (Qundefined_color
, Qerror_conditions
,
10957 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
10958 Fput (Qundefined_color
, Qerror_message
,
10959 build_string ("Undefined color"));
10961 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images
,
10962 doc
: /* Non-nil means always draw a cross over disabled images.
10963 Disabled images are those having an `:conversion disabled' property.
10964 A cross is always drawn on black & white displays. */);
10965 cross_disabled_images
= 0;
10967 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
10968 doc
: /* List of directories to search for window system bitmap files. */);
10969 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
10971 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
10972 doc
: /* The shape of the pointer when over text.
10973 Changing the value does not affect existing frames
10974 unless you set the mouse color. */);
10975 Vx_pointer_shape
= Qnil
;
10977 #if 0 /* This doesn't really do anything. */
10978 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
10979 doc
: /* The shape of the pointer when not over text.
10980 This variable takes effect when you create a new frame
10981 or when you set the mouse color. */);
10983 Vx_nontext_pointer_shape
= Qnil
;
10985 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
10986 doc
: /* The shape of the pointer when Emacs is busy.
10987 This variable takes effect when you create a new frame
10988 or when you set the mouse color. */);
10989 Vx_hourglass_pointer_shape
= Qnil
;
10991 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
10992 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
10993 display_hourglass_p
= 1;
10995 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
10996 doc
: /* *Seconds to wait before displaying an hourglass pointer.
10997 Value must be an integer or float. */);
10998 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
11000 #if 0 /* This doesn't really do anything. */
11001 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
11002 doc
: /* The shape of the pointer when over the mode line.
11003 This variable takes effect when you create a new frame
11004 or when you set the mouse color. */);
11006 Vx_mode_pointer_shape
= Qnil
;
11008 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
11009 &Vx_sensitive_text_pointer_shape
,
11010 doc
: /* The shape of the pointer when over mouse-sensitive text.
11011 This variable takes effect when you create a new frame
11012 or when you set the mouse color. */);
11013 Vx_sensitive_text_pointer_shape
= Qnil
;
11015 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
11016 &Vx_window_horizontal_drag_shape
,
11017 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
11018 This variable takes effect when you create a new frame
11019 or when you set the mouse color. */);
11020 Vx_window_horizontal_drag_shape
= Qnil
;
11022 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
11023 doc
: /* A string indicating the foreground color of the cursor box. */);
11024 Vx_cursor_fore_pixel
= Qnil
;
11026 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
11027 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
11028 Text larger than this is clipped. */);
11029 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
11031 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
11032 doc
: /* Non-nil if no X window manager is in use.
11033 Emacs doesn't try to figure this out; this is always nil
11034 unless you set it to something else. */);
11035 /* We don't have any way to find this out, so set it to nil
11036 and maybe the user would like to set it to t. */
11037 Vx_no_window_manager
= Qnil
;
11039 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
11040 &Vx_pixel_size_width_font_regexp
,
11041 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
11043 Since Emacs gets width of a font matching with this regexp from
11044 PIXEL_SIZE field of the name, font finding mechanism gets faster for
11045 such a font. This is especially effective for such large fonts as
11046 Chinese, Japanese, and Korean. */);
11047 Vx_pixel_size_width_font_regexp
= Qnil
;
11049 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
11050 doc
: /* Time after which cached images are removed from the cache.
11051 When an image has not been displayed this many seconds, remove it
11052 from the image cache. Value must be an integer or nil with nil
11053 meaning don't clear the cache. */);
11054 Vimage_cache_eviction_delay
= make_number (30 * 60);
11056 #ifdef USE_X_TOOLKIT
11057 Fprovide (intern ("x-toolkit"), Qnil
);
11059 Fprovide (intern ("motif"), Qnil
);
11061 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
11062 doc
: /* Version info for LessTif/Motif. */);
11063 Vmotif_version_string
= build_string (XmVERSION_STRING
);
11064 #endif /* USE_MOTIF */
11065 #endif /* USE_X_TOOLKIT */
11068 Fprovide (intern ("gtk"), Qnil
);
11070 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string
,
11071 doc
: /* Version info for GTK+. */);
11073 char gtk_version
[40];
11074 g_snprintf (gtk_version
, sizeof (gtk_version
), "%u.%u.%u",
11075 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
11076 Vgtk_version_string
= build_string (gtk_version
);
11078 #endif /* USE_GTK */
11080 /* X window properties. */
11081 defsubr (&Sx_change_window_property
);
11082 defsubr (&Sx_delete_window_property
);
11083 defsubr (&Sx_window_property
);
11085 defsubr (&Sxw_display_color_p
);
11086 defsubr (&Sx_display_grayscale_p
);
11087 defsubr (&Sxw_color_defined_p
);
11088 defsubr (&Sxw_color_values
);
11089 defsubr (&Sx_server_max_request_size
);
11090 defsubr (&Sx_server_vendor
);
11091 defsubr (&Sx_server_version
);
11092 defsubr (&Sx_display_pixel_width
);
11093 defsubr (&Sx_display_pixel_height
);
11094 defsubr (&Sx_display_mm_width
);
11095 defsubr (&Sx_display_mm_height
);
11096 defsubr (&Sx_display_screens
);
11097 defsubr (&Sx_display_planes
);
11098 defsubr (&Sx_display_color_cells
);
11099 defsubr (&Sx_display_visual_class
);
11100 defsubr (&Sx_display_backing_store
);
11101 defsubr (&Sx_display_save_under
);
11102 defsubr (&Sx_create_frame
);
11103 defsubr (&Sx_open_connection
);
11104 defsubr (&Sx_close_connection
);
11105 defsubr (&Sx_display_list
);
11106 defsubr (&Sx_synchronize
);
11107 defsubr (&Sx_focus_frame
);
11108 defsubr (&Sx_backspace_delete_keys_p
);
11110 /* Setting callback functions for fontset handler. */
11111 get_font_info_func
= x_get_font_info
;
11113 #if 0 /* This function pointer doesn't seem to be used anywhere.
11114 And the pointer assigned has the wrong type, anyway. */
11115 list_fonts_func
= x_list_fonts
;
11118 load_font_func
= x_load_font
;
11119 find_ccl_program_func
= x_find_ccl_program
;
11120 query_font_func
= x_query_font
;
11121 set_frame_fontset_func
= x_set_font
;
11122 check_window_system_func
= check_x
;
11125 Qxbm
= intern ("xbm");
11127 QCconversion
= intern (":conversion");
11128 staticpro (&QCconversion
);
11129 QCheuristic_mask
= intern (":heuristic-mask");
11130 staticpro (&QCheuristic_mask
);
11131 QCcolor_symbols
= intern (":color-symbols");
11132 staticpro (&QCcolor_symbols
);
11133 QCascent
= intern (":ascent");
11134 staticpro (&QCascent
);
11135 QCmargin
= intern (":margin");
11136 staticpro (&QCmargin
);
11137 QCrelief
= intern (":relief");
11138 staticpro (&QCrelief
);
11139 Qpostscript
= intern ("postscript");
11140 staticpro (&Qpostscript
);
11141 QCloader
= intern (":loader");
11142 staticpro (&QCloader
);
11143 QCbounding_box
= intern (":bounding-box");
11144 staticpro (&QCbounding_box
);
11145 QCpt_width
= intern (":pt-width");
11146 staticpro (&QCpt_width
);
11147 QCpt_height
= intern (":pt-height");
11148 staticpro (&QCpt_height
);
11149 QCindex
= intern (":index");
11150 staticpro (&QCindex
);
11151 Qpbm
= intern ("pbm");
11155 Qxpm
= intern ("xpm");
11160 Qjpeg
= intern ("jpeg");
11161 staticpro (&Qjpeg
);
11165 Qtiff
= intern ("tiff");
11166 staticpro (&Qtiff
);
11170 Qgif
= intern ("gif");
11175 Qpng
= intern ("png");
11179 defsubr (&Sclear_image_cache
);
11180 defsubr (&Simage_size
);
11181 defsubr (&Simage_mask_p
);
11183 hourglass_atimer
= NULL
;
11184 hourglass_shown_p
= 0;
11186 defsubr (&Sx_show_tip
);
11187 defsubr (&Sx_hide_tip
);
11189 staticpro (&tip_timer
);
11191 staticpro (&tip_frame
);
11193 last_show_tip_args
= Qnil
;
11194 staticpro (&last_show_tip_args
);
11197 defsubr (&Sx_file_dialog
);
11205 image_types
= NULL
;
11206 Vimage_types
= Qnil
;
11208 define_image_type (&xbm_type
);
11209 define_image_type (&gs_type
);
11210 define_image_type (&pbm_type
);
11213 define_image_type (&xpm_type
);
11217 define_image_type (&jpeg_type
);
11221 define_image_type (&tiff_type
);
11225 define_image_type (&gif_type
);
11229 define_image_type (&png_type
);
11233 #endif /* HAVE_X_WINDOWS */
11235 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
11236 (do not change this comment) */