1 /* Functions for the X window system.
2 Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 01, 02, 03
3 Free Software Foundation.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
31 /* This makes the fields of a Display accessible, in Xlib header files. */
33 #define XLIB_ILLEGAL_ACCESS
40 #include "intervals.h"
41 #include "dispextern.h"
43 #include "blockinput.h"
49 #include "termhooks.h"
55 #include <sys/types.h>
59 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
60 #include "bitmaps/gray.xbm"
62 #include <X11/bitmaps/gray>
65 #include "[.bitmaps]gray.xbm"
73 #include <X11/Shell.h>
76 #include <X11/Xaw/Paned.h>
77 #include <X11/Xaw/Label.h>
78 #endif /* USE_MOTIF */
81 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
90 #include "../lwlib/lwlib.h"
94 #include <Xm/DialogS.h>
95 #include <Xm/FileSB.h>
98 /* Do the EDITRES protocol if running X11R5
99 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
101 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
103 extern void _XEditResCheckMessages ();
104 #endif /* R5 + Athena */
106 /* Unique id counter for widgets created by the Lucid Widget Library. */
108 extern LWLIB_ID widget_id_tick
;
111 /* This is part of a kludge--see lwlib/xlwmenu.c. */
112 extern XFontStruct
*xlwmenu_default_font
;
115 extern void free_frame_menubar ();
116 extern double atof ();
120 /* LessTif/Motif version info. */
122 static Lisp_Object Vmotif_version_string
;
124 #endif /* USE_MOTIF */
126 #endif /* USE_X_TOOLKIT */
129 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
131 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
134 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
135 it, and including `bitmaps/gray' more than once is a problem when
136 config.h defines `static' as an empty replacement string. */
138 int gray_bitmap_width
= gray_width
;
139 int gray_bitmap_height
= gray_height
;
140 char *gray_bitmap_bits
= gray_bits
;
142 /* Non-zero means we're allowed to display an hourglass cursor. */
144 int display_hourglass_p
;
146 /* The background and shape of the mouse pointer, and shape when not
147 over text or in the modeline. */
149 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
150 Lisp_Object Vx_hourglass_pointer_shape
;
152 /* The shape when over mouse-sensitive text. */
154 Lisp_Object Vx_sensitive_text_pointer_shape
;
156 /* If non-nil, the pointer shape to indicate that windows can be
157 dragged horizontally. */
159 Lisp_Object Vx_window_horizontal_drag_shape
;
161 /* Color of chars displayed in cursor box. */
163 Lisp_Object Vx_cursor_fore_pixel
;
165 /* Nonzero if using X. */
169 /* Non nil if no window manager is in use. */
171 Lisp_Object Vx_no_window_manager
;
173 /* Search path for bitmap files. */
175 Lisp_Object Vx_bitmap_file_path
;
177 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
179 Lisp_Object Vx_pixel_size_width_font_regexp
;
182 Lisp_Object Qsuppress_icon
;
183 Lisp_Object Qundefined_color
;
185 Lisp_Object Qcompound_text
, Qcancel_timer
;
189 extern Lisp_Object Vwindow_system_version
;
191 /* The below are defined in frame.c. */
194 int image_cache_refcount
, dpyinfo_refcount
;
199 /* Error if we are not connected to X. */
205 error ("X windows are not in use or not initialized");
208 /* Nonzero if we can use mouse menus.
209 You should not call this unless HAVE_MENUS is defined. */
217 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
218 and checking validity for X. */
221 check_x_frame (frame
)
227 frame
= selected_frame
;
228 CHECK_LIVE_FRAME (frame
);
231 error ("Non-X frame used");
235 /* Let the user specify an X display with a frame.
236 nil stands for the selected frame--or, if that is not an X frame,
237 the first X display on the list. */
239 struct x_display_info
*
240 check_x_display_info (frame
)
243 struct x_display_info
*dpyinfo
= NULL
;
247 struct frame
*sf
= XFRAME (selected_frame
);
249 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
250 dpyinfo
= FRAME_X_DISPLAY_INFO (sf
);
251 else if (x_display_list
!= 0)
252 dpyinfo
= x_display_list
;
254 error ("X windows are not in use or not initialized");
256 else if (STRINGP (frame
))
257 dpyinfo
= x_display_info_for_name (frame
);
260 FRAME_PTR f
= check_x_frame (frame
);
261 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
268 /* Return the Emacs frame-object corresponding to an X window.
269 It could be the frame's main window or an icon window. */
271 /* This function can be called during GC, so use GC_xxx type test macros. */
274 x_window_to_frame (dpyinfo
, wdesc
)
275 struct x_display_info
*dpyinfo
;
278 Lisp_Object tail
, frame
;
281 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
284 if (!GC_FRAMEP (frame
))
287 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
289 if (f
->output_data
.x
->hourglass_window
== wdesc
)
292 if ((f
->output_data
.x
->edit_widget
293 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
294 /* A tooltip frame? */
295 || (!f
->output_data
.x
->edit_widget
296 && FRAME_X_WINDOW (f
) == wdesc
)
297 || f
->output_data
.x
->icon_desc
== wdesc
)
299 #else /* not USE_X_TOOLKIT */
301 if (f
->output_data
.x
->edit_widget
)
303 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
304 struct x_output
*x
= f
->output_data
.x
;
305 if (gwdesc
!= 0 && gwdesc
== x
->edit_widget
)
309 if (FRAME_X_WINDOW (f
) == wdesc
310 || f
->output_data
.x
->icon_desc
== wdesc
)
312 #endif /* not USE_X_TOOLKIT */
317 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
318 /* Like x_window_to_frame but also compares the window with the widget's
322 x_any_window_to_frame (dpyinfo
, wdesc
)
323 struct x_display_info
*dpyinfo
;
326 Lisp_Object tail
, frame
;
327 struct frame
*f
, *found
;
331 for (tail
= Vframe_list
; GC_CONSP (tail
) && !found
; tail
= XCDR (tail
))
334 if (!GC_FRAMEP (frame
))
338 if (FRAME_X_P (f
) && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
340 /* This frame matches if the window is any of its widgets. */
341 x
= f
->output_data
.x
;
342 if (x
->hourglass_window
== wdesc
)
347 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
349 && (gwdesc
== x
->widget
350 || gwdesc
== x
->edit_widget
351 || gwdesc
== x
->vbox_widget
352 || gwdesc
== x
->menubar_widget
))
355 if (wdesc
== XtWindow (x
->widget
)
356 || wdesc
== XtWindow (x
->column_widget
)
357 || wdesc
== XtWindow (x
->edit_widget
))
359 /* Match if the window is this frame's menubar. */
360 else if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
364 else if (FRAME_X_WINDOW (f
) == wdesc
)
365 /* A tooltip frame. */
373 /* Likewise, but exclude the menu bar widget. */
376 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
377 struct x_display_info
*dpyinfo
;
380 Lisp_Object tail
, frame
;
384 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
387 if (!GC_FRAMEP (frame
))
390 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
392 x
= f
->output_data
.x
;
393 /* This frame matches if the window is any of its widgets. */
394 if (x
->hourglass_window
== wdesc
)
399 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
401 && (gwdesc
== x
->widget
402 || gwdesc
== x
->edit_widget
403 || gwdesc
== x
->vbox_widget
))
406 if (wdesc
== XtWindow (x
->widget
)
407 || wdesc
== XtWindow (x
->column_widget
)
408 || wdesc
== XtWindow (x
->edit_widget
))
412 else if (FRAME_X_WINDOW (f
) == wdesc
)
413 /* A tooltip frame. */
419 /* Likewise, but consider only the menu bar widget. */
422 x_menubar_window_to_frame (dpyinfo
, wdesc
)
423 struct x_display_info
*dpyinfo
;
426 Lisp_Object tail
, frame
;
430 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
433 if (!GC_FRAMEP (frame
))
436 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
438 x
= f
->output_data
.x
;
439 /* Match if the window is this frame's menubar. */
441 if (x
->menubar_widget
)
443 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
448 && (gwdesc
== x
->menubar_widget
449 || gtk_widget_get_parent (gwdesc
) == x
->menubar_widget
))
455 if (x
->menubar_widget
456 && lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
463 /* Return the frame whose principal (outermost) window is WDESC.
464 If WDESC is some other (smaller) window, we return 0. */
467 x_top_window_to_frame (dpyinfo
, wdesc
)
468 struct x_display_info
*dpyinfo
;
471 Lisp_Object tail
, frame
;
475 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
478 if (!GC_FRAMEP (frame
))
481 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
483 x
= f
->output_data
.x
;
487 /* This frame matches if the window is its topmost widget. */
489 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
490 if (gwdesc
== x
->widget
)
493 if (wdesc
== XtWindow (x
->widget
))
495 #if 0 /* I don't know why it did this,
496 but it seems logically wrong,
497 and it causes trouble for MapNotify events. */
498 /* Match if the window is this frame's menubar. */
499 if (x
->menubar_widget
500 && wdesc
== XtWindow (x
->menubar_widget
))
505 else if (FRAME_X_WINDOW (f
) == wdesc
)
511 #endif /* USE_X_TOOLKIT || USE_GTK */
515 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
516 id, which is just an int that this section returns. Bitmaps are
517 reference counted so they can be shared among frames.
519 Bitmap indices are guaranteed to be > 0, so a negative number can
520 be used to indicate no bitmap.
522 If you use x_create_bitmap_from_data, then you must keep track of
523 the bitmaps yourself. That is, creating a bitmap from the same
524 data more than once will not be caught. */
527 /* Functions to access the contents of a bitmap, given an id. */
530 x_bitmap_height (f
, id
)
534 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
538 x_bitmap_width (f
, id
)
542 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
546 x_bitmap_pixmap (f
, id
)
550 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
554 x_bitmap_mask (f
, id
)
558 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].mask
;
562 /* Allocate a new bitmap record. Returns index of new record. */
565 x_allocate_bitmap_record (f
)
568 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
571 if (dpyinfo
->bitmaps
== NULL
)
573 dpyinfo
->bitmaps_size
= 10;
575 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
576 dpyinfo
->bitmaps_last
= 1;
580 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
581 return ++dpyinfo
->bitmaps_last
;
583 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
584 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
587 dpyinfo
->bitmaps_size
*= 2;
589 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
590 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
591 return ++dpyinfo
->bitmaps_last
;
594 /* Add one reference to the reference count of the bitmap with id ID. */
597 x_reference_bitmap (f
, id
)
601 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
604 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
607 x_create_bitmap_from_data (f
, bits
, width
, height
)
610 unsigned int width
, height
;
612 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
616 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
617 bits
, width
, height
);
624 id
= x_allocate_bitmap_record (f
);
625 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
626 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
627 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
628 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
629 dpyinfo
->bitmaps
[id
- 1].height
= height
;
630 dpyinfo
->bitmaps
[id
- 1].width
= width
;
635 /* Create bitmap from file FILE for frame F. */
638 x_create_bitmap_from_file (f
, file
)
642 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
643 unsigned int width
, height
;
645 int xhot
, yhot
, result
, id
;
650 /* Look for an existing bitmap with the same name. */
651 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
653 if (dpyinfo
->bitmaps
[id
].refcount
654 && dpyinfo
->bitmaps
[id
].file
655 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) SDATA (file
)))
657 ++dpyinfo
->bitmaps
[id
].refcount
;
662 /* Search bitmap-file-path for the file, if appropriate. */
663 fd
= openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, Qnil
);
668 filename
= (char *) SDATA (found
);
670 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
671 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
672 if (result
!= BitmapSuccess
)
675 id
= x_allocate_bitmap_record (f
);
676 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
677 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
678 dpyinfo
->bitmaps
[id
- 1].file
679 = (char *) xmalloc (SBYTES (file
) + 1);
680 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
681 dpyinfo
->bitmaps
[id
- 1].height
= height
;
682 dpyinfo
->bitmaps
[id
- 1].width
= width
;
683 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
688 /* Remove reference to bitmap with id number ID. */
691 x_destroy_bitmap (f
, id
)
695 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
699 --dpyinfo
->bitmaps
[id
- 1].refcount
;
700 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
703 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
704 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].mask
);
705 if (dpyinfo
->bitmaps
[id
- 1].file
)
707 xfree (dpyinfo
->bitmaps
[id
- 1].file
);
708 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
715 /* Free all the bitmaps for the display specified by DPYINFO. */
718 x_destroy_all_bitmaps (dpyinfo
)
719 struct x_display_info
*dpyinfo
;
722 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
723 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
725 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
726 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].mask
);
727 if (dpyinfo
->bitmaps
[i
].file
)
728 xfree (dpyinfo
->bitmaps
[i
].file
);
730 dpyinfo
->bitmaps_last
= 0;
736 /* Useful functions defined in the section
737 `Image type independent image structures' below. */
739 static unsigned long four_corners_best
P_ ((XImage
*ximg
, unsigned long width
,
740 unsigned long height
));
742 static int x_create_x_image_and_pixmap
P_ ((struct frame
*f
, int width
, int height
,
743 int depth
, XImage
**ximg
,
746 static void x_destroy_x_image
P_ ((XImage
*ximg
));
749 /* Create a mask of a bitmap. Note is this not a perfect mask.
750 It's nicer with some borders in this context */
753 x_create_bitmap_mask(f
, id
)
758 XImage
*ximg
, *mask_img
;
759 unsigned long width
, height
;
762 unsigned long x
, y
, xp
, xm
, yp
, ym
;
765 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
766 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
771 pixmap
= x_bitmap_pixmap(f
, id
);
772 width
= x_bitmap_width(f
, id
);
773 height
= x_bitmap_height(f
, id
);
776 ximg
= XGetImage (FRAME_X_DISPLAY (f
), pixmap
, 0, 0, width
, height
,
785 result
= x_create_x_image_and_pixmap (f
, width
, height
, 1, &mask_img
, &mask
);
794 bg
= four_corners_best (ximg
, width
, height
);
796 for (y
= 0; y
< ximg
->height
; ++y
)
798 for (x
= 0; x
< ximg
->width
; ++x
)
800 xp
= x
!= ximg
->width
- 1 ? x
+ 1 : 0;
801 xm
= x
!= 0 ? x
- 1 : ximg
->width
- 1;
802 yp
= y
!= ximg
->height
- 1 ? y
+ 1 : 0;
803 ym
= y
!= 0 ? y
- 1 : ximg
->height
- 1;
804 if (XGetPixel (ximg
, x
, y
) == bg
805 && XGetPixel (ximg
, x
, yp
) == bg
806 && XGetPixel (ximg
, x
, ym
) == bg
807 && XGetPixel (ximg
, xp
, y
) == bg
808 && XGetPixel (ximg
, xp
, yp
) == bg
809 && XGetPixel (ximg
, xp
, ym
) == bg
810 && XGetPixel (ximg
, xm
, y
) == bg
811 && XGetPixel (ximg
, xm
, yp
) == bg
812 && XGetPixel (ximg
, xm
, ym
) == bg
)
813 XPutPixel (mask_img
, x
, y
, 0);
815 XPutPixel (mask_img
, x
, y
, 1);
819 xassert (interrupt_input_blocked
);
820 gc
= XCreateGC (FRAME_X_DISPLAY (f
), mask
, 0, NULL
);
821 XPutImage (FRAME_X_DISPLAY (f
), mask
, gc
, mask_img
, 0, 0, 0, 0,
823 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
825 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
827 XDestroyImage (ximg
);
828 x_destroy_x_image(mask_img
);
833 static Lisp_Object unwind_create_frame
P_ ((Lisp_Object
));
834 static Lisp_Object unwind_create_tip_frame
P_ ((Lisp_Object
));
835 static void x_disable_image
P_ ((struct frame
*, struct image
*));
837 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
838 static void x_set_wait_for_wm
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
839 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
840 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
841 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
842 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
843 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
844 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
845 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
846 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
847 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
848 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
849 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
850 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
852 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
854 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
859 static void x_edge_detection
P_ ((struct frame
*, struct image
*, Lisp_Object
,
861 static void init_color_table
P_ ((void));
862 static void free_color_table
P_ ((void));
863 static unsigned long *colors_in_color_table
P_ ((int *n
));
864 static unsigned long lookup_rgb_color
P_ ((struct frame
*f
, int r
, int g
, int b
));
865 static unsigned long lookup_pixel_color
P_ ((struct frame
*f
, unsigned long p
));
871 /* Store the screen positions of frame F into XPTR and YPTR.
872 These are the positions of the containing window manager window,
873 not Emacs's own window. */
876 x_real_positions (f
, xptr
, yptr
)
880 int win_x
, win_y
, outer_x
, outer_y
;
881 int real_x
= 0, real_y
= 0;
883 Window win
= f
->output_data
.x
->parent_desc
;
889 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
891 if (win
== FRAME_X_DISPLAY_INFO (f
)->root_window
)
892 win
= FRAME_OUTER_WINDOW (f
);
894 /* This loop traverses up the containment tree until we hit the root
895 window. Window managers may intersect many windows between our window
896 and the root window. The window we find just before the root window
897 should be the outer WM window. */
900 Window wm_window
, rootw
;
901 Window
*tmp_children
;
902 unsigned int tmp_nchildren
;
905 success
= XQueryTree (FRAME_X_DISPLAY (f
), win
, &rootw
,
906 &wm_window
, &tmp_children
, &tmp_nchildren
);
908 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
910 /* Don't free tmp_children if XQueryTree failed. */
914 XFree ((char *) tmp_children
);
916 if (wm_window
== rootw
|| had_errors
)
927 /* Get the real coordinates for the WM window upper left corner */
928 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
929 &rootw
, &real_x
, &real_y
, &ign
, &ign
, &ign
, &ign
);
931 /* Translate real coordinates to coordinates relative to our
932 window. For our window, the upper left corner is 0, 0.
933 Since the upper left corner of the WM window is outside
934 our window, win_x and win_y will be negative:
936 ------------------ ---> x
938 | ----------------- v y
941 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
943 /* From-window, to-window. */
944 FRAME_X_DISPLAY_INFO (f
)->root_window
,
947 /* From-position, to-position. */
948 real_x
, real_y
, &win_x
, &win_y
,
953 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
960 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
962 /* From-window, to-window. */
963 FRAME_X_DISPLAY_INFO (f
)->root_window
,
964 FRAME_OUTER_WINDOW (f
),
966 /* From-position, to-position. */
967 real_x
, real_y
, &outer_x
, &outer_y
,
973 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
976 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
980 if (had_errors
) return;
982 f
->x_pixels_diff
= -win_x
;
983 f
->y_pixels_diff
= -win_y
;
985 FRAME_X_OUTPUT (f
)->x_pixels_outer_diff
= -outer_x
;
986 FRAME_X_OUTPUT (f
)->y_pixels_outer_diff
= -outer_y
;
995 /* Gamma-correct COLOR on frame F. */
998 gamma_correct (f
, color
)
1004 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
1005 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
1006 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
1011 /* Decide if color named COLOR_NAME is valid for use on frame F. If
1012 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
1013 allocate the color. Value is zero if COLOR_NAME is invalid, or
1014 no color could be allocated. */
1017 x_defined_color (f
, color_name
, color
, alloc_p
)
1024 Display
*dpy
= FRAME_X_DISPLAY (f
);
1025 Colormap cmap
= FRAME_X_COLORMAP (f
);
1028 success_p
= XParseColor (dpy
, cmap
, color_name
, color
);
1029 if (success_p
&& alloc_p
)
1030 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
1037 /* Return the pixel color value for color COLOR_NAME on frame F. If F
1038 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
1039 Signal an error if color can't be allocated. */
1042 x_decode_color (f
, color_name
, mono_color
)
1044 Lisp_Object color_name
;
1049 CHECK_STRING (color_name
);
1051 #if 0 /* Don't do this. It's wrong when we're not using the default
1052 colormap, it makes freeing difficult, and it's probably not
1053 an important optimization. */
1054 if (strcmp (SDATA (color_name
), "black") == 0)
1055 return BLACK_PIX_DEFAULT (f
);
1056 else if (strcmp (SDATA (color_name
), "white") == 0)
1057 return WHITE_PIX_DEFAULT (f
);
1060 /* Return MONO_COLOR for monochrome frames. */
1061 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1064 /* x_defined_color is responsible for coping with failures
1065 by looking for a near-miss. */
1066 if (x_defined_color (f
, SDATA (color_name
), &cdef
, 1))
1069 Fsignal (Qerror
, Fcons (build_string ("Undefined color"),
1070 Fcons (color_name
, Qnil
)));
1076 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
1077 the previous value of that parameter, NEW_VALUE is the new value.
1078 See also the comment of wait_for_wm in struct x_output. */
1081 x_set_wait_for_wm (f
, new_value
, old_value
)
1083 Lisp_Object new_value
, old_value
;
1085 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
1090 /* Wrapper for gtk_window_icon_from_file() */
1093 xg_set_icon(f
, file
)
1097 struct gcpro gcpro1
, gcpro2
, gcpro3
;
1100 Lisp_Object found
, search_path
;
1103 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
1105 GCPRO3 (found
, search_path
, file
);
1106 fd
= openp (search_path
, file
, Qnil
, &found
, Qnil
);
1109 filename
= (char *) SDATA (found
);
1112 gtk_window_set_icon_from_file (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1121 #endif /* USE_GTK */
1124 /* Functions called only from `x_set_frame_param'
1125 to set individual parameters.
1127 If FRAME_X_WINDOW (f) is 0,
1128 the frame is being created and its X-window does not exist yet.
1129 In that case, just record the parameter's new value
1130 in the standard place; do not attempt to change the window. */
1133 x_set_foreground_color (f
, arg
, oldval
)
1135 Lisp_Object arg
, oldval
;
1137 struct x_output
*x
= f
->output_data
.x
;
1138 unsigned long fg
, old_fg
;
1140 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1141 old_fg
= x
->foreground_pixel
;
1142 x
->foreground_pixel
= fg
;
1144 if (FRAME_X_WINDOW (f
) != 0)
1146 Display
*dpy
= FRAME_X_DISPLAY (f
);
1149 XSetForeground (dpy
, x
->normal_gc
, fg
);
1150 XSetBackground (dpy
, x
->reverse_gc
, fg
);
1152 if (x
->cursor_pixel
== old_fg
)
1154 unload_color (f
, x
->cursor_pixel
);
1155 x
->cursor_pixel
= x_copy_color (f
, fg
);
1156 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
1161 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
1163 if (FRAME_VISIBLE_P (f
))
1167 unload_color (f
, old_fg
);
1171 x_set_background_color (f
, arg
, oldval
)
1173 Lisp_Object arg
, oldval
;
1175 struct x_output
*x
= f
->output_data
.x
;
1178 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1179 unload_color (f
, x
->background_pixel
);
1180 x
->background_pixel
= bg
;
1182 if (FRAME_X_WINDOW (f
) != 0)
1184 Display
*dpy
= FRAME_X_DISPLAY (f
);
1187 XSetBackground (dpy
, x
->normal_gc
, bg
);
1188 XSetForeground (dpy
, x
->reverse_gc
, bg
);
1189 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
1190 XSetForeground (dpy
, x
->cursor_gc
, bg
);
1193 xg_set_background_color (f
, bg
);
1196 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
1197 toolkit scroll bars. */
1200 for (bar
= FRAME_SCROLL_BARS (f
);
1202 bar
= XSCROLL_BAR (bar
)->next
)
1204 Window window
= SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
));
1205 XSetWindowBackground (dpy
, window
, bg
);
1208 #endif /* USE_TOOLKIT_SCROLL_BARS */
1211 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
1213 if (FRAME_VISIBLE_P (f
))
1219 x_set_mouse_color (f
, arg
, oldval
)
1221 Lisp_Object arg
, oldval
;
1223 struct x_output
*x
= f
->output_data
.x
;
1224 Display
*dpy
= FRAME_X_DISPLAY (f
);
1225 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
1226 Cursor hourglass_cursor
, horizontal_drag_cursor
;
1228 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1229 unsigned long mask_color
= x
->background_pixel
;
1231 /* Don't let pointers be invisible. */
1232 if (mask_color
== pixel
)
1234 x_free_colors (f
, &pixel
, 1);
1235 pixel
= x_copy_color (f
, x
->foreground_pixel
);
1238 unload_color (f
, x
->mouse_pixel
);
1239 x
->mouse_pixel
= pixel
;
1243 /* It's not okay to crash if the user selects a screwy cursor. */
1244 count
= x_catch_errors (dpy
);
1246 if (!NILP (Vx_pointer_shape
))
1248 CHECK_NUMBER (Vx_pointer_shape
);
1249 cursor
= XCreateFontCursor (dpy
, XINT (Vx_pointer_shape
));
1252 cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1253 x_check_errors (dpy
, "bad text pointer cursor: %s");
1255 if (!NILP (Vx_nontext_pointer_shape
))
1257 CHECK_NUMBER (Vx_nontext_pointer_shape
);
1259 = XCreateFontCursor (dpy
, XINT (Vx_nontext_pointer_shape
));
1262 nontext_cursor
= XCreateFontCursor (dpy
, XC_left_ptr
);
1263 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
1265 if (!NILP (Vx_hourglass_pointer_shape
))
1267 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
1269 = XCreateFontCursor (dpy
, XINT (Vx_hourglass_pointer_shape
));
1272 hourglass_cursor
= XCreateFontCursor (dpy
, XC_watch
);
1273 x_check_errors (dpy
, "bad hourglass pointer cursor: %s");
1275 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
1276 if (!NILP (Vx_mode_pointer_shape
))
1278 CHECK_NUMBER (Vx_mode_pointer_shape
);
1279 mode_cursor
= XCreateFontCursor (dpy
, XINT (Vx_mode_pointer_shape
));
1282 mode_cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1283 x_check_errors (dpy
, "bad modeline pointer cursor: %s");
1285 if (!NILP (Vx_sensitive_text_pointer_shape
))
1287 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
1289 = XCreateFontCursor (dpy
, XINT (Vx_sensitive_text_pointer_shape
));
1292 hand_cursor
= XCreateFontCursor (dpy
, XC_hand2
);
1294 if (!NILP (Vx_window_horizontal_drag_shape
))
1296 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
1297 horizontal_drag_cursor
1298 = XCreateFontCursor (dpy
, XINT (Vx_window_horizontal_drag_shape
));
1301 horizontal_drag_cursor
1302 = XCreateFontCursor (dpy
, XC_sb_h_double_arrow
);
1304 /* Check and report errors with the above calls. */
1305 x_check_errors (dpy
, "can't set cursor shape: %s");
1306 x_uncatch_errors (dpy
, count
);
1309 XColor fore_color
, back_color
;
1311 fore_color
.pixel
= x
->mouse_pixel
;
1312 x_query_color (f
, &fore_color
);
1313 back_color
.pixel
= mask_color
;
1314 x_query_color (f
, &back_color
);
1316 XRecolorCursor (dpy
, cursor
, &fore_color
, &back_color
);
1317 XRecolorCursor (dpy
, nontext_cursor
, &fore_color
, &back_color
);
1318 XRecolorCursor (dpy
, mode_cursor
, &fore_color
, &back_color
);
1319 XRecolorCursor (dpy
, hand_cursor
, &fore_color
, &back_color
);
1320 XRecolorCursor (dpy
, hourglass_cursor
, &fore_color
, &back_color
);
1321 XRecolorCursor (dpy
, horizontal_drag_cursor
, &fore_color
, &back_color
);
1324 if (FRAME_X_WINDOW (f
) != 0)
1325 XDefineCursor (dpy
, FRAME_X_WINDOW (f
), cursor
);
1327 if (cursor
!= x
->text_cursor
1328 && x
->text_cursor
!= 0)
1329 XFreeCursor (dpy
, x
->text_cursor
);
1330 x
->text_cursor
= cursor
;
1332 if (nontext_cursor
!= x
->nontext_cursor
1333 && x
->nontext_cursor
!= 0)
1334 XFreeCursor (dpy
, x
->nontext_cursor
);
1335 x
->nontext_cursor
= nontext_cursor
;
1337 if (hourglass_cursor
!= x
->hourglass_cursor
1338 && x
->hourglass_cursor
!= 0)
1339 XFreeCursor (dpy
, x
->hourglass_cursor
);
1340 x
->hourglass_cursor
= hourglass_cursor
;
1342 if (mode_cursor
!= x
->modeline_cursor
1343 && x
->modeline_cursor
!= 0)
1344 XFreeCursor (dpy
, f
->output_data
.x
->modeline_cursor
);
1345 x
->modeline_cursor
= mode_cursor
;
1347 if (hand_cursor
!= x
->hand_cursor
1348 && x
->hand_cursor
!= 0)
1349 XFreeCursor (dpy
, x
->hand_cursor
);
1350 x
->hand_cursor
= hand_cursor
;
1352 if (horizontal_drag_cursor
!= x
->horizontal_drag_cursor
1353 && x
->horizontal_drag_cursor
!= 0)
1354 XFreeCursor (dpy
, x
->horizontal_drag_cursor
);
1355 x
->horizontal_drag_cursor
= horizontal_drag_cursor
;
1360 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1364 x_set_cursor_color (f
, arg
, oldval
)
1366 Lisp_Object arg
, oldval
;
1368 unsigned long fore_pixel
, pixel
;
1369 int fore_pixel_allocated_p
= 0, pixel_allocated_p
= 0;
1370 struct x_output
*x
= f
->output_data
.x
;
1372 if (!NILP (Vx_cursor_fore_pixel
))
1374 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1375 WHITE_PIX_DEFAULT (f
));
1376 fore_pixel_allocated_p
= 1;
1379 fore_pixel
= x
->background_pixel
;
1381 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1382 pixel_allocated_p
= 1;
1384 /* Make sure that the cursor color differs from the background color. */
1385 if (pixel
== x
->background_pixel
)
1387 if (pixel_allocated_p
)
1389 x_free_colors (f
, &pixel
, 1);
1390 pixel_allocated_p
= 0;
1393 pixel
= x
->mouse_pixel
;
1394 if (pixel
== fore_pixel
)
1396 if (fore_pixel_allocated_p
)
1398 x_free_colors (f
, &fore_pixel
, 1);
1399 fore_pixel_allocated_p
= 0;
1401 fore_pixel
= x
->background_pixel
;
1405 unload_color (f
, x
->cursor_foreground_pixel
);
1406 if (!fore_pixel_allocated_p
)
1407 fore_pixel
= x_copy_color (f
, fore_pixel
);
1408 x
->cursor_foreground_pixel
= fore_pixel
;
1410 unload_color (f
, x
->cursor_pixel
);
1411 if (!pixel_allocated_p
)
1412 pixel
= x_copy_color (f
, pixel
);
1413 x
->cursor_pixel
= pixel
;
1415 if (FRAME_X_WINDOW (f
) != 0)
1418 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
1419 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
1422 if (FRAME_VISIBLE_P (f
))
1424 x_update_cursor (f
, 0);
1425 x_update_cursor (f
, 1);
1429 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1432 /* Set the border-color of frame F to pixel value PIX.
1433 Note that this does not fully take effect if done before
1434 F has an x-window. */
1437 x_set_border_pixel (f
, pix
)
1441 unload_color (f
, f
->output_data
.x
->border_pixel
);
1442 f
->output_data
.x
->border_pixel
= pix
;
1444 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
1447 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1448 (unsigned long)pix
);
1451 if (FRAME_VISIBLE_P (f
))
1456 /* Set the border-color of frame F to value described by ARG.
1457 ARG can be a string naming a color.
1458 The border-color is used for the border that is drawn by the X server.
1459 Note that this does not fully take effect if done before
1460 F has an x-window; it must be redone when the window is created.
1462 Note: this is done in two routines because of the way X10 works.
1464 Note: under X11, this is normally the province of the window manager,
1465 and so emacs' border colors may be overridden. */
1468 x_set_border_color (f
, arg
, oldval
)
1470 Lisp_Object arg
, oldval
;
1475 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1476 x_set_border_pixel (f
, pix
);
1477 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1482 x_set_cursor_type (f
, arg
, oldval
)
1484 Lisp_Object arg
, oldval
;
1486 set_frame_cursor_types (f
, arg
);
1488 /* Make sure the cursor gets redrawn. */
1489 cursor_type_changed
= 1;
1493 x_set_icon_type (f
, arg
, oldval
)
1495 Lisp_Object arg
, oldval
;
1501 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1504 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1509 result
= x_text_icon (f
,
1510 (char *) SDATA ((!NILP (f
->icon_name
)
1514 result
= x_bitmap_icon (f
, arg
);
1519 error ("No icon window available");
1522 XFlush (FRAME_X_DISPLAY (f
));
1527 x_set_icon_name (f
, arg
, oldval
)
1529 Lisp_Object arg
, oldval
;
1535 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1538 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1543 if (f
->output_data
.x
->icon_bitmap
!= 0)
1548 result
= x_text_icon (f
,
1549 (char *) SDATA ((!NILP (f
->icon_name
)
1558 error ("No icon window available");
1561 XFlush (FRAME_X_DISPLAY (f
));
1567 x_set_menu_bar_lines (f
, value
, oldval
)
1569 Lisp_Object value
, oldval
;
1572 #ifndef USE_X_TOOLKIT
1573 int olines
= FRAME_MENU_BAR_LINES (f
);
1576 /* Right now, menu bars don't work properly in minibuf-only frames;
1577 most of the commands try to apply themselves to the minibuffer
1578 frame itself, and get an error because you can't switch buffers
1579 in or split the minibuffer window. */
1580 if (FRAME_MINIBUF_ONLY_P (f
))
1583 if (INTEGERP (value
))
1584 nlines
= XINT (value
);
1588 /* Make sure we redisplay all windows in this frame. */
1589 windows_or_buffers_changed
++;
1591 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1592 FRAME_MENU_BAR_LINES (f
) = 0;
1595 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1596 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1597 /* Make sure next redisplay shows the menu bar. */
1598 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1602 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1603 free_frame_menubar (f
);
1604 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1606 f
->output_data
.x
->menubar_widget
= 0;
1608 #else /* not USE_X_TOOLKIT && not USE_GTK */
1609 FRAME_MENU_BAR_LINES (f
) = nlines
;
1610 change_window_heights (f
->root_window
, nlines
- olines
);
1611 #endif /* not USE_X_TOOLKIT */
1616 /* Set the number of lines used for the tool bar of frame F to VALUE.
1617 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1618 is the old number of tool bar lines. This function changes the
1619 height of all windows on frame F to match the new tool bar height.
1620 The frame's height doesn't change. */
1623 x_set_tool_bar_lines (f
, value
, oldval
)
1625 Lisp_Object value
, oldval
;
1627 int delta
, nlines
, root_height
;
1628 Lisp_Object root_window
;
1630 /* Treat tool bars like menu bars. */
1631 if (FRAME_MINIBUF_ONLY_P (f
))
1634 /* Use VALUE only if an integer >= 0. */
1635 if (INTEGERP (value
) && XINT (value
) >= 0)
1636 nlines
= XFASTINT (value
);
1641 FRAME_TOOL_BAR_LINES (f
) = 0;
1644 FRAME_EXTERNAL_TOOL_BAR (f
) = 1;
1645 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1646 /* Make sure next redisplay shows the tool bar. */
1647 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1648 update_frame_tool_bar (f
);
1652 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1653 free_frame_tool_bar (f
);
1654 FRAME_EXTERNAL_TOOL_BAR (f
) = 0;
1660 /* Make sure we redisplay all windows in this frame. */
1661 ++windows_or_buffers_changed
;
1663 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
1665 /* Don't resize the tool-bar to more than we have room for. */
1666 root_window
= FRAME_ROOT_WINDOW (f
);
1667 root_height
= WINDOW_TOTAL_LINES (XWINDOW (root_window
));
1668 if (root_height
- delta
< 1)
1670 delta
= root_height
- 1;
1671 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
1674 FRAME_TOOL_BAR_LINES (f
) = nlines
;
1675 change_window_heights (root_window
, delta
);
1678 /* We also have to make sure that the internal border at the top of
1679 the frame, below the menu bar or tool bar, is redrawn when the
1680 tool bar disappears. This is so because the internal border is
1681 below the tool bar if one is displayed, but is below the menu bar
1682 if there isn't a tool bar. The tool bar draws into the area
1683 below the menu bar. */
1684 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
1688 clear_current_matrices (f
);
1689 updating_frame
= NULL
;
1692 /* If the tool bar gets smaller, the internal border below it
1693 has to be cleared. It was formerly part of the display
1694 of the larger tool bar, and updating windows won't clear it. */
1697 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1698 int width
= FRAME_PIXEL_WIDTH (f
);
1699 int y
= nlines
* FRAME_LINE_HEIGHT (f
);
1702 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1703 0, y
, width
, height
, False
);
1706 if (WINDOWP (f
->tool_bar_window
))
1707 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1712 /* Set the foreground color for scroll bars on frame F to VALUE.
1713 VALUE should be a string, a color name. If it isn't a string or
1714 isn't a valid color name, do nothing. OLDVAL is the old value of
1715 the frame parameter. */
1718 x_set_scroll_bar_foreground (f
, value
, oldval
)
1720 Lisp_Object value
, oldval
;
1722 unsigned long pixel
;
1724 if (STRINGP (value
))
1725 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1729 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1730 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1732 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1733 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1735 /* Remove all scroll bars because they have wrong colors. */
1736 if (condemn_scroll_bars_hook
)
1737 (*condemn_scroll_bars_hook
) (f
);
1738 if (judge_scroll_bars_hook
)
1739 (*judge_scroll_bars_hook
) (f
);
1741 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1747 /* Set the background color for scroll bars on frame F to VALUE VALUE
1748 should be a string, a color name. If it isn't a string or isn't a
1749 valid color name, do nothing. OLDVAL is the old value of the frame
1753 x_set_scroll_bar_background (f
, value
, oldval
)
1755 Lisp_Object value
, oldval
;
1757 unsigned long pixel
;
1759 if (STRINGP (value
))
1760 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1764 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1765 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1767 #ifdef USE_TOOLKIT_SCROLL_BARS
1768 /* Scrollbar shadow colors. */
1769 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1771 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1772 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1774 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1776 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1777 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1779 #endif /* USE_TOOLKIT_SCROLL_BARS */
1781 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1782 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1784 /* Remove all scroll bars because they have wrong colors. */
1785 if (condemn_scroll_bars_hook
)
1786 (*condemn_scroll_bars_hook
) (f
);
1787 if (judge_scroll_bars_hook
)
1788 (*judge_scroll_bars_hook
) (f
);
1790 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1796 /* Encode Lisp string STRING as a text in a format appropriate for
1797 XICCC (X Inter Client Communication Conventions).
1799 If STRING contains only ASCII characters, do no conversion and
1800 return the string data of STRING. Otherwise, encode the text by
1801 CODING_SYSTEM, and return a newly allocated memory area which
1802 should be freed by `xfree' by a caller.
1804 SELECTIONP non-zero means the string is being encoded for an X
1805 selection, so it is safe to run pre-write conversions (which
1808 Store the byte length of resulting text in *TEXT_BYTES.
1810 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1811 which means that the `encoding' of the result can be `STRING'.
1812 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1813 the result should be `COMPOUND_TEXT'. */
1816 x_encode_text (string
, coding_system
, selectionp
, text_bytes
, stringp
)
1817 Lisp_Object string
, coding_system
;
1818 int *text_bytes
, *stringp
;
1821 unsigned char *str
= SDATA (string
);
1822 int chars
= SCHARS (string
);
1823 int bytes
= SBYTES (string
);
1827 struct coding_system coding
;
1828 extern Lisp_Object Qcompound_text_with_extensions
;
1830 charset_info
= find_charset_in_text (str
, chars
, bytes
, NULL
, Qnil
);
1831 if (charset_info
== 0)
1833 /* No multibyte character in OBJ. We need not encode it. */
1834 *text_bytes
= bytes
;
1839 setup_coding_system (coding_system
, &coding
);
1841 && SYMBOLP (coding
.pre_write_conversion
)
1842 && !NILP (Ffboundp (coding
.pre_write_conversion
)))
1844 string
= run_pre_post_conversion_on_str (string
, &coding
, 1);
1845 str
= SDATA (string
);
1846 chars
= SCHARS (string
);
1847 bytes
= SBYTES (string
);
1849 coding
.src_multibyte
= 1;
1850 coding
.dst_multibyte
= 0;
1851 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1852 if (coding
.type
== coding_type_iso2022
)
1853 coding
.flags
|= CODING_FLAG_ISO_SAFE
;
1854 /* We suppress producing escape sequences for composition. */
1855 coding
.composing
= COMPOSITION_DISABLED
;
1856 bufsize
= encoding_buffer_size (&coding
, bytes
);
1857 buf
= (unsigned char *) xmalloc (bufsize
);
1858 encode_coding (&coding
, str
, buf
, bytes
, bufsize
);
1859 *text_bytes
= coding
.produced
;
1860 *stringp
= (charset_info
== 1
1861 || (!EQ (coding_system
, Qcompound_text
)
1862 && !EQ (coding_system
, Qcompound_text_with_extensions
)));
1867 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1870 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1871 name; if NAME is a string, set F's name to NAME and set
1872 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1874 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1875 suggesting a new name, which lisp code should override; if
1876 F->explicit_name is set, ignore the new name; otherwise, set it. */
1879 x_set_name (f
, name
, explicit)
1884 /* Make sure that requests from lisp code override requests from
1885 Emacs redisplay code. */
1888 /* If we're switching from explicit to implicit, we had better
1889 update the mode lines and thereby update the title. */
1890 if (f
->explicit_name
&& NILP (name
))
1891 update_mode_lines
= 1;
1893 f
->explicit_name
= ! NILP (name
);
1895 else if (f
->explicit_name
)
1898 /* If NAME is nil, set the name to the x_id_name. */
1901 /* Check for no change needed in this very common case
1902 before we do any consing. */
1903 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1906 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1909 CHECK_STRING (name
);
1911 /* Don't change the name if it's already NAME. */
1912 if (! NILP (Fstring_equal (name
, f
->name
)))
1917 /* For setting the frame title, the title parameter should override
1918 the name parameter. */
1919 if (! NILP (f
->title
))
1922 if (FRAME_X_WINDOW (f
))
1927 XTextProperty text
, icon
;
1929 Lisp_Object coding_system
;
1931 /* Note: Encoding strategy
1933 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1934 text.encoding. But, there are non-internationalized window
1935 managers which don't support that encoding. So, if NAME
1936 contains only ASCII and 8859-1 characters, encode it by
1937 iso-latin-1, and use "STRING" in text.encoding hoping that
1938 such window managers at least analyze this format correctly,
1939 i.e. treat 8-bit bytes as 8859-1 characters.
1941 We may also be able to use "UTF8_STRING" in text.encoding
1942 in the future which can encode all Unicode characters.
1943 But, for the moment, there's no way to know that the
1944 current window manager supports it or not. */
1945 coding_system
= Qcompound_text
;
1946 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
1947 text
.encoding
= (stringp
? XA_STRING
1948 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1950 text
.nitems
= bytes
;
1952 if (NILP (f
->icon_name
))
1958 /* See the above comment "Note: Encoding strategy". */
1959 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
1961 icon
.encoding
= (stringp
? XA_STRING
1962 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1964 icon
.nitems
= bytes
;
1967 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1969 #else /* not USE_GTK */
1970 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1971 #endif /* not USE_GTK */
1973 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1975 if (!NILP (f
->icon_name
)
1976 && icon
.value
!= (unsigned char *) SDATA (f
->icon_name
))
1978 if (text
.value
!= (unsigned char *) SDATA (name
))
1981 #else /* not HAVE_X11R4 */
1982 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1984 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1986 #endif /* not HAVE_X11R4 */
1991 /* This function should be called when the user's lisp code has
1992 specified a name for the frame; the name will override any set by the
1995 x_explicitly_set_name (f
, arg
, oldval
)
1997 Lisp_Object arg
, oldval
;
1999 x_set_name (f
, arg
, 1);
2002 /* This function should be called by Emacs redisplay code to set the
2003 name; names set this way will never override names set by the user's
2006 x_implicitly_set_name (f
, arg
, oldval
)
2008 Lisp_Object arg
, oldval
;
2010 x_set_name (f
, arg
, 0);
2013 /* Change the title of frame F to NAME.
2014 If NAME is nil, use the frame name as the title.
2016 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2017 name; if NAME is a string, set F's name to NAME and set
2018 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2020 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2021 suggesting a new name, which lisp code should override; if
2022 F->explicit_name is set, ignore the new name; otherwise, set it. */
2025 x_set_title (f
, name
, old_name
)
2027 Lisp_Object name
, old_name
;
2029 /* Don't change the title if it's already NAME. */
2030 if (EQ (name
, f
->title
))
2033 update_mode_lines
= 1;
2040 CHECK_STRING (name
);
2042 if (FRAME_X_WINDOW (f
))
2047 XTextProperty text
, icon
;
2049 Lisp_Object coding_system
;
2051 coding_system
= Qcompound_text
;
2052 /* See the comment "Note: Encoding strategy" in x_set_name. */
2053 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
2054 text
.encoding
= (stringp
? XA_STRING
2055 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
2057 text
.nitems
= bytes
;
2059 if (NILP (f
->icon_name
))
2065 /* See the comment "Note: Encoding strategy" in x_set_name. */
2066 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
2068 icon
.encoding
= (stringp
? XA_STRING
2069 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
2071 icon
.nitems
= bytes
;
2075 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
2077 #else /* not USE_GTK */
2078 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
2079 #endif /* not USE_GTK */
2081 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
2084 if (!NILP (f
->icon_name
)
2085 && icon
.value
!= (unsigned char *) SDATA (f
->icon_name
))
2087 if (text
.value
!= (unsigned char *) SDATA (name
))
2090 #else /* not HAVE_X11R4 */
2091 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2093 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2095 #endif /* not HAVE_X11R4 */
2101 x_set_scroll_bar_default_width (f
)
2104 int wid
= FRAME_COLUMN_WIDTH (f
);
2106 #ifdef USE_TOOLKIT_SCROLL_BARS
2107 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
2108 int width
= 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
2109 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (width
+ wid
- 1) / wid
;
2110 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = width
;
2112 /* Make the actual width at least 14 pixels and a multiple of a
2114 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
2116 /* Use all of that space (aside from required margins) for the
2118 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 0;
2123 /* Record in frame F the specified or default value according to ALIST
2124 of the parameter named PROP (a Lisp symbol). If no value is
2125 specified for PROP, look for an X default for XPROP on the frame
2126 named NAME. If that is not found either, use the value DEFLT. */
2129 x_default_scroll_bar_color_parameter (f
, alist
, prop
, xprop
, xclass
,
2138 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2141 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
2142 if (EQ (tem
, Qunbound
))
2144 #ifdef USE_TOOLKIT_SCROLL_BARS
2146 /* See if an X resource for the scroll bar color has been
2148 tem
= display_x_get_resource (dpyinfo
,
2149 build_string (foreground_p
2153 build_string ("verticalScrollBar"),
2157 /* If nothing has been specified, scroll bars will use a
2158 toolkit-dependent default. Because these defaults are
2159 difficult to get at without actually creating a scroll
2160 bar, use nil to indicate that no color has been
2165 #else /* not USE_TOOLKIT_SCROLL_BARS */
2169 #endif /* not USE_TOOLKIT_SCROLL_BARS */
2172 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2178 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2181 XSetWMProtocols (dpy
, w
, protocols
, count
)
2188 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2189 if (prop
== None
) return False
;
2190 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2191 (unsigned char *) protocols
, count
);
2194 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2196 #ifdef USE_X_TOOLKIT
2198 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2199 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2200 already be present because of the toolkit (Motif adds some of them,
2201 for example, but Xt doesn't). */
2204 hack_wm_protocols (f
, widget
)
2208 Display
*dpy
= XtDisplay (widget
);
2209 Window w
= XtWindow (widget
);
2210 int need_delete
= 1;
2216 Atom type
, *atoms
= 0;
2218 unsigned long nitems
= 0;
2219 unsigned long bytes_after
;
2221 if ((XGetWindowProperty (dpy
, w
,
2222 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2223 (long)0, (long)100, False
, XA_ATOM
,
2224 &type
, &format
, &nitems
, &bytes_after
,
2225 (unsigned char **) &atoms
)
2227 && format
== 32 && type
== XA_ATOM
)
2231 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2233 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2235 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2238 if (atoms
) XFree ((char *) atoms
);
2244 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2246 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2248 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2250 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2251 XA_ATOM
, 32, PropModeAppend
,
2252 (unsigned char *) props
, count
);
2260 /* Support routines for XIC (X Input Context). */
2264 static XFontSet xic_create_xfontset
P_ ((struct frame
*, char *));
2265 static XIMStyle best_xim_style
P_ ((XIMStyles
*, XIMStyles
*));
2268 /* Supported XIM styles, ordered by preference. */
2270 static XIMStyle supported_xim_styles
[] =
2272 XIMPreeditPosition
| XIMStatusArea
,
2273 XIMPreeditPosition
| XIMStatusNothing
,
2274 XIMPreeditPosition
| XIMStatusNone
,
2275 XIMPreeditNothing
| XIMStatusArea
,
2276 XIMPreeditNothing
| XIMStatusNothing
,
2277 XIMPreeditNothing
| XIMStatusNone
,
2278 XIMPreeditNone
| XIMStatusArea
,
2279 XIMPreeditNone
| XIMStatusNothing
,
2280 XIMPreeditNone
| XIMStatusNone
,
2285 /* Create an X fontset on frame F with base font name
2289 xic_create_xfontset (f
, base_fontname
)
2291 char *base_fontname
;
2294 char **missing_list
;
2298 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
2299 base_fontname
, &missing_list
,
2300 &missing_count
, &def_string
);
2302 XFreeStringList (missing_list
);
2304 /* No need to free def_string. */
2309 /* Value is the best input style, given user preferences USER (already
2310 checked to be supported by Emacs), and styles supported by the
2311 input method XIM. */
2314 best_xim_style (user
, xim
)
2320 for (i
= 0; i
< user
->count_styles
; ++i
)
2321 for (j
= 0; j
< xim
->count_styles
; ++j
)
2322 if (user
->supported_styles
[i
] == xim
->supported_styles
[j
])
2323 return user
->supported_styles
[i
];
2325 /* Return the default style. */
2326 return XIMPreeditNothing
| XIMStatusNothing
;
2329 /* Create XIC for frame F. */
2331 static XIMStyle xic_style
;
2334 create_frame_xic (f
)
2339 XFontSet xfs
= NULL
;
2344 xim
= FRAME_X_XIM (f
);
2349 XVaNestedList preedit_attr
;
2350 XVaNestedList status_attr
;
2351 char *base_fontname
;
2354 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2355 spot
.x
= 0; spot
.y
= 1;
2356 /* Create X fontset. */
2357 fontset
= FRAME_FONTSET (f
);
2359 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2362 /* Determine the base fontname from the ASCII font name of
2364 char *ascii_font
= (char *) SDATA (fontset_ascii (fontset
));
2365 char *p
= ascii_font
;
2368 for (i
= 0; *p
; p
++)
2371 /* As the font name doesn't conform to XLFD, we can't
2372 modify it to get a suitable base fontname for the
2374 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2377 int len
= strlen (ascii_font
) + 1;
2380 for (i
= 0, p
= ascii_font
; i
< 8; p
++)
2389 base_fontname
= (char *) alloca (len
);
2390 bzero (base_fontname
, len
);
2391 strcpy (base_fontname
, "-*-*-");
2392 bcopy (p1
, base_fontname
+ 5, p
- p1
);
2393 strcat (base_fontname
, "*-*-*-*-*-*-*");
2396 xfs
= xic_create_xfontset (f
, base_fontname
);
2398 /* Determine XIC style. */
2401 XIMStyles supported_list
;
2402 supported_list
.count_styles
= (sizeof supported_xim_styles
2403 / sizeof supported_xim_styles
[0]);
2404 supported_list
.supported_styles
= supported_xim_styles
;
2405 xic_style
= best_xim_style (&supported_list
,
2406 FRAME_X_XIM_STYLES (f
));
2409 preedit_attr
= XVaCreateNestedList (0,
2412 FRAME_FOREGROUND_PIXEL (f
),
2414 FRAME_BACKGROUND_PIXEL (f
),
2415 (xic_style
& XIMPreeditPosition
2420 status_attr
= XVaCreateNestedList (0,
2426 FRAME_FOREGROUND_PIXEL (f
),
2428 FRAME_BACKGROUND_PIXEL (f
),
2431 xic
= XCreateIC (xim
,
2432 XNInputStyle
, xic_style
,
2433 XNClientWindow
, FRAME_X_WINDOW(f
),
2434 XNFocusWindow
, FRAME_X_WINDOW(f
),
2435 XNStatusAttributes
, status_attr
,
2436 XNPreeditAttributes
, preedit_attr
,
2438 XFree (preedit_attr
);
2439 XFree (status_attr
);
2442 FRAME_XIC (f
) = xic
;
2443 FRAME_XIC_STYLE (f
) = xic_style
;
2444 FRAME_XIC_FONTSET (f
) = xfs
;
2448 /* Destroy XIC and free XIC fontset of frame F, if any. */
2454 if (FRAME_XIC (f
) == NULL
)
2457 XDestroyIC (FRAME_XIC (f
));
2458 if (FRAME_XIC_FONTSET (f
))
2459 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2461 FRAME_XIC (f
) = NULL
;
2462 FRAME_XIC_FONTSET (f
) = NULL
;
2466 /* Place preedit area for XIC of window W's frame to specified
2467 pixel position X/Y. X and Y are relative to window W. */
2470 xic_set_preeditarea (w
, x
, y
)
2474 struct frame
*f
= XFRAME (w
->frame
);
2478 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
);
2479 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2480 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2481 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2486 /* Place status area for XIC in bottom right corner of frame F.. */
2489 xic_set_statusarea (f
)
2492 XIC xic
= FRAME_XIC (f
);
2497 /* Negotiate geometry of status area. If input method has existing
2498 status area, use its current size. */
2499 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2500 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2501 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2504 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2505 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2508 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2510 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2511 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2515 area
.width
= needed
->width
;
2516 area
.height
= needed
->height
;
2517 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2518 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2519 - FRAME_MENUBAR_HEIGHT (f
)
2520 - FRAME_TOOLBAR_HEIGHT (f
)
2521 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2524 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2525 XSetICValues(xic
, XNStatusAttributes
, attr
, NULL
);
2530 /* Set X fontset for XIC of frame F, using base font name
2531 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2534 xic_set_xfontset (f
, base_fontname
)
2536 char *base_fontname
;
2541 xfs
= xic_create_xfontset (f
, base_fontname
);
2543 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2544 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2545 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2546 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2547 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2550 if (FRAME_XIC_FONTSET (f
))
2551 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2552 FRAME_XIC_FONTSET (f
) = xfs
;
2555 #endif /* HAVE_X_I18N */
2559 #ifdef USE_X_TOOLKIT
2561 /* Create and set up the X widget for frame F. */
2564 x_window (f
, window_prompting
, minibuffer_only
)
2566 long window_prompting
;
2567 int minibuffer_only
;
2569 XClassHint class_hints
;
2570 XSetWindowAttributes attributes
;
2571 unsigned long attribute_mask
;
2572 Widget shell_widget
;
2574 Widget frame_widget
;
2580 /* Use the resource name as the top-level widget name
2581 for looking up resources. Make a non-Lisp copy
2582 for the window manager, so GC relocation won't bother it.
2584 Elsewhere we specify the window name for the window manager. */
2587 char *str
= (char *) SDATA (Vx_resource_name
);
2588 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2589 strcpy (f
->namebuf
, str
);
2593 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2594 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2595 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2596 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2597 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2598 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2599 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2600 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2601 applicationShellWidgetClass
,
2602 FRAME_X_DISPLAY (f
), al
, ac
);
2604 f
->output_data
.x
->widget
= shell_widget
;
2605 /* maybe_set_screen_title_format (shell_widget); */
2607 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2608 (widget_value
*) NULL
,
2609 shell_widget
, False
,
2613 (lw_callback
) NULL
);
2616 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2617 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2618 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2619 XtSetValues (pane_widget
, al
, ac
);
2620 f
->output_data
.x
->column_widget
= pane_widget
;
2622 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2623 the emacs screen when changing menubar. This reduces flickering. */
2626 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2627 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2628 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2629 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2630 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2631 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2632 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2633 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2634 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2637 f
->output_data
.x
->edit_widget
= frame_widget
;
2639 XtManageChild (frame_widget
);
2641 /* Do some needed geometry management. */
2644 char *tem
, shell_position
[32];
2647 int extra_borders
= 0;
2649 = (f
->output_data
.x
->menubar_widget
2650 ? (f
->output_data
.x
->menubar_widget
->core
.height
2651 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2654 #if 0 /* Experimentally, we now get the right results
2655 for -geometry -0-0 without this. 24 Aug 96, rms. */
2656 if (FRAME_EXTERNAL_MENU_BAR (f
))
2659 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2660 menubar_size
+= ibw
;
2664 f
->output_data
.x
->menubar_height
= menubar_size
;
2667 /* Motif seems to need this amount added to the sizes
2668 specified for the shell widget. The Athena/Lucid widgets don't.
2669 Both conclusions reached experimentally. -- rms. */
2670 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2671 &extra_borders
, NULL
);
2675 /* Convert our geometry parameters into a geometry string
2677 Note that we do not specify here whether the position
2678 is a user-specified or program-specified one.
2679 We pass that information later, in x_wm_set_size_hints. */
2681 int left
= f
->left_pos
;
2682 int xneg
= window_prompting
& XNegative
;
2683 int top
= f
->top_pos
;
2684 int yneg
= window_prompting
& YNegative
;
2690 if (window_prompting
& USPosition
)
2691 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2692 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2693 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2694 (xneg
? '-' : '+'), left
,
2695 (yneg
? '-' : '+'), top
);
2697 sprintf (shell_position
, "=%dx%d",
2698 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2699 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2702 len
= strlen (shell_position
) + 1;
2703 /* We don't free this because we don't know whether
2704 it is safe to free it while the frame exists.
2705 It isn't worth the trouble of arranging to free it
2706 when the frame is deleted. */
2707 tem
= (char *) xmalloc (len
);
2708 strncpy (tem
, shell_position
, len
);
2709 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2710 XtSetValues (shell_widget
, al
, ac
);
2713 XtManageChild (pane_widget
);
2714 XtRealizeWidget (shell_widget
);
2716 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2718 validate_x_resource_name ();
2720 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2721 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2722 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2725 FRAME_XIC (f
) = NULL
;
2727 create_frame_xic (f
);
2730 f
->output_data
.x
->wm_hints
.input
= True
;
2731 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2732 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2733 &f
->output_data
.x
->wm_hints
);
2735 hack_wm_protocols (f
, shell_widget
);
2738 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2741 /* Do a stupid property change to force the server to generate a
2742 PropertyNotify event so that the event_stream server timestamp will
2743 be initialized to something relevant to the time we created the window.
2745 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2746 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2747 XA_ATOM
, 32, PropModeAppend
,
2748 (unsigned char*) NULL
, 0);
2750 /* Make all the standard events reach the Emacs frame. */
2751 attributes
.event_mask
= STANDARD_EVENT_SET
;
2756 /* XIM server might require some X events. */
2757 unsigned long fevent
= NoEventMask
;
2758 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2759 attributes
.event_mask
|= fevent
;
2761 #endif /* HAVE_X_I18N */
2763 attribute_mask
= CWEventMask
;
2764 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2765 attribute_mask
, &attributes
);
2767 XtMapWidget (frame_widget
);
2769 /* x_set_name normally ignores requests to set the name if the
2770 requested name is the same as the current name. This is the one
2771 place where that assumption isn't correct; f->name is set, but
2772 the X server hasn't been told. */
2775 int explicit = f
->explicit_name
;
2777 f
->explicit_name
= 0;
2780 x_set_name (f
, name
, explicit);
2783 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2784 f
->output_data
.x
->text_cursor
);
2788 /* This is a no-op, except under Motif. Make sure main areas are
2789 set to something reasonable, in case we get an error later. */
2790 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2793 #else /* not USE_X_TOOLKIT */
2799 if (! xg_create_frame_widgets (f
))
2800 error ("Unable to create window");
2803 FRAME_XIC (f
) = NULL
;
2807 create_frame_xic (f
);
2810 /* XIM server might require some X events. */
2811 unsigned long fevent
= NoEventMask
;
2812 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2814 if (fevent
!= NoEventMask
)
2816 XSetWindowAttributes attributes
;
2817 XWindowAttributes wattr
;
2818 unsigned long attribute_mask
;
2820 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2822 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2823 attribute_mask
= CWEventMask
;
2824 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2825 attribute_mask
, &attributes
);
2833 #else /*! USE_GTK */
2834 /* Create and set up the X window for frame F. */
2841 XClassHint class_hints
;
2842 XSetWindowAttributes attributes
;
2843 unsigned long attribute_mask
;
2845 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2846 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2847 attributes
.bit_gravity
= StaticGravity
;
2848 attributes
.backing_store
= NotUseful
;
2849 attributes
.save_under
= True
;
2850 attributes
.event_mask
= STANDARD_EVENT_SET
;
2851 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2852 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2857 = XCreateWindow (FRAME_X_DISPLAY (f
),
2858 f
->output_data
.x
->parent_desc
,
2861 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2863 CopyFromParent
, /* depth */
2864 InputOutput
, /* class */
2866 attribute_mask
, &attributes
);
2871 create_frame_xic (f
);
2874 /* XIM server might require some X events. */
2875 unsigned long fevent
= NoEventMask
;
2876 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2877 attributes
.event_mask
|= fevent
;
2878 attribute_mask
= CWEventMask
;
2879 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2880 attribute_mask
, &attributes
);
2883 #endif /* HAVE_X_I18N */
2885 validate_x_resource_name ();
2887 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2888 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2889 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2891 /* The menubar is part of the ordinary display;
2892 it does not count in addition to the height of the window. */
2893 f
->output_data
.x
->menubar_height
= 0;
2895 /* This indicates that we use the "Passive Input" input model.
2896 Unless we do this, we don't get the Focus{In,Out} events that we
2897 need to draw the cursor correctly. Accursed bureaucrats.
2898 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2900 f
->output_data
.x
->wm_hints
.input
= True
;
2901 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2902 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2903 &f
->output_data
.x
->wm_hints
);
2904 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2906 /* Request "save yourself" and "delete window" commands from wm. */
2909 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2910 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2911 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2914 /* x_set_name normally ignores requests to set the name if the
2915 requested name is the same as the current name. This is the one
2916 place where that assumption isn't correct; f->name is set, but
2917 the X server hasn't been told. */
2920 int explicit = f
->explicit_name
;
2922 f
->explicit_name
= 0;
2925 x_set_name (f
, name
, explicit);
2928 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2929 f
->output_data
.x
->text_cursor
);
2933 if (FRAME_X_WINDOW (f
) == 0)
2934 error ("Unable to create window");
2937 #endif /* not USE_GTK */
2938 #endif /* not USE_X_TOOLKIT */
2940 /* Handle the icon stuff for this window. Perhaps later we might
2941 want an x_set_icon_position which can be called interactively as
2949 Lisp_Object icon_x
, icon_y
;
2950 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2952 /* Set the position of the icon. Note that twm groups all
2953 icons in an icon window. */
2954 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2955 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2956 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2958 CHECK_NUMBER (icon_x
);
2959 CHECK_NUMBER (icon_y
);
2961 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2962 error ("Both left and top icon corners of icon must be specified");
2966 if (! EQ (icon_x
, Qunbound
))
2967 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2969 /* Start up iconic or window? */
2970 x_wm_set_window_state
2971 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2976 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
2983 /* Make the GCs needed for this window, setting the
2984 background, border and mouse colors; also create the
2985 mouse cursor and the gray border tile. */
2987 static char cursor_bits
[] =
2989 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2990 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2999 XGCValues gc_values
;
3003 /* Create the GCs of this frame.
3004 Note that many default values are used. */
3007 gc_values
.font
= FRAME_FONT (f
)->fid
;
3008 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
3009 gc_values
.background
= f
->output_data
.x
->background_pixel
;
3010 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
3011 f
->output_data
.x
->normal_gc
3012 = XCreateGC (FRAME_X_DISPLAY (f
),
3014 GCLineWidth
| GCFont
| GCForeground
| GCBackground
,
3017 /* Reverse video style. */
3018 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3019 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
3020 f
->output_data
.x
->reverse_gc
3021 = XCreateGC (FRAME_X_DISPLAY (f
),
3023 GCFont
| GCForeground
| GCBackground
| GCLineWidth
,
3026 /* Cursor has cursor-color background, background-color foreground. */
3027 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3028 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
3029 gc_values
.fill_style
= FillOpaqueStippled
;
3031 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
3032 FRAME_X_DISPLAY_INFO (f
)->root_window
,
3033 cursor_bits
, 16, 16);
3034 f
->output_data
.x
->cursor_gc
3035 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3036 (GCFont
| GCForeground
| GCBackground
3037 | GCFillStyle
/* | GCStipple */ | GCLineWidth
),
3041 f
->output_data
.x
->white_relief
.gc
= 0;
3042 f
->output_data
.x
->black_relief
.gc
= 0;
3044 /* Create the gray border tile used when the pointer is not in
3045 the frame. Since this depends on the frame's pixel values,
3046 this must be done on a per-frame basis. */
3047 f
->output_data
.x
->border_tile
3048 = (XCreatePixmapFromBitmapData
3049 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
3050 gray_bits
, gray_width
, gray_height
,
3051 f
->output_data
.x
->foreground_pixel
,
3052 f
->output_data
.x
->background_pixel
,
3053 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
3059 /* Free what was was allocated in x_make_gc. */
3065 Display
*dpy
= FRAME_X_DISPLAY (f
);
3069 if (f
->output_data
.x
->normal_gc
)
3071 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
3072 f
->output_data
.x
->normal_gc
= 0;
3075 if (f
->output_data
.x
->reverse_gc
)
3077 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
3078 f
->output_data
.x
->reverse_gc
= 0;
3081 if (f
->output_data
.x
->cursor_gc
)
3083 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
3084 f
->output_data
.x
->cursor_gc
= 0;
3087 if (f
->output_data
.x
->border_tile
)
3089 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
3090 f
->output_data
.x
->border_tile
= 0;
3097 /* Handler for signals raised during x_create_frame and
3098 x_create_top_frame. FRAME is the frame which is partially
3102 unwind_create_frame (frame
)
3105 struct frame
*f
= XFRAME (frame
);
3107 /* If frame is ``official'', nothing to do. */
3108 if (!CONSP (Vframe_list
) || !EQ (XCAR (Vframe_list
), frame
))
3111 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3114 x_free_frame_resources (f
);
3116 /* Check that reference counts are indeed correct. */
3117 xassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
3118 xassert (dpyinfo
->image_cache
->refcount
== image_cache_refcount
);
3126 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3128 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
3129 Returns an Emacs frame object.
3130 ALIST is an alist of frame parameters.
3131 If the parameters specify that the frame should not have a minibuffer,
3132 and do not specify a specific minibuffer window to use,
3133 then `default-minibuffer-frame' must be a frame whose minibuffer can
3134 be shared by the new frame.
3136 This function is an internal primitive--use `make-frame' instead. */)
3141 Lisp_Object frame
, tem
;
3143 int minibuffer_only
= 0;
3144 long window_prompting
= 0;
3146 int count
= SPECPDL_INDEX ();
3147 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3148 Lisp_Object display
;
3149 struct x_display_info
*dpyinfo
= NULL
;
3155 /* Use this general default value to start with
3156 until we know if this frame has a specified name. */
3157 Vx_resource_name
= Vinvocation_name
;
3159 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3160 if (EQ (display
, Qunbound
))
3162 dpyinfo
= check_x_display_info (display
);
3164 kb
= dpyinfo
->kboard
;
3166 kb
= &the_only_kboard
;
3169 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3171 && ! EQ (name
, Qunbound
)
3173 error ("Invalid frame name--not a string or nil");
3176 Vx_resource_name
= name
;
3178 /* See if parent window is specified. */
3179 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3180 if (EQ (parent
, Qunbound
))
3182 if (! NILP (parent
))
3183 CHECK_NUMBER (parent
);
3185 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3186 /* No need to protect DISPLAY because that's not used after passing
3187 it to make_frame_without_minibuffer. */
3189 GCPRO4 (parms
, parent
, name
, frame
);
3190 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3192 if (EQ (tem
, Qnone
) || NILP (tem
))
3193 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3194 else if (EQ (tem
, Qonly
))
3196 f
= make_minibuffer_frame ();
3197 minibuffer_only
= 1;
3199 else if (WINDOWP (tem
))
3200 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3204 XSETFRAME (frame
, f
);
3206 /* Note that X Windows does support scroll bars. */
3207 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3209 f
->output_method
= output_x_window
;
3210 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3211 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3212 f
->output_data
.x
->icon_bitmap
= -1;
3213 FRAME_FONTSET (f
) = -1;
3214 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3215 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3216 #ifdef USE_TOOLKIT_SCROLL_BARS
3217 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3218 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3219 #endif /* USE_TOOLKIT_SCROLL_BARS */
3220 record_unwind_protect (unwind_create_frame
, frame
);
3223 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3225 if (! STRINGP (f
->icon_name
))
3226 f
->icon_name
= Qnil
;
3228 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3230 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
3231 dpyinfo_refcount
= dpyinfo
->reference_count
;
3232 #endif /* GLYPH_DEBUG */
3234 FRAME_KBOARD (f
) = kb
;
3237 /* These colors will be set anyway later, but it's important
3238 to get the color reference counts right, so initialize them! */
3241 struct gcpro gcpro1
;
3243 /* Function x_decode_color can signal an error. Make
3244 sure to initialize color slots so that we won't try
3245 to free colors we haven't allocated. */
3246 f
->output_data
.x
->foreground_pixel
= -1;
3247 f
->output_data
.x
->background_pixel
= -1;
3248 f
->output_data
.x
->cursor_pixel
= -1;
3249 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3250 f
->output_data
.x
->border_pixel
= -1;
3251 f
->output_data
.x
->mouse_pixel
= -1;
3253 black
= build_string ("black");
3255 f
->output_data
.x
->foreground_pixel
3256 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3257 f
->output_data
.x
->background_pixel
3258 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3259 f
->output_data
.x
->cursor_pixel
3260 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3261 f
->output_data
.x
->cursor_foreground_pixel
3262 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3263 f
->output_data
.x
->border_pixel
3264 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3265 f
->output_data
.x
->mouse_pixel
3266 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3270 /* Specify the parent under which to make this X window. */
3274 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3275 f
->output_data
.x
->explicit_parent
= 1;
3279 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3280 f
->output_data
.x
->explicit_parent
= 0;
3283 /* Set the name; the functions to which we pass f expect the name to
3285 if (EQ (name
, Qunbound
) || NILP (name
))
3287 f
->name
= build_string (dpyinfo
->x_id_name
);
3288 f
->explicit_name
= 0;
3293 f
->explicit_name
= 1;
3294 /* use the frame's title when getting resources for this frame. */
3295 specbind (Qx_resource_name
, name
);
3298 /* Extract the window parameters from the supplied values
3299 that are needed to determine window geometry. */
3303 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3306 /* First, try whatever font the caller has specified. */
3309 tem
= Fquery_fontset (font
, Qnil
);
3311 font
= x_new_fontset (f
, SDATA (tem
));
3313 font
= x_new_font (f
, SDATA (font
));
3316 /* Try out a font which we hope has bold and italic variations. */
3317 if (!STRINGP (font
))
3318 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
3319 if (!STRINGP (font
))
3320 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3321 if (! STRINGP (font
))
3322 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3323 if (! STRINGP (font
))
3324 /* This was formerly the first thing tried, but it finds too many fonts
3325 and takes too long. */
3326 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3327 /* If those didn't work, look for something which will at least work. */
3328 if (! STRINGP (font
))
3329 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3331 if (! STRINGP (font
))
3332 font
= build_string ("fixed");
3334 x_default_parameter (f
, parms
, Qfont
, font
,
3335 "font", "Font", RES_TYPE_STRING
);
3339 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3340 whereby it fails to get any font. */
3341 xlwmenu_default_font
= FRAME_FONT (f
);
3344 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3345 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3347 /* This defaults to 1 in order to match xterm. We recognize either
3348 internalBorderWidth or internalBorder (which is what xterm calls
3350 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3354 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3355 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3356 if (! EQ (value
, Qunbound
))
3357 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3360 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3361 "internalBorderWidth", "internalBorderWidth",
3363 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3364 "verticalScrollBars", "ScrollBars",
3367 /* Also do the stuff which must be set before the window exists. */
3368 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3369 "foreground", "Foreground", RES_TYPE_STRING
);
3370 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3371 "background", "Background", RES_TYPE_STRING
);
3372 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3373 "pointerColor", "Foreground", RES_TYPE_STRING
);
3374 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3375 "cursorColor", "Foreground", RES_TYPE_STRING
);
3376 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3377 "borderColor", "BorderColor", RES_TYPE_STRING
);
3378 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3379 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3380 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3381 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3382 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3383 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3384 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3385 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3387 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3388 "scrollBarForeground",
3389 "ScrollBarForeground", 1);
3390 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3391 "scrollBarBackground",
3392 "ScrollBarBackground", 0);
3394 /* Init faces before x_default_parameter is called for scroll-bar
3395 parameters because that function calls x_set_scroll_bar_width,
3396 which calls change_frame_size, which calls Fset_window_buffer,
3397 which runs hooks, which call Fvertical_motion. At the end, we
3398 end up in init_iterator with a null face cache, which should not
3400 init_frame_faces (f
);
3402 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3403 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3404 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (1),
3405 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3406 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3407 "bufferPredicate", "BufferPredicate",
3409 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3410 "title", "Title", RES_TYPE_STRING
);
3411 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3412 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3413 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3414 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3416 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3418 /* Compute the size of the X window. */
3419 window_prompting
= x_figure_window_size (f
, parms
, 1);
3421 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3422 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3424 /* Create the X widget or window. */
3425 #ifdef USE_X_TOOLKIT
3426 x_window (f
, window_prompting
, minibuffer_only
);
3434 /* Now consider the frame official. */
3435 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3436 Vframe_list
= Fcons (frame
, Vframe_list
);
3438 /* We need to do this after creating the X window, so that the
3439 icon-creation functions can say whose icon they're describing. */
3440 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3441 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
3443 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3444 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3445 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3446 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3447 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3448 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3449 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3450 "scrollBarWidth", "ScrollBarWidth",
3453 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3454 Change will not be effected unless different from the current
3456 width
= FRAME_COLS (f
);
3457 height
= FRAME_LINES (f
);
3459 SET_FRAME_COLS (f
, 0);
3460 FRAME_LINES (f
) = 0;
3461 change_frame_size (f
, height
, width
, 1, 0, 0);
3463 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3464 /* Create the menu bar. */
3465 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3467 /* If this signals an error, we haven't set size hints for the
3468 frame and we didn't make it visible. */
3469 initialize_frame_menubar (f
);
3472 /* This is a no-op, except under Motif where it arranges the
3473 main window for the widgets on it. */
3474 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3475 f
->output_data
.x
->menubar_widget
,
3476 f
->output_data
.x
->edit_widget
);
3477 #endif /* not USE_GTK */
3479 #endif /* USE_X_TOOLKIT || USE_GTK */
3481 /* Tell the server what size and position, etc, we want, and how
3482 badly we want them. This should be done after we have the menu
3483 bar so that its size can be taken into account. */
3485 x_wm_set_size_hint (f
, window_prompting
, 0);
3488 /* Make the window appear on the frame and enable display, unless
3489 the caller says not to. However, with explicit parent, Emacs
3490 cannot control visibility, so don't try. */
3491 if (! f
->output_data
.x
->explicit_parent
)
3493 Lisp_Object visibility
;
3495 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3497 if (EQ (visibility
, Qunbound
))
3500 if (EQ (visibility
, Qicon
))
3501 x_iconify_frame (f
);
3502 else if (! NILP (visibility
))
3503 x_make_frame_visible (f
);
3505 /* Must have been Qnil. */
3511 /* Make sure windows on this frame appear in calls to next-window
3512 and similar functions. */
3513 Vwindow_list
= Qnil
;
3515 return unbind_to (count
, frame
);
3519 /* FRAME is used only to get a handle on the X display. We don't pass the
3520 display info directly because we're called from frame.c, which doesn't
3521 know about that structure. */
3524 x_get_focus_frame (frame
)
3525 struct frame
*frame
;
3527 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3529 if (! dpyinfo
->x_focus_frame
)
3532 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3537 /* In certain situations, when the window manager follows a
3538 click-to-focus policy, there seems to be no way around calling
3539 XSetInputFocus to give another frame the input focus .
3541 In an ideal world, XSetInputFocus should generally be avoided so
3542 that applications don't interfere with the window manager's focus
3543 policy. But I think it's okay to use when it's clearly done
3544 following a user-command. */
3546 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
3547 doc
: /* Set the input focus to FRAME.
3548 FRAME nil means use the selected frame. */)
3552 struct frame
*f
= check_x_frame (frame
);
3553 Display
*dpy
= FRAME_X_DISPLAY (f
);
3557 count
= x_catch_errors (dpy
);
3558 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3559 RevertToParent
, CurrentTime
);
3560 x_uncatch_errors (dpy
, count
);
3567 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3568 doc
: /* Internal function called by `color-defined-p', which see. */)
3570 Lisp_Object color
, frame
;
3573 FRAME_PTR f
= check_x_frame (frame
);
3575 CHECK_STRING (color
);
3577 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3583 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3584 doc
: /* Internal function called by `color-values', which see. */)
3586 Lisp_Object color
, frame
;
3589 FRAME_PTR f
= check_x_frame (frame
);
3591 CHECK_STRING (color
);
3593 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3597 rgb
[0] = make_number (foo
.red
);
3598 rgb
[1] = make_number (foo
.green
);
3599 rgb
[2] = make_number (foo
.blue
);
3600 return Flist (3, rgb
);
3606 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3607 doc
: /* Internal function called by `display-color-p', which see. */)
3609 Lisp_Object display
;
3611 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3613 if (dpyinfo
->n_planes
<= 2)
3616 switch (dpyinfo
->visual
->class)
3629 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3631 doc
: /* Return t if the X display supports shades of gray.
3632 Note that color displays do support shades of gray.
3633 The optional argument DISPLAY specifies which display to ask about.
3634 DISPLAY should be either a frame or a display name (a string).
3635 If omitted or nil, that stands for the selected frame's display. */)
3637 Lisp_Object display
;
3639 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3641 if (dpyinfo
->n_planes
<= 1)
3644 switch (dpyinfo
->visual
->class)
3659 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3661 doc
: /* Returns the width in pixels of the X display DISPLAY.
3662 The optional argument DISPLAY specifies which display to ask about.
3663 DISPLAY should be either a frame or a display name (a string).
3664 If omitted or nil, that stands for the selected frame's display. */)
3666 Lisp_Object display
;
3668 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3670 return make_number (dpyinfo
->width
);
3673 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3674 Sx_display_pixel_height
, 0, 1, 0,
3675 doc
: /* Returns the height in pixels of the X display DISPLAY.
3676 The optional argument DISPLAY specifies which display to ask about.
3677 DISPLAY should be either a frame or a display name (a string).
3678 If omitted or nil, that stands for the selected frame's display. */)
3680 Lisp_Object display
;
3682 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3684 return make_number (dpyinfo
->height
);
3687 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3689 doc
: /* Returns the number of bitplanes of the X display DISPLAY.
3690 The optional argument DISPLAY specifies which display to ask about.
3691 DISPLAY should be either a frame or a display name (a string).
3692 If omitted or nil, that stands for the selected frame's display. */)
3694 Lisp_Object display
;
3696 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3698 return make_number (dpyinfo
->n_planes
);
3701 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3703 doc
: /* Returns the number of color cells of the X display DISPLAY.
3704 The optional argument DISPLAY specifies which display to ask about.
3705 DISPLAY should be either a frame or a display name (a string).
3706 If omitted or nil, that stands for the selected frame's display. */)
3708 Lisp_Object display
;
3710 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3712 return make_number (DisplayCells (dpyinfo
->display
,
3713 XScreenNumberOfScreen (dpyinfo
->screen
)));
3716 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3717 Sx_server_max_request_size
,
3719 doc
: /* Returns the maximum request size of the X server of display DISPLAY.
3720 The optional argument DISPLAY specifies which display to ask about.
3721 DISPLAY should be either a frame or a display name (a string).
3722 If omitted or nil, that stands for the selected frame's display. */)
3724 Lisp_Object display
;
3726 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3728 return make_number (MAXREQUEST (dpyinfo
->display
));
3731 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3732 doc
: /* Returns the vendor ID string of the X server of display DISPLAY.
3733 The optional argument DISPLAY specifies which display to ask about.
3734 DISPLAY should be either a frame or a display name (a string).
3735 If omitted or nil, that stands for the selected frame's display. */)
3737 Lisp_Object display
;
3739 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3740 char *vendor
= ServerVendor (dpyinfo
->display
);
3742 if (! vendor
) vendor
= "";
3743 return build_string (vendor
);
3746 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3747 doc
: /* Returns the version numbers of the X server of display DISPLAY.
3748 The value is a list of three integers: the major and minor
3749 version numbers of the X Protocol in use, and the vendor-specific release
3750 number. See also the function `x-server-vendor'.
3752 The optional argument DISPLAY specifies which display to ask about.
3753 DISPLAY should be either a frame or a display name (a string).
3754 If omitted or nil, that stands for the selected frame's display. */)
3756 Lisp_Object display
;
3758 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3759 Display
*dpy
= dpyinfo
->display
;
3761 return Fcons (make_number (ProtocolVersion (dpy
)),
3762 Fcons (make_number (ProtocolRevision (dpy
)),
3763 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3766 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3767 doc
: /* Return the number of screens on the X server of display DISPLAY.
3768 The optional argument DISPLAY specifies which display to ask about.
3769 DISPLAY should be either a frame or a display name (a string).
3770 If omitted or nil, that stands for the selected frame's display. */)
3772 Lisp_Object display
;
3774 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3776 return make_number (ScreenCount (dpyinfo
->display
));
3779 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3780 doc
: /* Return the height in millimeters of the X display DISPLAY.
3781 The optional argument DISPLAY specifies which display to ask about.
3782 DISPLAY should be either a frame or a display name (a string).
3783 If omitted or nil, that stands for the selected frame's display. */)
3785 Lisp_Object display
;
3787 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3789 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3792 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3793 doc
: /* Return the width in millimeters of the X display DISPLAY.
3794 The optional argument DISPLAY specifies which display to ask about.
3795 DISPLAY should be either a frame or a display name (a string).
3796 If omitted or nil, that stands for the selected frame's display. */)
3798 Lisp_Object display
;
3800 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3802 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3805 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3806 Sx_display_backing_store
, 0, 1, 0,
3807 doc
: /* Returns an indication of whether X display DISPLAY does backing store.
3808 The value may be `always', `when-mapped', or `not-useful'.
3809 The optional argument DISPLAY specifies which display to ask about.
3810 DISPLAY should be either a frame or a display name (a string).
3811 If omitted or nil, that stands for the selected frame's display. */)
3813 Lisp_Object display
;
3815 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3818 switch (DoesBackingStore (dpyinfo
->screen
))
3821 result
= intern ("always");
3825 result
= intern ("when-mapped");
3829 result
= intern ("not-useful");
3833 error ("Strange value for BackingStore parameter of screen");
3840 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3841 Sx_display_visual_class
, 0, 1, 0,
3842 doc
: /* Return the visual class of the X display DISPLAY.
3843 The value is one of the symbols `static-gray', `gray-scale',
3844 `static-color', `pseudo-color', `true-color', or `direct-color'.
3846 The optional argument DISPLAY specifies which display to ask about.
3847 DISPLAY should be either a frame or a display name (a string).
3848 If omitted or nil, that stands for the selected frame's display. */)
3850 Lisp_Object display
;
3852 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3855 switch (dpyinfo
->visual
->class)
3858 result
= intern ("static-gray");
3861 result
= intern ("gray-scale");
3864 result
= intern ("static-color");
3867 result
= intern ("pseudo-color");
3870 result
= intern ("true-color");
3873 result
= intern ("direct-color");
3876 error ("Display has an unknown visual class");
3883 DEFUN ("x-display-save-under", Fx_display_save_under
,
3884 Sx_display_save_under
, 0, 1, 0,
3885 doc
: /* Returns t if the X display DISPLAY supports the save-under feature.
3886 The optional argument DISPLAY specifies which display to ask about.
3887 DISPLAY should be either a frame or a display name (a string).
3888 If omitted or nil, that stands for the selected frame's display. */)
3890 Lisp_Object display
;
3892 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3894 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3902 register struct frame
*f
;
3904 return FRAME_PIXEL_WIDTH (f
);
3909 register struct frame
*f
;
3911 return FRAME_PIXEL_HEIGHT (f
);
3916 register struct frame
*f
;
3918 return FRAME_COLUMN_WIDTH (f
);
3923 register struct frame
*f
;
3925 return FRAME_LINE_HEIGHT (f
);
3930 register struct frame
*f
;
3932 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
3937 /************************************************************************
3939 ************************************************************************/
3942 /* Mapping visual names to visuals. */
3944 static struct visual_class
3951 {"StaticGray", StaticGray
},
3952 {"GrayScale", GrayScale
},
3953 {"StaticColor", StaticColor
},
3954 {"PseudoColor", PseudoColor
},
3955 {"TrueColor", TrueColor
},
3956 {"DirectColor", DirectColor
},
3961 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3963 /* Value is the screen number of screen SCR. This is a substitute for
3964 the X function with the same name when that doesn't exist. */
3967 XScreenNumberOfScreen (scr
)
3968 register Screen
*scr
;
3970 Display
*dpy
= scr
->display
;
3973 for (i
= 0; i
< dpy
->nscreens
; ++i
)
3974 if (scr
== dpy
->screens
+ i
)
3980 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3983 /* Select the visual that should be used on display DPYINFO. Set
3984 members of DPYINFO appropriately. Called from x_term_init. */
3987 select_visual (dpyinfo
)
3988 struct x_display_info
*dpyinfo
;
3990 Display
*dpy
= dpyinfo
->display
;
3991 Screen
*screen
= dpyinfo
->screen
;
3994 /* See if a visual is specified. */
3995 value
= display_x_get_resource (dpyinfo
,
3996 build_string ("visualClass"),
3997 build_string ("VisualClass"),
3999 if (STRINGP (value
))
4001 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4002 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4003 depth, a decimal number. NAME is compared with case ignored. */
4004 char *s
= (char *) alloca (SBYTES (value
) + 1);
4009 strcpy (s
, SDATA (value
));
4010 dash
= index (s
, '-');
4013 dpyinfo
->n_planes
= atoi (dash
+ 1);
4017 /* We won't find a matching visual with depth 0, so that
4018 an error will be printed below. */
4019 dpyinfo
->n_planes
= 0;
4021 /* Determine the visual class. */
4022 for (i
= 0; visual_classes
[i
].name
; ++i
)
4023 if (xstricmp (s
, visual_classes
[i
].name
) == 0)
4025 class = visual_classes
[i
].class;
4029 /* Look up a matching visual for the specified class. */
4031 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4032 dpyinfo
->n_planes
, class, &vinfo
))
4033 fatal ("Invalid visual specification `%s'", SDATA (value
));
4035 dpyinfo
->visual
= vinfo
.visual
;
4040 XVisualInfo
*vinfo
, vinfo_template
;
4042 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4045 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4047 vinfo_template
.visualid
= dpyinfo
->visual
->visualid
;
4049 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4050 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4051 &vinfo_template
, &n_visuals
);
4053 fatal ("Can't get proper X visual info");
4055 dpyinfo
->n_planes
= vinfo
->depth
;
4056 XFree ((char *) vinfo
);
4061 /* Return the X display structure for the display named NAME.
4062 Open a new connection if necessary. */
4064 struct x_display_info
*
4065 x_display_info_for_name (name
)
4069 struct x_display_info
*dpyinfo
;
4071 CHECK_STRING (name
);
4073 if (! EQ (Vwindow_system
, intern ("x")))
4074 error ("Not using X Windows");
4076 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4078 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4081 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4086 /* Use this general default value to start with. */
4087 Vx_resource_name
= Vinvocation_name
;
4089 validate_x_resource_name ();
4091 dpyinfo
= x_term_init (name
, (char *)0,
4092 (char *) SDATA (Vx_resource_name
));
4095 error ("Cannot connect to X server %s", SDATA (name
));
4098 XSETFASTINT (Vwindow_system_version
, 11);
4104 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4106 doc
: /* Open a connection to an X server.
4107 DISPLAY is the name of the display to connect to.
4108 Optional second arg XRM-STRING is a string of resources in xrdb format.
4109 If the optional third arg MUST-SUCCEED is non-nil,
4110 terminate Emacs if we can't open the connection. */)
4111 (display
, xrm_string
, must_succeed
)
4112 Lisp_Object display
, xrm_string
, must_succeed
;
4114 unsigned char *xrm_option
;
4115 struct x_display_info
*dpyinfo
;
4117 CHECK_STRING (display
);
4118 if (! NILP (xrm_string
))
4119 CHECK_STRING (xrm_string
);
4121 if (! EQ (Vwindow_system
, intern ("x")))
4122 error ("Not using X Windows");
4124 if (! NILP (xrm_string
))
4125 xrm_option
= (unsigned char *) SDATA (xrm_string
);
4127 xrm_option
= (unsigned char *) 0;
4129 validate_x_resource_name ();
4131 /* This is what opens the connection and sets x_current_display.
4132 This also initializes many symbols, such as those used for input. */
4133 dpyinfo
= x_term_init (display
, xrm_option
,
4134 (char *) SDATA (Vx_resource_name
));
4138 if (!NILP (must_succeed
))
4139 fatal ("Cannot connect to X server %s.\n\
4140 Check the DISPLAY environment variable or use `-d'.\n\
4141 Also use the `xauth' program to verify that you have the proper\n\
4142 authorization information needed to connect the X server.\n\
4143 An insecure way to solve the problem may be to use `xhost'.\n",
4146 error ("Cannot connect to X server %s", SDATA (display
));
4151 XSETFASTINT (Vwindow_system_version
, 11);
4155 DEFUN ("x-close-connection", Fx_close_connection
,
4156 Sx_close_connection
, 1, 1, 0,
4157 doc
: /* Close the connection to DISPLAY's X server.
4158 For DISPLAY, specify either a frame or a display name (a string).
4159 If DISPLAY is nil, that stands for the selected frame's display. */)
4161 Lisp_Object display
;
4163 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4166 if (dpyinfo
->reference_count
> 0)
4167 error ("Display still has frames on it");
4170 /* Free the fonts in the font table. */
4171 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4172 if (dpyinfo
->font_table
[i
].name
)
4174 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
4175 xfree (dpyinfo
->font_table
[i
].full_name
);
4176 xfree (dpyinfo
->font_table
[i
].name
);
4177 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4180 x_destroy_all_bitmaps (dpyinfo
);
4181 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4183 #ifdef USE_X_TOOLKIT
4184 XtCloseDisplay (dpyinfo
->display
);
4186 XCloseDisplay (dpyinfo
->display
);
4189 x_delete_display (dpyinfo
);
4195 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4196 doc
: /* Return the list of display names that Emacs has connections to. */)
4199 Lisp_Object tail
, result
;
4202 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
4203 result
= Fcons (XCAR (XCAR (tail
)), result
);
4208 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4209 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4210 If ON is nil, allow buffering of requests.
4211 Turning on synchronization prohibits the Xlib routines from buffering
4212 requests and seriously degrades performance, but makes debugging much
4214 The optional second argument DISPLAY specifies which display to act on.
4215 DISPLAY should be either a frame or a display name (a string).
4216 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4218 Lisp_Object display
, on
;
4220 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4222 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4227 /* Wait for responses to all X commands issued so far for frame F. */
4234 XSync (FRAME_X_DISPLAY (f
), False
);
4239 /***********************************************************************
4241 ***********************************************************************/
4243 /* Value is the number of elements of vector VECTOR. */
4245 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
4247 /* List of supported image types. Use define_image_type to add new
4248 types. Use lookup_image_type to find a type for a given symbol. */
4250 static struct image_type
*image_types
;
4252 /* The symbol `image' which is the car of the lists used to represent
4255 extern Lisp_Object Qimage
;
4257 /* The symbol `xbm' which is used as the type symbol for XBM images. */
4263 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
4264 extern Lisp_Object QCdata
, QCtype
;
4265 Lisp_Object QCascent
, QCmargin
, QCrelief
;
4266 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
4267 Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
;
4269 /* Other symbols. */
4271 Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
4273 /* Time in seconds after which images should be removed from the cache
4274 if not displayed. */
4276 Lisp_Object Vimage_cache_eviction_delay
;
4278 /* Function prototypes. */
4280 static void define_image_type
P_ ((struct image_type
*type
));
4281 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
4282 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
4283 static void x_laplace
P_ ((struct frame
*, struct image
*));
4284 static void x_emboss
P_ ((struct frame
*, struct image
*));
4285 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
4289 /* Define a new image type from TYPE. This adds a copy of TYPE to
4290 image_types and adds the symbol *TYPE->type to Vimage_types. */
4293 define_image_type (type
)
4294 struct image_type
*type
;
4296 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
4297 The initialized data segment is read-only. */
4298 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
4299 bcopy (type
, p
, sizeof *p
);
4300 p
->next
= image_types
;
4302 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
4306 /* Look up image type SYMBOL, and return a pointer to its image_type
4307 structure. Value is null if SYMBOL is not a known image type. */
4309 static INLINE
struct image_type
*
4310 lookup_image_type (symbol
)
4313 struct image_type
*type
;
4315 for (type
= image_types
; type
; type
= type
->next
)
4316 if (EQ (symbol
, *type
->type
))
4323 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
4324 valid image specification is a list whose car is the symbol
4325 `image', and whose rest is a property list. The property list must
4326 contain a value for key `:type'. That value must be the name of a
4327 supported image type. The rest of the property list depends on the
4331 valid_image_p (object
)
4336 if (CONSP (object
) && EQ (XCAR (object
), Qimage
))
4340 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
4341 if (EQ (XCAR (tem
), QCtype
))
4344 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
4346 struct image_type
*type
;
4347 type
= lookup_image_type (XCAR (tem
));
4349 valid_p
= type
->valid_p (object
);
4360 /* Log error message with format string FORMAT and argument ARG.
4361 Signaling an error, e.g. when an image cannot be loaded, is not a
4362 good idea because this would interrupt redisplay, and the error
4363 message display would lead to another redisplay. This function
4364 therefore simply displays a message. */
4367 image_error (format
, arg1
, arg2
)
4369 Lisp_Object arg1
, arg2
;
4371 add_to_log (format
, arg1
, arg2
);
4376 /***********************************************************************
4377 Image specifications
4378 ***********************************************************************/
4380 enum image_value_type
4382 IMAGE_DONT_CHECK_VALUE_TYPE
,
4384 IMAGE_STRING_OR_NIL_VALUE
,
4386 IMAGE_POSITIVE_INTEGER_VALUE
,
4387 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
4388 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
4390 IMAGE_INTEGER_VALUE
,
4391 IMAGE_FUNCTION_VALUE
,
4396 /* Structure used when parsing image specifications. */
4398 struct image_keyword
4400 /* Name of keyword. */
4403 /* The type of value allowed. */
4404 enum image_value_type type
;
4406 /* Non-zero means key must be present. */
4409 /* Used to recognize duplicate keywords in a property list. */
4412 /* The value that was found. */
4417 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
4419 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
4422 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
4423 has the format (image KEYWORD VALUE ...). One of the keyword/
4424 value pairs must be `:type TYPE'. KEYWORDS is a vector of
4425 image_keywords structures of size NKEYWORDS describing other
4426 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
4429 parse_image_spec (spec
, keywords
, nkeywords
, type
)
4431 struct image_keyword
*keywords
;
4438 if (!CONSP (spec
) || !EQ (XCAR (spec
), Qimage
))
4441 plist
= XCDR (spec
);
4442 while (CONSP (plist
))
4444 Lisp_Object key
, value
;
4446 /* First element of a pair must be a symbol. */
4448 plist
= XCDR (plist
);
4452 /* There must follow a value. */
4455 value
= XCAR (plist
);
4456 plist
= XCDR (plist
);
4458 /* Find key in KEYWORDS. Error if not found. */
4459 for (i
= 0; i
< nkeywords
; ++i
)
4460 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
4466 /* Record that we recognized the keyword. If a keywords
4467 was found more than once, it's an error. */
4468 keywords
[i
].value
= value
;
4469 ++keywords
[i
].count
;
4471 if (keywords
[i
].count
> 1)
4474 /* Check type of value against allowed type. */
4475 switch (keywords
[i
].type
)
4477 case IMAGE_STRING_VALUE
:
4478 if (!STRINGP (value
))
4482 case IMAGE_STRING_OR_NIL_VALUE
:
4483 if (!STRINGP (value
) && !NILP (value
))
4487 case IMAGE_SYMBOL_VALUE
:
4488 if (!SYMBOLP (value
))
4492 case IMAGE_POSITIVE_INTEGER_VALUE
:
4493 if (!INTEGERP (value
) || XINT (value
) <= 0)
4497 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
4498 if (INTEGERP (value
) && XINT (value
) >= 0)
4501 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
4502 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
4506 case IMAGE_ASCENT_VALUE
:
4507 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
4509 else if (INTEGERP (value
)
4510 && XINT (value
) >= 0
4511 && XINT (value
) <= 100)
4515 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
4516 if (!INTEGERP (value
) || XINT (value
) < 0)
4520 case IMAGE_DONT_CHECK_VALUE_TYPE
:
4523 case IMAGE_FUNCTION_VALUE
:
4524 value
= indirect_function (value
);
4526 || COMPILEDP (value
)
4527 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
4531 case IMAGE_NUMBER_VALUE
:
4532 if (!INTEGERP (value
) && !FLOATP (value
))
4536 case IMAGE_INTEGER_VALUE
:
4537 if (!INTEGERP (value
))
4541 case IMAGE_BOOL_VALUE
:
4542 if (!NILP (value
) && !EQ (value
, Qt
))
4551 if (EQ (key
, QCtype
) && !EQ (type
, value
))
4555 /* Check that all mandatory fields are present. */
4556 for (i
= 0; i
< nkeywords
; ++i
)
4557 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
4560 return NILP (plist
);
4564 /* Return the value of KEY in image specification SPEC. Value is nil
4565 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
4566 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
4569 image_spec_value (spec
, key
, found
)
4570 Lisp_Object spec
, key
;
4575 xassert (valid_image_p (spec
));
4577 for (tail
= XCDR (spec
);
4578 CONSP (tail
) && CONSP (XCDR (tail
));
4579 tail
= XCDR (XCDR (tail
)))
4581 if (EQ (XCAR (tail
), key
))
4585 return XCAR (XCDR (tail
));
4595 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
4596 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
4597 PIXELS non-nil means return the size in pixels, otherwise return the
4598 size in canonical character units.
4599 FRAME is the frame on which the image will be displayed. FRAME nil
4600 or omitted means use the selected frame. */)
4601 (spec
, pixels
, frame
)
4602 Lisp_Object spec
, pixels
, frame
;
4607 if (valid_image_p (spec
))
4609 struct frame
*f
= check_x_frame (frame
);
4610 int id
= lookup_image (f
, spec
);
4611 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4612 int width
= img
->width
+ 2 * img
->hmargin
;
4613 int height
= img
->height
+ 2 * img
->vmargin
;
4616 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
4617 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
4619 size
= Fcons (make_number (width
), make_number (height
));
4622 error ("Invalid image specification");
4628 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
4629 doc
: /* Return t if image SPEC has a mask bitmap.
4630 FRAME is the frame on which the image will be displayed. FRAME nil
4631 or omitted means use the selected frame. */)
4633 Lisp_Object spec
, frame
;
4638 if (valid_image_p (spec
))
4640 struct frame
*f
= check_x_frame (frame
);
4641 int id
= lookup_image (f
, spec
);
4642 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4647 error ("Invalid image specification");
4654 /***********************************************************************
4655 Image type independent image structures
4656 ***********************************************************************/
4658 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
4659 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
4662 /* Allocate and return a new image structure for image specification
4663 SPEC. SPEC has a hash value of HASH. */
4665 static struct image
*
4666 make_image (spec
, hash
)
4670 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
4672 xassert (valid_image_p (spec
));
4673 bzero (img
, sizeof *img
);
4674 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
4675 xassert (img
->type
!= NULL
);
4677 img
->data
.lisp_val
= Qnil
;
4678 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
4684 /* Free image IMG which was used on frame F, including its resources. */
4693 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4695 /* Remove IMG from the hash table of its cache. */
4697 img
->prev
->next
= img
->next
;
4699 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
4702 img
->next
->prev
= img
->prev
;
4704 c
->images
[img
->id
] = NULL
;
4706 /* Free resources, then free IMG. */
4707 img
->type
->free (f
, img
);
4713 /* Prepare image IMG for display on frame F. Must be called before
4714 drawing an image. */
4717 prepare_image_for_display (f
, img
)
4723 /* We're about to display IMG, so set its timestamp to `now'. */
4725 img
->timestamp
= EMACS_SECS (t
);
4727 /* If IMG doesn't have a pixmap yet, load it now, using the image
4728 type dependent loader function. */
4729 if (img
->pixmap
== None
&& !img
->load_failed_p
)
4730 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
4734 /* Value is the number of pixels for the ascent of image IMG when
4735 drawn in face FACE. */
4738 image_ascent (img
, face
)
4742 int height
= img
->height
+ img
->vmargin
;
4745 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
4748 /* This expression is arranged so that if the image can't be
4749 exactly centered, it will be moved slightly up. This is
4750 because a typical font is `top-heavy' (due to the presence
4751 uppercase letters), so the image placement should err towards
4752 being top-heavy too. It also just generally looks better. */
4753 ascent
= (height
+ face
->font
->ascent
- face
->font
->descent
+ 1) / 2;
4755 ascent
= height
/ 2;
4758 ascent
= height
* img
->ascent
/ 100.0;
4764 /* Image background colors. */
4766 static unsigned long
4767 four_corners_best (ximg
, width
, height
)
4769 unsigned long width
, height
;
4771 unsigned long corners
[4], best
;
4774 /* Get the colors at the corners of ximg. */
4775 corners
[0] = XGetPixel (ximg
, 0, 0);
4776 corners
[1] = XGetPixel (ximg
, width
- 1, 0);
4777 corners
[2] = XGetPixel (ximg
, width
- 1, height
- 1);
4778 corners
[3] = XGetPixel (ximg
, 0, height
- 1);
4780 /* Choose the most frequently found color as background. */
4781 for (i
= best_count
= 0; i
< 4; ++i
)
4785 for (j
= n
= 0; j
< 4; ++j
)
4786 if (corners
[i
] == corners
[j
])
4790 best
= corners
[i
], best_count
= n
;
4796 /* Return the `background' field of IMG. If IMG doesn't have one yet,
4797 it is guessed heuristically. If non-zero, XIMG is an existing XImage
4798 object to use for the heuristic. */
4801 image_background (img
, f
, ximg
)
4806 if (! img
->background_valid
)
4807 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4809 int free_ximg
= !ximg
;
4812 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4813 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4815 img
->background
= four_corners_best (ximg
, img
->width
, img
->height
);
4818 XDestroyImage (ximg
);
4820 img
->background_valid
= 1;
4823 return img
->background
;
4826 /* Return the `background_transparent' field of IMG. If IMG doesn't
4827 have one yet, it is guessed heuristically. If non-zero, MASK is an
4828 existing XImage object to use for the heuristic. */
4831 image_background_transparent (img
, f
, mask
)
4836 if (! img
->background_transparent_valid
)
4837 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4841 int free_mask
= !mask
;
4844 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
4845 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4847 img
->background_transparent
4848 = !four_corners_best (mask
, img
->width
, img
->height
);
4851 XDestroyImage (mask
);
4854 img
->background_transparent
= 0;
4856 img
->background_transparent_valid
= 1;
4859 return img
->background_transparent
;
4863 /***********************************************************************
4864 Helper functions for X image types
4865 ***********************************************************************/
4867 static void x_clear_image_1
P_ ((struct frame
*, struct image
*, int,
4869 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
4870 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
4872 Lisp_Object color_name
,
4873 unsigned long dflt
));
4876 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
4877 free the pixmap if any. MASK_P non-zero means clear the mask
4878 pixmap if any. COLORS_P non-zero means free colors allocated for
4879 the image, if any. */
4882 x_clear_image_1 (f
, img
, pixmap_p
, mask_p
, colors_p
)
4885 int pixmap_p
, mask_p
, colors_p
;
4887 if (pixmap_p
&& img
->pixmap
)
4889 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
4891 img
->background_valid
= 0;
4894 if (mask_p
&& img
->mask
)
4896 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4898 img
->background_transparent_valid
= 0;
4901 if (colors_p
&& img
->ncolors
)
4903 x_free_colors (f
, img
->colors
, img
->ncolors
);
4904 xfree (img
->colors
);
4910 /* Free X resources of image IMG which is used on frame F. */
4913 x_clear_image (f
, img
)
4918 x_clear_image_1 (f
, img
, 1, 1, 1);
4923 /* Allocate color COLOR_NAME for image IMG on frame F. If color
4924 cannot be allocated, use DFLT. Add a newly allocated color to
4925 IMG->colors, so that it can be freed again. Value is the pixel
4928 static unsigned long
4929 x_alloc_image_color (f
, img
, color_name
, dflt
)
4932 Lisp_Object color_name
;
4936 unsigned long result
;
4938 xassert (STRINGP (color_name
));
4940 if (x_defined_color (f
, SDATA (color_name
), &color
, 1))
4942 /* This isn't called frequently so we get away with simply
4943 reallocating the color vector to the needed size, here. */
4946 (unsigned long *) xrealloc (img
->colors
,
4947 img
->ncolors
* sizeof *img
->colors
);
4948 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
4949 result
= color
.pixel
;
4959 /***********************************************************************
4961 ***********************************************************************/
4963 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
4964 static void postprocess_image
P_ ((struct frame
*, struct image
*));
4967 /* Return a new, initialized image cache that is allocated from the
4968 heap. Call free_image_cache to free an image cache. */
4970 struct image_cache
*
4973 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
4976 bzero (c
, sizeof *c
);
4978 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
4979 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
4980 c
->buckets
= (struct image
**) xmalloc (size
);
4981 bzero (c
->buckets
, size
);
4986 /* Free image cache of frame F. Be aware that X frames share images
4990 free_image_cache (f
)
4993 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4998 /* Cache should not be referenced by any frame when freed. */
4999 xassert (c
->refcount
== 0);
5001 for (i
= 0; i
< c
->used
; ++i
)
5002 free_image (f
, c
->images
[i
]);
5006 FRAME_X_IMAGE_CACHE (f
) = NULL
;
5011 /* Clear image cache of frame F. FORCE_P non-zero means free all
5012 images. FORCE_P zero means clear only images that haven't been
5013 displayed for some time. Should be called from time to time to
5014 reduce the number of loaded images. If image-eviction-seconds is
5015 non-nil, this frees images in the cache which weren't displayed for
5016 at least that many seconds. */
5019 clear_image_cache (f
, force_p
)
5023 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5025 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
5032 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
5034 /* Block input so that we won't be interrupted by a SIGIO
5035 while being in an inconsistent state. */
5038 for (i
= nfreed
= 0; i
< c
->used
; ++i
)
5040 struct image
*img
= c
->images
[i
];
5042 && (force_p
|| img
->timestamp
< old
))
5044 free_image (f
, img
);
5049 /* We may be clearing the image cache because, for example,
5050 Emacs was iconified for a longer period of time. In that
5051 case, current matrices may still contain references to
5052 images freed above. So, clear these matrices. */
5055 Lisp_Object tail
, frame
;
5057 FOR_EACH_FRAME (tail
, frame
)
5059 struct frame
*f
= XFRAME (frame
);
5061 && FRAME_X_IMAGE_CACHE (f
) == c
)
5062 clear_current_matrices (f
);
5065 ++windows_or_buffers_changed
;
5073 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
5075 doc
: /* Clear the image cache of FRAME.
5076 FRAME nil or omitted means use the selected frame.
5077 FRAME t means clear the image caches of all frames. */)
5085 FOR_EACH_FRAME (tail
, frame
)
5086 if (FRAME_X_P (XFRAME (frame
)))
5087 clear_image_cache (XFRAME (frame
), 1);
5090 clear_image_cache (check_x_frame (frame
), 1);
5096 /* Compute masks and transform image IMG on frame F, as specified
5097 by the image's specification, */
5100 postprocess_image (f
, img
)
5104 /* Manipulation of the image's mask. */
5107 Lisp_Object conversion
, spec
;
5112 /* `:heuristic-mask t'
5114 means build a mask heuristically.
5115 `:heuristic-mask (R G B)'
5116 `:mask (heuristic (R G B))'
5117 means build a mask from color (R G B) in the
5120 means remove a mask, if any. */
5122 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
5124 x_build_heuristic_mask (f
, img
, mask
);
5129 mask
= image_spec_value (spec
, QCmask
, &found_p
);
5131 if (EQ (mask
, Qheuristic
))
5132 x_build_heuristic_mask (f
, img
, Qt
);
5133 else if (CONSP (mask
)
5134 && EQ (XCAR (mask
), Qheuristic
))
5136 if (CONSP (XCDR (mask
)))
5137 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
5139 x_build_heuristic_mask (f
, img
, XCDR (mask
));
5141 else if (NILP (mask
) && found_p
&& img
->mask
)
5143 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
5149 /* Should we apply an image transformation algorithm? */
5150 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
5151 if (EQ (conversion
, Qdisabled
))
5152 x_disable_image (f
, img
);
5153 else if (EQ (conversion
, Qlaplace
))
5155 else if (EQ (conversion
, Qemboss
))
5157 else if (CONSP (conversion
)
5158 && EQ (XCAR (conversion
), Qedge_detection
))
5161 tem
= XCDR (conversion
);
5163 x_edge_detection (f
, img
,
5164 Fplist_get (tem
, QCmatrix
),
5165 Fplist_get (tem
, QCcolor_adjustment
));
5171 /* Return the id of image with Lisp specification SPEC on frame F.
5172 SPEC must be a valid Lisp image specification (see valid_image_p). */
5175 lookup_image (f
, spec
)
5179 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5183 struct gcpro gcpro1
;
5186 /* F must be a window-system frame, and SPEC must be a valid image
5188 xassert (FRAME_WINDOW_P (f
));
5189 xassert (valid_image_p (spec
));
5193 /* Look up SPEC in the hash table of the image cache. */
5194 hash
= sxhash (spec
, 0);
5195 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5197 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
5198 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
5201 /* If not found, create a new image and cache it. */
5204 extern Lisp_Object Qpostscript
;
5207 img
= make_image (spec
, hash
);
5208 cache_image (f
, img
);
5209 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5211 /* If we can't load the image, and we don't have a width and
5212 height, use some arbitrary width and height so that we can
5213 draw a rectangle for it. */
5214 if (img
->load_failed_p
)
5218 value
= image_spec_value (spec
, QCwidth
, NULL
);
5219 img
->width
= (INTEGERP (value
)
5220 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
5221 value
= image_spec_value (spec
, QCheight
, NULL
);
5222 img
->height
= (INTEGERP (value
)
5223 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
5227 /* Handle image type independent image attributes
5228 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
5229 `:background COLOR'. */
5230 Lisp_Object ascent
, margin
, relief
, bg
;
5232 ascent
= image_spec_value (spec
, QCascent
, NULL
);
5233 if (INTEGERP (ascent
))
5234 img
->ascent
= XFASTINT (ascent
);
5235 else if (EQ (ascent
, Qcenter
))
5236 img
->ascent
= CENTERED_IMAGE_ASCENT
;
5238 margin
= image_spec_value (spec
, QCmargin
, NULL
);
5239 if (INTEGERP (margin
) && XINT (margin
) >= 0)
5240 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
5241 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
5242 && INTEGERP (XCDR (margin
)))
5244 if (XINT (XCAR (margin
)) > 0)
5245 img
->hmargin
= XFASTINT (XCAR (margin
));
5246 if (XINT (XCDR (margin
)) > 0)
5247 img
->vmargin
= XFASTINT (XCDR (margin
));
5250 relief
= image_spec_value (spec
, QCrelief
, NULL
);
5251 if (INTEGERP (relief
))
5253 img
->relief
= XINT (relief
);
5254 img
->hmargin
+= abs (img
->relief
);
5255 img
->vmargin
+= abs (img
->relief
);
5258 if (! img
->background_valid
)
5260 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
5264 = x_alloc_image_color (f
, img
, bg
,
5265 FRAME_BACKGROUND_PIXEL (f
));
5266 img
->background_valid
= 1;
5270 /* Do image transformations and compute masks, unless we
5271 don't have the image yet. */
5272 if (!EQ (*img
->type
->type
, Qpostscript
))
5273 postprocess_image (f
, img
);
5277 xassert (!interrupt_input_blocked
);
5280 /* We're using IMG, so set its timestamp to `now'. */
5281 EMACS_GET_TIME (now
);
5282 img
->timestamp
= EMACS_SECS (now
);
5286 /* Value is the image id. */
5291 /* Cache image IMG in the image cache of frame F. */
5294 cache_image (f
, img
)
5298 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5301 /* Find a free slot in c->images. */
5302 for (i
= 0; i
< c
->used
; ++i
)
5303 if (c
->images
[i
] == NULL
)
5306 /* If no free slot found, maybe enlarge c->images. */
5307 if (i
== c
->used
&& c
->used
== c
->size
)
5310 c
->images
= (struct image
**) xrealloc (c
->images
,
5311 c
->size
* sizeof *c
->images
);
5314 /* Add IMG to c->images, and assign IMG an id. */
5320 /* Add IMG to the cache's hash table. */
5321 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5322 img
->next
= c
->buckets
[i
];
5324 img
->next
->prev
= img
;
5326 c
->buckets
[i
] = img
;
5330 /* Call FN on every image in the image cache of frame F. Used to mark
5331 Lisp Objects in the image cache. */
5334 forall_images_in_image_cache (f
, fn
)
5336 void (*fn
) P_ ((struct image
*img
));
5338 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
))
5340 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5344 for (i
= 0; i
< c
->used
; ++i
)
5353 /***********************************************************************
5355 ***********************************************************************/
5357 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
5358 XImage
**, Pixmap
*));
5359 static void x_destroy_x_image
P_ ((XImage
*));
5360 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
5363 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
5364 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
5365 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
5366 via xmalloc. Print error messages via image_error if an error
5367 occurs. Value is non-zero if successful. */
5370 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
5372 int width
, height
, depth
;
5376 Display
*display
= FRAME_X_DISPLAY (f
);
5377 Screen
*screen
= FRAME_X_SCREEN (f
);
5378 Window window
= FRAME_X_WINDOW (f
);
5380 xassert (interrupt_input_blocked
);
5383 depth
= DefaultDepthOfScreen (screen
);
5384 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
5385 depth
, ZPixmap
, 0, NULL
, width
, height
,
5386 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
5389 image_error ("Unable to allocate X image", Qnil
, Qnil
);
5393 /* Allocate image raster. */
5394 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
5396 /* Allocate a pixmap of the same size. */
5397 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
5398 if (*pixmap
== None
)
5400 x_destroy_x_image (*ximg
);
5402 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
5410 /* Destroy XImage XIMG. Free XIMG->data. */
5413 x_destroy_x_image (ximg
)
5416 xassert (interrupt_input_blocked
);
5421 XDestroyImage (ximg
);
5426 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
5427 are width and height of both the image and pixmap. */
5430 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
5438 xassert (interrupt_input_blocked
);
5439 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
5440 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
5441 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5446 /***********************************************************************
5448 ***********************************************************************/
5450 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
5451 static char *slurp_file
P_ ((char *, int *));
5454 /* Find image file FILE. Look in data-directory, then
5455 x-bitmap-file-path. Value is the full name of the file found, or
5456 nil if not found. */
5459 x_find_image_file (file
)
5462 Lisp_Object file_found
, search_path
;
5463 struct gcpro gcpro1
, gcpro2
;
5467 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
5468 GCPRO2 (file_found
, search_path
);
5470 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
5471 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
5483 /* Read FILE into memory. Value is a pointer to a buffer allocated
5484 with xmalloc holding FILE's contents. Value is null if an error
5485 occurred. *SIZE is set to the size of the file. */
5488 slurp_file (file
, size
)
5496 if (stat (file
, &st
) == 0
5497 && (fp
= fopen (file
, "r")) != NULL
5498 && (buf
= (char *) xmalloc (st
.st_size
),
5499 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5520 /***********************************************************************
5522 ***********************************************************************/
5524 static int xbm_scan
P_ ((char **, char *, char *, int *));
5525 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
5526 static int xbm_load_image
P_ ((struct frame
*f
, struct image
*img
,
5528 static int xbm_image_p
P_ ((Lisp_Object object
));
5529 static int xbm_read_bitmap_data
P_ ((char *, char *, int *, int *,
5531 static int xbm_file_p
P_ ((Lisp_Object
));
5534 /* Indices of image specification fields in xbm_format, below. */
5536 enum xbm_keyword_index
5554 /* Vector of image_keyword structures describing the format
5555 of valid XBM image specifications. */
5557 static struct image_keyword xbm_format
[XBM_LAST
] =
5559 {":type", IMAGE_SYMBOL_VALUE
, 1},
5560 {":file", IMAGE_STRING_VALUE
, 0},
5561 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5562 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5563 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5564 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
5565 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
5566 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5567 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5568 {":relief", IMAGE_INTEGER_VALUE
, 0},
5569 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5570 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5571 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5574 /* Structure describing the image type XBM. */
5576 static struct image_type xbm_type
=
5585 /* Tokens returned from xbm_scan. */
5594 /* Return non-zero if OBJECT is a valid XBM-type image specification.
5595 A valid specification is a list starting with the symbol `image'
5596 The rest of the list is a property list which must contain an
5599 If the specification specifies a file to load, it must contain
5600 an entry `:file FILENAME' where FILENAME is a string.
5602 If the specification is for a bitmap loaded from memory it must
5603 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
5604 WIDTH and HEIGHT are integers > 0. DATA may be:
5606 1. a string large enough to hold the bitmap data, i.e. it must
5607 have a size >= (WIDTH + 7) / 8 * HEIGHT
5609 2. a bool-vector of size >= WIDTH * HEIGHT
5611 3. a vector of strings or bool-vectors, one for each line of the
5614 4. A string containing an in-memory XBM file. WIDTH and HEIGHT
5615 may not be specified in this case because they are defined in the
5618 Both the file and data forms may contain the additional entries
5619 `:background COLOR' and `:foreground COLOR'. If not present,
5620 foreground and background of the frame on which the image is
5621 displayed is used. */
5624 xbm_image_p (object
)
5627 struct image_keyword kw
[XBM_LAST
];
5629 bcopy (xbm_format
, kw
, sizeof kw
);
5630 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
5633 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
5635 if (kw
[XBM_FILE
].count
)
5637 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
5640 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
5642 /* In-memory XBM file. */
5643 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
5651 /* Entries for `:width', `:height' and `:data' must be present. */
5652 if (!kw
[XBM_WIDTH
].count
5653 || !kw
[XBM_HEIGHT
].count
5654 || !kw
[XBM_DATA
].count
)
5657 data
= kw
[XBM_DATA
].value
;
5658 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
5659 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
5661 /* Check type of data, and width and height against contents of
5667 /* Number of elements of the vector must be >= height. */
5668 if (XVECTOR (data
)->size
< height
)
5671 /* Each string or bool-vector in data must be large enough
5672 for one line of the image. */
5673 for (i
= 0; i
< height
; ++i
)
5675 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
5680 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
5683 else if (BOOL_VECTOR_P (elt
))
5685 if (XBOOL_VECTOR (elt
)->size
< width
)
5692 else if (STRINGP (data
))
5695 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
5698 else if (BOOL_VECTOR_P (data
))
5700 if (XBOOL_VECTOR (data
)->size
< width
* height
)
5711 /* Scan a bitmap file. FP is the stream to read from. Value is
5712 either an enumerator from enum xbm_token, or a character for a
5713 single-character token, or 0 at end of file. If scanning an
5714 identifier, store the lexeme of the identifier in SVAL. If
5715 scanning a number, store its value in *IVAL. */
5718 xbm_scan (s
, end
, sval
, ival
)
5727 /* Skip white space. */
5728 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5733 else if (isdigit (c
))
5735 int value
= 0, digit
;
5737 if (c
== '0' && *s
< end
)
5740 if (c
== 'x' || c
== 'X')
5747 else if (c
>= 'a' && c
<= 'f')
5748 digit
= c
- 'a' + 10;
5749 else if (c
>= 'A' && c
<= 'F')
5750 digit
= c
- 'A' + 10;
5753 value
= 16 * value
+ digit
;
5756 else if (isdigit (c
))
5760 && (c
= *(*s
)++, isdigit (c
)))
5761 value
= 8 * value
+ c
- '0';
5768 && (c
= *(*s
)++, isdigit (c
)))
5769 value
= 10 * value
+ c
- '0';
5777 else if (isalpha (c
) || c
== '_')
5781 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
5788 else if (c
== '/' && **s
== '*')
5790 /* C-style comment. */
5792 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
5805 /* Replacement for XReadBitmapFileData which isn't available under old
5806 X versions. CONTENTS is a pointer to a buffer to parse; END is the
5807 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
5808 the image. Return in *DATA the bitmap data allocated with xmalloc.
5809 Value is non-zero if successful. DATA null means just test if
5810 CONTENTS looks like an in-memory XBM file. */
5813 xbm_read_bitmap_data (contents
, end
, width
, height
, data
)
5814 char *contents
, *end
;
5815 int *width
, *height
;
5816 unsigned char **data
;
5819 char buffer
[BUFSIZ
];
5822 int bytes_per_line
, i
, nbytes
;
5828 LA1 = xbm_scan (&s, end, buffer, &value)
5830 #define expect(TOKEN) \
5831 if (LA1 != (TOKEN)) \
5836 #define expect_ident(IDENT) \
5837 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
5842 *width
= *height
= -1;
5845 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
5847 /* Parse defines for width, height and hot-spots. */
5851 expect_ident ("define");
5852 expect (XBM_TK_IDENT
);
5854 if (LA1
== XBM_TK_NUMBER
);
5856 char *p
= strrchr (buffer
, '_');
5857 p
= p
? p
+ 1 : buffer
;
5858 if (strcmp (p
, "width") == 0)
5860 else if (strcmp (p
, "height") == 0)
5863 expect (XBM_TK_NUMBER
);
5866 if (*width
< 0 || *height
< 0)
5868 else if (data
== NULL
)
5871 /* Parse bits. Must start with `static'. */
5872 expect_ident ("static");
5873 if (LA1
== XBM_TK_IDENT
)
5875 if (strcmp (buffer
, "unsigned") == 0)
5878 expect_ident ("char");
5880 else if (strcmp (buffer
, "short") == 0)
5884 if (*width
% 16 && *width
% 16 < 9)
5887 else if (strcmp (buffer
, "char") == 0)
5895 expect (XBM_TK_IDENT
);
5901 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
5902 nbytes
= bytes_per_line
* *height
;
5903 p
= *data
= (char *) xmalloc (nbytes
);
5907 for (i
= 0; i
< nbytes
; i
+= 2)
5910 expect (XBM_TK_NUMBER
);
5913 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
5916 if (LA1
== ',' || LA1
== '}')
5924 for (i
= 0; i
< nbytes
; ++i
)
5927 expect (XBM_TK_NUMBER
);
5931 if (LA1
== ',' || LA1
== '}')
5956 /* Load XBM image IMG which will be displayed on frame F from buffer
5957 CONTENTS. END is the end of the buffer. Value is non-zero if
5961 xbm_load_image (f
, img
, contents
, end
)
5964 char *contents
, *end
;
5967 unsigned char *data
;
5970 rc
= xbm_read_bitmap_data (contents
, end
, &img
->width
, &img
->height
, &data
);
5973 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
5974 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
5975 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
5978 xassert (img
->width
> 0 && img
->height
> 0);
5980 /* Get foreground and background colors, maybe allocate colors. */
5981 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
5983 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
5984 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
5987 background
= x_alloc_image_color (f
, img
, value
, background
);
5988 img
->background
= background
;
5989 img
->background_valid
= 1;
5993 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
5996 img
->width
, img
->height
,
5997 foreground
, background
,
6001 if (img
->pixmap
== None
)
6003 x_clear_image (f
, img
);
6004 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
6010 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6016 /* Value is non-zero if DATA looks like an in-memory XBM file. */
6023 return (STRINGP (data
)
6024 && xbm_read_bitmap_data (SDATA (data
),
6031 /* Fill image IMG which is used on frame F with pixmap data. Value is
6032 non-zero if successful. */
6040 Lisp_Object file_name
;
6042 xassert (xbm_image_p (img
->spec
));
6044 /* If IMG->spec specifies a file name, create a non-file spec from it. */
6045 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
6046 if (STRINGP (file_name
))
6051 struct gcpro gcpro1
;
6053 file
= x_find_image_file (file_name
);
6055 if (!STRINGP (file
))
6057 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
6062 contents
= slurp_file (SDATA (file
), &size
);
6063 if (contents
== NULL
)
6065 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6070 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
6075 struct image_keyword fmt
[XBM_LAST
];
6078 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6079 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6082 int in_memory_file_p
= 0;
6084 /* See if data looks like an in-memory XBM file. */
6085 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6086 in_memory_file_p
= xbm_file_p (data
);
6088 /* Parse the image specification. */
6089 bcopy (xbm_format
, fmt
, sizeof fmt
);
6090 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
6093 /* Get specified width, and height. */
6094 if (!in_memory_file_p
)
6096 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
6097 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
6098 xassert (img
->width
> 0 && img
->height
> 0);
6101 /* Get foreground and background colors, maybe allocate colors. */
6102 if (fmt
[XBM_FOREGROUND
].count
6103 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
6104 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
6106 if (fmt
[XBM_BACKGROUND
].count
6107 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
6108 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
6111 if (in_memory_file_p
)
6112 success_p
= xbm_load_image (f
, img
, SDATA (data
),
6121 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
6123 p
= bits
= (char *) alloca (nbytes
* img
->height
);
6124 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
6126 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
6128 bcopy (SDATA (line
), p
, nbytes
);
6130 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
6133 else if (STRINGP (data
))
6134 bits
= SDATA (data
);
6136 bits
= XBOOL_VECTOR (data
)->data
;
6138 /* Create the pixmap. */
6139 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6141 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
6144 img
->width
, img
->height
,
6145 foreground
, background
,
6151 image_error ("Unable to create pixmap for XBM image `%s'",
6153 x_clear_image (f
, img
);
6163 /***********************************************************************
6165 ***********************************************************************/
6169 static int xpm_image_p
P_ ((Lisp_Object object
));
6170 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
6171 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
6173 #include "X11/xpm.h"
6175 /* The symbol `xpm' identifying XPM-format images. */
6179 /* Indices of image specification fields in xpm_format, below. */
6181 enum xpm_keyword_index
6197 /* Vector of image_keyword structures describing the format
6198 of valid XPM image specifications. */
6200 static struct image_keyword xpm_format
[XPM_LAST
] =
6202 {":type", IMAGE_SYMBOL_VALUE
, 1},
6203 {":file", IMAGE_STRING_VALUE
, 0},
6204 {":data", IMAGE_STRING_VALUE
, 0},
6205 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6206 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6207 {":relief", IMAGE_INTEGER_VALUE
, 0},
6208 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6209 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6210 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6211 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6212 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6215 /* Structure describing the image type XBM. */
6217 static struct image_type xpm_type
=
6227 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
6228 functions for allocating image colors. Our own functions handle
6229 color allocation failures more gracefully than the ones on the XPM
6232 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
6233 #define ALLOC_XPM_COLORS
6236 #ifdef ALLOC_XPM_COLORS
6238 static void xpm_init_color_cache
P_ ((struct frame
*, XpmAttributes
*));
6239 static void xpm_free_color_cache
P_ ((void));
6240 static int xpm_lookup_color
P_ ((struct frame
*, char *, XColor
*));
6241 static int xpm_color_bucket
P_ ((char *));
6242 static struct xpm_cached_color
*xpm_cache_color
P_ ((struct frame
*, char *,
6245 /* An entry in a hash table used to cache color definitions of named
6246 colors. This cache is necessary to speed up XPM image loading in
6247 case we do color allocations ourselves. Without it, we would need
6248 a call to XParseColor per pixel in the image. */
6250 struct xpm_cached_color
6252 /* Next in collision chain. */
6253 struct xpm_cached_color
*next
;
6255 /* Color definition (RGB and pixel color). */
6262 /* The hash table used for the color cache, and its bucket vector
6265 #define XPM_COLOR_CACHE_BUCKETS 1001
6266 struct xpm_cached_color
**xpm_color_cache
;
6268 /* Initialize the color cache. */
6271 xpm_init_color_cache (f
, attrs
)
6273 XpmAttributes
*attrs
;
6275 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
6276 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
6277 memset (xpm_color_cache
, 0, nbytes
);
6278 init_color_table ();
6280 if (attrs
->valuemask
& XpmColorSymbols
)
6285 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
6286 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6287 attrs
->colorsymbols
[i
].value
, &color
))
6289 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
6291 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
6297 /* Free the color cache. */
6300 xpm_free_color_cache ()
6302 struct xpm_cached_color
*p
, *next
;
6305 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
6306 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
6312 xfree (xpm_color_cache
);
6313 xpm_color_cache
= NULL
;
6314 free_color_table ();
6318 /* Return the bucket index for color named COLOR_NAME in the color
6322 xpm_color_bucket (color_name
)
6328 for (s
= color_name
; *s
; ++s
)
6330 return h
%= XPM_COLOR_CACHE_BUCKETS
;
6334 /* On frame F, cache values COLOR for color with name COLOR_NAME.
6335 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
6338 static struct xpm_cached_color
*
6339 xpm_cache_color (f
, color_name
, color
, bucket
)
6346 struct xpm_cached_color
*p
;
6349 bucket
= xpm_color_bucket (color_name
);
6351 nbytes
= sizeof *p
+ strlen (color_name
);
6352 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
6353 strcpy (p
->name
, color_name
);
6355 p
->next
= xpm_color_cache
[bucket
];
6356 xpm_color_cache
[bucket
] = p
;
6361 /* Look up color COLOR_NAME for frame F in the color cache. If found,
6362 return the cached definition in *COLOR. Otherwise, make a new
6363 entry in the cache and allocate the color. Value is zero if color
6364 allocation failed. */
6367 xpm_lookup_color (f
, color_name
, color
)
6372 struct xpm_cached_color
*p
;
6373 int h
= xpm_color_bucket (color_name
);
6375 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
6376 if (strcmp (p
->name
, color_name
) == 0)
6381 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6384 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
6386 p
= xpm_cache_color (f
, color_name
, color
, h
);
6388 /* You get `opaque' at least from ImageMagick converting pbm to xpm
6389 with transparency, and it's useful. */
6390 else if (strcmp ("opaque", color_name
) == 0)
6392 bzero (color
, sizeof (XColor
)); /* Is this necessary/correct? */
6393 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
6394 p
= xpm_cache_color (f
, color_name
, color
, h
);
6401 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
6402 CLOSURE is a pointer to the frame on which we allocate the
6403 color. Return in *COLOR the allocated color. Value is non-zero
6407 xpm_alloc_color (dpy
, cmap
, color_name
, color
, closure
)
6414 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
6418 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
6419 is a pointer to the frame on which we allocate the color. Value is
6420 non-zero if successful. */
6423 xpm_free_colors (dpy
, cmap
, pixels
, npixels
, closure
)
6433 #endif /* ALLOC_XPM_COLORS */
6436 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
6437 for XPM images. Such a list must consist of conses whose car and
6441 xpm_valid_color_symbols_p (color_symbols
)
6442 Lisp_Object color_symbols
;
6444 while (CONSP (color_symbols
))
6446 Lisp_Object sym
= XCAR (color_symbols
);
6448 || !STRINGP (XCAR (sym
))
6449 || !STRINGP (XCDR (sym
)))
6451 color_symbols
= XCDR (color_symbols
);
6454 return NILP (color_symbols
);
6458 /* Value is non-zero if OBJECT is a valid XPM image specification. */
6461 xpm_image_p (object
)
6464 struct image_keyword fmt
[XPM_LAST
];
6465 bcopy (xpm_format
, fmt
, sizeof fmt
);
6466 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
6467 /* Either `:file' or `:data' must be present. */
6468 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
6469 /* Either no `:color-symbols' or it's a list of conses
6470 whose car and cdr are strings. */
6471 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
6472 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
6476 /* Load image IMG which will be displayed on frame F. Value is
6477 non-zero if successful. */
6485 XpmAttributes attrs
;
6486 Lisp_Object specified_file
, color_symbols
;
6488 /* Configure the XPM lib. Use the visual of frame F. Allocate
6489 close colors. Return colors allocated. */
6490 bzero (&attrs
, sizeof attrs
);
6491 attrs
.visual
= FRAME_X_VISUAL (f
);
6492 attrs
.colormap
= FRAME_X_COLORMAP (f
);
6493 attrs
.valuemask
|= XpmVisual
;
6494 attrs
.valuemask
|= XpmColormap
;
6496 #ifdef ALLOC_XPM_COLORS
6497 /* Allocate colors with our own functions which handle
6498 failing color allocation more gracefully. */
6499 attrs
.color_closure
= f
;
6500 attrs
.alloc_color
= xpm_alloc_color
;
6501 attrs
.free_colors
= xpm_free_colors
;
6502 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
6503 #else /* not ALLOC_XPM_COLORS */
6504 /* Let the XPM lib allocate colors. */
6505 attrs
.valuemask
|= XpmReturnAllocPixels
;
6506 #ifdef XpmAllocCloseColors
6507 attrs
.alloc_close_colors
= 1;
6508 attrs
.valuemask
|= XpmAllocCloseColors
;
6509 #else /* not XpmAllocCloseColors */
6510 attrs
.closeness
= 600;
6511 attrs
.valuemask
|= XpmCloseness
;
6512 #endif /* not XpmAllocCloseColors */
6513 #endif /* ALLOC_XPM_COLORS */
6515 /* If image specification contains symbolic color definitions, add
6516 these to `attrs'. */
6517 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
6518 if (CONSP (color_symbols
))
6521 XpmColorSymbol
*xpm_syms
;
6524 attrs
.valuemask
|= XpmColorSymbols
;
6526 /* Count number of symbols. */
6527 attrs
.numsymbols
= 0;
6528 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
6531 /* Allocate an XpmColorSymbol array. */
6532 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
6533 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
6534 bzero (xpm_syms
, size
);
6535 attrs
.colorsymbols
= xpm_syms
;
6537 /* Fill the color symbol array. */
6538 for (tail
= color_symbols
, i
= 0;
6540 ++i
, tail
= XCDR (tail
))
6542 Lisp_Object name
= XCAR (XCAR (tail
));
6543 Lisp_Object color
= XCDR (XCAR (tail
));
6544 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
6545 strcpy (xpm_syms
[i
].name
, SDATA (name
));
6546 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
6547 strcpy (xpm_syms
[i
].value
, SDATA (color
));
6551 /* Create a pixmap for the image, either from a file, or from a
6552 string buffer containing data in the same format as an XPM file. */
6553 #ifdef ALLOC_XPM_COLORS
6554 xpm_init_color_cache (f
, &attrs
);
6557 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6558 if (STRINGP (specified_file
))
6560 Lisp_Object file
= x_find_image_file (specified_file
);
6561 if (!STRINGP (file
))
6563 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6567 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6568 SDATA (file
), &img
->pixmap
, &img
->mask
,
6573 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
6574 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6576 &img
->pixmap
, &img
->mask
,
6580 if (rc
== XpmSuccess
)
6582 #ifdef ALLOC_XPM_COLORS
6583 img
->colors
= colors_in_color_table (&img
->ncolors
);
6584 #else /* not ALLOC_XPM_COLORS */
6587 img
->ncolors
= attrs
.nalloc_pixels
;
6588 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
6589 * sizeof *img
->colors
);
6590 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
6592 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
6593 #ifdef DEBUG_X_COLORS
6594 register_color (img
->colors
[i
]);
6597 #endif /* not ALLOC_XPM_COLORS */
6599 img
->width
= attrs
.width
;
6600 img
->height
= attrs
.height
;
6601 xassert (img
->width
> 0 && img
->height
> 0);
6603 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
6604 XpmFreeAttributes (&attrs
);
6611 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
6614 case XpmFileInvalid
:
6615 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
6619 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
6622 case XpmColorFailed
:
6623 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
6627 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
6632 #ifdef ALLOC_XPM_COLORS
6633 xpm_free_color_cache ();
6635 return rc
== XpmSuccess
;
6638 #endif /* HAVE_XPM != 0 */
6641 /***********************************************************************
6643 ***********************************************************************/
6645 /* An entry in the color table mapping an RGB color to a pixel color. */
6650 unsigned long pixel
;
6652 /* Next in color table collision list. */
6653 struct ct_color
*next
;
6656 /* The bucket vector size to use. Must be prime. */
6660 /* Value is a hash of the RGB color given by R, G, and B. */
6662 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
6664 /* The color hash table. */
6666 struct ct_color
**ct_table
;
6668 /* Number of entries in the color table. */
6670 int ct_colors_allocated
;
6672 /* Initialize the color table. */
6677 int size
= CT_SIZE
* sizeof (*ct_table
);
6678 ct_table
= (struct ct_color
**) xmalloc (size
);
6679 bzero (ct_table
, size
);
6680 ct_colors_allocated
= 0;
6684 /* Free memory associated with the color table. */
6690 struct ct_color
*p
, *next
;
6692 for (i
= 0; i
< CT_SIZE
; ++i
)
6693 for (p
= ct_table
[i
]; p
; p
= next
)
6704 /* Value is a pixel color for RGB color R, G, B on frame F. If an
6705 entry for that color already is in the color table, return the
6706 pixel color of that entry. Otherwise, allocate a new color for R,
6707 G, B, and make an entry in the color table. */
6709 static unsigned long
6710 lookup_rgb_color (f
, r
, g
, b
)
6714 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
6715 int i
= hash
% CT_SIZE
;
6718 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6719 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
6732 cmap
= FRAME_X_COLORMAP (f
);
6733 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6737 ++ct_colors_allocated
;
6739 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6743 p
->pixel
= color
.pixel
;
6744 p
->next
= ct_table
[i
];
6748 return FRAME_FOREGROUND_PIXEL (f
);
6755 /* Look up pixel color PIXEL which is used on frame F in the color
6756 table. If not already present, allocate it. Value is PIXEL. */
6758 static unsigned long
6759 lookup_pixel_color (f
, pixel
)
6761 unsigned long pixel
;
6763 int i
= pixel
% CT_SIZE
;
6766 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6767 if (p
->pixel
== pixel
)
6776 cmap
= FRAME_X_COLORMAP (f
);
6777 color
.pixel
= pixel
;
6778 x_query_color (f
, &color
);
6779 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6783 ++ct_colors_allocated
;
6785 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6790 p
->next
= ct_table
[i
];
6794 return FRAME_FOREGROUND_PIXEL (f
);
6801 /* Value is a vector of all pixel colors contained in the color table,
6802 allocated via xmalloc. Set *N to the number of colors. */
6804 static unsigned long *
6805 colors_in_color_table (n
)
6810 unsigned long *colors
;
6812 if (ct_colors_allocated
== 0)
6819 colors
= (unsigned long *) xmalloc (ct_colors_allocated
6821 *n
= ct_colors_allocated
;
6823 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
6824 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6825 colors
[j
++] = p
->pixel
;
6833 /***********************************************************************
6835 ***********************************************************************/
6837 static XColor
*x_to_xcolors
P_ ((struct frame
*, struct image
*, int));
6838 static void x_from_xcolors
P_ ((struct frame
*, struct image
*, XColor
*));
6839 static void x_detect_edges
P_ ((struct frame
*, struct image
*, int[9], int));
6841 /* Non-zero means draw a cross on images having `:conversion
6844 int cross_disabled_images
;
6846 /* Edge detection matrices for different edge-detection
6849 static int emboss_matrix
[9] = {
6851 2, -1, 0, /* y - 1 */
6853 0, 1, -2 /* y + 1 */
6856 static int laplace_matrix
[9] = {
6858 1, 0, 0, /* y - 1 */
6860 0, 0, -1 /* y + 1 */
6863 /* Value is the intensity of the color whose red/green/blue values
6866 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
6869 /* On frame F, return an array of XColor structures describing image
6870 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
6871 non-zero means also fill the red/green/blue members of the XColor
6872 structures. Value is a pointer to the array of XColors structures,
6873 allocated with xmalloc; it must be freed by the caller. */
6876 x_to_xcolors (f
, img
, rgb_p
)
6885 colors
= (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *colors
);
6887 /* Get the X image IMG->pixmap. */
6888 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
6889 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
6891 /* Fill the `pixel' members of the XColor array. I wished there
6892 were an easy and portable way to circumvent XGetPixel. */
6894 for (y
= 0; y
< img
->height
; ++y
)
6898 for (x
= 0; x
< img
->width
; ++x
, ++p
)
6899 p
->pixel
= XGetPixel (ximg
, x
, y
);
6902 x_query_colors (f
, row
, img
->width
);
6905 XDestroyImage (ximg
);
6910 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
6911 RGB members are set. F is the frame on which this all happens.
6912 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
6915 x_from_xcolors (f
, img
, colors
)
6925 init_color_table ();
6927 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
6930 for (y
= 0; y
< img
->height
; ++y
)
6931 for (x
= 0; x
< img
->width
; ++x
, ++p
)
6933 unsigned long pixel
;
6934 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
6935 XPutPixel (oimg
, x
, y
, pixel
);
6939 x_clear_image_1 (f
, img
, 1, 0, 1);
6941 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
6942 x_destroy_x_image (oimg
);
6943 img
->pixmap
= pixmap
;
6944 img
->colors
= colors_in_color_table (&img
->ncolors
);
6945 free_color_table ();
6949 /* On frame F, perform edge-detection on image IMG.
6951 MATRIX is a nine-element array specifying the transformation
6952 matrix. See emboss_matrix for an example.
6954 COLOR_ADJUST is a color adjustment added to each pixel of the
6958 x_detect_edges (f
, img
, matrix
, color_adjust
)
6961 int matrix
[9], color_adjust
;
6963 XColor
*colors
= x_to_xcolors (f
, img
, 1);
6967 for (i
= sum
= 0; i
< 9; ++i
)
6968 sum
+= abs (matrix
[i
]);
6970 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
6972 new = (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *new);
6974 for (y
= 0; y
< img
->height
; ++y
)
6976 p
= COLOR (new, 0, y
);
6977 p
->red
= p
->green
= p
->blue
= 0xffff/2;
6978 p
= COLOR (new, img
->width
- 1, y
);
6979 p
->red
= p
->green
= p
->blue
= 0xffff/2;
6982 for (x
= 1; x
< img
->width
- 1; ++x
)
6984 p
= COLOR (new, x
, 0);
6985 p
->red
= p
->green
= p
->blue
= 0xffff/2;
6986 p
= COLOR (new, x
, img
->height
- 1);
6987 p
->red
= p
->green
= p
->blue
= 0xffff/2;
6990 for (y
= 1; y
< img
->height
- 1; ++y
)
6992 p
= COLOR (new, 1, y
);
6994 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
6996 int r
, g
, b
, y1
, x1
;
6999 for (y1
= y
- 1; y1
< y
+ 2; ++y1
)
7000 for (x1
= x
- 1; x1
< x
+ 2; ++x1
, ++i
)
7003 XColor
*t
= COLOR (colors
, x1
, y1
);
7004 r
+= matrix
[i
] * t
->red
;
7005 g
+= matrix
[i
] * t
->green
;
7006 b
+= matrix
[i
] * t
->blue
;
7009 r
= (r
/ sum
+ color_adjust
) & 0xffff;
7010 g
= (g
/ sum
+ color_adjust
) & 0xffff;
7011 b
= (b
/ sum
+ color_adjust
) & 0xffff;
7012 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
7017 x_from_xcolors (f
, img
, new);
7023 /* Perform the pre-defined `emboss' edge-detection on image IMG
7031 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
7035 /* Perform the pre-defined `laplace' edge-detection on image IMG
7043 x_detect_edges (f
, img
, laplace_matrix
, 45000);
7047 /* Perform edge-detection on image IMG on frame F, with specified
7048 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
7050 MATRIX must be either
7052 - a list of at least 9 numbers in row-major form
7053 - a vector of at least 9 numbers
7055 COLOR_ADJUST nil means use a default; otherwise it must be a
7059 x_edge_detection (f
, img
, matrix
, color_adjust
)
7062 Lisp_Object matrix
, color_adjust
;
7070 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
7071 ++i
, matrix
= XCDR (matrix
))
7072 trans
[i
] = XFLOATINT (XCAR (matrix
));
7074 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
7076 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
7077 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
7080 if (NILP (color_adjust
))
7081 color_adjust
= make_number (0xffff / 2);
7083 if (i
== 9 && NUMBERP (color_adjust
))
7084 x_detect_edges (f
, img
, trans
, (int) XFLOATINT (color_adjust
));
7088 /* Transform image IMG on frame F so that it looks disabled. */
7091 x_disable_image (f
, img
)
7095 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7097 if (dpyinfo
->n_planes
>= 2)
7099 /* Color (or grayscale). Convert to gray, and equalize. Just
7100 drawing such images with a stipple can look very odd, so
7101 we're using this method instead. */
7102 XColor
*colors
= x_to_xcolors (f
, img
, 1);
7104 const int h
= 15000;
7105 const int l
= 30000;
7107 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
7111 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
7112 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
7113 p
->red
= p
->green
= p
->blue
= i2
;
7116 x_from_xcolors (f
, img
, colors
);
7119 /* Draw a cross over the disabled image, if we must or if we
7121 if (dpyinfo
->n_planes
< 2 || cross_disabled_images
)
7123 Display
*dpy
= FRAME_X_DISPLAY (f
);
7126 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
7127 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
7128 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
7129 img
->width
- 1, img
->height
- 1);
7130 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
7136 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
7137 XSetForeground (dpy
, gc
, WHITE_PIX_DEFAULT (f
));
7138 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
7139 img
->width
- 1, img
->height
- 1);
7140 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
7148 /* Build a mask for image IMG which is used on frame F. FILE is the
7149 name of an image file, for error messages. HOW determines how to
7150 determine the background color of IMG. If it is a list '(R G B)',
7151 with R, G, and B being integers >= 0, take that as the color of the
7152 background. Otherwise, determine the background color of IMG
7153 heuristically. Value is non-zero if successful. */
7156 x_build_heuristic_mask (f
, img
, how
)
7161 Display
*dpy
= FRAME_X_DISPLAY (f
);
7162 XImage
*ximg
, *mask_img
;
7163 int x
, y
, rc
, use_img_background
;
7164 unsigned long bg
= 0;
7168 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
7170 img
->background_transparent_valid
= 0;
7173 /* Create an image and pixmap serving as mask. */
7174 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
7175 &mask_img
, &img
->mask
);
7179 /* Get the X image of IMG->pixmap. */
7180 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
7183 /* Determine the background color of ximg. If HOW is `(R G B)'
7184 take that as color. Otherwise, use the image's background color. */
7185 use_img_background
= 1;
7191 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
7193 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
7197 if (i
== 3 && NILP (how
))
7199 char color_name
[30];
7200 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
7201 bg
= x_alloc_image_color (f
, img
, build_string (color_name
), 0);
7202 use_img_background
= 0;
7206 if (use_img_background
)
7207 bg
= four_corners_best (ximg
, img
->width
, img
->height
);
7209 /* Set all bits in mask_img to 1 whose color in ximg is different
7210 from the background color bg. */
7211 for (y
= 0; y
< img
->height
; ++y
)
7212 for (x
= 0; x
< img
->width
; ++x
)
7213 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
7215 /* Fill in the background_transparent field while we have the mask handy. */
7216 image_background_transparent (img
, f
, mask_img
);
7218 /* Put mask_img into img->mask. */
7219 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
7220 x_destroy_x_image (mask_img
);
7221 XDestroyImage (ximg
);
7228 /***********************************************************************
7229 PBM (mono, gray, color)
7230 ***********************************************************************/
7232 static int pbm_image_p
P_ ((Lisp_Object object
));
7233 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
7234 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
7236 /* The symbol `pbm' identifying images of this type. */
7240 /* Indices of image specification fields in gs_format, below. */
7242 enum pbm_keyword_index
7258 /* Vector of image_keyword structures describing the format
7259 of valid user-defined image specifications. */
7261 static struct image_keyword pbm_format
[PBM_LAST
] =
7263 {":type", IMAGE_SYMBOL_VALUE
, 1},
7264 {":file", IMAGE_STRING_VALUE
, 0},
7265 {":data", IMAGE_STRING_VALUE
, 0},
7266 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7267 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7268 {":relief", IMAGE_INTEGER_VALUE
, 0},
7269 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7270 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7271 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7272 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
7273 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7276 /* Structure describing the image type `pbm'. */
7278 static struct image_type pbm_type
=
7288 /* Return non-zero if OBJECT is a valid PBM image specification. */
7291 pbm_image_p (object
)
7294 struct image_keyword fmt
[PBM_LAST
];
7296 bcopy (pbm_format
, fmt
, sizeof fmt
);
7298 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
7301 /* Must specify either :data or :file. */
7302 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
7306 /* Scan a decimal number from *S and return it. Advance *S while
7307 reading the number. END is the end of the string. Value is -1 at
7311 pbm_scan_number (s
, end
)
7312 unsigned char **s
, *end
;
7314 int c
= 0, val
= -1;
7318 /* Skip white-space. */
7319 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
7324 /* Skip comment to end of line. */
7325 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
7328 else if (isdigit (c
))
7330 /* Read decimal number. */
7332 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
7333 val
= 10 * val
+ c
- '0';
7344 /* Load PBM image IMG for use on frame F. */
7352 int width
, height
, max_color_idx
= 0;
7354 Lisp_Object file
, specified_file
;
7355 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
7356 struct gcpro gcpro1
;
7357 unsigned char *contents
= NULL
;
7358 unsigned char *end
, *p
;
7361 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7365 if (STRINGP (specified_file
))
7367 file
= x_find_image_file (specified_file
);
7368 if (!STRINGP (file
))
7370 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7375 contents
= slurp_file (SDATA (file
), &size
);
7376 if (contents
== NULL
)
7378 image_error ("Error reading `%s'", file
, Qnil
);
7384 end
= contents
+ size
;
7389 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7391 end
= p
+ SBYTES (data
);
7394 /* Check magic number. */
7395 if (end
- p
< 2 || *p
++ != 'P')
7397 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7407 raw_p
= 0, type
= PBM_MONO
;
7411 raw_p
= 0, type
= PBM_GRAY
;
7415 raw_p
= 0, type
= PBM_COLOR
;
7419 raw_p
= 1, type
= PBM_MONO
;
7423 raw_p
= 1, type
= PBM_GRAY
;
7427 raw_p
= 1, type
= PBM_COLOR
;
7431 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7435 /* Read width, height, maximum color-component. Characters
7436 starting with `#' up to the end of a line are ignored. */
7437 width
= pbm_scan_number (&p
, end
);
7438 height
= pbm_scan_number (&p
, end
);
7440 if (type
!= PBM_MONO
)
7442 max_color_idx
= pbm_scan_number (&p
, end
);
7443 if (raw_p
&& max_color_idx
> 255)
7444 max_color_idx
= 255;
7449 || (type
!= PBM_MONO
&& max_color_idx
< 0))
7452 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7453 &ximg
, &img
->pixmap
))
7456 /* Initialize the color hash table. */
7457 init_color_table ();
7459 if (type
== PBM_MONO
)
7462 struct image_keyword fmt
[PBM_LAST
];
7463 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
7464 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
7466 /* Parse the image specification. */
7467 bcopy (pbm_format
, fmt
, sizeof fmt
);
7468 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
7470 /* Get foreground and background colors, maybe allocate colors. */
7471 if (fmt
[PBM_FOREGROUND
].count
7472 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
7473 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
7474 if (fmt
[PBM_BACKGROUND
].count
7475 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
7477 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
7478 img
->background
= bg
;
7479 img
->background_valid
= 1;
7482 for (y
= 0; y
< height
; ++y
)
7483 for (x
= 0; x
< width
; ++x
)
7493 g
= pbm_scan_number (&p
, end
);
7495 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
7500 for (y
= 0; y
< height
; ++y
)
7501 for (x
= 0; x
< width
; ++x
)
7505 if (type
== PBM_GRAY
)
7506 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
7515 r
= pbm_scan_number (&p
, end
);
7516 g
= pbm_scan_number (&p
, end
);
7517 b
= pbm_scan_number (&p
, end
);
7520 if (r
< 0 || g
< 0 || b
< 0)
7524 XDestroyImage (ximg
);
7525 image_error ("Invalid pixel value in image `%s'",
7530 /* RGB values are now in the range 0..max_color_idx.
7531 Scale this to the range 0..0xffff supported by X. */
7532 r
= (double) r
* 65535 / max_color_idx
;
7533 g
= (double) g
* 65535 / max_color_idx
;
7534 b
= (double) b
* 65535 / max_color_idx
;
7535 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7539 /* Store in IMG->colors the colors allocated for the image, and
7540 free the color table. */
7541 img
->colors
= colors_in_color_table (&img
->ncolors
);
7542 free_color_table ();
7544 /* Maybe fill in the background field while we have ximg handy. */
7545 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7546 IMAGE_BACKGROUND (img
, f
, ximg
);
7548 /* Put the image into a pixmap. */
7549 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7550 x_destroy_x_image (ximg
);
7553 img
->height
= height
;
7562 /***********************************************************************
7564 ***********************************************************************/
7568 #if defined HAVE_LIBPNG_PNG_H
7569 # include <libpng/png.h>
7574 /* Function prototypes. */
7576 static int png_image_p
P_ ((Lisp_Object object
));
7577 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
7579 /* The symbol `png' identifying images of this type. */
7583 /* Indices of image specification fields in png_format, below. */
7585 enum png_keyword_index
7600 /* Vector of image_keyword structures describing the format
7601 of valid user-defined image specifications. */
7603 static struct image_keyword png_format
[PNG_LAST
] =
7605 {":type", IMAGE_SYMBOL_VALUE
, 1},
7606 {":data", IMAGE_STRING_VALUE
, 0},
7607 {":file", IMAGE_STRING_VALUE
, 0},
7608 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7609 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7610 {":relief", IMAGE_INTEGER_VALUE
, 0},
7611 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7612 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7613 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7614 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7617 /* Structure describing the image type `png'. */
7619 static struct image_type png_type
=
7629 /* Return non-zero if OBJECT is a valid PNG image specification. */
7632 png_image_p (object
)
7635 struct image_keyword fmt
[PNG_LAST
];
7636 bcopy (png_format
, fmt
, sizeof fmt
);
7638 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
7641 /* Must specify either the :data or :file keyword. */
7642 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
7646 /* Error and warning handlers installed when the PNG library
7650 my_png_error (png_ptr
, msg
)
7651 png_struct
*png_ptr
;
7654 xassert (png_ptr
!= NULL
);
7655 image_error ("PNG error: %s", build_string (msg
), Qnil
);
7656 longjmp (png_ptr
->jmpbuf
, 1);
7661 my_png_warning (png_ptr
, msg
)
7662 png_struct
*png_ptr
;
7665 xassert (png_ptr
!= NULL
);
7666 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
7669 /* Memory source for PNG decoding. */
7671 struct png_memory_storage
7673 unsigned char *bytes
; /* The data */
7674 size_t len
; /* How big is it? */
7675 int index
; /* Where are we? */
7679 /* Function set as reader function when reading PNG image from memory.
7680 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
7681 bytes from the input to DATA. */
7684 png_read_from_memory (png_ptr
, data
, length
)
7685 png_structp png_ptr
;
7689 struct png_memory_storage
*tbr
7690 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
7692 if (length
> tbr
->len
- tbr
->index
)
7693 png_error (png_ptr
, "Read error");
7695 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
7696 tbr
->index
= tbr
->index
+ length
;
7699 /* Load PNG image IMG for use on frame F. Value is non-zero if
7707 Lisp_Object file
, specified_file
;
7708 Lisp_Object specified_data
;
7710 XImage
*ximg
, *mask_img
= NULL
;
7711 struct gcpro gcpro1
;
7712 png_struct
*png_ptr
= NULL
;
7713 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
7714 FILE *volatile fp
= NULL
;
7716 png_byte
* volatile pixels
= NULL
;
7717 png_byte
** volatile rows
= NULL
;
7718 png_uint_32 width
, height
;
7719 int bit_depth
, color_type
, interlace_type
;
7721 png_uint_32 row_bytes
;
7723 double screen_gamma
;
7724 struct png_memory_storage tbr
; /* Data to be read */
7726 /* Find out what file to load. */
7727 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7728 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7732 if (NILP (specified_data
))
7734 file
= x_find_image_file (specified_file
);
7735 if (!STRINGP (file
))
7737 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7742 /* Open the image file. */
7743 fp
= fopen (SDATA (file
), "rb");
7746 image_error ("Cannot open image file `%s'", file
, Qnil
);
7752 /* Check PNG signature. */
7753 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
7754 || !png_check_sig (sig
, sizeof sig
))
7756 image_error ("Not a PNG file: `%s'", file
, Qnil
);
7764 /* Read from memory. */
7765 tbr
.bytes
= SDATA (specified_data
);
7766 tbr
.len
= SBYTES (specified_data
);
7769 /* Check PNG signature. */
7770 if (tbr
.len
< sizeof sig
7771 || !png_check_sig (tbr
.bytes
, sizeof sig
))
7773 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
7778 /* Need to skip past the signature. */
7779 tbr
.bytes
+= sizeof (sig
);
7782 /* Initialize read and info structs for PNG lib. */
7783 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
7784 my_png_error
, my_png_warning
);
7787 if (fp
) fclose (fp
);
7792 info_ptr
= png_create_info_struct (png_ptr
);
7795 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
7796 if (fp
) fclose (fp
);
7801 end_info
= png_create_info_struct (png_ptr
);
7804 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
7805 if (fp
) fclose (fp
);
7810 /* Set error jump-back. We come back here when the PNG library
7811 detects an error. */
7812 if (setjmp (png_ptr
->jmpbuf
))
7816 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7819 if (fp
) fclose (fp
);
7824 /* Read image info. */
7825 if (!NILP (specified_data
))
7826 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
7828 png_init_io (png_ptr
, fp
);
7830 png_set_sig_bytes (png_ptr
, sizeof sig
);
7831 png_read_info (png_ptr
, info_ptr
);
7832 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
7833 &interlace_type
, NULL
, NULL
);
7835 /* If image contains simply transparency data, we prefer to
7836 construct a clipping mask. */
7837 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
7842 /* This function is easier to write if we only have to handle
7843 one data format: RGB or RGBA with 8 bits per channel. Let's
7844 transform other formats into that format. */
7846 /* Strip more than 8 bits per channel. */
7847 if (bit_depth
== 16)
7848 png_set_strip_16 (png_ptr
);
7850 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
7852 png_set_expand (png_ptr
);
7854 /* Convert grayscale images to RGB. */
7855 if (color_type
== PNG_COLOR_TYPE_GRAY
7856 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
7857 png_set_gray_to_rgb (png_ptr
);
7859 screen_gamma
= (f
->gamma
? 1 / f
->gamma
/ 0.45455 : 2.2);
7861 #if 0 /* Avoid double gamma correction for PNG images. */
7862 { /* Tell the PNG lib to handle gamma correction for us. */
7865 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
7866 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
7867 /* The libpng documentation says this is right in this case. */
7868 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7871 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
7872 /* Image contains gamma information. */
7873 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
7875 /* Use the standard default for the image gamma. */
7876 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7880 /* Handle alpha channel by combining the image with a background
7881 color. Do this only if a real alpha channel is supplied. For
7882 simple transparency, we prefer a clipping mask. */
7885 png_color_16
*image_bg
;
7886 Lisp_Object specified_bg
7887 = image_spec_value (img
->spec
, QCbackground
, NULL
);
7889 if (STRINGP (specified_bg
))
7890 /* The user specified `:background', use that. */
7893 if (x_defined_color (f
, SDATA (specified_bg
), &color
, 0))
7895 png_color_16 user_bg
;
7897 bzero (&user_bg
, sizeof user_bg
);
7898 user_bg
.red
= color
.red
;
7899 user_bg
.green
= color
.green
;
7900 user_bg
.blue
= color
.blue
;
7902 png_set_background (png_ptr
, &user_bg
,
7903 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7906 else if (png_get_bKGD (png_ptr
, info_ptr
, &image_bg
))
7907 /* Image contains a background color with which to
7908 combine the image. */
7909 png_set_background (png_ptr
, image_bg
,
7910 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
7913 /* Image does not contain a background color with which
7914 to combine the image data via an alpha channel. Use
7915 the frame's background instead. */
7918 png_color_16 frame_background
;
7920 cmap
= FRAME_X_COLORMAP (f
);
7921 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7922 x_query_color (f
, &color
);
7924 bzero (&frame_background
, sizeof frame_background
);
7925 frame_background
.red
= color
.red
;
7926 frame_background
.green
= color
.green
;
7927 frame_background
.blue
= color
.blue
;
7929 png_set_background (png_ptr
, &frame_background
,
7930 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7934 /* Update info structure. */
7935 png_read_update_info (png_ptr
, info_ptr
);
7937 /* Get number of channels. Valid values are 1 for grayscale images
7938 and images with a palette, 2 for grayscale images with transparency
7939 information (alpha channel), 3 for RGB images, and 4 for RGB
7940 images with alpha channel, i.e. RGBA. If conversions above were
7941 sufficient we should only have 3 or 4 channels here. */
7942 channels
= png_get_channels (png_ptr
, info_ptr
);
7943 xassert (channels
== 3 || channels
== 4);
7945 /* Number of bytes needed for one row of the image. */
7946 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
7948 /* Allocate memory for the image. */
7949 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
7950 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
7951 for (i
= 0; i
< height
; ++i
)
7952 rows
[i
] = pixels
+ i
* row_bytes
;
7954 /* Read the entire image. */
7955 png_read_image (png_ptr
, rows
);
7956 png_read_end (png_ptr
, info_ptr
);
7963 /* Create the X image and pixmap. */
7964 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
7968 /* Create an image and pixmap serving as mask if the PNG image
7969 contains an alpha channel. */
7972 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
7973 &mask_img
, &img
->mask
))
7975 x_destroy_x_image (ximg
);
7976 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
7981 /* Fill the X image and mask from PNG data. */
7982 init_color_table ();
7984 for (y
= 0; y
< height
; ++y
)
7986 png_byte
*p
= rows
[y
];
7988 for (x
= 0; x
< width
; ++x
)
7995 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7997 /* An alpha channel, aka mask channel, associates variable
7998 transparency with an image. Where other image formats
7999 support binary transparency---fully transparent or fully
8000 opaque---PNG allows up to 254 levels of partial transparency.
8001 The PNG library implements partial transparency by combining
8002 the image with a specified background color.
8004 I'm not sure how to handle this here nicely: because the
8005 background on which the image is displayed may change, for
8006 real alpha channel support, it would be necessary to create
8007 a new image for each possible background.
8009 What I'm doing now is that a mask is created if we have
8010 boolean transparency information. Otherwise I'm using
8011 the frame's background color to combine the image with. */
8016 XPutPixel (mask_img
, x
, y
, *p
> 0);
8022 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8023 /* Set IMG's background color from the PNG image, unless the user
8027 if (png_get_bKGD (png_ptr
, info_ptr
, &bg
))
8029 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
8030 img
->background_valid
= 1;
8034 /* Remember colors allocated for this image. */
8035 img
->colors
= colors_in_color_table (&img
->ncolors
);
8036 free_color_table ();
8039 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
8044 img
->height
= height
;
8046 /* Maybe fill in the background field while we have ximg handy. */
8047 IMAGE_BACKGROUND (img
, f
, ximg
);
8049 /* Put the image into the pixmap, then free the X image and its buffer. */
8050 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8051 x_destroy_x_image (ximg
);
8053 /* Same for the mask. */
8056 /* Fill in the background_transparent field while we have the mask
8058 image_background_transparent (img
, f
, mask_img
);
8060 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
8061 x_destroy_x_image (mask_img
);
8068 #endif /* HAVE_PNG != 0 */
8072 /***********************************************************************
8074 ***********************************************************************/
8078 /* Work around a warning about HAVE_STDLIB_H being redefined in
8080 #ifdef HAVE_STDLIB_H
8081 #define HAVE_STDLIB_H_1
8082 #undef HAVE_STDLIB_H
8083 #endif /* HAVE_STLIB_H */
8085 #include <jpeglib.h>
8089 #ifdef HAVE_STLIB_H_1
8090 #define HAVE_STDLIB_H 1
8093 static int jpeg_image_p
P_ ((Lisp_Object object
));
8094 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
8096 /* The symbol `jpeg' identifying images of this type. */
8100 /* Indices of image specification fields in gs_format, below. */
8102 enum jpeg_keyword_index
8111 JPEG_HEURISTIC_MASK
,
8117 /* Vector of image_keyword structures describing the format
8118 of valid user-defined image specifications. */
8120 static struct image_keyword jpeg_format
[JPEG_LAST
] =
8122 {":type", IMAGE_SYMBOL_VALUE
, 1},
8123 {":data", IMAGE_STRING_VALUE
, 0},
8124 {":file", IMAGE_STRING_VALUE
, 0},
8125 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8126 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8127 {":relief", IMAGE_INTEGER_VALUE
, 0},
8128 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8129 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8130 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8131 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8134 /* Structure describing the image type `jpeg'. */
8136 static struct image_type jpeg_type
=
8146 /* Return non-zero if OBJECT is a valid JPEG image specification. */
8149 jpeg_image_p (object
)
8152 struct image_keyword fmt
[JPEG_LAST
];
8154 bcopy (jpeg_format
, fmt
, sizeof fmt
);
8156 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
8159 /* Must specify either the :data or :file keyword. */
8160 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
8164 struct my_jpeg_error_mgr
8166 struct jpeg_error_mgr pub
;
8167 jmp_buf setjmp_buffer
;
8172 my_error_exit (cinfo
)
8175 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
8176 longjmp (mgr
->setjmp_buffer
, 1);
8180 /* Init source method for JPEG data source manager. Called by
8181 jpeg_read_header() before any data is actually read. See
8182 libjpeg.doc from the JPEG lib distribution. */
8185 our_init_source (cinfo
)
8186 j_decompress_ptr cinfo
;
8191 /* Fill input buffer method for JPEG data source manager. Called
8192 whenever more data is needed. We read the whole image in one step,
8193 so this only adds a fake end of input marker at the end. */
8196 our_fill_input_buffer (cinfo
)
8197 j_decompress_ptr cinfo
;
8199 /* Insert a fake EOI marker. */
8200 struct jpeg_source_mgr
*src
= cinfo
->src
;
8201 static JOCTET buffer
[2];
8203 buffer
[0] = (JOCTET
) 0xFF;
8204 buffer
[1] = (JOCTET
) JPEG_EOI
;
8206 src
->next_input_byte
= buffer
;
8207 src
->bytes_in_buffer
= 2;
8212 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
8213 is the JPEG data source manager. */
8216 our_skip_input_data (cinfo
, num_bytes
)
8217 j_decompress_ptr cinfo
;
8220 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8224 if (num_bytes
> src
->bytes_in_buffer
)
8225 ERREXIT (cinfo
, JERR_INPUT_EOF
);
8227 src
->bytes_in_buffer
-= num_bytes
;
8228 src
->next_input_byte
+= num_bytes
;
8233 /* Method to terminate data source. Called by
8234 jpeg_finish_decompress() after all data has been processed. */
8237 our_term_source (cinfo
)
8238 j_decompress_ptr cinfo
;
8243 /* Set up the JPEG lib for reading an image from DATA which contains
8244 LEN bytes. CINFO is the decompression info structure created for
8245 reading the image. */
8248 jpeg_memory_src (cinfo
, data
, len
)
8249 j_decompress_ptr cinfo
;
8253 struct jpeg_source_mgr
*src
;
8255 if (cinfo
->src
== NULL
)
8257 /* First time for this JPEG object? */
8258 cinfo
->src
= (struct jpeg_source_mgr
*)
8259 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
8260 sizeof (struct jpeg_source_mgr
));
8261 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8262 src
->next_input_byte
= data
;
8265 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8266 src
->init_source
= our_init_source
;
8267 src
->fill_input_buffer
= our_fill_input_buffer
;
8268 src
->skip_input_data
= our_skip_input_data
;
8269 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
8270 src
->term_source
= our_term_source
;
8271 src
->bytes_in_buffer
= len
;
8272 src
->next_input_byte
= data
;
8276 /* Load image IMG for use on frame F. Patterned after example.c
8277 from the JPEG lib. */
8284 struct jpeg_decompress_struct cinfo
;
8285 struct my_jpeg_error_mgr mgr
;
8286 Lisp_Object file
, specified_file
;
8287 Lisp_Object specified_data
;
8288 FILE * volatile fp
= NULL
;
8290 int row_stride
, x
, y
;
8291 XImage
*ximg
= NULL
;
8293 unsigned long *colors
;
8295 struct gcpro gcpro1
;
8297 /* Open the JPEG file. */
8298 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8299 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8303 if (NILP (specified_data
))
8305 file
= x_find_image_file (specified_file
);
8306 if (!STRINGP (file
))
8308 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8313 fp
= fopen (SDATA (file
), "r");
8316 image_error ("Cannot open `%s'", file
, Qnil
);
8322 /* Customize libjpeg's error handling to call my_error_exit when an
8323 error is detected. This function will perform a longjmp. */
8324 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
8325 mgr
.pub
.error_exit
= my_error_exit
;
8327 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
8331 /* Called from my_error_exit. Display a JPEG error. */
8332 char buffer
[JMSG_LENGTH_MAX
];
8333 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
8334 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
8335 build_string (buffer
));
8338 /* Close the input file and destroy the JPEG object. */
8340 fclose ((FILE *) fp
);
8341 jpeg_destroy_decompress (&cinfo
);
8343 /* If we already have an XImage, free that. */
8344 x_destroy_x_image (ximg
);
8346 /* Free pixmap and colors. */
8347 x_clear_image (f
, img
);
8353 /* Create the JPEG decompression object. Let it read from fp.
8354 Read the JPEG image header. */
8355 jpeg_create_decompress (&cinfo
);
8357 if (NILP (specified_data
))
8358 jpeg_stdio_src (&cinfo
, (FILE *) fp
);
8360 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
8361 SBYTES (specified_data
));
8363 jpeg_read_header (&cinfo
, TRUE
);
8365 /* Customize decompression so that color quantization will be used.
8366 Start decompression. */
8367 cinfo
.quantize_colors
= TRUE
;
8368 jpeg_start_decompress (&cinfo
);
8369 width
= img
->width
= cinfo
.output_width
;
8370 height
= img
->height
= cinfo
.output_height
;
8372 /* Create X image and pixmap. */
8373 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8374 longjmp (mgr
.setjmp_buffer
, 2);
8376 /* Allocate colors. When color quantization is used,
8377 cinfo.actual_number_of_colors has been set with the number of
8378 colors generated, and cinfo.colormap is a two-dimensional array
8379 of color indices in the range 0..cinfo.actual_number_of_colors.
8380 No more than 255 colors will be generated. */
8384 if (cinfo
.out_color_components
> 2)
8385 ir
= 0, ig
= 1, ib
= 2;
8386 else if (cinfo
.out_color_components
> 1)
8387 ir
= 0, ig
= 1, ib
= 0;
8389 ir
= 0, ig
= 0, ib
= 0;
8391 /* Use the color table mechanism because it handles colors that
8392 cannot be allocated nicely. Such colors will be replaced with
8393 a default color, and we don't have to care about which colors
8394 can be freed safely, and which can't. */
8395 init_color_table ();
8396 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
8399 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
8401 /* Multiply RGB values with 255 because X expects RGB values
8402 in the range 0..0xffff. */
8403 int r
= cinfo
.colormap
[ir
][i
] << 8;
8404 int g
= cinfo
.colormap
[ig
][i
] << 8;
8405 int b
= cinfo
.colormap
[ib
][i
] << 8;
8406 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8409 /* Remember those colors actually allocated. */
8410 img
->colors
= colors_in_color_table (&img
->ncolors
);
8411 free_color_table ();
8415 row_stride
= width
* cinfo
.output_components
;
8416 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
8418 for (y
= 0; y
< height
; ++y
)
8420 jpeg_read_scanlines (&cinfo
, buffer
, 1);
8421 for (x
= 0; x
< cinfo
.output_width
; ++x
)
8422 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
8426 jpeg_finish_decompress (&cinfo
);
8427 jpeg_destroy_decompress (&cinfo
);
8429 fclose ((FILE *) fp
);
8431 /* Maybe fill in the background field while we have ximg handy. */
8432 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8433 IMAGE_BACKGROUND (img
, f
, ximg
);
8435 /* Put the image into the pixmap. */
8436 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8437 x_destroy_x_image (ximg
);
8442 #endif /* HAVE_JPEG */
8446 /***********************************************************************
8448 ***********************************************************************/
8454 static int tiff_image_p
P_ ((Lisp_Object object
));
8455 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
8457 /* The symbol `tiff' identifying images of this type. */
8461 /* Indices of image specification fields in tiff_format, below. */
8463 enum tiff_keyword_index
8472 TIFF_HEURISTIC_MASK
,
8478 /* Vector of image_keyword structures describing the format
8479 of valid user-defined image specifications. */
8481 static struct image_keyword tiff_format
[TIFF_LAST
] =
8483 {":type", IMAGE_SYMBOL_VALUE
, 1},
8484 {":data", IMAGE_STRING_VALUE
, 0},
8485 {":file", IMAGE_STRING_VALUE
, 0},
8486 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8487 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8488 {":relief", IMAGE_INTEGER_VALUE
, 0},
8489 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8490 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8491 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8492 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8495 /* Structure describing the image type `tiff'. */
8497 static struct image_type tiff_type
=
8507 /* Return non-zero if OBJECT is a valid TIFF image specification. */
8510 tiff_image_p (object
)
8513 struct image_keyword fmt
[TIFF_LAST
];
8514 bcopy (tiff_format
, fmt
, sizeof fmt
);
8516 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
8519 /* Must specify either the :data or :file keyword. */
8520 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
8524 /* Reading from a memory buffer for TIFF images Based on the PNG
8525 memory source, but we have to provide a lot of extra functions.
8528 We really only need to implement read and seek, but I am not
8529 convinced that the TIFF library is smart enough not to destroy
8530 itself if we only hand it the function pointers we need to
8535 unsigned char *bytes
;
8543 tiff_read_from_memory (data
, buf
, size
)
8548 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8550 if (size
> src
->len
- src
->index
)
8552 bcopy (src
->bytes
+ src
->index
, buf
, size
);
8559 tiff_write_from_memory (data
, buf
, size
)
8569 tiff_seek_in_memory (data
, off
, whence
)
8574 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8579 case SEEK_SET
: /* Go from beginning of source. */
8583 case SEEK_END
: /* Go from end of source. */
8584 idx
= src
->len
+ off
;
8587 case SEEK_CUR
: /* Go from current position. */
8588 idx
= src
->index
+ off
;
8591 default: /* Invalid `whence'. */
8595 if (idx
> src
->len
|| idx
< 0)
8604 tiff_close_memory (data
)
8613 tiff_mmap_memory (data
, pbase
, psize
)
8618 /* It is already _IN_ memory. */
8624 tiff_unmap_memory (data
, base
, size
)
8629 /* We don't need to do this. */
8634 tiff_size_of_memory (data
)
8637 return ((tiff_memory_source
*) data
)->len
;
8642 tiff_error_handler (title
, format
, ap
)
8643 const char *title
, *format
;
8649 len
= sprintf (buf
, "TIFF error: %s ", title
);
8650 vsprintf (buf
+ len
, format
, ap
);
8651 add_to_log (buf
, Qnil
, Qnil
);
8656 tiff_warning_handler (title
, format
, ap
)
8657 const char *title
, *format
;
8663 len
= sprintf (buf
, "TIFF warning: %s ", title
);
8664 vsprintf (buf
+ len
, format
, ap
);
8665 add_to_log (buf
, Qnil
, Qnil
);
8669 /* Load TIFF image IMG for use on frame F. Value is non-zero if
8677 Lisp_Object file
, specified_file
;
8678 Lisp_Object specified_data
;
8680 int width
, height
, x
, y
;
8684 struct gcpro gcpro1
;
8685 tiff_memory_source memsrc
;
8687 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8688 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8692 TIFFSetErrorHandler (tiff_error_handler
);
8693 TIFFSetWarningHandler (tiff_warning_handler
);
8695 if (NILP (specified_data
))
8697 /* Read from a file */
8698 file
= x_find_image_file (specified_file
);
8699 if (!STRINGP (file
))
8701 image_error ("Cannot find image file `%s'", file
, Qnil
);
8706 /* Try to open the image file. */
8707 tiff
= TIFFOpen (SDATA (file
), "r");
8710 image_error ("Cannot open `%s'", file
, Qnil
);
8717 /* Memory source! */
8718 memsrc
.bytes
= SDATA (specified_data
);
8719 memsrc
.len
= SBYTES (specified_data
);
8722 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
8723 (TIFFReadWriteProc
) tiff_read_from_memory
,
8724 (TIFFReadWriteProc
) tiff_write_from_memory
,
8725 tiff_seek_in_memory
,
8727 tiff_size_of_memory
,
8733 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
8739 /* Get width and height of the image, and allocate a raster buffer
8740 of width x height 32-bit values. */
8741 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
8742 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
8743 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
8745 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
8749 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
8755 /* Create the X image and pixmap. */
8756 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8763 /* Initialize the color table. */
8764 init_color_table ();
8766 /* Process the pixel raster. Origin is in the lower-left corner. */
8767 for (y
= 0; y
< height
; ++y
)
8769 uint32
*row
= buf
+ y
* width
;
8771 for (x
= 0; x
< width
; ++x
)
8773 uint32 abgr
= row
[x
];
8774 int r
= TIFFGetR (abgr
) << 8;
8775 int g
= TIFFGetG (abgr
) << 8;
8776 int b
= TIFFGetB (abgr
) << 8;
8777 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
8781 /* Remember the colors allocated for the image. Free the color table. */
8782 img
->colors
= colors_in_color_table (&img
->ncolors
);
8783 free_color_table ();
8786 img
->height
= height
;
8788 /* Maybe fill in the background field while we have ximg handy. */
8789 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8790 IMAGE_BACKGROUND (img
, f
, ximg
);
8792 /* Put the image into the pixmap, then free the X image and its buffer. */
8793 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8794 x_destroy_x_image (ximg
);
8801 #endif /* HAVE_TIFF != 0 */
8805 /***********************************************************************
8807 ***********************************************************************/
8811 #include <gif_lib.h>
8813 static int gif_image_p
P_ ((Lisp_Object object
));
8814 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
8816 /* The symbol `gif' identifying images of this type. */
8820 /* Indices of image specification fields in gif_format, below. */
8822 enum gif_keyword_index
8838 /* Vector of image_keyword structures describing the format
8839 of valid user-defined image specifications. */
8841 static struct image_keyword gif_format
[GIF_LAST
] =
8843 {":type", IMAGE_SYMBOL_VALUE
, 1},
8844 {":data", IMAGE_STRING_VALUE
, 0},
8845 {":file", IMAGE_STRING_VALUE
, 0},
8846 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8847 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8848 {":relief", IMAGE_INTEGER_VALUE
, 0},
8849 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8850 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8851 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8852 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8853 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8856 /* Structure describing the image type `gif'. */
8858 static struct image_type gif_type
=
8868 /* Return non-zero if OBJECT is a valid GIF image specification. */
8871 gif_image_p (object
)
8874 struct image_keyword fmt
[GIF_LAST
];
8875 bcopy (gif_format
, fmt
, sizeof fmt
);
8877 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
8880 /* Must specify either the :data or :file keyword. */
8881 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
8885 /* Reading a GIF image from memory
8886 Based on the PNG memory stuff to a certain extent. */
8890 unsigned char *bytes
;
8897 /* Make the current memory source available to gif_read_from_memory.
8898 It's done this way because not all versions of libungif support
8899 a UserData field in the GifFileType structure. */
8900 static gif_memory_source
*current_gif_memory_src
;
8903 gif_read_from_memory (file
, buf
, len
)
8908 gif_memory_source
*src
= current_gif_memory_src
;
8910 if (len
> src
->len
- src
->index
)
8913 bcopy (src
->bytes
+ src
->index
, buf
, len
);
8919 /* Load GIF image IMG for use on frame F. Value is non-zero if
8927 Lisp_Object file
, specified_file
;
8928 Lisp_Object specified_data
;
8929 int rc
, width
, height
, x
, y
, i
;
8931 ColorMapObject
*gif_color_map
;
8932 unsigned long pixel_colors
[256];
8934 struct gcpro gcpro1
;
8936 int ino
, image_left
, image_top
, image_width
, image_height
;
8937 gif_memory_source memsrc
;
8938 unsigned char *raster
;
8940 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8941 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8945 if (NILP (specified_data
))
8947 file
= x_find_image_file (specified_file
);
8948 if (!STRINGP (file
))
8950 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8955 /* Open the GIF file. */
8956 gif
= DGifOpenFileName (SDATA (file
));
8959 image_error ("Cannot open `%s'", file
, Qnil
);
8966 /* Read from memory! */
8967 current_gif_memory_src
= &memsrc
;
8968 memsrc
.bytes
= SDATA (specified_data
);
8969 memsrc
.len
= SBYTES (specified_data
);
8972 gif
= DGifOpen(&memsrc
, gif_read_from_memory
);
8975 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
8981 /* Read entire contents. */
8982 rc
= DGifSlurp (gif
);
8983 if (rc
== GIF_ERROR
)
8985 image_error ("Error reading `%s'", img
->spec
, Qnil
);
8986 DGifCloseFile (gif
);
8991 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
8992 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
8993 if (ino
>= gif
->ImageCount
)
8995 image_error ("Invalid image number `%s' in image `%s'",
8997 DGifCloseFile (gif
);
9002 width
= img
->width
= max (gif
->SWidth
, gif
->Image
.Left
+ gif
->Image
.Width
);
9003 height
= img
->height
= max (gif
->SHeight
, gif
->Image
.Top
+ gif
->Image
.Height
);
9005 /* Create the X image and pixmap. */
9006 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
9008 DGifCloseFile (gif
);
9013 /* Allocate colors. */
9014 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
9016 gif_color_map
= gif
->SColorMap
;
9017 init_color_table ();
9018 bzero (pixel_colors
, sizeof pixel_colors
);
9020 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
9022 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
9023 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
9024 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
9025 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
9028 img
->colors
= colors_in_color_table (&img
->ncolors
);
9029 free_color_table ();
9031 /* Clear the part of the screen image that are not covered by
9032 the image from the GIF file. Full animated GIF support
9033 requires more than can be done here (see the gif89 spec,
9034 disposal methods). Let's simply assume that the part
9035 not covered by a sub-image is in the frame's background color. */
9036 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
9037 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
9038 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
9039 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
9041 for (y
= 0; y
< image_top
; ++y
)
9042 for (x
= 0; x
< width
; ++x
)
9043 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9045 for (y
= image_top
+ image_height
; y
< height
; ++y
)
9046 for (x
= 0; x
< width
; ++x
)
9047 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9049 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
9051 for (x
= 0; x
< image_left
; ++x
)
9052 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9053 for (x
= image_left
+ image_width
; x
< width
; ++x
)
9054 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9057 /* Read the GIF image into the X image. We use a local variable
9058 `raster' here because RasterBits below is a char *, and invites
9059 problems with bytes >= 0x80. */
9060 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
9062 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
9064 static int interlace_start
[] = {0, 4, 2, 1};
9065 static int interlace_increment
[] = {8, 8, 4, 2};
9067 int row
= interlace_start
[0];
9071 for (y
= 0; y
< image_height
; y
++)
9073 if (row
>= image_height
)
9075 row
= interlace_start
[++pass
];
9076 while (row
>= image_height
)
9077 row
= interlace_start
[++pass
];
9080 for (x
= 0; x
< image_width
; x
++)
9082 int i
= raster
[(y
* image_width
) + x
];
9083 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
9087 row
+= interlace_increment
[pass
];
9092 for (y
= 0; y
< image_height
; ++y
)
9093 for (x
= 0; x
< image_width
; ++x
)
9095 int i
= raster
[y
* image_width
+ x
];
9096 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
9100 DGifCloseFile (gif
);
9102 /* Maybe fill in the background field while we have ximg handy. */
9103 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
9104 IMAGE_BACKGROUND (img
, f
, ximg
);
9106 /* Put the image into the pixmap, then free the X image and its buffer. */
9107 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
9108 x_destroy_x_image (ximg
);
9114 #endif /* HAVE_GIF != 0 */
9118 /***********************************************************************
9120 ***********************************************************************/
9122 static int gs_image_p
P_ ((Lisp_Object object
));
9123 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
9124 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
9126 /* The symbol `postscript' identifying images of this type. */
9128 Lisp_Object Qpostscript
;
9130 /* Keyword symbols. */
9132 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
9134 /* Indices of image specification fields in gs_format, below. */
9136 enum gs_keyword_index
9154 /* Vector of image_keyword structures describing the format
9155 of valid user-defined image specifications. */
9157 static struct image_keyword gs_format
[GS_LAST
] =
9159 {":type", IMAGE_SYMBOL_VALUE
, 1},
9160 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9161 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9162 {":file", IMAGE_STRING_VALUE
, 1},
9163 {":loader", IMAGE_FUNCTION_VALUE
, 0},
9164 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
9165 {":ascent", IMAGE_ASCENT_VALUE
, 0},
9166 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
9167 {":relief", IMAGE_INTEGER_VALUE
, 0},
9168 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9169 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9170 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9171 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
9174 /* Structure describing the image type `ghostscript'. */
9176 static struct image_type gs_type
=
9186 /* Free X resources of Ghostscript image IMG which is used on frame F. */
9189 gs_clear_image (f
, img
)
9193 /* IMG->data.ptr_val may contain a recorded colormap. */
9194 xfree (img
->data
.ptr_val
);
9195 x_clear_image (f
, img
);
9199 /* Return non-zero if OBJECT is a valid Ghostscript image
9206 struct image_keyword fmt
[GS_LAST
];
9210 bcopy (gs_format
, fmt
, sizeof fmt
);
9212 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
9215 /* Bounding box must be a list or vector containing 4 integers. */
9216 tem
= fmt
[GS_BOUNDING_BOX
].value
;
9219 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
9220 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
9225 else if (VECTORP (tem
))
9227 if (XVECTOR (tem
)->size
!= 4)
9229 for (i
= 0; i
< 4; ++i
)
9230 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
9240 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
9249 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
9250 struct gcpro gcpro1
, gcpro2
;
9252 double in_width
, in_height
;
9253 Lisp_Object pixel_colors
= Qnil
;
9255 /* Compute pixel size of pixmap needed from the given size in the
9256 image specification. Sizes in the specification are in pt. 1 pt
9257 = 1/72 in, xdpi and ydpi are stored in the frame's X display
9259 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
9260 in_width
= XFASTINT (pt_width
) / 72.0;
9261 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
9262 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
9263 in_height
= XFASTINT (pt_height
) / 72.0;
9264 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
9266 /* Create the pixmap. */
9267 xassert (img
->pixmap
== None
);
9268 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9269 img
->width
, img
->height
,
9270 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
9274 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
9278 /* Call the loader to fill the pixmap. It returns a process object
9279 if successful. We do not record_unwind_protect here because
9280 other places in redisplay like calling window scroll functions
9281 don't either. Let the Lisp loader use `unwind-protect' instead. */
9282 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
9284 sprintf (buffer
, "%lu %lu",
9285 (unsigned long) FRAME_X_WINDOW (f
),
9286 (unsigned long) img
->pixmap
);
9287 window_and_pixmap_id
= build_string (buffer
);
9289 sprintf (buffer
, "%lu %lu",
9290 FRAME_FOREGROUND_PIXEL (f
),
9291 FRAME_BACKGROUND_PIXEL (f
));
9292 pixel_colors
= build_string (buffer
);
9294 XSETFRAME (frame
, f
);
9295 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
9297 loader
= intern ("gs-load-image");
9299 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
9300 make_number (img
->width
),
9301 make_number (img
->height
),
9302 window_and_pixmap_id
,
9305 return PROCESSP (img
->data
.lisp_val
);
9309 /* Kill the Ghostscript process that was started to fill PIXMAP on
9310 frame F. Called from XTread_socket when receiving an event
9311 telling Emacs that Ghostscript has finished drawing. */
9314 x_kill_gs_process (pixmap
, f
)
9318 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
9322 /* Find the image containing PIXMAP. */
9323 for (i
= 0; i
< c
->used
; ++i
)
9324 if (c
->images
[i
]->pixmap
== pixmap
)
9327 /* Should someone in between have cleared the image cache, for
9328 instance, give up. */
9332 /* Kill the GS process. We should have found PIXMAP in the image
9333 cache and its image should contain a process object. */
9335 xassert (PROCESSP (img
->data
.lisp_val
));
9336 Fkill_process (img
->data
.lisp_val
, Qnil
);
9337 img
->data
.lisp_val
= Qnil
;
9339 /* On displays with a mutable colormap, figure out the colors
9340 allocated for the image by looking at the pixels of an XImage for
9342 class = FRAME_X_VISUAL (f
)->class;
9343 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
9349 /* Try to get an XImage for img->pixmep. */
9350 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
9351 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
9356 /* Initialize the color table. */
9357 init_color_table ();
9359 /* For each pixel of the image, look its color up in the
9360 color table. After having done so, the color table will
9361 contain an entry for each color used by the image. */
9362 for (y
= 0; y
< img
->height
; ++y
)
9363 for (x
= 0; x
< img
->width
; ++x
)
9365 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
9366 lookup_pixel_color (f
, pixel
);
9369 /* Record colors in the image. Free color table and XImage. */
9370 img
->colors
= colors_in_color_table (&img
->ncolors
);
9371 free_color_table ();
9372 XDestroyImage (ximg
);
9374 #if 0 /* This doesn't seem to be the case. If we free the colors
9375 here, we get a BadAccess later in x_clear_image when
9376 freeing the colors. */
9377 /* We have allocated colors once, but Ghostscript has also
9378 allocated colors on behalf of us. So, to get the
9379 reference counts right, free them once. */
9381 x_free_colors (f
, img
->colors
, img
->ncolors
);
9385 image_error ("Cannot get X image of `%s'; colors will not be freed",
9391 /* Now that we have the pixmap, compute mask and transform the
9392 image if requested. */
9394 postprocess_image (f
, img
);
9400 /***********************************************************************
9402 ***********************************************************************/
9404 DEFUN ("x-change-window-property", Fx_change_window_property
,
9405 Sx_change_window_property
, 2, 3, 0,
9406 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
9407 PROP and VALUE must be strings. FRAME nil or omitted means use the
9408 selected frame. Value is VALUE. */)
9409 (prop
, value
, frame
)
9410 Lisp_Object frame
, prop
, value
;
9412 struct frame
*f
= check_x_frame (frame
);
9415 CHECK_STRING (prop
);
9416 CHECK_STRING (value
);
9419 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9420 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9421 prop_atom
, XA_STRING
, 8, PropModeReplace
,
9422 SDATA (value
), SCHARS (value
));
9424 /* Make sure the property is set when we return. */
9425 XFlush (FRAME_X_DISPLAY (f
));
9432 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
9433 Sx_delete_window_property
, 1, 2, 0,
9434 doc
: /* Remove window property PROP from X window of FRAME.
9435 FRAME nil or omitted means use the selected frame. Value is PROP. */)
9437 Lisp_Object prop
, frame
;
9439 struct frame
*f
= check_x_frame (frame
);
9442 CHECK_STRING (prop
);
9444 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9445 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
9447 /* Make sure the property is removed when we return. */
9448 XFlush (FRAME_X_DISPLAY (f
));
9455 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
9457 doc
: /* Value is the value of window property PROP on FRAME.
9458 If FRAME is nil or omitted, use the selected frame. Value is nil
9459 if FRAME hasn't a property with name PROP or if PROP has no string
9462 Lisp_Object prop
, frame
;
9464 struct frame
*f
= check_x_frame (frame
);
9467 Lisp_Object prop_value
= Qnil
;
9468 char *tmp_data
= NULL
;
9471 unsigned long actual_size
, bytes_remaining
;
9473 CHECK_STRING (prop
);
9475 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9476 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9477 prop_atom
, 0, 0, False
, XA_STRING
,
9478 &actual_type
, &actual_format
, &actual_size
,
9479 &bytes_remaining
, (unsigned char **) &tmp_data
);
9482 int size
= bytes_remaining
;
9487 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9488 prop_atom
, 0, bytes_remaining
,
9490 &actual_type
, &actual_format
,
9491 &actual_size
, &bytes_remaining
,
9492 (unsigned char **) &tmp_data
);
9493 if (rc
== Success
&& tmp_data
)
9494 prop_value
= make_string (tmp_data
, size
);
9505 /***********************************************************************
9507 ***********************************************************************/
9509 /* If non-null, an asynchronous timer that, when it expires, displays
9510 an hourglass cursor on all frames. */
9512 static struct atimer
*hourglass_atimer
;
9514 /* Non-zero means an hourglass cursor is currently shown. */
9516 static int hourglass_shown_p
;
9518 /* Number of seconds to wait before displaying an hourglass cursor. */
9520 static Lisp_Object Vhourglass_delay
;
9522 /* Default number of seconds to wait before displaying an hourglass
9525 #define DEFAULT_HOURGLASS_DELAY 1
9527 /* Function prototypes. */
9529 static void show_hourglass
P_ ((struct atimer
*));
9530 static void hide_hourglass
P_ ((void));
9533 /* Cancel a currently active hourglass timer, and start a new one. */
9539 int secs
, usecs
= 0;
9541 cancel_hourglass ();
9543 if (INTEGERP (Vhourglass_delay
)
9544 && XINT (Vhourglass_delay
) > 0)
9545 secs
= XFASTINT (Vhourglass_delay
);
9546 else if (FLOATP (Vhourglass_delay
)
9547 && XFLOAT_DATA (Vhourglass_delay
) > 0)
9550 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
9551 secs
= XFASTINT (tem
);
9552 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
9555 secs
= DEFAULT_HOURGLASS_DELAY
;
9557 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
9558 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
9559 show_hourglass
, NULL
);
9563 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
9569 if (hourglass_atimer
)
9571 cancel_atimer (hourglass_atimer
);
9572 hourglass_atimer
= NULL
;
9575 if (hourglass_shown_p
)
9580 /* Timer function of hourglass_atimer. TIMER is equal to
9583 Display an hourglass pointer on all frames by mapping the frames'
9584 hourglass_window. Set the hourglass_p flag in the frames'
9585 output_data.x structure to indicate that an hourglass cursor is
9586 shown on the frames. */
9589 show_hourglass (timer
)
9590 struct atimer
*timer
;
9592 /* The timer implementation will cancel this timer automatically
9593 after this function has run. Set hourglass_atimer to null
9594 so that we know the timer doesn't have to be canceled. */
9595 hourglass_atimer
= NULL
;
9597 if (!hourglass_shown_p
)
9599 Lisp_Object rest
, frame
;
9603 FOR_EACH_FRAME (rest
, frame
)
9605 struct frame
*f
= XFRAME (frame
);
9607 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
9609 Display
*dpy
= FRAME_X_DISPLAY (f
);
9611 #ifdef USE_X_TOOLKIT
9612 if (f
->output_data
.x
->widget
)
9614 if (FRAME_OUTER_WINDOW (f
))
9617 f
->output_data
.x
->hourglass_p
= 1;
9619 if (!f
->output_data
.x
->hourglass_window
)
9621 unsigned long mask
= CWCursor
;
9622 XSetWindowAttributes attrs
;
9624 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
9626 f
->output_data
.x
->hourglass_window
9627 = XCreateWindow (dpy
, FRAME_OUTER_WINDOW (f
),
9628 0, 0, 32000, 32000, 0, 0,
9634 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
9640 hourglass_shown_p
= 1;
9646 /* Hide the hourglass pointer on all frames, if it is currently
9652 if (hourglass_shown_p
)
9654 Lisp_Object rest
, frame
;
9657 FOR_EACH_FRAME (rest
, frame
)
9659 struct frame
*f
= XFRAME (frame
);
9662 /* Watch out for newly created frames. */
9663 && f
->output_data
.x
->hourglass_window
)
9665 XUnmapWindow (FRAME_X_DISPLAY (f
),
9666 f
->output_data
.x
->hourglass_window
);
9667 /* Sync here because XTread_socket looks at the
9668 hourglass_p flag that is reset to zero below. */
9669 XSync (FRAME_X_DISPLAY (f
), False
);
9670 f
->output_data
.x
->hourglass_p
= 0;
9674 hourglass_shown_p
= 0;
9681 /***********************************************************************
9683 ***********************************************************************/
9685 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
9686 Lisp_Object
, Lisp_Object
));
9687 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
9688 Lisp_Object
, int, int, int *, int *));
9690 /* The frame of a currently visible tooltip. */
9692 Lisp_Object tip_frame
;
9694 /* If non-nil, a timer started that hides the last tooltip when it
9697 Lisp_Object tip_timer
;
9700 /* If non-nil, a vector of 3 elements containing the last args
9701 with which x-show-tip was called. See there. */
9703 Lisp_Object last_show_tip_args
;
9705 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
9707 Lisp_Object Vx_max_tooltip_size
;
9711 unwind_create_tip_frame (frame
)
9714 Lisp_Object deleted
;
9716 deleted
= unwind_create_frame (frame
);
9717 if (EQ (deleted
, Qt
))
9727 /* Create a frame for a tooltip on the display described by DPYINFO.
9728 PARMS is a list of frame parameters. TEXT is the string to
9729 display in the tip frame. Value is the frame.
9731 Note that functions called here, esp. x_default_parameter can
9732 signal errors, for instance when a specified color name is
9733 undefined. We have to make sure that we're in a consistent state
9734 when this happens. */
9737 x_create_tip_frame (dpyinfo
, parms
, text
)
9738 struct x_display_info
*dpyinfo
;
9739 Lisp_Object parms
, text
;
9742 Lisp_Object frame
, tem
;
9744 long window_prompting
= 0;
9746 int count
= SPECPDL_INDEX ();
9747 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9749 int face_change_count_before
= face_change_count
;
9751 struct buffer
*old_buffer
;
9755 /* Use this general default value to start with until we know if
9756 this frame has a specified name. */
9757 Vx_resource_name
= Vinvocation_name
;
9760 kb
= dpyinfo
->kboard
;
9762 kb
= &the_only_kboard
;
9765 /* Get the name of the frame to use for resource lookup. */
9766 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
9768 && !EQ (name
, Qunbound
)
9770 error ("Invalid frame name--not a string or nil");
9771 Vx_resource_name
= name
;
9774 GCPRO3 (parms
, name
, frame
);
9776 XSETFRAME (frame
, f
);
9778 buffer
= Fget_buffer_create (build_string (" *tip*"));
9779 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
9780 old_buffer
= current_buffer
;
9781 set_buffer_internal_1 (XBUFFER (buffer
));
9782 current_buffer
->truncate_lines
= Qnil
;
9785 set_buffer_internal_1 (old_buffer
);
9787 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
9788 record_unwind_protect (unwind_create_tip_frame
, frame
);
9790 /* By setting the output method, we're essentially saying that
9791 the frame is live, as per FRAME_LIVE_P. If we get a signal
9792 from this point on, x_destroy_window might screw up reference
9794 f
->output_method
= output_x_window
;
9795 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
9796 bzero (f
->output_data
.x
, sizeof (struct x_output
));
9797 f
->output_data
.x
->icon_bitmap
= -1;
9798 FRAME_FONTSET (f
) = -1;
9799 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
9800 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
9801 #ifdef USE_TOOLKIT_SCROLL_BARS
9802 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
9803 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
9804 #endif /* USE_TOOLKIT_SCROLL_BARS */
9805 f
->icon_name
= Qnil
;
9806 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
9808 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
9809 dpyinfo_refcount
= dpyinfo
->reference_count
;
9810 #endif /* GLYPH_DEBUG */
9812 FRAME_KBOARD (f
) = kb
;
9814 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
9815 f
->output_data
.x
->explicit_parent
= 0;
9817 /* These colors will be set anyway later, but it's important
9818 to get the color reference counts right, so initialize them! */
9821 struct gcpro gcpro1
;
9823 black
= build_string ("black");
9825 f
->output_data
.x
->foreground_pixel
9826 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9827 f
->output_data
.x
->background_pixel
9828 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9829 f
->output_data
.x
->cursor_pixel
9830 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9831 f
->output_data
.x
->cursor_foreground_pixel
9832 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9833 f
->output_data
.x
->border_pixel
9834 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9835 f
->output_data
.x
->mouse_pixel
9836 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9840 /* Set the name; the functions to which we pass f expect the name to
9842 if (EQ (name
, Qunbound
) || NILP (name
))
9844 f
->name
= build_string (dpyinfo
->x_id_name
);
9845 f
->explicit_name
= 0;
9850 f
->explicit_name
= 1;
9851 /* use the frame's title when getting resources for this frame. */
9852 specbind (Qx_resource_name
, name
);
9855 /* Extract the window parameters from the supplied values that are
9856 needed to determine window geometry. */
9860 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
9863 /* First, try whatever font the caller has specified. */
9866 tem
= Fquery_fontset (font
, Qnil
);
9868 font
= x_new_fontset (f
, SDATA (tem
));
9870 font
= x_new_font (f
, SDATA (font
));
9873 /* Try out a font which we hope has bold and italic variations. */
9874 if (!STRINGP (font
))
9875 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
9876 if (!STRINGP (font
))
9877 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9878 if (! STRINGP (font
))
9879 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9880 if (! STRINGP (font
))
9881 /* This was formerly the first thing tried, but it finds too many fonts
9882 and takes too long. */
9883 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
9884 /* If those didn't work, look for something which will at least work. */
9885 if (! STRINGP (font
))
9886 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
9888 if (! STRINGP (font
))
9889 font
= build_string ("fixed");
9891 x_default_parameter (f
, parms
, Qfont
, font
,
9892 "font", "Font", RES_TYPE_STRING
);
9895 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
9896 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
9898 /* This defaults to 2 in order to match xterm. We recognize either
9899 internalBorderWidth or internalBorder (which is what xterm calls
9901 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9905 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
9906 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
9907 if (! EQ (value
, Qunbound
))
9908 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
9912 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
9913 "internalBorderWidth", "internalBorderWidth",
9916 /* Also do the stuff which must be set before the window exists. */
9917 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
9918 "foreground", "Foreground", RES_TYPE_STRING
);
9919 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
9920 "background", "Background", RES_TYPE_STRING
);
9921 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
9922 "pointerColor", "Foreground", RES_TYPE_STRING
);
9923 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
9924 "cursorColor", "Foreground", RES_TYPE_STRING
);
9925 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
9926 "borderColor", "BorderColor", RES_TYPE_STRING
);
9928 /* Init faces before x_default_parameter is called for scroll-bar
9929 parameters because that function calls x_set_scroll_bar_width,
9930 which calls change_frame_size, which calls Fset_window_buffer,
9931 which runs hooks, which call Fvertical_motion. At the end, we
9932 end up in init_iterator with a null face cache, which should not
9934 init_frame_faces (f
);
9936 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
9938 window_prompting
= x_figure_window_size (f
, parms
, 0);
9941 XSetWindowAttributes attrs
;
9945 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
9946 if (DoesSaveUnders (dpyinfo
->screen
))
9947 mask
|= CWSaveUnder
;
9949 /* Window managers look at the override-redirect flag to determine
9950 whether or net to give windows a decoration (Xlib spec, chapter
9952 attrs
.override_redirect
= True
;
9953 attrs
.save_under
= True
;
9954 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
9955 /* Arrange for getting MapNotify and UnmapNotify events. */
9956 attrs
.event_mask
= StructureNotifyMask
;
9958 = FRAME_X_WINDOW (f
)
9959 = XCreateWindow (FRAME_X_DISPLAY (f
),
9960 FRAME_X_DISPLAY_INFO (f
)->root_window
,
9961 /* x, y, width, height */
9965 CopyFromParent
, InputOutput
, CopyFromParent
,
9972 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
9973 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9974 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
9975 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9976 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
9977 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
9979 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
9980 Change will not be effected unless different from the current
9982 width
= FRAME_COLS (f
);
9983 height
= FRAME_LINES (f
);
9984 SET_FRAME_COLS (f
, 0);
9985 FRAME_LINES (f
) = 0;
9986 change_frame_size (f
, height
, width
, 1, 0, 0);
9988 /* Add `tooltip' frame parameter's default value. */
9989 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
9990 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
9993 /* Set up faces after all frame parameters are known. This call
9994 also merges in face attributes specified for new frames.
9996 Frame parameters may be changed if .Xdefaults contains
9997 specifications for the default font. For example, if there is an
9998 `Emacs.default.attributeBackground: pink', the `background-color'
9999 attribute of the frame get's set, which let's the internal border
10000 of the tooltip frame appear in pink. Prevent this. */
10002 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
10004 /* Set tip_frame here, so that */
10006 call1 (Qface_set_after_frame_default
, frame
);
10008 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
10009 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
10017 /* It is now ok to make the frame official even if we get an error
10018 below. And the frame needs to be on Vframe_list or making it
10019 visible won't work. */
10020 Vframe_list
= Fcons (frame
, Vframe_list
);
10022 /* Now that the frame is official, it counts as a reference to
10024 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
10026 /* Setting attributes of faces of the tooltip frame from resources
10027 and similar will increment face_change_count, which leads to the
10028 clearing of all current matrices. Since this isn't necessary
10029 here, avoid it by resetting face_change_count to the value it
10030 had before we created the tip frame. */
10031 face_change_count
= face_change_count_before
;
10033 /* Discard the unwind_protect. */
10034 return unbind_to (count
, frame
);
10038 /* Compute where to display tip frame F. PARMS is the list of frame
10039 parameters for F. DX and DY are specified offsets from the current
10040 location of the mouse. WIDTH and HEIGHT are the width and height
10041 of the tooltip. Return coordinates relative to the root window of
10042 the display in *ROOT_X, and *ROOT_Y. */
10045 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
10047 Lisp_Object parms
, dx
, dy
;
10049 int *root_x
, *root_y
;
10051 Lisp_Object left
, top
;
10053 Window root
, child
;
10056 /* User-specified position? */
10057 left
= Fcdr (Fassq (Qleft
, parms
));
10058 top
= Fcdr (Fassq (Qtop
, parms
));
10060 /* Move the tooltip window where the mouse pointer is. Resize and
10062 if (!INTEGERP (left
) || !INTEGERP (top
))
10065 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
10066 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
10070 if (INTEGERP (top
))
10071 *root_y
= XINT (top
);
10072 else if (*root_y
+ XINT (dy
) - height
< 0)
10073 *root_y
-= XINT (dy
);
10077 *root_y
+= XINT (dy
);
10080 if (INTEGERP (left
))
10081 *root_x
= XINT (left
);
10082 else if (*root_x
+ XINT (dx
) + width
<= FRAME_X_DISPLAY_INFO (f
)->width
)
10083 /* It fits to the right of the pointer. */
10084 *root_x
+= XINT (dx
);
10085 else if (width
+ XINT (dx
) <= *root_x
)
10086 /* It fits to the left of the pointer. */
10087 *root_x
-= width
+ XINT (dx
);
10089 /* Put it left-justified on the screen--it ought to fit that way. */
10094 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
10095 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
10096 A tooltip window is a small X window displaying a string.
10098 FRAME nil or omitted means use the selected frame.
10100 PARMS is an optional list of frame parameters which can be used to
10101 change the tooltip's appearance.
10103 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
10104 means use the default timeout of 5 seconds.
10106 If the list of frame parameters PARAMS contains a `left' parameters,
10107 the tooltip is displayed at that x-position. Otherwise it is
10108 displayed at the mouse position, with offset DX added (default is 5 if
10109 DX isn't specified). Likewise for the y-position; if a `top' frame
10110 parameter is specified, it determines the y-position of the tooltip
10111 window, otherwise it is displayed at the mouse position, with offset
10112 DY added (default is -10).
10114 A tooltip's maximum size is specified by `x-max-tooltip-size'.
10115 Text larger than the specified size is clipped. */)
10116 (string
, frame
, parms
, timeout
, dx
, dy
)
10117 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
10121 int root_x
, root_y
;
10122 struct buffer
*old_buffer
;
10123 struct text_pos pos
;
10124 int i
, width
, height
;
10125 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
10126 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
10127 int count
= SPECPDL_INDEX ();
10129 specbind (Qinhibit_redisplay
, Qt
);
10131 GCPRO4 (string
, parms
, frame
, timeout
);
10133 CHECK_STRING (string
);
10134 f
= check_x_frame (frame
);
10135 if (NILP (timeout
))
10136 timeout
= make_number (5);
10138 CHECK_NATNUM (timeout
);
10141 dx
= make_number (5);
10146 dy
= make_number (-10);
10150 if (NILP (last_show_tip_args
))
10151 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
10153 if (!NILP (tip_frame
))
10155 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
10156 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
10157 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
10159 if (EQ (frame
, last_frame
)
10160 && !NILP (Fequal (last_string
, string
))
10161 && !NILP (Fequal (last_parms
, parms
)))
10163 struct frame
*f
= XFRAME (tip_frame
);
10165 /* Only DX and DY have changed. */
10166 if (!NILP (tip_timer
))
10168 Lisp_Object timer
= tip_timer
;
10170 call1 (Qcancel_timer
, timer
);
10174 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
10175 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
10176 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10183 /* Hide a previous tip, if any. */
10186 ASET (last_show_tip_args
, 0, string
);
10187 ASET (last_show_tip_args
, 1, frame
);
10188 ASET (last_show_tip_args
, 2, parms
);
10190 /* Add default values to frame parameters. */
10191 if (NILP (Fassq (Qname
, parms
)))
10192 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
10193 if (NILP (Fassq (Qinternal_border_width
, parms
)))
10194 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
10195 if (NILP (Fassq (Qborder_width
, parms
)))
10196 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
10197 if (NILP (Fassq (Qborder_color
, parms
)))
10198 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
10199 if (NILP (Fassq (Qbackground_color
, parms
)))
10200 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
10203 /* Create a frame for the tooltip, and record it in the global
10204 variable tip_frame. */
10205 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
10206 f
= XFRAME (frame
);
10208 /* Set up the frame's root window. */
10209 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
10210 w
->left_col
= w
->top_line
= make_number (0);
10212 if (CONSP (Vx_max_tooltip_size
)
10213 && INTEGERP (XCAR (Vx_max_tooltip_size
))
10214 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
10215 && INTEGERP (XCDR (Vx_max_tooltip_size
))
10216 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
10218 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
10219 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
10223 w
->total_cols
= make_number (80);
10224 w
->total_lines
= make_number (40);
10227 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
10229 w
->pseudo_window_p
= 1;
10231 /* Display the tooltip text in a temporary buffer. */
10232 old_buffer
= current_buffer
;
10233 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
10234 current_buffer
->truncate_lines
= Qnil
;
10235 clear_glyph_matrix (w
->desired_matrix
);
10236 clear_glyph_matrix (w
->current_matrix
);
10237 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
10238 try_window (FRAME_ROOT_WINDOW (f
), pos
);
10240 /* Compute width and height of the tooltip. */
10241 width
= height
= 0;
10242 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
10244 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
10245 struct glyph
*last
;
10248 /* Stop at the first empty row at the end. */
10249 if (!row
->enabled_p
|| !row
->displays_text_p
)
10252 /* Let the row go over the full width of the frame. */
10253 row
->full_width_p
= 1;
10255 /* There's a glyph at the end of rows that is used to place
10256 the cursor there. Don't include the width of this glyph. */
10257 if (row
->used
[TEXT_AREA
])
10259 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
10260 row_width
= row
->pixel_width
- last
->pixel_width
;
10263 row_width
= row
->pixel_width
;
10265 height
+= row
->height
;
10266 width
= max (width
, row_width
);
10269 /* Add the frame's internal border to the width and height the X
10270 window should have. */
10271 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10272 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10274 /* Move the tooltip window where the mouse pointer is. Resize and
10276 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
10279 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10280 root_x
, root_y
, width
, height
);
10281 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
10284 /* Draw into the window. */
10285 w
->must_be_updated_p
= 1;
10286 update_single_window (w
, 1);
10288 /* Restore original current buffer. */
10289 set_buffer_internal_1 (old_buffer
);
10290 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
10293 /* Let the tip disappear after timeout seconds. */
10294 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
10295 intern ("x-hide-tip"));
10298 return unbind_to (count
, Qnil
);
10302 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
10303 doc
: /* Hide the current tooltip window, if there is any.
10304 Value is t if tooltip was open, nil otherwise. */)
10308 Lisp_Object deleted
, frame
, timer
;
10309 struct gcpro gcpro1
, gcpro2
;
10311 /* Return quickly if nothing to do. */
10312 if (NILP (tip_timer
) && NILP (tip_frame
))
10317 GCPRO2 (frame
, timer
);
10318 tip_frame
= tip_timer
= deleted
= Qnil
;
10320 count
= SPECPDL_INDEX ();
10321 specbind (Qinhibit_redisplay
, Qt
);
10322 specbind (Qinhibit_quit
, Qt
);
10325 call1 (Qcancel_timer
, timer
);
10327 if (FRAMEP (frame
))
10329 Fdelete_frame (frame
, Qnil
);
10333 /* Bloodcurdling hack alert: The Lucid menu bar widget's
10334 redisplay procedure is not called when a tip frame over menu
10335 items is unmapped. Redisplay the menu manually... */
10337 struct frame
*f
= SELECTED_FRAME ();
10338 Widget w
= f
->output_data
.x
->menubar_widget
;
10339 extern void xlwmenu_redisplay
P_ ((Widget
));
10341 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
10345 xlwmenu_redisplay (w
);
10349 #endif /* USE_LUCID */
10353 return unbind_to (count
, deleted
);
10358 /***********************************************************************
10359 File selection dialog
10360 ***********************************************************************/
10364 /* Callback for "OK" and "Cancel" on file selection dialog. */
10367 file_dialog_cb (widget
, client_data
, call_data
)
10369 XtPointer call_data
, client_data
;
10371 int *result
= (int *) client_data
;
10372 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
10373 *result
= cb
->reason
;
10377 /* Callback for unmapping a file selection dialog. This is used to
10378 capture the case where a dialog is closed via a window manager's
10379 closer button, for example. Using a XmNdestroyCallback didn't work
10383 file_dialog_unmap_cb (widget
, client_data
, call_data
)
10385 XtPointer call_data
, client_data
;
10387 int *result
= (int *) client_data
;
10388 *result
= XmCR_CANCEL
;
10392 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10393 doc
: /* Read file name, prompting with PROMPT in directory DIR.
10394 Use a file selection dialog.
10395 Select DEFAULT-FILENAME in the dialog's file selection box, if
10396 specified. Don't let the user enter a file name in the file
10397 selection dialog's entry field, if MUSTMATCH is non-nil. */)
10398 (prompt
, dir
, default_filename
, mustmatch
)
10399 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10402 struct frame
*f
= SELECTED_FRAME ();
10403 Lisp_Object file
= Qnil
;
10404 Widget dialog
, text
, list
, help
;
10407 extern XtAppContext Xt_app_con
;
10408 XmString dir_xmstring
, pattern_xmstring
;
10409 int count
= SPECPDL_INDEX ();
10410 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10412 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10413 CHECK_STRING (prompt
);
10414 CHECK_STRING (dir
);
10416 /* Prevent redisplay. */
10417 specbind (Qinhibit_redisplay
, Qt
);
10421 /* Create the dialog with PROMPT as title, using DIR as initial
10422 directory and using "*" as pattern. */
10423 dir
= Fexpand_file_name (dir
, Qnil
);
10424 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
10425 pattern_xmstring
= XmStringCreateLocalized ("*");
10427 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
10428 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
10429 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
10430 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
10431 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
10432 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
10434 XmStringFree (dir_xmstring
);
10435 XmStringFree (pattern_xmstring
);
10437 /* Add callbacks for OK and Cancel. */
10438 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
10439 (XtPointer
) &result
);
10440 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
10441 (XtPointer
) &result
);
10442 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
10443 (XtPointer
) &result
);
10445 /* Disable the help button since we can't display help. */
10446 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
10447 XtSetSensitive (help
, False
);
10449 /* Mark OK button as default. */
10450 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
10451 XmNshowAsDefault
, True
, NULL
);
10453 /* If MUSTMATCH is non-nil, disable the file entry field of the
10454 dialog, so that the user must select a file from the files list
10455 box. We can't remove it because we wouldn't have a way to get at
10456 the result file name, then. */
10457 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
10458 if (!NILP (mustmatch
))
10461 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
10462 XtSetSensitive (text
, False
);
10463 XtSetSensitive (label
, False
);
10466 /* Manage the dialog, so that list boxes get filled. */
10467 XtManageChild (dialog
);
10469 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
10470 must include the path for this to work. */
10471 list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
10472 if (STRINGP (default_filename
))
10474 XmString default_xmstring
;
10478 = XmStringCreateLocalized (SDATA (default_filename
));
10480 if (!XmListItemExists (list
, default_xmstring
))
10482 /* Add a new item if DEFAULT_FILENAME is not in the list. */
10483 XmListAddItem (list
, default_xmstring
, 0);
10487 item_pos
= XmListItemPos (list
, default_xmstring
);
10488 XmStringFree (default_xmstring
);
10490 /* Select the item and scroll it into view. */
10491 XmListSelectPos (list
, item_pos
, True
);
10492 XmListSetPos (list
, item_pos
);
10495 /* Process events until the user presses Cancel or OK. */
10497 while (result
== 0)
10500 XtAppNextEvent (Xt_app_con
, &event
);
10501 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
) );
10504 /* Get the result. */
10505 if (result
== XmCR_OK
)
10510 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
10511 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
10512 XmStringFree (text
);
10513 file
= build_string (data
);
10520 XtUnmanageChild (dialog
);
10521 XtDestroyWidget (dialog
);
10525 /* Make "Cancel" equivalent to C-g. */
10527 Fsignal (Qquit
, Qnil
);
10529 return unbind_to (count
, file
);
10532 #endif /* USE_MOTIF */
10536 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10537 "Read file name, prompting with PROMPT in directory DIR.\n\
10538 Use a file selection dialog.\n\
10539 Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
10540 specified. Don't let the user enter a file name in the file\n\
10541 selection dialog's entry field, if MUSTMATCH is non-nil.")
10542 (prompt
, dir
, default_filename
, mustmatch
)
10543 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10545 FRAME_PTR f
= SELECTED_FRAME ();
10547 Lisp_Object file
= Qnil
;
10548 int count
= specpdl_ptr
- specpdl
;
10549 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10553 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10554 CHECK_STRING (prompt
);
10555 CHECK_STRING (dir
);
10557 /* Prevent redisplay. */
10558 specbind (Qinhibit_redisplay
, Qt
);
10562 if (STRINGP (default_filename
))
10563 cdef_file
= SDATA (default_filename
);
10565 cdef_file
= SDATA (dir
);
10567 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
, ! NILP (mustmatch
));
10571 file
= build_string (fn
);
10578 /* Make "Cancel" equivalent to C-g. */
10580 Fsignal (Qquit
, Qnil
);
10582 return unbind_to (count
, file
);
10585 #endif /* USE_GTK */
10588 /***********************************************************************
10590 ***********************************************************************/
10592 #ifdef HAVE_XKBGETKEYBOARD
10593 #include <X11/XKBlib.h>
10594 #include <X11/keysym.h>
10597 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
10598 Sx_backspace_delete_keys_p
, 0, 1, 0,
10599 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
10600 FRAME nil means use the selected frame.
10601 Value is t if we know that both keys are present, and are mapped to the
10602 usual X keysyms. */)
10606 #ifdef HAVE_XKBGETKEYBOARD
10608 struct frame
*f
= check_x_frame (frame
);
10609 Display
*dpy
= FRAME_X_DISPLAY (f
);
10610 Lisp_Object have_keys
;
10611 int major
, minor
, op
, event
, error
;
10615 /* Check library version in case we're dynamically linked. */
10616 major
= XkbMajorVersion
;
10617 minor
= XkbMinorVersion
;
10618 if (!XkbLibraryVersion (&major
, &minor
))
10624 /* Check that the server supports XKB. */
10625 major
= XkbMajorVersion
;
10626 minor
= XkbMinorVersion
;
10627 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
10634 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
10637 int delete_keycode
= 0, backspace_keycode
= 0, i
;
10639 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
10641 for (i
= kb
->min_key_code
;
10642 (i
< kb
->max_key_code
10643 && (delete_keycode
== 0 || backspace_keycode
== 0));
10646 /* The XKB symbolic key names can be seen most easily in
10647 the PS file generated by `xkbprint -label name
10649 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
10650 delete_keycode
= i
;
10651 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
10652 backspace_keycode
= i
;
10655 XkbFreeNames (kb
, 0, True
);
10658 XkbFreeClientMap (kb
, 0, True
);
10661 && backspace_keycode
10662 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
10663 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
10668 #else /* not HAVE_XKBGETKEYBOARD */
10670 #endif /* not HAVE_XKBGETKEYBOARD */
10675 /***********************************************************************
10677 ***********************************************************************/
10679 /* Keep this list in the same order as frame_parms in frame.c.
10680 Use 0 for unsupported frame parameters. */
10682 frame_parm_handler x_frame_parm_handlers
[] =
10686 x_set_background_color
,
10687 x_set_border_color
,
10688 x_set_border_width
,
10689 x_set_cursor_color
,
10692 x_set_foreground_color
,
10695 x_set_internal_border_width
,
10696 x_set_menu_bar_lines
,
10698 x_explicitly_set_name
,
10699 x_set_scroll_bar_width
,
10701 x_set_unsplittable
,
10702 x_set_vertical_scroll_bars
,
10704 x_set_tool_bar_lines
,
10705 x_set_scroll_bar_foreground
,
10706 x_set_scroll_bar_background
,
10707 x_set_screen_gamma
,
10708 x_set_line_spacing
,
10709 x_set_fringe_width
,
10710 x_set_fringe_width
,
10718 /* This is zero if not using X windows. */
10721 /* The section below is built by the lisp expression at the top of the file,
10722 just above where these variables are declared. */
10723 /*&&& init symbols here &&&*/
10724 Qnone
= intern ("none");
10725 staticpro (&Qnone
);
10726 Qsuppress_icon
= intern ("suppress-icon");
10727 staticpro (&Qsuppress_icon
);
10728 Qundefined_color
= intern ("undefined-color");
10729 staticpro (&Qundefined_color
);
10730 Qcenter
= intern ("center");
10731 staticpro (&Qcenter
);
10732 Qcompound_text
= intern ("compound-text");
10733 staticpro (&Qcompound_text
);
10734 Qcancel_timer
= intern ("cancel-timer");
10735 staticpro (&Qcancel_timer
);
10736 /* This is the end of symbol initialization. */
10738 /* Text property `display' should be nonsticky by default. */
10739 Vtext_property_default_nonsticky
10740 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
10743 Qlaplace
= intern ("laplace");
10744 staticpro (&Qlaplace
);
10745 Qemboss
= intern ("emboss");
10746 staticpro (&Qemboss
);
10747 Qedge_detection
= intern ("edge-detection");
10748 staticpro (&Qedge_detection
);
10749 Qheuristic
= intern ("heuristic");
10750 staticpro (&Qheuristic
);
10751 QCmatrix
= intern (":matrix");
10752 staticpro (&QCmatrix
);
10753 QCcolor_adjustment
= intern (":color-adjustment");
10754 staticpro (&QCcolor_adjustment
);
10755 QCmask
= intern (":mask");
10756 staticpro (&QCmask
);
10758 Fput (Qundefined_color
, Qerror_conditions
,
10759 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
10760 Fput (Qundefined_color
, Qerror_message
,
10761 build_string ("Undefined color"));
10763 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images
,
10764 doc
: /* Non-nil means always draw a cross over disabled images.
10765 Disabled images are those having an `:conversion disabled' property.
10766 A cross is always drawn on black & white displays. */);
10767 cross_disabled_images
= 0;
10769 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
10770 doc
: /* List of directories to search for window system bitmap files. */);
10771 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
10773 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
10774 doc
: /* The shape of the pointer when over text.
10775 Changing the value does not affect existing frames
10776 unless you set the mouse color. */);
10777 Vx_pointer_shape
= Qnil
;
10779 #if 0 /* This doesn't really do anything. */
10780 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
10781 doc
: /* The shape of the pointer when not over text.
10782 This variable takes effect when you create a new frame
10783 or when you set the mouse color. */);
10785 Vx_nontext_pointer_shape
= Qnil
;
10787 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
10788 doc
: /* The shape of the pointer when Emacs is busy.
10789 This variable takes effect when you create a new frame
10790 or when you set the mouse color. */);
10791 Vx_hourglass_pointer_shape
= Qnil
;
10793 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
10794 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
10795 display_hourglass_p
= 1;
10797 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
10798 doc
: /* *Seconds to wait before displaying an hourglass pointer.
10799 Value must be an integer or float. */);
10800 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
10802 #if 0 /* This doesn't really do anything. */
10803 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
10804 doc
: /* The shape of the pointer when over the mode line.
10805 This variable takes effect when you create a new frame
10806 or when you set the mouse color. */);
10808 Vx_mode_pointer_shape
= Qnil
;
10810 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
10811 &Vx_sensitive_text_pointer_shape
,
10812 doc
: /* The shape of the pointer when over mouse-sensitive text.
10813 This variable takes effect when you create a new frame
10814 or when you set the mouse color. */);
10815 Vx_sensitive_text_pointer_shape
= Qnil
;
10817 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
10818 &Vx_window_horizontal_drag_shape
,
10819 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
10820 This variable takes effect when you create a new frame
10821 or when you set the mouse color. */);
10822 Vx_window_horizontal_drag_shape
= Qnil
;
10824 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
10825 doc
: /* A string indicating the foreground color of the cursor box. */);
10826 Vx_cursor_fore_pixel
= Qnil
;
10828 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
10829 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
10830 Text larger than this is clipped. */);
10831 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
10833 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
10834 doc
: /* Non-nil if no X window manager is in use.
10835 Emacs doesn't try to figure this out; this is always nil
10836 unless you set it to something else. */);
10837 /* We don't have any way to find this out, so set it to nil
10838 and maybe the user would like to set it to t. */
10839 Vx_no_window_manager
= Qnil
;
10841 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
10842 &Vx_pixel_size_width_font_regexp
,
10843 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
10845 Since Emacs gets width of a font matching with this regexp from
10846 PIXEL_SIZE field of the name, font finding mechanism gets faster for
10847 such a font. This is especially effective for such large fonts as
10848 Chinese, Japanese, and Korean. */);
10849 Vx_pixel_size_width_font_regexp
= Qnil
;
10851 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
10852 doc
: /* Time after which cached images are removed from the cache.
10853 When an image has not been displayed this many seconds, remove it
10854 from the image cache. Value must be an integer or nil with nil
10855 meaning don't clear the cache. */);
10856 Vimage_cache_eviction_delay
= make_number (30 * 60);
10858 #ifdef USE_X_TOOLKIT
10859 Fprovide (intern ("x-toolkit"), Qnil
);
10861 Fprovide (intern ("motif"), Qnil
);
10863 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
10864 doc
: /* Version info for LessTif/Motif. */);
10865 Vmotif_version_string
= build_string (XmVERSION_STRING
);
10866 #endif /* USE_MOTIF */
10867 #endif /* USE_X_TOOLKIT */
10869 /* X window properties. */
10870 defsubr (&Sx_change_window_property
);
10871 defsubr (&Sx_delete_window_property
);
10872 defsubr (&Sx_window_property
);
10874 defsubr (&Sxw_display_color_p
);
10875 defsubr (&Sx_display_grayscale_p
);
10876 defsubr (&Sxw_color_defined_p
);
10877 defsubr (&Sxw_color_values
);
10878 defsubr (&Sx_server_max_request_size
);
10879 defsubr (&Sx_server_vendor
);
10880 defsubr (&Sx_server_version
);
10881 defsubr (&Sx_display_pixel_width
);
10882 defsubr (&Sx_display_pixel_height
);
10883 defsubr (&Sx_display_mm_width
);
10884 defsubr (&Sx_display_mm_height
);
10885 defsubr (&Sx_display_screens
);
10886 defsubr (&Sx_display_planes
);
10887 defsubr (&Sx_display_color_cells
);
10888 defsubr (&Sx_display_visual_class
);
10889 defsubr (&Sx_display_backing_store
);
10890 defsubr (&Sx_display_save_under
);
10891 defsubr (&Sx_create_frame
);
10892 defsubr (&Sx_open_connection
);
10893 defsubr (&Sx_close_connection
);
10894 defsubr (&Sx_display_list
);
10895 defsubr (&Sx_synchronize
);
10896 defsubr (&Sx_focus_frame
);
10897 defsubr (&Sx_backspace_delete_keys_p
);
10899 /* Setting callback functions for fontset handler. */
10900 get_font_info_func
= x_get_font_info
;
10902 #if 0 /* This function pointer doesn't seem to be used anywhere.
10903 And the pointer assigned has the wrong type, anyway. */
10904 list_fonts_func
= x_list_fonts
;
10907 load_font_func
= x_load_font
;
10908 find_ccl_program_func
= x_find_ccl_program
;
10909 query_font_func
= x_query_font
;
10910 set_frame_fontset_func
= x_set_font
;
10911 check_window_system_func
= check_x
;
10914 Qxbm
= intern ("xbm");
10916 QCconversion
= intern (":conversion");
10917 staticpro (&QCconversion
);
10918 QCheuristic_mask
= intern (":heuristic-mask");
10919 staticpro (&QCheuristic_mask
);
10920 QCcolor_symbols
= intern (":color-symbols");
10921 staticpro (&QCcolor_symbols
);
10922 QCascent
= intern (":ascent");
10923 staticpro (&QCascent
);
10924 QCmargin
= intern (":margin");
10925 staticpro (&QCmargin
);
10926 QCrelief
= intern (":relief");
10927 staticpro (&QCrelief
);
10928 Qpostscript
= intern ("postscript");
10929 staticpro (&Qpostscript
);
10930 QCloader
= intern (":loader");
10931 staticpro (&QCloader
);
10932 QCbounding_box
= intern (":bounding-box");
10933 staticpro (&QCbounding_box
);
10934 QCpt_width
= intern (":pt-width");
10935 staticpro (&QCpt_width
);
10936 QCpt_height
= intern (":pt-height");
10937 staticpro (&QCpt_height
);
10938 QCindex
= intern (":index");
10939 staticpro (&QCindex
);
10940 Qpbm
= intern ("pbm");
10944 Qxpm
= intern ("xpm");
10949 Qjpeg
= intern ("jpeg");
10950 staticpro (&Qjpeg
);
10954 Qtiff
= intern ("tiff");
10955 staticpro (&Qtiff
);
10959 Qgif
= intern ("gif");
10964 Qpng
= intern ("png");
10968 defsubr (&Sclear_image_cache
);
10969 defsubr (&Simage_size
);
10970 defsubr (&Simage_mask_p
);
10972 hourglass_atimer
= NULL
;
10973 hourglass_shown_p
= 0;
10975 defsubr (&Sx_show_tip
);
10976 defsubr (&Sx_hide_tip
);
10978 staticpro (&tip_timer
);
10980 staticpro (&tip_frame
);
10982 last_show_tip_args
= Qnil
;
10983 staticpro (&last_show_tip_args
);
10986 defsubr (&Sx_file_dialog
);
10994 image_types
= NULL
;
10995 Vimage_types
= Qnil
;
10997 define_image_type (&xbm_type
);
10998 define_image_type (&gs_type
);
10999 define_image_type (&pbm_type
);
11002 define_image_type (&xpm_type
);
11006 define_image_type (&jpeg_type
);
11010 define_image_type (&tiff_type
);
11014 define_image_type (&gif_type
);
11018 define_image_type (&png_type
);
11022 #endif /* HAVE_X_WINDOWS */