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 manager at least analize 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 feature 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 #include <libpng/png.h>
7570 /* Function prototypes. */
7572 static int png_image_p
P_ ((Lisp_Object object
));
7573 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
7575 /* The symbol `png' identifying images of this type. */
7579 /* Indices of image specification fields in png_format, below. */
7581 enum png_keyword_index
7596 /* Vector of image_keyword structures describing the format
7597 of valid user-defined image specifications. */
7599 static struct image_keyword png_format
[PNG_LAST
] =
7601 {":type", IMAGE_SYMBOL_VALUE
, 1},
7602 {":data", IMAGE_STRING_VALUE
, 0},
7603 {":file", IMAGE_STRING_VALUE
, 0},
7604 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7605 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7606 {":relief", IMAGE_INTEGER_VALUE
, 0},
7607 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7608 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7609 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7610 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7613 /* Structure describing the image type `png'. */
7615 static struct image_type png_type
=
7625 /* Return non-zero if OBJECT is a valid PNG image specification. */
7628 png_image_p (object
)
7631 struct image_keyword fmt
[PNG_LAST
];
7632 bcopy (png_format
, fmt
, sizeof fmt
);
7634 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
7637 /* Must specify either the :data or :file keyword. */
7638 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
7642 /* Error and warning handlers installed when the PNG library
7646 my_png_error (png_ptr
, msg
)
7647 png_struct
*png_ptr
;
7650 xassert (png_ptr
!= NULL
);
7651 image_error ("PNG error: %s", build_string (msg
), Qnil
);
7652 longjmp (png_ptr
->jmpbuf
, 1);
7657 my_png_warning (png_ptr
, msg
)
7658 png_struct
*png_ptr
;
7661 xassert (png_ptr
!= NULL
);
7662 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
7665 /* Memory source for PNG decoding. */
7667 struct png_memory_storage
7669 unsigned char *bytes
; /* The data */
7670 size_t len
; /* How big is it? */
7671 int index
; /* Where are we? */
7675 /* Function set as reader function when reading PNG image from memory.
7676 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
7677 bytes from the input to DATA. */
7680 png_read_from_memory (png_ptr
, data
, length
)
7681 png_structp png_ptr
;
7685 struct png_memory_storage
*tbr
7686 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
7688 if (length
> tbr
->len
- tbr
->index
)
7689 png_error (png_ptr
, "Read error");
7691 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
7692 tbr
->index
= tbr
->index
+ length
;
7695 /* Load PNG image IMG for use on frame F. Value is non-zero if
7703 Lisp_Object file
, specified_file
;
7704 Lisp_Object specified_data
;
7706 XImage
*ximg
, *mask_img
= NULL
;
7707 struct gcpro gcpro1
;
7708 png_struct
*png_ptr
= NULL
;
7709 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
7710 FILE *volatile fp
= NULL
;
7712 png_byte
* volatile pixels
= NULL
;
7713 png_byte
** volatile rows
= NULL
;
7714 png_uint_32 width
, height
;
7715 int bit_depth
, color_type
, interlace_type
;
7717 png_uint_32 row_bytes
;
7719 double screen_gamma
;
7720 struct png_memory_storage tbr
; /* Data to be read */
7722 /* Find out what file to load. */
7723 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7724 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7728 if (NILP (specified_data
))
7730 file
= x_find_image_file (specified_file
);
7731 if (!STRINGP (file
))
7733 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7738 /* Open the image file. */
7739 fp
= fopen (SDATA (file
), "rb");
7742 image_error ("Cannot open image file `%s'", file
, Qnil
);
7748 /* Check PNG signature. */
7749 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
7750 || !png_check_sig (sig
, sizeof sig
))
7752 image_error ("Not a PNG file: `%s'", file
, Qnil
);
7760 /* Read from memory. */
7761 tbr
.bytes
= SDATA (specified_data
);
7762 tbr
.len
= SBYTES (specified_data
);
7765 /* Check PNG signature. */
7766 if (tbr
.len
< sizeof sig
7767 || !png_check_sig (tbr
.bytes
, sizeof sig
))
7769 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
7774 /* Need to skip past the signature. */
7775 tbr
.bytes
+= sizeof (sig
);
7778 /* Initialize read and info structs for PNG lib. */
7779 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
7780 my_png_error
, my_png_warning
);
7783 if (fp
) fclose (fp
);
7788 info_ptr
= png_create_info_struct (png_ptr
);
7791 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
7792 if (fp
) fclose (fp
);
7797 end_info
= png_create_info_struct (png_ptr
);
7800 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
7801 if (fp
) fclose (fp
);
7806 /* Set error jump-back. We come back here when the PNG library
7807 detects an error. */
7808 if (setjmp (png_ptr
->jmpbuf
))
7812 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7815 if (fp
) fclose (fp
);
7820 /* Read image info. */
7821 if (!NILP (specified_data
))
7822 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
7824 png_init_io (png_ptr
, fp
);
7826 png_set_sig_bytes (png_ptr
, sizeof sig
);
7827 png_read_info (png_ptr
, info_ptr
);
7828 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
7829 &interlace_type
, NULL
, NULL
);
7831 /* If image contains simply transparency data, we prefer to
7832 construct a clipping mask. */
7833 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
7838 /* This function is easier to write if we only have to handle
7839 one data format: RGB or RGBA with 8 bits per channel. Let's
7840 transform other formats into that format. */
7842 /* Strip more than 8 bits per channel. */
7843 if (bit_depth
== 16)
7844 png_set_strip_16 (png_ptr
);
7846 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
7848 png_set_expand (png_ptr
);
7850 /* Convert grayscale images to RGB. */
7851 if (color_type
== PNG_COLOR_TYPE_GRAY
7852 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
7853 png_set_gray_to_rgb (png_ptr
);
7855 screen_gamma
= (f
->gamma
? 1 / f
->gamma
/ 0.45455 : 2.2);
7857 #if 0 /* Avoid double gamma correction for PNG images. */
7858 { /* Tell the PNG lib to handle gamma correction for us. */
7861 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
7862 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
7863 /* The libpng documentation says this is right in this case. */
7864 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7867 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
7868 /* Image contains gamma information. */
7869 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
7871 /* Use the standard default for the image gamma. */
7872 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7876 /* Handle alpha channel by combining the image with a background
7877 color. Do this only if a real alpha channel is supplied. For
7878 simple transparency, we prefer a clipping mask. */
7881 png_color_16
*image_bg
;
7882 Lisp_Object specified_bg
7883 = image_spec_value (img
->spec
, QCbackground
, NULL
);
7885 if (STRINGP (specified_bg
))
7886 /* The user specified `:background', use that. */
7889 if (x_defined_color (f
, SDATA (specified_bg
), &color
, 0))
7891 png_color_16 user_bg
;
7893 bzero (&user_bg
, sizeof user_bg
);
7894 user_bg
.red
= color
.red
;
7895 user_bg
.green
= color
.green
;
7896 user_bg
.blue
= color
.blue
;
7898 png_set_background (png_ptr
, &user_bg
,
7899 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7902 else if (png_get_bKGD (png_ptr
, info_ptr
, &image_bg
))
7903 /* Image contains a background color with which to
7904 combine the image. */
7905 png_set_background (png_ptr
, image_bg
,
7906 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
7909 /* Image does not contain a background color with which
7910 to combine the image data via an alpha channel. Use
7911 the frame's background instead. */
7914 png_color_16 frame_background
;
7916 cmap
= FRAME_X_COLORMAP (f
);
7917 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7918 x_query_color (f
, &color
);
7920 bzero (&frame_background
, sizeof frame_background
);
7921 frame_background
.red
= color
.red
;
7922 frame_background
.green
= color
.green
;
7923 frame_background
.blue
= color
.blue
;
7925 png_set_background (png_ptr
, &frame_background
,
7926 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7930 /* Update info structure. */
7931 png_read_update_info (png_ptr
, info_ptr
);
7933 /* Get number of channels. Valid values are 1 for grayscale images
7934 and images with a palette, 2 for grayscale images with transparency
7935 information (alpha channel), 3 for RGB images, and 4 for RGB
7936 images with alpha channel, i.e. RGBA. If conversions above were
7937 sufficient we should only have 3 or 4 channels here. */
7938 channels
= png_get_channels (png_ptr
, info_ptr
);
7939 xassert (channels
== 3 || channels
== 4);
7941 /* Number of bytes needed for one row of the image. */
7942 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
7944 /* Allocate memory for the image. */
7945 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
7946 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
7947 for (i
= 0; i
< height
; ++i
)
7948 rows
[i
] = pixels
+ i
* row_bytes
;
7950 /* Read the entire image. */
7951 png_read_image (png_ptr
, rows
);
7952 png_read_end (png_ptr
, info_ptr
);
7959 /* Create the X image and pixmap. */
7960 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
7964 /* Create an image and pixmap serving as mask if the PNG image
7965 contains an alpha channel. */
7968 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
7969 &mask_img
, &img
->mask
))
7971 x_destroy_x_image (ximg
);
7972 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
7977 /* Fill the X image and mask from PNG data. */
7978 init_color_table ();
7980 for (y
= 0; y
< height
; ++y
)
7982 png_byte
*p
= rows
[y
];
7984 for (x
= 0; x
< width
; ++x
)
7991 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7993 /* An alpha channel, aka mask channel, associates variable
7994 transparency with an image. Where other image formats
7995 support binary transparency---fully transparent or fully
7996 opaque---PNG allows up to 254 levels of partial transparency.
7997 The PNG library implements partial transparency by combining
7998 the image with a specified background color.
8000 I'm not sure how to handle this here nicely: because the
8001 background on which the image is displayed may change, for
8002 real alpha channel support, it would be necessary to create
8003 a new image for each possible background.
8005 What I'm doing now is that a mask is created if we have
8006 boolean transparency information. Otherwise I'm using
8007 the frame's background color to combine the image with. */
8012 XPutPixel (mask_img
, x
, y
, *p
> 0);
8018 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8019 /* Set IMG's background color from the PNG image, unless the user
8023 if (png_get_bKGD (png_ptr
, info_ptr
, &bg
))
8025 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
8026 img
->background_valid
= 1;
8030 /* Remember colors allocated for this image. */
8031 img
->colors
= colors_in_color_table (&img
->ncolors
);
8032 free_color_table ();
8035 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
8040 img
->height
= height
;
8042 /* Maybe fill in the background field while we have ximg handy. */
8043 IMAGE_BACKGROUND (img
, f
, ximg
);
8045 /* Put the image into the pixmap, then free the X image and its buffer. */
8046 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8047 x_destroy_x_image (ximg
);
8049 /* Same for the mask. */
8052 /* Fill in the background_transparent field while we have the mask
8054 image_background_transparent (img
, f
, mask_img
);
8056 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
8057 x_destroy_x_image (mask_img
);
8064 #endif /* HAVE_PNG != 0 */
8068 /***********************************************************************
8070 ***********************************************************************/
8074 /* Work around a warning about HAVE_STDLIB_H being redefined in
8076 #ifdef HAVE_STDLIB_H
8077 #define HAVE_STDLIB_H_1
8078 #undef HAVE_STDLIB_H
8079 #endif /* HAVE_STLIB_H */
8081 #include <jpeglib.h>
8085 #ifdef HAVE_STLIB_H_1
8086 #define HAVE_STDLIB_H 1
8089 static int jpeg_image_p
P_ ((Lisp_Object object
));
8090 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
8092 /* The symbol `jpeg' identifying images of this type. */
8096 /* Indices of image specification fields in gs_format, below. */
8098 enum jpeg_keyword_index
8107 JPEG_HEURISTIC_MASK
,
8113 /* Vector of image_keyword structures describing the format
8114 of valid user-defined image specifications. */
8116 static struct image_keyword jpeg_format
[JPEG_LAST
] =
8118 {":type", IMAGE_SYMBOL_VALUE
, 1},
8119 {":data", IMAGE_STRING_VALUE
, 0},
8120 {":file", IMAGE_STRING_VALUE
, 0},
8121 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8122 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8123 {":relief", IMAGE_INTEGER_VALUE
, 0},
8124 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8125 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8126 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8127 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8130 /* Structure describing the image type `jpeg'. */
8132 static struct image_type jpeg_type
=
8142 /* Return non-zero if OBJECT is a valid JPEG image specification. */
8145 jpeg_image_p (object
)
8148 struct image_keyword fmt
[JPEG_LAST
];
8150 bcopy (jpeg_format
, fmt
, sizeof fmt
);
8152 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
8155 /* Must specify either the :data or :file keyword. */
8156 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
8160 struct my_jpeg_error_mgr
8162 struct jpeg_error_mgr pub
;
8163 jmp_buf setjmp_buffer
;
8168 my_error_exit (cinfo
)
8171 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
8172 longjmp (mgr
->setjmp_buffer
, 1);
8176 /* Init source method for JPEG data source manager. Called by
8177 jpeg_read_header() before any data is actually read. See
8178 libjpeg.doc from the JPEG lib distribution. */
8181 our_init_source (cinfo
)
8182 j_decompress_ptr cinfo
;
8187 /* Fill input buffer method for JPEG data source manager. Called
8188 whenever more data is needed. We read the whole image in one step,
8189 so this only adds a fake end of input marker at the end. */
8192 our_fill_input_buffer (cinfo
)
8193 j_decompress_ptr cinfo
;
8195 /* Insert a fake EOI marker. */
8196 struct jpeg_source_mgr
*src
= cinfo
->src
;
8197 static JOCTET buffer
[2];
8199 buffer
[0] = (JOCTET
) 0xFF;
8200 buffer
[1] = (JOCTET
) JPEG_EOI
;
8202 src
->next_input_byte
= buffer
;
8203 src
->bytes_in_buffer
= 2;
8208 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
8209 is the JPEG data source manager. */
8212 our_skip_input_data (cinfo
, num_bytes
)
8213 j_decompress_ptr cinfo
;
8216 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8220 if (num_bytes
> src
->bytes_in_buffer
)
8221 ERREXIT (cinfo
, JERR_INPUT_EOF
);
8223 src
->bytes_in_buffer
-= num_bytes
;
8224 src
->next_input_byte
+= num_bytes
;
8229 /* Method to terminate data source. Called by
8230 jpeg_finish_decompress() after all data has been processed. */
8233 our_term_source (cinfo
)
8234 j_decompress_ptr cinfo
;
8239 /* Set up the JPEG lib for reading an image from DATA which contains
8240 LEN bytes. CINFO is the decompression info structure created for
8241 reading the image. */
8244 jpeg_memory_src (cinfo
, data
, len
)
8245 j_decompress_ptr cinfo
;
8249 struct jpeg_source_mgr
*src
;
8251 if (cinfo
->src
== NULL
)
8253 /* First time for this JPEG object? */
8254 cinfo
->src
= (struct jpeg_source_mgr
*)
8255 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
8256 sizeof (struct jpeg_source_mgr
));
8257 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8258 src
->next_input_byte
= data
;
8261 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8262 src
->init_source
= our_init_source
;
8263 src
->fill_input_buffer
= our_fill_input_buffer
;
8264 src
->skip_input_data
= our_skip_input_data
;
8265 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
8266 src
->term_source
= our_term_source
;
8267 src
->bytes_in_buffer
= len
;
8268 src
->next_input_byte
= data
;
8272 /* Load image IMG for use on frame F. Patterned after example.c
8273 from the JPEG lib. */
8280 struct jpeg_decompress_struct cinfo
;
8281 struct my_jpeg_error_mgr mgr
;
8282 Lisp_Object file
, specified_file
;
8283 Lisp_Object specified_data
;
8284 FILE * volatile fp
= NULL
;
8286 int row_stride
, x
, y
;
8287 XImage
*ximg
= NULL
;
8289 unsigned long *colors
;
8291 struct gcpro gcpro1
;
8293 /* Open the JPEG file. */
8294 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8295 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8299 if (NILP (specified_data
))
8301 file
= x_find_image_file (specified_file
);
8302 if (!STRINGP (file
))
8304 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8309 fp
= fopen (SDATA (file
), "r");
8312 image_error ("Cannot open `%s'", file
, Qnil
);
8318 /* Customize libjpeg's error handling to call my_error_exit when an
8319 error is detected. This function will perform a longjmp. */
8320 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
8321 mgr
.pub
.error_exit
= my_error_exit
;
8323 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
8327 /* Called from my_error_exit. Display a JPEG error. */
8328 char buffer
[JMSG_LENGTH_MAX
];
8329 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
8330 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
8331 build_string (buffer
));
8334 /* Close the input file and destroy the JPEG object. */
8336 fclose ((FILE *) fp
);
8337 jpeg_destroy_decompress (&cinfo
);
8339 /* If we already have an XImage, free that. */
8340 x_destroy_x_image (ximg
);
8342 /* Free pixmap and colors. */
8343 x_clear_image (f
, img
);
8349 /* Create the JPEG decompression object. Let it read from fp.
8350 Read the JPEG image header. */
8351 jpeg_create_decompress (&cinfo
);
8353 if (NILP (specified_data
))
8354 jpeg_stdio_src (&cinfo
, (FILE *) fp
);
8356 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
8357 SBYTES (specified_data
));
8359 jpeg_read_header (&cinfo
, TRUE
);
8361 /* Customize decompression so that color quantization will be used.
8362 Start decompression. */
8363 cinfo
.quantize_colors
= TRUE
;
8364 jpeg_start_decompress (&cinfo
);
8365 width
= img
->width
= cinfo
.output_width
;
8366 height
= img
->height
= cinfo
.output_height
;
8368 /* Create X image and pixmap. */
8369 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8370 longjmp (mgr
.setjmp_buffer
, 2);
8372 /* Allocate colors. When color quantization is used,
8373 cinfo.actual_number_of_colors has been set with the number of
8374 colors generated, and cinfo.colormap is a two-dimensional array
8375 of color indices in the range 0..cinfo.actual_number_of_colors.
8376 No more than 255 colors will be generated. */
8380 if (cinfo
.out_color_components
> 2)
8381 ir
= 0, ig
= 1, ib
= 2;
8382 else if (cinfo
.out_color_components
> 1)
8383 ir
= 0, ig
= 1, ib
= 0;
8385 ir
= 0, ig
= 0, ib
= 0;
8387 /* Use the color table mechanism because it handles colors that
8388 cannot be allocated nicely. Such colors will be replaced with
8389 a default color, and we don't have to care about which colors
8390 can be freed safely, and which can't. */
8391 init_color_table ();
8392 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
8395 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
8397 /* Multiply RGB values with 255 because X expects RGB values
8398 in the range 0..0xffff. */
8399 int r
= cinfo
.colormap
[ir
][i
] << 8;
8400 int g
= cinfo
.colormap
[ig
][i
] << 8;
8401 int b
= cinfo
.colormap
[ib
][i
] << 8;
8402 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8405 /* Remember those colors actually allocated. */
8406 img
->colors
= colors_in_color_table (&img
->ncolors
);
8407 free_color_table ();
8411 row_stride
= width
* cinfo
.output_components
;
8412 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
8414 for (y
= 0; y
< height
; ++y
)
8416 jpeg_read_scanlines (&cinfo
, buffer
, 1);
8417 for (x
= 0; x
< cinfo
.output_width
; ++x
)
8418 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
8422 jpeg_finish_decompress (&cinfo
);
8423 jpeg_destroy_decompress (&cinfo
);
8425 fclose ((FILE *) fp
);
8427 /* Maybe fill in the background field while we have ximg handy. */
8428 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8429 IMAGE_BACKGROUND (img
, f
, ximg
);
8431 /* Put the image into the pixmap. */
8432 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8433 x_destroy_x_image (ximg
);
8438 #endif /* HAVE_JPEG */
8442 /***********************************************************************
8444 ***********************************************************************/
8450 static int tiff_image_p
P_ ((Lisp_Object object
));
8451 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
8453 /* The symbol `tiff' identifying images of this type. */
8457 /* Indices of image specification fields in tiff_format, below. */
8459 enum tiff_keyword_index
8468 TIFF_HEURISTIC_MASK
,
8474 /* Vector of image_keyword structures describing the format
8475 of valid user-defined image specifications. */
8477 static struct image_keyword tiff_format
[TIFF_LAST
] =
8479 {":type", IMAGE_SYMBOL_VALUE
, 1},
8480 {":data", IMAGE_STRING_VALUE
, 0},
8481 {":file", IMAGE_STRING_VALUE
, 0},
8482 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8483 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8484 {":relief", IMAGE_INTEGER_VALUE
, 0},
8485 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8486 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8487 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8488 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8491 /* Structure describing the image type `tiff'. */
8493 static struct image_type tiff_type
=
8503 /* Return non-zero if OBJECT is a valid TIFF image specification. */
8506 tiff_image_p (object
)
8509 struct image_keyword fmt
[TIFF_LAST
];
8510 bcopy (tiff_format
, fmt
, sizeof fmt
);
8512 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
8515 /* Must specify either the :data or :file keyword. */
8516 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
8520 /* Reading from a memory buffer for TIFF images Based on the PNG
8521 memory source, but we have to provide a lot of extra functions.
8524 We really only need to implement read and seek, but I am not
8525 convinced that the TIFF library is smart enough not to destroy
8526 itself if we only hand it the function pointers we need to
8531 unsigned char *bytes
;
8539 tiff_read_from_memory (data
, buf
, size
)
8544 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8546 if (size
> src
->len
- src
->index
)
8548 bcopy (src
->bytes
+ src
->index
, buf
, size
);
8555 tiff_write_from_memory (data
, buf
, size
)
8565 tiff_seek_in_memory (data
, off
, whence
)
8570 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8575 case SEEK_SET
: /* Go from beginning of source. */
8579 case SEEK_END
: /* Go from end of source. */
8580 idx
= src
->len
+ off
;
8583 case SEEK_CUR
: /* Go from current position. */
8584 idx
= src
->index
+ off
;
8587 default: /* Invalid `whence'. */
8591 if (idx
> src
->len
|| idx
< 0)
8600 tiff_close_memory (data
)
8609 tiff_mmap_memory (data
, pbase
, psize
)
8614 /* It is already _IN_ memory. */
8620 tiff_unmap_memory (data
, base
, size
)
8625 /* We don't need to do this. */
8630 tiff_size_of_memory (data
)
8633 return ((tiff_memory_source
*) data
)->len
;
8638 tiff_error_handler (title
, format
, ap
)
8639 const char *title
, *format
;
8645 len
= sprintf (buf
, "TIFF error: %s ", title
);
8646 vsprintf (buf
+ len
, format
, ap
);
8647 add_to_log (buf
, Qnil
, Qnil
);
8652 tiff_warning_handler (title
, format
, ap
)
8653 const char *title
, *format
;
8659 len
= sprintf (buf
, "TIFF warning: %s ", title
);
8660 vsprintf (buf
+ len
, format
, ap
);
8661 add_to_log (buf
, Qnil
, Qnil
);
8665 /* Load TIFF image IMG for use on frame F. Value is non-zero if
8673 Lisp_Object file
, specified_file
;
8674 Lisp_Object specified_data
;
8676 int width
, height
, x
, y
;
8680 struct gcpro gcpro1
;
8681 tiff_memory_source memsrc
;
8683 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8684 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8688 TIFFSetErrorHandler (tiff_error_handler
);
8689 TIFFSetWarningHandler (tiff_warning_handler
);
8691 if (NILP (specified_data
))
8693 /* Read from a file */
8694 file
= x_find_image_file (specified_file
);
8695 if (!STRINGP (file
))
8697 image_error ("Cannot find image file `%s'", file
, Qnil
);
8702 /* Try to open the image file. */
8703 tiff
= TIFFOpen (SDATA (file
), "r");
8706 image_error ("Cannot open `%s'", file
, Qnil
);
8713 /* Memory source! */
8714 memsrc
.bytes
= SDATA (specified_data
);
8715 memsrc
.len
= SBYTES (specified_data
);
8718 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
8719 (TIFFReadWriteProc
) tiff_read_from_memory
,
8720 (TIFFReadWriteProc
) tiff_write_from_memory
,
8721 tiff_seek_in_memory
,
8723 tiff_size_of_memory
,
8729 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
8735 /* Get width and height of the image, and allocate a raster buffer
8736 of width x height 32-bit values. */
8737 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
8738 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
8739 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
8741 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
8745 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
8751 /* Create the X image and pixmap. */
8752 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8759 /* Initialize the color table. */
8760 init_color_table ();
8762 /* Process the pixel raster. Origin is in the lower-left corner. */
8763 for (y
= 0; y
< height
; ++y
)
8765 uint32
*row
= buf
+ y
* width
;
8767 for (x
= 0; x
< width
; ++x
)
8769 uint32 abgr
= row
[x
];
8770 int r
= TIFFGetR (abgr
) << 8;
8771 int g
= TIFFGetG (abgr
) << 8;
8772 int b
= TIFFGetB (abgr
) << 8;
8773 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
8777 /* Remember the colors allocated for the image. Free the color table. */
8778 img
->colors
= colors_in_color_table (&img
->ncolors
);
8779 free_color_table ();
8782 img
->height
= height
;
8784 /* Maybe fill in the background field while we have ximg handy. */
8785 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8786 IMAGE_BACKGROUND (img
, f
, ximg
);
8788 /* Put the image into the pixmap, then free the X image and its buffer. */
8789 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8790 x_destroy_x_image (ximg
);
8797 #endif /* HAVE_TIFF != 0 */
8801 /***********************************************************************
8803 ***********************************************************************/
8807 #include <gif_lib.h>
8809 static int gif_image_p
P_ ((Lisp_Object object
));
8810 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
8812 /* The symbol `gif' identifying images of this type. */
8816 /* Indices of image specification fields in gif_format, below. */
8818 enum gif_keyword_index
8834 /* Vector of image_keyword structures describing the format
8835 of valid user-defined image specifications. */
8837 static struct image_keyword gif_format
[GIF_LAST
] =
8839 {":type", IMAGE_SYMBOL_VALUE
, 1},
8840 {":data", IMAGE_STRING_VALUE
, 0},
8841 {":file", IMAGE_STRING_VALUE
, 0},
8842 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8843 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8844 {":relief", IMAGE_INTEGER_VALUE
, 0},
8845 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8846 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8847 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8848 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8849 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8852 /* Structure describing the image type `gif'. */
8854 static struct image_type gif_type
=
8864 /* Return non-zero if OBJECT is a valid GIF image specification. */
8867 gif_image_p (object
)
8870 struct image_keyword fmt
[GIF_LAST
];
8871 bcopy (gif_format
, fmt
, sizeof fmt
);
8873 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
8876 /* Must specify either the :data or :file keyword. */
8877 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
8881 /* Reading a GIF image from memory
8882 Based on the PNG memory stuff to a certain extent. */
8886 unsigned char *bytes
;
8893 /* Make the current memory source available to gif_read_from_memory.
8894 It's done this way because not all versions of libungif support
8895 a UserData field in the GifFileType structure. */
8896 static gif_memory_source
*current_gif_memory_src
;
8899 gif_read_from_memory (file
, buf
, len
)
8904 gif_memory_source
*src
= current_gif_memory_src
;
8906 if (len
> src
->len
- src
->index
)
8909 bcopy (src
->bytes
+ src
->index
, buf
, len
);
8915 /* Load GIF image IMG for use on frame F. Value is non-zero if
8923 Lisp_Object file
, specified_file
;
8924 Lisp_Object specified_data
;
8925 int rc
, width
, height
, x
, y
, i
;
8927 ColorMapObject
*gif_color_map
;
8928 unsigned long pixel_colors
[256];
8930 struct gcpro gcpro1
;
8932 int ino
, image_left
, image_top
, image_width
, image_height
;
8933 gif_memory_source memsrc
;
8934 unsigned char *raster
;
8936 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8937 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8941 if (NILP (specified_data
))
8943 file
= x_find_image_file (specified_file
);
8944 if (!STRINGP (file
))
8946 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8951 /* Open the GIF file. */
8952 gif
= DGifOpenFileName (SDATA (file
));
8955 image_error ("Cannot open `%s'", file
, Qnil
);
8962 /* Read from memory! */
8963 current_gif_memory_src
= &memsrc
;
8964 memsrc
.bytes
= SDATA (specified_data
);
8965 memsrc
.len
= SBYTES (specified_data
);
8968 gif
= DGifOpen(&memsrc
, gif_read_from_memory
);
8971 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
8977 /* Read entire contents. */
8978 rc
= DGifSlurp (gif
);
8979 if (rc
== GIF_ERROR
)
8981 image_error ("Error reading `%s'", img
->spec
, Qnil
);
8982 DGifCloseFile (gif
);
8987 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
8988 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
8989 if (ino
>= gif
->ImageCount
)
8991 image_error ("Invalid image number `%s' in image `%s'",
8993 DGifCloseFile (gif
);
8998 width
= img
->width
= max (gif
->SWidth
, gif
->Image
.Left
+ gif
->Image
.Width
);
8999 height
= img
->height
= max (gif
->SHeight
, gif
->Image
.Top
+ gif
->Image
.Height
);
9001 /* Create the X image and pixmap. */
9002 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
9004 DGifCloseFile (gif
);
9009 /* Allocate colors. */
9010 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
9012 gif_color_map
= gif
->SColorMap
;
9013 init_color_table ();
9014 bzero (pixel_colors
, sizeof pixel_colors
);
9016 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
9018 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
9019 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
9020 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
9021 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
9024 img
->colors
= colors_in_color_table (&img
->ncolors
);
9025 free_color_table ();
9027 /* Clear the part of the screen image that are not covered by
9028 the image from the GIF file. Full animated GIF support
9029 requires more than can be done here (see the gif89 spec,
9030 disposal methods). Let's simply assume that the part
9031 not covered by a sub-image is in the frame's background color. */
9032 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
9033 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
9034 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
9035 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
9037 for (y
= 0; y
< image_top
; ++y
)
9038 for (x
= 0; x
< width
; ++x
)
9039 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9041 for (y
= image_top
+ image_height
; y
< height
; ++y
)
9042 for (x
= 0; x
< width
; ++x
)
9043 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9045 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
9047 for (x
= 0; x
< image_left
; ++x
)
9048 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9049 for (x
= image_left
+ image_width
; x
< width
; ++x
)
9050 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9053 /* Read the GIF image into the X image. We use a local variable
9054 `raster' here because RasterBits below is a char *, and invites
9055 problems with bytes >= 0x80. */
9056 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
9058 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
9060 static int interlace_start
[] = {0, 4, 2, 1};
9061 static int interlace_increment
[] = {8, 8, 4, 2};
9063 int row
= interlace_start
[0];
9067 for (y
= 0; y
< image_height
; y
++)
9069 if (row
>= image_height
)
9071 row
= interlace_start
[++pass
];
9072 while (row
>= image_height
)
9073 row
= interlace_start
[++pass
];
9076 for (x
= 0; x
< image_width
; x
++)
9078 int i
= raster
[(y
* image_width
) + x
];
9079 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
9083 row
+= interlace_increment
[pass
];
9088 for (y
= 0; y
< image_height
; ++y
)
9089 for (x
= 0; x
< image_width
; ++x
)
9091 int i
= raster
[y
* image_width
+ x
];
9092 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
9096 DGifCloseFile (gif
);
9098 /* Maybe fill in the background field while we have ximg handy. */
9099 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
9100 IMAGE_BACKGROUND (img
, f
, ximg
);
9102 /* Put the image into the pixmap, then free the X image and its buffer. */
9103 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
9104 x_destroy_x_image (ximg
);
9110 #endif /* HAVE_GIF != 0 */
9114 /***********************************************************************
9116 ***********************************************************************/
9118 static int gs_image_p
P_ ((Lisp_Object object
));
9119 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
9120 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
9122 /* The symbol `postscript' identifying images of this type. */
9124 Lisp_Object Qpostscript
;
9126 /* Keyword symbols. */
9128 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
9130 /* Indices of image specification fields in gs_format, below. */
9132 enum gs_keyword_index
9150 /* Vector of image_keyword structures describing the format
9151 of valid user-defined image specifications. */
9153 static struct image_keyword gs_format
[GS_LAST
] =
9155 {":type", IMAGE_SYMBOL_VALUE
, 1},
9156 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9157 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9158 {":file", IMAGE_STRING_VALUE
, 1},
9159 {":loader", IMAGE_FUNCTION_VALUE
, 0},
9160 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
9161 {":ascent", IMAGE_ASCENT_VALUE
, 0},
9162 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
9163 {":relief", IMAGE_INTEGER_VALUE
, 0},
9164 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9165 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9166 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9167 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
9170 /* Structure describing the image type `ghostscript'. */
9172 static struct image_type gs_type
=
9182 /* Free X resources of Ghostscript image IMG which is used on frame F. */
9185 gs_clear_image (f
, img
)
9189 /* IMG->data.ptr_val may contain a recorded colormap. */
9190 xfree (img
->data
.ptr_val
);
9191 x_clear_image (f
, img
);
9195 /* Return non-zero if OBJECT is a valid Ghostscript image
9202 struct image_keyword fmt
[GS_LAST
];
9206 bcopy (gs_format
, fmt
, sizeof fmt
);
9208 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
9211 /* Bounding box must be a list or vector containing 4 integers. */
9212 tem
= fmt
[GS_BOUNDING_BOX
].value
;
9215 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
9216 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
9221 else if (VECTORP (tem
))
9223 if (XVECTOR (tem
)->size
!= 4)
9225 for (i
= 0; i
< 4; ++i
)
9226 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
9236 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
9245 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
9246 struct gcpro gcpro1
, gcpro2
;
9248 double in_width
, in_height
;
9249 Lisp_Object pixel_colors
= Qnil
;
9251 /* Compute pixel size of pixmap needed from the given size in the
9252 image specification. Sizes in the specification are in pt. 1 pt
9253 = 1/72 in, xdpi and ydpi are stored in the frame's X display
9255 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
9256 in_width
= XFASTINT (pt_width
) / 72.0;
9257 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
9258 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
9259 in_height
= XFASTINT (pt_height
) / 72.0;
9260 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
9262 /* Create the pixmap. */
9263 xassert (img
->pixmap
== None
);
9264 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9265 img
->width
, img
->height
,
9266 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
9270 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
9274 /* Call the loader to fill the pixmap. It returns a process object
9275 if successful. We do not record_unwind_protect here because
9276 other places in redisplay like calling window scroll functions
9277 don't either. Let the Lisp loader use `unwind-protect' instead. */
9278 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
9280 sprintf (buffer
, "%lu %lu",
9281 (unsigned long) FRAME_X_WINDOW (f
),
9282 (unsigned long) img
->pixmap
);
9283 window_and_pixmap_id
= build_string (buffer
);
9285 sprintf (buffer
, "%lu %lu",
9286 FRAME_FOREGROUND_PIXEL (f
),
9287 FRAME_BACKGROUND_PIXEL (f
));
9288 pixel_colors
= build_string (buffer
);
9290 XSETFRAME (frame
, f
);
9291 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
9293 loader
= intern ("gs-load-image");
9295 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
9296 make_number (img
->width
),
9297 make_number (img
->height
),
9298 window_and_pixmap_id
,
9301 return PROCESSP (img
->data
.lisp_val
);
9305 /* Kill the Ghostscript process that was started to fill PIXMAP on
9306 frame F. Called from XTread_socket when receiving an event
9307 telling Emacs that Ghostscript has finished drawing. */
9310 x_kill_gs_process (pixmap
, f
)
9314 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
9318 /* Find the image containing PIXMAP. */
9319 for (i
= 0; i
< c
->used
; ++i
)
9320 if (c
->images
[i
]->pixmap
== pixmap
)
9323 /* Should someone in between have cleared the image cache, for
9324 instance, give up. */
9328 /* Kill the GS process. We should have found PIXMAP in the image
9329 cache and its image should contain a process object. */
9331 xassert (PROCESSP (img
->data
.lisp_val
));
9332 Fkill_process (img
->data
.lisp_val
, Qnil
);
9333 img
->data
.lisp_val
= Qnil
;
9335 /* On displays with a mutable colormap, figure out the colors
9336 allocated for the image by looking at the pixels of an XImage for
9338 class = FRAME_X_VISUAL (f
)->class;
9339 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
9345 /* Try to get an XImage for img->pixmep. */
9346 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
9347 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
9352 /* Initialize the color table. */
9353 init_color_table ();
9355 /* For each pixel of the image, look its color up in the
9356 color table. After having done so, the color table will
9357 contain an entry for each color used by the image. */
9358 for (y
= 0; y
< img
->height
; ++y
)
9359 for (x
= 0; x
< img
->width
; ++x
)
9361 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
9362 lookup_pixel_color (f
, pixel
);
9365 /* Record colors in the image. Free color table and XImage. */
9366 img
->colors
= colors_in_color_table (&img
->ncolors
);
9367 free_color_table ();
9368 XDestroyImage (ximg
);
9370 #if 0 /* This doesn't seem to be the case. If we free the colors
9371 here, we get a BadAccess later in x_clear_image when
9372 freeing the colors. */
9373 /* We have allocated colors once, but Ghostscript has also
9374 allocated colors on behalf of us. So, to get the
9375 reference counts right, free them once. */
9377 x_free_colors (f
, img
->colors
, img
->ncolors
);
9381 image_error ("Cannot get X image of `%s'; colors will not be freed",
9387 /* Now that we have the pixmap, compute mask and transform the
9388 image if requested. */
9390 postprocess_image (f
, img
);
9396 /***********************************************************************
9398 ***********************************************************************/
9400 DEFUN ("x-change-window-property", Fx_change_window_property
,
9401 Sx_change_window_property
, 2, 3, 0,
9402 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
9403 PROP and VALUE must be strings. FRAME nil or omitted means use the
9404 selected frame. Value is VALUE. */)
9405 (prop
, value
, frame
)
9406 Lisp_Object frame
, prop
, value
;
9408 struct frame
*f
= check_x_frame (frame
);
9411 CHECK_STRING (prop
);
9412 CHECK_STRING (value
);
9415 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9416 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9417 prop_atom
, XA_STRING
, 8, PropModeReplace
,
9418 SDATA (value
), SCHARS (value
));
9420 /* Make sure the property is set when we return. */
9421 XFlush (FRAME_X_DISPLAY (f
));
9428 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
9429 Sx_delete_window_property
, 1, 2, 0,
9430 doc
: /* Remove window property PROP from X window of FRAME.
9431 FRAME nil or omitted means use the selected frame. Value is PROP. */)
9433 Lisp_Object prop
, frame
;
9435 struct frame
*f
= check_x_frame (frame
);
9438 CHECK_STRING (prop
);
9440 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9441 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
9443 /* Make sure the property is removed when we return. */
9444 XFlush (FRAME_X_DISPLAY (f
));
9451 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
9453 doc
: /* Value is the value of window property PROP on FRAME.
9454 If FRAME is nil or omitted, use the selected frame. Value is nil
9455 if FRAME hasn't a property with name PROP or if PROP has no string
9458 Lisp_Object prop
, frame
;
9460 struct frame
*f
= check_x_frame (frame
);
9463 Lisp_Object prop_value
= Qnil
;
9464 char *tmp_data
= NULL
;
9467 unsigned long actual_size
, bytes_remaining
;
9469 CHECK_STRING (prop
);
9471 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9472 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9473 prop_atom
, 0, 0, False
, XA_STRING
,
9474 &actual_type
, &actual_format
, &actual_size
,
9475 &bytes_remaining
, (unsigned char **) &tmp_data
);
9478 int size
= bytes_remaining
;
9483 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9484 prop_atom
, 0, bytes_remaining
,
9486 &actual_type
, &actual_format
,
9487 &actual_size
, &bytes_remaining
,
9488 (unsigned char **) &tmp_data
);
9489 if (rc
== Success
&& tmp_data
)
9490 prop_value
= make_string (tmp_data
, size
);
9501 /***********************************************************************
9503 ***********************************************************************/
9505 /* If non-null, an asynchronous timer that, when it expires, displays
9506 an hourglass cursor on all frames. */
9508 static struct atimer
*hourglass_atimer
;
9510 /* Non-zero means an hourglass cursor is currently shown. */
9512 static int hourglass_shown_p
;
9514 /* Number of seconds to wait before displaying an hourglass cursor. */
9516 static Lisp_Object Vhourglass_delay
;
9518 /* Default number of seconds to wait before displaying an hourglass
9521 #define DEFAULT_HOURGLASS_DELAY 1
9523 /* Function prototypes. */
9525 static void show_hourglass
P_ ((struct atimer
*));
9526 static void hide_hourglass
P_ ((void));
9529 /* Cancel a currently active hourglass timer, and start a new one. */
9535 int secs
, usecs
= 0;
9537 cancel_hourglass ();
9539 if (INTEGERP (Vhourglass_delay
)
9540 && XINT (Vhourglass_delay
) > 0)
9541 secs
= XFASTINT (Vhourglass_delay
);
9542 else if (FLOATP (Vhourglass_delay
)
9543 && XFLOAT_DATA (Vhourglass_delay
) > 0)
9546 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
9547 secs
= XFASTINT (tem
);
9548 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
9551 secs
= DEFAULT_HOURGLASS_DELAY
;
9553 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
9554 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
9555 show_hourglass
, NULL
);
9559 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
9565 if (hourglass_atimer
)
9567 cancel_atimer (hourglass_atimer
);
9568 hourglass_atimer
= NULL
;
9571 if (hourglass_shown_p
)
9576 /* Timer function of hourglass_atimer. TIMER is equal to
9579 Display an hourglass pointer on all frames by mapping the frames'
9580 hourglass_window. Set the hourglass_p flag in the frames'
9581 output_data.x structure to indicate that an hourglass cursor is
9582 shown on the frames. */
9585 show_hourglass (timer
)
9586 struct atimer
*timer
;
9588 /* The timer implementation will cancel this timer automatically
9589 after this function has run. Set hourglass_atimer to null
9590 so that we know the timer doesn't have to be canceled. */
9591 hourglass_atimer
= NULL
;
9593 if (!hourglass_shown_p
)
9595 Lisp_Object rest
, frame
;
9599 FOR_EACH_FRAME (rest
, frame
)
9601 struct frame
*f
= XFRAME (frame
);
9603 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
9605 Display
*dpy
= FRAME_X_DISPLAY (f
);
9607 #ifdef USE_X_TOOLKIT
9608 if (f
->output_data
.x
->widget
)
9610 if (FRAME_OUTER_WINDOW (f
))
9613 f
->output_data
.x
->hourglass_p
= 1;
9615 if (!f
->output_data
.x
->hourglass_window
)
9617 unsigned long mask
= CWCursor
;
9618 XSetWindowAttributes attrs
;
9620 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
9622 f
->output_data
.x
->hourglass_window
9623 = XCreateWindow (dpy
, FRAME_OUTER_WINDOW (f
),
9624 0, 0, 32000, 32000, 0, 0,
9630 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
9636 hourglass_shown_p
= 1;
9642 /* Hide the hourglass pointer on all frames, if it is currently
9648 if (hourglass_shown_p
)
9650 Lisp_Object rest
, frame
;
9653 FOR_EACH_FRAME (rest
, frame
)
9655 struct frame
*f
= XFRAME (frame
);
9658 /* Watch out for newly created frames. */
9659 && f
->output_data
.x
->hourglass_window
)
9661 XUnmapWindow (FRAME_X_DISPLAY (f
),
9662 f
->output_data
.x
->hourglass_window
);
9663 /* Sync here because XTread_socket looks at the
9664 hourglass_p flag that is reset to zero below. */
9665 XSync (FRAME_X_DISPLAY (f
), False
);
9666 f
->output_data
.x
->hourglass_p
= 0;
9670 hourglass_shown_p
= 0;
9677 /***********************************************************************
9679 ***********************************************************************/
9681 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
9682 Lisp_Object
, Lisp_Object
));
9683 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
9684 Lisp_Object
, int, int, int *, int *));
9686 /* The frame of a currently visible tooltip. */
9688 Lisp_Object tip_frame
;
9690 /* If non-nil, a timer started that hides the last tooltip when it
9693 Lisp_Object tip_timer
;
9696 /* If non-nil, a vector of 3 elements containing the last args
9697 with which x-show-tip was called. See there. */
9699 Lisp_Object last_show_tip_args
;
9701 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
9703 Lisp_Object Vx_max_tooltip_size
;
9707 unwind_create_tip_frame (frame
)
9710 Lisp_Object deleted
;
9712 deleted
= unwind_create_frame (frame
);
9713 if (EQ (deleted
, Qt
))
9723 /* Create a frame for a tooltip on the display described by DPYINFO.
9724 PARMS is a list of frame parameters. TEXT is the string to
9725 display in the tip frame. Value is the frame.
9727 Note that functions called here, esp. x_default_parameter can
9728 signal errors, for instance when a specified color name is
9729 undefined. We have to make sure that we're in a consistent state
9730 when this happens. */
9733 x_create_tip_frame (dpyinfo
, parms
, text
)
9734 struct x_display_info
*dpyinfo
;
9735 Lisp_Object parms
, text
;
9738 Lisp_Object frame
, tem
;
9740 long window_prompting
= 0;
9742 int count
= SPECPDL_INDEX ();
9743 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9745 int face_change_count_before
= face_change_count
;
9747 struct buffer
*old_buffer
;
9751 /* Use this general default value to start with until we know if
9752 this frame has a specified name. */
9753 Vx_resource_name
= Vinvocation_name
;
9756 kb
= dpyinfo
->kboard
;
9758 kb
= &the_only_kboard
;
9761 /* Get the name of the frame to use for resource lookup. */
9762 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
9764 && !EQ (name
, Qunbound
)
9766 error ("Invalid frame name--not a string or nil");
9767 Vx_resource_name
= name
;
9770 GCPRO3 (parms
, name
, frame
);
9772 XSETFRAME (frame
, f
);
9774 buffer
= Fget_buffer_create (build_string (" *tip*"));
9775 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
9776 old_buffer
= current_buffer
;
9777 set_buffer_internal_1 (XBUFFER (buffer
));
9778 current_buffer
->truncate_lines
= Qnil
;
9781 set_buffer_internal_1 (old_buffer
);
9783 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
9784 record_unwind_protect (unwind_create_tip_frame
, frame
);
9786 /* By setting the output method, we're essentially saying that
9787 the frame is live, as per FRAME_LIVE_P. If we get a signal
9788 from this point on, x_destroy_window might screw up reference
9790 f
->output_method
= output_x_window
;
9791 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
9792 bzero (f
->output_data
.x
, sizeof (struct x_output
));
9793 f
->output_data
.x
->icon_bitmap
= -1;
9794 FRAME_FONTSET (f
) = -1;
9795 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
9796 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
9797 #ifdef USE_TOOLKIT_SCROLL_BARS
9798 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
9799 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
9800 #endif /* USE_TOOLKIT_SCROLL_BARS */
9801 f
->icon_name
= Qnil
;
9802 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
9804 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
9805 dpyinfo_refcount
= dpyinfo
->reference_count
;
9806 #endif /* GLYPH_DEBUG */
9808 FRAME_KBOARD (f
) = kb
;
9810 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
9811 f
->output_data
.x
->explicit_parent
= 0;
9813 /* These colors will be set anyway later, but it's important
9814 to get the color reference counts right, so initialize them! */
9817 struct gcpro gcpro1
;
9819 black
= build_string ("black");
9821 f
->output_data
.x
->foreground_pixel
9822 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9823 f
->output_data
.x
->background_pixel
9824 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9825 f
->output_data
.x
->cursor_pixel
9826 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9827 f
->output_data
.x
->cursor_foreground_pixel
9828 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9829 f
->output_data
.x
->border_pixel
9830 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9831 f
->output_data
.x
->mouse_pixel
9832 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9836 /* Set the name; the functions to which we pass f expect the name to
9838 if (EQ (name
, Qunbound
) || NILP (name
))
9840 f
->name
= build_string (dpyinfo
->x_id_name
);
9841 f
->explicit_name
= 0;
9846 f
->explicit_name
= 1;
9847 /* use the frame's title when getting resources for this frame. */
9848 specbind (Qx_resource_name
, name
);
9851 /* Extract the window parameters from the supplied values that are
9852 needed to determine window geometry. */
9856 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
9859 /* First, try whatever font the caller has specified. */
9862 tem
= Fquery_fontset (font
, Qnil
);
9864 font
= x_new_fontset (f
, SDATA (tem
));
9866 font
= x_new_font (f
, SDATA (font
));
9869 /* Try out a font which we hope has bold and italic variations. */
9870 if (!STRINGP (font
))
9871 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
9872 if (!STRINGP (font
))
9873 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9874 if (! STRINGP (font
))
9875 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9876 if (! STRINGP (font
))
9877 /* This was formerly the first thing tried, but it finds too many fonts
9878 and takes too long. */
9879 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
9880 /* If those didn't work, look for something which will at least work. */
9881 if (! STRINGP (font
))
9882 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
9884 if (! STRINGP (font
))
9885 font
= build_string ("fixed");
9887 x_default_parameter (f
, parms
, Qfont
, font
,
9888 "font", "Font", RES_TYPE_STRING
);
9891 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
9892 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
9894 /* This defaults to 2 in order to match xterm. We recognize either
9895 internalBorderWidth or internalBorder (which is what xterm calls
9897 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9901 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
9902 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
9903 if (! EQ (value
, Qunbound
))
9904 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
9908 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
9909 "internalBorderWidth", "internalBorderWidth",
9912 /* Also do the stuff which must be set before the window exists. */
9913 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
9914 "foreground", "Foreground", RES_TYPE_STRING
);
9915 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
9916 "background", "Background", RES_TYPE_STRING
);
9917 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
9918 "pointerColor", "Foreground", RES_TYPE_STRING
);
9919 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
9920 "cursorColor", "Foreground", RES_TYPE_STRING
);
9921 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
9922 "borderColor", "BorderColor", RES_TYPE_STRING
);
9924 /* Init faces before x_default_parameter is called for scroll-bar
9925 parameters because that function calls x_set_scroll_bar_width,
9926 which calls change_frame_size, which calls Fset_window_buffer,
9927 which runs hooks, which call Fvertical_motion. At the end, we
9928 end up in init_iterator with a null face cache, which should not
9930 init_frame_faces (f
);
9932 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
9934 window_prompting
= x_figure_window_size (f
, parms
, 0);
9937 XSetWindowAttributes attrs
;
9941 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
9942 if (DoesSaveUnders (dpyinfo
->screen
))
9943 mask
|= CWSaveUnder
;
9945 /* Window managers look at the override-redirect flag to determine
9946 whether or net to give windows a decoration (Xlib spec, chapter
9948 attrs
.override_redirect
= True
;
9949 attrs
.save_under
= True
;
9950 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
9951 /* Arrange for getting MapNotify and UnmapNotify events. */
9952 attrs
.event_mask
= StructureNotifyMask
;
9954 = FRAME_X_WINDOW (f
)
9955 = XCreateWindow (FRAME_X_DISPLAY (f
),
9956 FRAME_X_DISPLAY_INFO (f
)->root_window
,
9957 /* x, y, width, height */
9961 CopyFromParent
, InputOutput
, CopyFromParent
,
9968 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
9969 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9970 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
9971 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9972 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
9973 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
9975 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
9976 Change will not be effected unless different from the current
9978 width
= FRAME_COLS (f
);
9979 height
= FRAME_LINES (f
);
9980 SET_FRAME_COLS (f
, 0);
9981 FRAME_LINES (f
) = 0;
9982 change_frame_size (f
, height
, width
, 1, 0, 0);
9984 /* Add `tooltip' frame parameter's default value. */
9985 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
9986 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
9989 /* Set up faces after all frame parameters are known. This call
9990 also merges in face attributes specified for new frames.
9992 Frame parameters may be changed if .Xdefaults contains
9993 specifications for the default font. For example, if there is an
9994 `Emacs.default.attributeBackground: pink', the `background-color'
9995 attribute of the frame get's set, which let's the internal border
9996 of the tooltip frame appear in pink. Prevent this. */
9998 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
10000 /* Set tip_frame here, so that */
10002 call1 (Qface_set_after_frame_default
, frame
);
10004 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
10005 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
10013 /* It is now ok to make the frame official even if we get an error
10014 below. And the frame needs to be on Vframe_list or making it
10015 visible won't work. */
10016 Vframe_list
= Fcons (frame
, Vframe_list
);
10018 /* Now that the frame is official, it counts as a reference to
10020 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
10022 /* Setting attributes of faces of the tooltip frame from resources
10023 and similar will increment face_change_count, which leads to the
10024 clearing of all current matrices. Since this isn't necessary
10025 here, avoid it by resetting face_change_count to the value it
10026 had before we created the tip frame. */
10027 face_change_count
= face_change_count_before
;
10029 /* Discard the unwind_protect. */
10030 return unbind_to (count
, frame
);
10034 /* Compute where to display tip frame F. PARMS is the list of frame
10035 parameters for F. DX and DY are specified offsets from the current
10036 location of the mouse. WIDTH and HEIGHT are the width and height
10037 of the tooltip. Return coordinates relative to the root window of
10038 the display in *ROOT_X, and *ROOT_Y. */
10041 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
10043 Lisp_Object parms
, dx
, dy
;
10045 int *root_x
, *root_y
;
10047 Lisp_Object left
, top
;
10049 Window root
, child
;
10052 /* User-specified position? */
10053 left
= Fcdr (Fassq (Qleft
, parms
));
10054 top
= Fcdr (Fassq (Qtop
, parms
));
10056 /* Move the tooltip window where the mouse pointer is. Resize and
10058 if (!INTEGERP (left
) || !INTEGERP (top
))
10061 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
10062 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
10066 if (INTEGERP (top
))
10067 *root_y
= XINT (top
);
10068 else if (*root_y
+ XINT (dy
) - height
< 0)
10069 *root_y
-= XINT (dy
);
10073 *root_y
+= XINT (dy
);
10076 if (INTEGERP (left
))
10077 *root_x
= XINT (left
);
10078 else if (*root_x
+ XINT (dx
) + width
<= FRAME_X_DISPLAY_INFO (f
)->width
)
10079 /* It fits to the right of the pointer. */
10080 *root_x
+= XINT (dx
);
10081 else if (width
+ XINT (dx
) <= *root_x
)
10082 /* It fits to the left of the pointer. */
10083 *root_x
-= width
+ XINT (dx
);
10085 /* Put it left-justified on the screen--it ought to fit that way. */
10090 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
10091 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
10092 A tooltip window is a small X window displaying a string.
10094 FRAME nil or omitted means use the selected frame.
10096 PARMS is an optional list of frame parameters which can be used to
10097 change the tooltip's appearance.
10099 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
10100 means use the default timeout of 5 seconds.
10102 If the list of frame parameters PARAMS contains a `left' parameters,
10103 the tooltip is displayed at that x-position. Otherwise it is
10104 displayed at the mouse position, with offset DX added (default is 5 if
10105 DX isn't specified). Likewise for the y-position; if a `top' frame
10106 parameter is specified, it determines the y-position of the tooltip
10107 window, otherwise it is displayed at the mouse position, with offset
10108 DY added (default is -10).
10110 A tooltip's maximum size is specified by `x-max-tooltip-size'.
10111 Text larger than the specified size is clipped. */)
10112 (string
, frame
, parms
, timeout
, dx
, dy
)
10113 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
10117 int root_x
, root_y
;
10118 struct buffer
*old_buffer
;
10119 struct text_pos pos
;
10120 int i
, width
, height
;
10121 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
10122 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
10123 int count
= SPECPDL_INDEX ();
10125 specbind (Qinhibit_redisplay
, Qt
);
10127 GCPRO4 (string
, parms
, frame
, timeout
);
10129 CHECK_STRING (string
);
10130 f
= check_x_frame (frame
);
10131 if (NILP (timeout
))
10132 timeout
= make_number (5);
10134 CHECK_NATNUM (timeout
);
10137 dx
= make_number (5);
10142 dy
= make_number (-10);
10146 if (NILP (last_show_tip_args
))
10147 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
10149 if (!NILP (tip_frame
))
10151 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
10152 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
10153 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
10155 if (EQ (frame
, last_frame
)
10156 && !NILP (Fequal (last_string
, string
))
10157 && !NILP (Fequal (last_parms
, parms
)))
10159 struct frame
*f
= XFRAME (tip_frame
);
10161 /* Only DX and DY have changed. */
10162 if (!NILP (tip_timer
))
10164 Lisp_Object timer
= tip_timer
;
10166 call1 (Qcancel_timer
, timer
);
10170 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
10171 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
10172 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10179 /* Hide a previous tip, if any. */
10182 ASET (last_show_tip_args
, 0, string
);
10183 ASET (last_show_tip_args
, 1, frame
);
10184 ASET (last_show_tip_args
, 2, parms
);
10186 /* Add default values to frame parameters. */
10187 if (NILP (Fassq (Qname
, parms
)))
10188 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
10189 if (NILP (Fassq (Qinternal_border_width
, parms
)))
10190 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
10191 if (NILP (Fassq (Qborder_width
, parms
)))
10192 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
10193 if (NILP (Fassq (Qborder_color
, parms
)))
10194 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
10195 if (NILP (Fassq (Qbackground_color
, parms
)))
10196 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
10199 /* Create a frame for the tooltip, and record it in the global
10200 variable tip_frame. */
10201 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
10202 f
= XFRAME (frame
);
10204 /* Set up the frame's root window. */
10205 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
10206 w
->left_col
= w
->top_line
= make_number (0);
10208 if (CONSP (Vx_max_tooltip_size
)
10209 && INTEGERP (XCAR (Vx_max_tooltip_size
))
10210 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
10211 && INTEGERP (XCDR (Vx_max_tooltip_size
))
10212 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
10214 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
10215 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
10219 w
->total_cols
= make_number (80);
10220 w
->total_lines
= make_number (40);
10223 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
10225 w
->pseudo_window_p
= 1;
10227 /* Display the tooltip text in a temporary buffer. */
10228 old_buffer
= current_buffer
;
10229 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
10230 current_buffer
->truncate_lines
= Qnil
;
10231 clear_glyph_matrix (w
->desired_matrix
);
10232 clear_glyph_matrix (w
->current_matrix
);
10233 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
10234 try_window (FRAME_ROOT_WINDOW (f
), pos
);
10236 /* Compute width and height of the tooltip. */
10237 width
= height
= 0;
10238 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
10240 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
10241 struct glyph
*last
;
10244 /* Stop at the first empty row at the end. */
10245 if (!row
->enabled_p
|| !row
->displays_text_p
)
10248 /* Let the row go over the full width of the frame. */
10249 row
->full_width_p
= 1;
10251 /* There's a glyph at the end of rows that is used to place
10252 the cursor there. Don't include the width of this glyph. */
10253 if (row
->used
[TEXT_AREA
])
10255 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
10256 row_width
= row
->pixel_width
- last
->pixel_width
;
10259 row_width
= row
->pixel_width
;
10261 height
+= row
->height
;
10262 width
= max (width
, row_width
);
10265 /* Add the frame's internal border to the width and height the X
10266 window should have. */
10267 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10268 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10270 /* Move the tooltip window where the mouse pointer is. Resize and
10272 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
10275 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10276 root_x
, root_y
, width
, height
);
10277 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
10280 /* Draw into the window. */
10281 w
->must_be_updated_p
= 1;
10282 update_single_window (w
, 1);
10284 /* Restore original current buffer. */
10285 set_buffer_internal_1 (old_buffer
);
10286 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
10289 /* Let the tip disappear after timeout seconds. */
10290 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
10291 intern ("x-hide-tip"));
10294 return unbind_to (count
, Qnil
);
10298 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
10299 doc
: /* Hide the current tooltip window, if there is any.
10300 Value is t if tooltip was open, nil otherwise. */)
10304 Lisp_Object deleted
, frame
, timer
;
10305 struct gcpro gcpro1
, gcpro2
;
10307 /* Return quickly if nothing to do. */
10308 if (NILP (tip_timer
) && NILP (tip_frame
))
10313 GCPRO2 (frame
, timer
);
10314 tip_frame
= tip_timer
= deleted
= Qnil
;
10316 count
= SPECPDL_INDEX ();
10317 specbind (Qinhibit_redisplay
, Qt
);
10318 specbind (Qinhibit_quit
, Qt
);
10321 call1 (Qcancel_timer
, timer
);
10323 if (FRAMEP (frame
))
10325 Fdelete_frame (frame
, Qnil
);
10329 /* Bloodcurdling hack alert: The Lucid menu bar widget's
10330 redisplay procedure is not called when a tip frame over menu
10331 items is unmapped. Redisplay the menu manually... */
10333 struct frame
*f
= SELECTED_FRAME ();
10334 Widget w
= f
->output_data
.x
->menubar_widget
;
10335 extern void xlwmenu_redisplay
P_ ((Widget
));
10337 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
10341 xlwmenu_redisplay (w
);
10345 #endif /* USE_LUCID */
10349 return unbind_to (count
, deleted
);
10354 /***********************************************************************
10355 File selection dialog
10356 ***********************************************************************/
10360 /* Callback for "OK" and "Cancel" on file selection dialog. */
10363 file_dialog_cb (widget
, client_data
, call_data
)
10365 XtPointer call_data
, client_data
;
10367 int *result
= (int *) client_data
;
10368 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
10369 *result
= cb
->reason
;
10373 /* Callback for unmapping a file selection dialog. This is used to
10374 capture the case where a dialog is closed via a window manager's
10375 closer button, for example. Using a XmNdestroyCallback didn't work
10379 file_dialog_unmap_cb (widget
, client_data
, call_data
)
10381 XtPointer call_data
, client_data
;
10383 int *result
= (int *) client_data
;
10384 *result
= XmCR_CANCEL
;
10388 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10389 doc
: /* Read file name, prompting with PROMPT in directory DIR.
10390 Use a file selection dialog.
10391 Select DEFAULT-FILENAME in the dialog's file selection box, if
10392 specified. Don't let the user enter a file name in the file
10393 selection dialog's entry field, if MUSTMATCH is non-nil. */)
10394 (prompt
, dir
, default_filename
, mustmatch
)
10395 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10398 struct frame
*f
= SELECTED_FRAME ();
10399 Lisp_Object file
= Qnil
;
10400 Widget dialog
, text
, list
, help
;
10403 extern XtAppContext Xt_app_con
;
10404 XmString dir_xmstring
, pattern_xmstring
;
10405 int count
= SPECPDL_INDEX ();
10406 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10408 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10409 CHECK_STRING (prompt
);
10410 CHECK_STRING (dir
);
10412 /* Prevent redisplay. */
10413 specbind (Qinhibit_redisplay
, Qt
);
10417 /* Create the dialog with PROMPT as title, using DIR as initial
10418 directory and using "*" as pattern. */
10419 dir
= Fexpand_file_name (dir
, Qnil
);
10420 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
10421 pattern_xmstring
= XmStringCreateLocalized ("*");
10423 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
10424 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
10425 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
10426 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
10427 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
10428 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
10430 XmStringFree (dir_xmstring
);
10431 XmStringFree (pattern_xmstring
);
10433 /* Add callbacks for OK and Cancel. */
10434 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
10435 (XtPointer
) &result
);
10436 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
10437 (XtPointer
) &result
);
10438 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
10439 (XtPointer
) &result
);
10441 /* Disable the help button since we can't display help. */
10442 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
10443 XtSetSensitive (help
, False
);
10445 /* Mark OK button as default. */
10446 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
10447 XmNshowAsDefault
, True
, NULL
);
10449 /* If MUSTMATCH is non-nil, disable the file entry field of the
10450 dialog, so that the user must select a file from the files list
10451 box. We can't remove it because we wouldn't have a way to get at
10452 the result file name, then. */
10453 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
10454 if (!NILP (mustmatch
))
10457 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
10458 XtSetSensitive (text
, False
);
10459 XtSetSensitive (label
, False
);
10462 /* Manage the dialog, so that list boxes get filled. */
10463 XtManageChild (dialog
);
10465 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
10466 must include the path for this to work. */
10467 list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
10468 if (STRINGP (default_filename
))
10470 XmString default_xmstring
;
10474 = XmStringCreateLocalized (SDATA (default_filename
));
10476 if (!XmListItemExists (list
, default_xmstring
))
10478 /* Add a new item if DEFAULT_FILENAME is not in the list. */
10479 XmListAddItem (list
, default_xmstring
, 0);
10483 item_pos
= XmListItemPos (list
, default_xmstring
);
10484 XmStringFree (default_xmstring
);
10486 /* Select the item and scroll it into view. */
10487 XmListSelectPos (list
, item_pos
, True
);
10488 XmListSetPos (list
, item_pos
);
10491 /* Process events until the user presses Cancel or OK. */
10493 while (result
== 0)
10496 XtAppNextEvent (Xt_app_con
, &event
);
10497 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
) );
10500 /* Get the result. */
10501 if (result
== XmCR_OK
)
10506 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
10507 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
10508 XmStringFree (text
);
10509 file
= build_string (data
);
10516 XtUnmanageChild (dialog
);
10517 XtDestroyWidget (dialog
);
10521 /* Make "Cancel" equivalent to C-g. */
10523 Fsignal (Qquit
, Qnil
);
10525 return unbind_to (count
, file
);
10528 #endif /* USE_MOTIF */
10532 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10533 "Read file name, prompting with PROMPT in directory DIR.\n\
10534 Use a file selection dialog.\n\
10535 Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
10536 specified. Don't let the user enter a file name in the file\n\
10537 selection dialog's entry field, if MUSTMATCH is non-nil.")
10538 (prompt
, dir
, default_filename
, mustmatch
)
10539 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10541 FRAME_PTR f
= SELECTED_FRAME ();
10543 Lisp_Object file
= Qnil
;
10544 int count
= specpdl_ptr
- specpdl
;
10545 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10549 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10550 CHECK_STRING (prompt
);
10551 CHECK_STRING (dir
);
10553 /* Prevent redisplay. */
10554 specbind (Qinhibit_redisplay
, Qt
);
10558 if (STRINGP (default_filename
))
10559 cdef_file
= SDATA (default_filename
);
10561 cdef_file
= SDATA (dir
);
10563 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
, ! NILP (mustmatch
));
10567 file
= build_string (fn
);
10574 /* Make "Cancel" equivalent to C-g. */
10576 Fsignal (Qquit
, Qnil
);
10578 return unbind_to (count
, file
);
10581 #endif /* USE_GTK */
10584 /***********************************************************************
10586 ***********************************************************************/
10588 #ifdef HAVE_XKBGETKEYBOARD
10589 #include <X11/XKBlib.h>
10590 #include <X11/keysym.h>
10593 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
10594 Sx_backspace_delete_keys_p
, 0, 1, 0,
10595 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
10596 FRAME nil means use the selected frame.
10597 Value is t if we know that both keys are present, and are mapped to the
10598 usual X keysyms. */)
10602 #ifdef HAVE_XKBGETKEYBOARD
10604 struct frame
*f
= check_x_frame (frame
);
10605 Display
*dpy
= FRAME_X_DISPLAY (f
);
10606 Lisp_Object have_keys
;
10607 int major
, minor
, op
, event
, error
;
10611 /* Check library version in case we're dynamically linked. */
10612 major
= XkbMajorVersion
;
10613 minor
= XkbMinorVersion
;
10614 if (!XkbLibraryVersion (&major
, &minor
))
10620 /* Check that the server supports XKB. */
10621 major
= XkbMajorVersion
;
10622 minor
= XkbMinorVersion
;
10623 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
10630 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
10633 int delete_keycode
= 0, backspace_keycode
= 0, i
;
10635 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
10637 for (i
= kb
->min_key_code
;
10638 (i
< kb
->max_key_code
10639 && (delete_keycode
== 0 || backspace_keycode
== 0));
10642 /* The XKB symbolic key names can be seen most easily in
10643 the PS file generated by `xkbprint -label name
10645 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
10646 delete_keycode
= i
;
10647 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
10648 backspace_keycode
= i
;
10651 XkbFreeNames (kb
, 0, True
);
10654 XkbFreeClientMap (kb
, 0, True
);
10657 && backspace_keycode
10658 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
10659 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
10664 #else /* not HAVE_XKBGETKEYBOARD */
10666 #endif /* not HAVE_XKBGETKEYBOARD */
10671 /***********************************************************************
10673 ***********************************************************************/
10675 /* Keep this list in the same order as frame_parms in frame.c.
10676 Use 0 for unsupported frame parameters. */
10678 frame_parm_handler x_frame_parm_handlers
[] =
10682 x_set_background_color
,
10683 x_set_border_color
,
10684 x_set_border_width
,
10685 x_set_cursor_color
,
10688 x_set_foreground_color
,
10691 x_set_internal_border_width
,
10692 x_set_menu_bar_lines
,
10694 x_explicitly_set_name
,
10695 x_set_scroll_bar_width
,
10697 x_set_unsplittable
,
10698 x_set_vertical_scroll_bars
,
10700 x_set_tool_bar_lines
,
10701 x_set_scroll_bar_foreground
,
10702 x_set_scroll_bar_background
,
10703 x_set_screen_gamma
,
10704 x_set_line_spacing
,
10705 x_set_fringe_width
,
10706 x_set_fringe_width
,
10714 /* This is zero if not using X windows. */
10717 /* The section below is built by the lisp expression at the top of the file,
10718 just above where these variables are declared. */
10719 /*&&& init symbols here &&&*/
10720 Qnone
= intern ("none");
10721 staticpro (&Qnone
);
10722 Qsuppress_icon
= intern ("suppress-icon");
10723 staticpro (&Qsuppress_icon
);
10724 Qundefined_color
= intern ("undefined-color");
10725 staticpro (&Qundefined_color
);
10726 Qcenter
= intern ("center");
10727 staticpro (&Qcenter
);
10728 Qcompound_text
= intern ("compound-text");
10729 staticpro (&Qcompound_text
);
10730 Qcancel_timer
= intern ("cancel-timer");
10731 staticpro (&Qcancel_timer
);
10732 /* This is the end of symbol initialization. */
10734 /* Text property `display' should be nonsticky by default. */
10735 Vtext_property_default_nonsticky
10736 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
10739 Qlaplace
= intern ("laplace");
10740 staticpro (&Qlaplace
);
10741 Qemboss
= intern ("emboss");
10742 staticpro (&Qemboss
);
10743 Qedge_detection
= intern ("edge-detection");
10744 staticpro (&Qedge_detection
);
10745 Qheuristic
= intern ("heuristic");
10746 staticpro (&Qheuristic
);
10747 QCmatrix
= intern (":matrix");
10748 staticpro (&QCmatrix
);
10749 QCcolor_adjustment
= intern (":color-adjustment");
10750 staticpro (&QCcolor_adjustment
);
10751 QCmask
= intern (":mask");
10752 staticpro (&QCmask
);
10754 Fput (Qundefined_color
, Qerror_conditions
,
10755 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
10756 Fput (Qundefined_color
, Qerror_message
,
10757 build_string ("Undefined color"));
10759 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images
,
10760 doc
: /* Non-nil means always draw a cross over disabled images.
10761 Disabled images are those having an `:conversion disabled' property.
10762 A cross is always drawn on black & white displays. */);
10763 cross_disabled_images
= 0;
10765 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
10766 doc
: /* List of directories to search for window system bitmap files. */);
10767 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
10769 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
10770 doc
: /* The shape of the pointer when over text.
10771 Changing the value does not affect existing frames
10772 unless you set the mouse color. */);
10773 Vx_pointer_shape
= Qnil
;
10775 #if 0 /* This doesn't really do anything. */
10776 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
10777 doc
: /* The shape of the pointer when not over text.
10778 This variable takes effect when you create a new frame
10779 or when you set the mouse color. */);
10781 Vx_nontext_pointer_shape
= Qnil
;
10783 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
10784 doc
: /* The shape of the pointer when Emacs is busy.
10785 This variable takes effect when you create a new frame
10786 or when you set the mouse color. */);
10787 Vx_hourglass_pointer_shape
= Qnil
;
10789 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
10790 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
10791 display_hourglass_p
= 1;
10793 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
10794 doc
: /* *Seconds to wait before displaying an hourglass pointer.
10795 Value must be an integer or float. */);
10796 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
10798 #if 0 /* This doesn't really do anything. */
10799 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
10800 doc
: /* The shape of the pointer when over the mode line.
10801 This variable takes effect when you create a new frame
10802 or when you set the mouse color. */);
10804 Vx_mode_pointer_shape
= Qnil
;
10806 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
10807 &Vx_sensitive_text_pointer_shape
,
10808 doc
: /* The shape of the pointer when over mouse-sensitive text.
10809 This variable takes effect when you create a new frame
10810 or when you set the mouse color. */);
10811 Vx_sensitive_text_pointer_shape
= Qnil
;
10813 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
10814 &Vx_window_horizontal_drag_shape
,
10815 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
10816 This variable takes effect when you create a new frame
10817 or when you set the mouse color. */);
10818 Vx_window_horizontal_drag_shape
= Qnil
;
10820 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
10821 doc
: /* A string indicating the foreground color of the cursor box. */);
10822 Vx_cursor_fore_pixel
= Qnil
;
10824 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
10825 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
10826 Text larger than this is clipped. */);
10827 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
10829 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
10830 doc
: /* Non-nil if no X window manager is in use.
10831 Emacs doesn't try to figure this out; this is always nil
10832 unless you set it to something else. */);
10833 /* We don't have any way to find this out, so set it to nil
10834 and maybe the user would like to set it to t. */
10835 Vx_no_window_manager
= Qnil
;
10837 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
10838 &Vx_pixel_size_width_font_regexp
,
10839 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
10841 Since Emacs gets width of a font matching with this regexp from
10842 PIXEL_SIZE field of the name, font finding mechanism gets faster for
10843 such a font. This is especially effective for such large fonts as
10844 Chinese, Japanese, and Korean. */);
10845 Vx_pixel_size_width_font_regexp
= Qnil
;
10847 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
10848 doc
: /* Time after which cached images are removed from the cache.
10849 When an image has not been displayed this many seconds, remove it
10850 from the image cache. Value must be an integer or nil with nil
10851 meaning don't clear the cache. */);
10852 Vimage_cache_eviction_delay
= make_number (30 * 60);
10854 #ifdef USE_X_TOOLKIT
10855 Fprovide (intern ("x-toolkit"), Qnil
);
10857 Fprovide (intern ("motif"), Qnil
);
10859 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
10860 doc
: /* Version info for LessTif/Motif. */);
10861 Vmotif_version_string
= build_string (XmVERSION_STRING
);
10862 #endif /* USE_MOTIF */
10863 #endif /* USE_X_TOOLKIT */
10865 /* X window properties. */
10866 defsubr (&Sx_change_window_property
);
10867 defsubr (&Sx_delete_window_property
);
10868 defsubr (&Sx_window_property
);
10870 defsubr (&Sxw_display_color_p
);
10871 defsubr (&Sx_display_grayscale_p
);
10872 defsubr (&Sxw_color_defined_p
);
10873 defsubr (&Sxw_color_values
);
10874 defsubr (&Sx_server_max_request_size
);
10875 defsubr (&Sx_server_vendor
);
10876 defsubr (&Sx_server_version
);
10877 defsubr (&Sx_display_pixel_width
);
10878 defsubr (&Sx_display_pixel_height
);
10879 defsubr (&Sx_display_mm_width
);
10880 defsubr (&Sx_display_mm_height
);
10881 defsubr (&Sx_display_screens
);
10882 defsubr (&Sx_display_planes
);
10883 defsubr (&Sx_display_color_cells
);
10884 defsubr (&Sx_display_visual_class
);
10885 defsubr (&Sx_display_backing_store
);
10886 defsubr (&Sx_display_save_under
);
10887 defsubr (&Sx_create_frame
);
10888 defsubr (&Sx_open_connection
);
10889 defsubr (&Sx_close_connection
);
10890 defsubr (&Sx_display_list
);
10891 defsubr (&Sx_synchronize
);
10892 defsubr (&Sx_focus_frame
);
10893 defsubr (&Sx_backspace_delete_keys_p
);
10895 /* Setting callback functions for fontset handler. */
10896 get_font_info_func
= x_get_font_info
;
10898 #if 0 /* This function pointer doesn't seem to be used anywhere.
10899 And the pointer assigned has the wrong type, anyway. */
10900 list_fonts_func
= x_list_fonts
;
10903 load_font_func
= x_load_font
;
10904 find_ccl_program_func
= x_find_ccl_program
;
10905 query_font_func
= x_query_font
;
10906 set_frame_fontset_func
= x_set_font
;
10907 check_window_system_func
= check_x
;
10910 Qxbm
= intern ("xbm");
10912 QCconversion
= intern (":conversion");
10913 staticpro (&QCconversion
);
10914 QCheuristic_mask
= intern (":heuristic-mask");
10915 staticpro (&QCheuristic_mask
);
10916 QCcolor_symbols
= intern (":color-symbols");
10917 staticpro (&QCcolor_symbols
);
10918 QCascent
= intern (":ascent");
10919 staticpro (&QCascent
);
10920 QCmargin
= intern (":margin");
10921 staticpro (&QCmargin
);
10922 QCrelief
= intern (":relief");
10923 staticpro (&QCrelief
);
10924 Qpostscript
= intern ("postscript");
10925 staticpro (&Qpostscript
);
10926 QCloader
= intern (":loader");
10927 staticpro (&QCloader
);
10928 QCbounding_box
= intern (":bounding-box");
10929 staticpro (&QCbounding_box
);
10930 QCpt_width
= intern (":pt-width");
10931 staticpro (&QCpt_width
);
10932 QCpt_height
= intern (":pt-height");
10933 staticpro (&QCpt_height
);
10934 QCindex
= intern (":index");
10935 staticpro (&QCindex
);
10936 Qpbm
= intern ("pbm");
10940 Qxpm
= intern ("xpm");
10945 Qjpeg
= intern ("jpeg");
10946 staticpro (&Qjpeg
);
10950 Qtiff
= intern ("tiff");
10951 staticpro (&Qtiff
);
10955 Qgif
= intern ("gif");
10960 Qpng
= intern ("png");
10964 defsubr (&Sclear_image_cache
);
10965 defsubr (&Simage_size
);
10966 defsubr (&Simage_mask_p
);
10968 hourglass_atimer
= NULL
;
10969 hourglass_shown_p
= 0;
10971 defsubr (&Sx_show_tip
);
10972 defsubr (&Sx_hide_tip
);
10974 staticpro (&tip_timer
);
10976 staticpro (&tip_frame
);
10978 last_show_tip_args
= Qnil
;
10979 staticpro (&last_show_tip_args
);
10982 defsubr (&Sx_file_dialog
);
10990 image_types
= NULL
;
10991 Vimage_types
= Qnil
;
10993 define_image_type (&xbm_type
);
10994 define_image_type (&gs_type
);
10995 define_image_type (&pbm_type
);
10998 define_image_type (&xpm_type
);
11002 define_image_type (&jpeg_type
);
11006 define_image_type (&tiff_type
);
11010 define_image_type (&gif_type
);
11014 define_image_type (&png_type
);
11018 #endif /* HAVE_X_WINDOWS */