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].have_mask
= 0;
627 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
628 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
629 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
630 dpyinfo
->bitmaps
[id
- 1].height
= height
;
631 dpyinfo
->bitmaps
[id
- 1].width
= width
;
636 /* Create bitmap from file FILE for frame F. */
639 x_create_bitmap_from_file (f
, file
)
643 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
644 unsigned int width
, height
;
646 int xhot
, yhot
, result
, id
;
651 /* Look for an existing bitmap with the same name. */
652 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
654 if (dpyinfo
->bitmaps
[id
].refcount
655 && dpyinfo
->bitmaps
[id
].file
656 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) SDATA (file
)))
658 ++dpyinfo
->bitmaps
[id
].refcount
;
663 /* Search bitmap-file-path for the file, if appropriate. */
664 fd
= openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, Qnil
);
669 filename
= (char *) SDATA (found
);
671 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
672 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
673 if (result
!= BitmapSuccess
)
676 id
= x_allocate_bitmap_record (f
);
677 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
678 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
679 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
680 dpyinfo
->bitmaps
[id
- 1].file
681 = (char *) xmalloc (SBYTES (file
) + 1);
682 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
683 dpyinfo
->bitmaps
[id
- 1].height
= height
;
684 dpyinfo
->bitmaps
[id
- 1].width
= width
;
685 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
690 /* Remove reference to bitmap with id number ID. */
693 x_destroy_bitmap (f
, id
)
697 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
701 --dpyinfo
->bitmaps
[id
- 1].refcount
;
702 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
705 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
706 if (dpyinfo
->bitmaps
[id
- 1].have_mask
)
707 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].mask
);
708 if (dpyinfo
->bitmaps
[id
- 1].file
)
710 xfree (dpyinfo
->bitmaps
[id
- 1].file
);
711 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
718 /* Free all the bitmaps for the display specified by DPYINFO. */
721 x_destroy_all_bitmaps (dpyinfo
)
722 struct x_display_info
*dpyinfo
;
725 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
726 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
728 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
729 if (dpyinfo
->bitmaps
[i
].have_mask
)
730 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].mask
);
731 if (dpyinfo
->bitmaps
[i
].file
)
732 xfree (dpyinfo
->bitmaps
[i
].file
);
734 dpyinfo
->bitmaps_last
= 0;
740 /* Useful functions defined in the section
741 `Image type independent image structures' below. */
743 static unsigned long four_corners_best
P_ ((XImage
*ximg
, unsigned long width
,
744 unsigned long height
));
746 static int x_create_x_image_and_pixmap
P_ ((struct frame
*f
, int width
, int height
,
747 int depth
, XImage
**ximg
,
750 static void x_destroy_x_image
P_ ((XImage
*ximg
));
753 /* Create a mask of a bitmap. Note is this not a perfect mask.
754 It's nicer with some borders in this context */
757 x_create_bitmap_mask(f
, id
)
762 XImage
*ximg
, *mask_img
;
763 unsigned long width
, height
;
766 unsigned long x
, y
, xp
, xm
, yp
, ym
;
769 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
770 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
775 pixmap
= x_bitmap_pixmap(f
, id
);
776 width
= x_bitmap_width(f
, id
);
777 height
= x_bitmap_height(f
, id
);
780 ximg
= XGetImage (FRAME_X_DISPLAY (f
), pixmap
, 0, 0, width
, height
,
789 result
= x_create_x_image_and_pixmap (f
, width
, height
, 1, &mask_img
, &mask
);
798 bg
= four_corners_best (ximg
, width
, height
);
800 for (y
= 0; y
< ximg
->height
; ++y
)
802 for (x
= 0; x
< ximg
->width
; ++x
)
804 xp
= x
!= ximg
->width
- 1 ? x
+ 1 : 0;
805 xm
= x
!= 0 ? x
- 1 : ximg
->width
- 1;
806 yp
= y
!= ximg
->height
- 1 ? y
+ 1 : 0;
807 ym
= y
!= 0 ? y
- 1 : ximg
->height
- 1;
808 if (XGetPixel (ximg
, x
, y
) == bg
809 && XGetPixel (ximg
, x
, yp
) == bg
810 && XGetPixel (ximg
, x
, ym
) == bg
811 && XGetPixel (ximg
, xp
, y
) == bg
812 && XGetPixel (ximg
, xp
, yp
) == bg
813 && XGetPixel (ximg
, xp
, ym
) == bg
814 && XGetPixel (ximg
, xm
, y
) == bg
815 && XGetPixel (ximg
, xm
, yp
) == bg
816 && XGetPixel (ximg
, xm
, ym
) == bg
)
817 XPutPixel (mask_img
, x
, y
, 0);
819 XPutPixel (mask_img
, x
, y
, 1);
823 xassert (interrupt_input_blocked
);
824 gc
= XCreateGC (FRAME_X_DISPLAY (f
), mask
, 0, NULL
);
825 XPutImage (FRAME_X_DISPLAY (f
), mask
, gc
, mask_img
, 0, 0, 0, 0,
827 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
829 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
830 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
832 XDestroyImage (ximg
);
833 x_destroy_x_image(mask_img
);
838 static Lisp_Object unwind_create_frame
P_ ((Lisp_Object
));
839 static Lisp_Object unwind_create_tip_frame
P_ ((Lisp_Object
));
840 static void x_disable_image
P_ ((struct frame
*, struct image
*));
842 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
843 static void x_set_wait_for_wm
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
844 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
845 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
846 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
847 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
848 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
849 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
850 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
851 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
852 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
853 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
854 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
855 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
857 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
859 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
864 static void x_edge_detection
P_ ((struct frame
*, struct image
*, Lisp_Object
,
866 static void init_color_table
P_ ((void));
867 static void free_color_table
P_ ((void));
868 static unsigned long *colors_in_color_table
P_ ((int *n
));
869 static unsigned long lookup_rgb_color
P_ ((struct frame
*f
, int r
, int g
, int b
));
870 static unsigned long lookup_pixel_color
P_ ((struct frame
*f
, unsigned long p
));
876 /* Store the screen positions of frame F into XPTR and YPTR.
877 These are the positions of the containing window manager window,
878 not Emacs's own window. */
881 x_real_positions (f
, xptr
, yptr
)
885 int win_x
, win_y
, outer_x
, outer_y
;
886 int real_x
= 0, real_y
= 0;
888 Window win
= f
->output_data
.x
->parent_desc
;
894 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
896 if (win
== FRAME_X_DISPLAY_INFO (f
)->root_window
)
897 win
= FRAME_OUTER_WINDOW (f
);
899 /* This loop traverses up the containment tree until we hit the root
900 window. Window managers may intersect many windows between our window
901 and the root window. The window we find just before the root window
902 should be the outer WM window. */
905 Window wm_window
, rootw
;
906 Window
*tmp_children
;
907 unsigned int tmp_nchildren
;
910 success
= XQueryTree (FRAME_X_DISPLAY (f
), win
, &rootw
,
911 &wm_window
, &tmp_children
, &tmp_nchildren
);
913 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
915 /* Don't free tmp_children if XQueryTree failed. */
919 XFree ((char *) tmp_children
);
921 if (wm_window
== rootw
|| had_errors
)
932 /* Get the real coordinates for the WM window upper left corner */
933 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
934 &rootw
, &real_x
, &real_y
, &ign
, &ign
, &ign
, &ign
);
936 /* Translate real coordinates to coordinates relative to our
937 window. For our window, the upper left corner is 0, 0.
938 Since the upper left corner of the WM window is outside
939 our window, win_x and win_y will be negative:
941 ------------------ ---> x
943 | ----------------- v y
946 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
948 /* From-window, to-window. */
949 FRAME_X_DISPLAY_INFO (f
)->root_window
,
952 /* From-position, to-position. */
953 real_x
, real_y
, &win_x
, &win_y
,
958 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
965 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
967 /* From-window, to-window. */
968 FRAME_X_DISPLAY_INFO (f
)->root_window
,
969 FRAME_OUTER_WINDOW (f
),
971 /* From-position, to-position. */
972 real_x
, real_y
, &outer_x
, &outer_y
,
978 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
981 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
985 if (had_errors
) return;
987 f
->x_pixels_diff
= -win_x
;
988 f
->y_pixels_diff
= -win_y
;
990 FRAME_X_OUTPUT (f
)->x_pixels_outer_diff
= -outer_x
;
991 FRAME_X_OUTPUT (f
)->y_pixels_outer_diff
= -outer_y
;
1000 /* Gamma-correct COLOR on frame F. */
1003 gamma_correct (f
, color
)
1009 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
1010 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
1011 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
1016 /* Decide if color named COLOR_NAME is valid for use on frame F. If
1017 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
1018 allocate the color. Value is zero if COLOR_NAME is invalid, or
1019 no color could be allocated. */
1022 x_defined_color (f
, color_name
, color
, alloc_p
)
1029 Display
*dpy
= FRAME_X_DISPLAY (f
);
1030 Colormap cmap
= FRAME_X_COLORMAP (f
);
1033 success_p
= XParseColor (dpy
, cmap
, color_name
, color
);
1034 if (success_p
&& alloc_p
)
1035 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
1042 /* Return the pixel color value for color COLOR_NAME on frame F. If F
1043 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
1044 Signal an error if color can't be allocated. */
1047 x_decode_color (f
, color_name
, mono_color
)
1049 Lisp_Object color_name
;
1054 CHECK_STRING (color_name
);
1056 #if 0 /* Don't do this. It's wrong when we're not using the default
1057 colormap, it makes freeing difficult, and it's probably not
1058 an important optimization. */
1059 if (strcmp (SDATA (color_name
), "black") == 0)
1060 return BLACK_PIX_DEFAULT (f
);
1061 else if (strcmp (SDATA (color_name
), "white") == 0)
1062 return WHITE_PIX_DEFAULT (f
);
1065 /* Return MONO_COLOR for monochrome frames. */
1066 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1069 /* x_defined_color is responsible for coping with failures
1070 by looking for a near-miss. */
1071 if (x_defined_color (f
, SDATA (color_name
), &cdef
, 1))
1074 Fsignal (Qerror
, Fcons (build_string ("Undefined color"),
1075 Fcons (color_name
, Qnil
)));
1081 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
1082 the previous value of that parameter, NEW_VALUE is the new value.
1083 See also the comment of wait_for_wm in struct x_output. */
1086 x_set_wait_for_wm (f
, new_value
, old_value
)
1088 Lisp_Object new_value
, old_value
;
1090 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
1095 static Lisp_Object x_find_image_file
P_ ((Lisp_Object file
));
1097 /* Set icon from FILE for frame F. By using GTK functions the icon
1098 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
1101 xg_set_icon(f
, file
)
1105 struct gcpro gcpro1
;
1111 found
= x_find_image_file (file
);
1119 filename
= SDATA (found
);
1122 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
1126 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1128 g_object_unref (pixbuf
);
1141 #endif /* USE_GTK */
1144 /* Functions called only from `x_set_frame_param'
1145 to set individual parameters.
1147 If FRAME_X_WINDOW (f) is 0,
1148 the frame is being created and its X-window does not exist yet.
1149 In that case, just record the parameter's new value
1150 in the standard place; do not attempt to change the window. */
1153 x_set_foreground_color (f
, arg
, oldval
)
1155 Lisp_Object arg
, oldval
;
1157 struct x_output
*x
= f
->output_data
.x
;
1158 unsigned long fg
, old_fg
;
1160 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1161 old_fg
= x
->foreground_pixel
;
1162 x
->foreground_pixel
= fg
;
1164 if (FRAME_X_WINDOW (f
) != 0)
1166 Display
*dpy
= FRAME_X_DISPLAY (f
);
1169 XSetForeground (dpy
, x
->normal_gc
, fg
);
1170 XSetBackground (dpy
, x
->reverse_gc
, fg
);
1172 if (x
->cursor_pixel
== old_fg
)
1174 unload_color (f
, x
->cursor_pixel
);
1175 x
->cursor_pixel
= x_copy_color (f
, fg
);
1176 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
1181 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
1183 if (FRAME_VISIBLE_P (f
))
1187 unload_color (f
, old_fg
);
1191 x_set_background_color (f
, arg
, oldval
)
1193 Lisp_Object arg
, oldval
;
1195 struct x_output
*x
= f
->output_data
.x
;
1198 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1199 unload_color (f
, x
->background_pixel
);
1200 x
->background_pixel
= bg
;
1202 if (FRAME_X_WINDOW (f
) != 0)
1204 Display
*dpy
= FRAME_X_DISPLAY (f
);
1207 XSetBackground (dpy
, x
->normal_gc
, bg
);
1208 XSetForeground (dpy
, x
->reverse_gc
, bg
);
1209 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
1210 XSetForeground (dpy
, x
->cursor_gc
, bg
);
1213 xg_set_background_color (f
, bg
);
1216 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
1217 toolkit scroll bars. */
1220 for (bar
= FRAME_SCROLL_BARS (f
);
1222 bar
= XSCROLL_BAR (bar
)->next
)
1224 Window window
= SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
));
1225 XSetWindowBackground (dpy
, window
, bg
);
1228 #endif /* USE_TOOLKIT_SCROLL_BARS */
1231 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
1233 if (FRAME_VISIBLE_P (f
))
1239 x_set_mouse_color (f
, arg
, oldval
)
1241 Lisp_Object arg
, oldval
;
1243 struct x_output
*x
= f
->output_data
.x
;
1244 Display
*dpy
= FRAME_X_DISPLAY (f
);
1245 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
1246 Cursor hourglass_cursor
, horizontal_drag_cursor
;
1248 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1249 unsigned long mask_color
= x
->background_pixel
;
1251 /* Don't let pointers be invisible. */
1252 if (mask_color
== pixel
)
1254 x_free_colors (f
, &pixel
, 1);
1255 pixel
= x_copy_color (f
, x
->foreground_pixel
);
1258 unload_color (f
, x
->mouse_pixel
);
1259 x
->mouse_pixel
= pixel
;
1263 /* It's not okay to crash if the user selects a screwy cursor. */
1264 count
= x_catch_errors (dpy
);
1266 if (!NILP (Vx_pointer_shape
))
1268 CHECK_NUMBER (Vx_pointer_shape
);
1269 cursor
= XCreateFontCursor (dpy
, XINT (Vx_pointer_shape
));
1272 cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1273 x_check_errors (dpy
, "bad text pointer cursor: %s");
1275 if (!NILP (Vx_nontext_pointer_shape
))
1277 CHECK_NUMBER (Vx_nontext_pointer_shape
);
1279 = XCreateFontCursor (dpy
, XINT (Vx_nontext_pointer_shape
));
1282 nontext_cursor
= XCreateFontCursor (dpy
, XC_left_ptr
);
1283 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
1285 if (!NILP (Vx_hourglass_pointer_shape
))
1287 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
1289 = XCreateFontCursor (dpy
, XINT (Vx_hourglass_pointer_shape
));
1292 hourglass_cursor
= XCreateFontCursor (dpy
, XC_watch
);
1293 x_check_errors (dpy
, "bad hourglass pointer cursor: %s");
1295 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
1296 if (!NILP (Vx_mode_pointer_shape
))
1298 CHECK_NUMBER (Vx_mode_pointer_shape
);
1299 mode_cursor
= XCreateFontCursor (dpy
, XINT (Vx_mode_pointer_shape
));
1302 mode_cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1303 x_check_errors (dpy
, "bad modeline pointer cursor: %s");
1305 if (!NILP (Vx_sensitive_text_pointer_shape
))
1307 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
1309 = XCreateFontCursor (dpy
, XINT (Vx_sensitive_text_pointer_shape
));
1312 hand_cursor
= XCreateFontCursor (dpy
, XC_hand2
);
1314 if (!NILP (Vx_window_horizontal_drag_shape
))
1316 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
1317 horizontal_drag_cursor
1318 = XCreateFontCursor (dpy
, XINT (Vx_window_horizontal_drag_shape
));
1321 horizontal_drag_cursor
1322 = XCreateFontCursor (dpy
, XC_sb_h_double_arrow
);
1324 /* Check and report errors with the above calls. */
1325 x_check_errors (dpy
, "can't set cursor shape: %s");
1326 x_uncatch_errors (dpy
, count
);
1329 XColor fore_color
, back_color
;
1331 fore_color
.pixel
= x
->mouse_pixel
;
1332 x_query_color (f
, &fore_color
);
1333 back_color
.pixel
= mask_color
;
1334 x_query_color (f
, &back_color
);
1336 XRecolorCursor (dpy
, cursor
, &fore_color
, &back_color
);
1337 XRecolorCursor (dpy
, nontext_cursor
, &fore_color
, &back_color
);
1338 XRecolorCursor (dpy
, mode_cursor
, &fore_color
, &back_color
);
1339 XRecolorCursor (dpy
, hand_cursor
, &fore_color
, &back_color
);
1340 XRecolorCursor (dpy
, hourglass_cursor
, &fore_color
, &back_color
);
1341 XRecolorCursor (dpy
, horizontal_drag_cursor
, &fore_color
, &back_color
);
1344 if (FRAME_X_WINDOW (f
) != 0)
1345 XDefineCursor (dpy
, FRAME_X_WINDOW (f
), cursor
);
1347 if (cursor
!= x
->text_cursor
1348 && x
->text_cursor
!= 0)
1349 XFreeCursor (dpy
, x
->text_cursor
);
1350 x
->text_cursor
= cursor
;
1352 if (nontext_cursor
!= x
->nontext_cursor
1353 && x
->nontext_cursor
!= 0)
1354 XFreeCursor (dpy
, x
->nontext_cursor
);
1355 x
->nontext_cursor
= nontext_cursor
;
1357 if (hourglass_cursor
!= x
->hourglass_cursor
1358 && x
->hourglass_cursor
!= 0)
1359 XFreeCursor (dpy
, x
->hourglass_cursor
);
1360 x
->hourglass_cursor
= hourglass_cursor
;
1362 if (mode_cursor
!= x
->modeline_cursor
1363 && x
->modeline_cursor
!= 0)
1364 XFreeCursor (dpy
, f
->output_data
.x
->modeline_cursor
);
1365 x
->modeline_cursor
= mode_cursor
;
1367 if (hand_cursor
!= x
->hand_cursor
1368 && x
->hand_cursor
!= 0)
1369 XFreeCursor (dpy
, x
->hand_cursor
);
1370 x
->hand_cursor
= hand_cursor
;
1372 if (horizontal_drag_cursor
!= x
->horizontal_drag_cursor
1373 && x
->horizontal_drag_cursor
!= 0)
1374 XFreeCursor (dpy
, x
->horizontal_drag_cursor
);
1375 x
->horizontal_drag_cursor
= horizontal_drag_cursor
;
1380 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1384 x_set_cursor_color (f
, arg
, oldval
)
1386 Lisp_Object arg
, oldval
;
1388 unsigned long fore_pixel
, pixel
;
1389 int fore_pixel_allocated_p
= 0, pixel_allocated_p
= 0;
1390 struct x_output
*x
= f
->output_data
.x
;
1392 if (!NILP (Vx_cursor_fore_pixel
))
1394 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1395 WHITE_PIX_DEFAULT (f
));
1396 fore_pixel_allocated_p
= 1;
1399 fore_pixel
= x
->background_pixel
;
1401 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1402 pixel_allocated_p
= 1;
1404 /* Make sure that the cursor color differs from the background color. */
1405 if (pixel
== x
->background_pixel
)
1407 if (pixel_allocated_p
)
1409 x_free_colors (f
, &pixel
, 1);
1410 pixel_allocated_p
= 0;
1413 pixel
= x
->mouse_pixel
;
1414 if (pixel
== fore_pixel
)
1416 if (fore_pixel_allocated_p
)
1418 x_free_colors (f
, &fore_pixel
, 1);
1419 fore_pixel_allocated_p
= 0;
1421 fore_pixel
= x
->background_pixel
;
1425 unload_color (f
, x
->cursor_foreground_pixel
);
1426 if (!fore_pixel_allocated_p
)
1427 fore_pixel
= x_copy_color (f
, fore_pixel
);
1428 x
->cursor_foreground_pixel
= fore_pixel
;
1430 unload_color (f
, x
->cursor_pixel
);
1431 if (!pixel_allocated_p
)
1432 pixel
= x_copy_color (f
, pixel
);
1433 x
->cursor_pixel
= pixel
;
1435 if (FRAME_X_WINDOW (f
) != 0)
1438 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
1439 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
1442 if (FRAME_VISIBLE_P (f
))
1444 x_update_cursor (f
, 0);
1445 x_update_cursor (f
, 1);
1449 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1452 /* Set the border-color of frame F to pixel value PIX.
1453 Note that this does not fully take effect if done before
1454 F has an x-window. */
1457 x_set_border_pixel (f
, pix
)
1461 unload_color (f
, f
->output_data
.x
->border_pixel
);
1462 f
->output_data
.x
->border_pixel
= pix
;
1464 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
1467 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1468 (unsigned long)pix
);
1471 if (FRAME_VISIBLE_P (f
))
1476 /* Set the border-color of frame F to value described by ARG.
1477 ARG can be a string naming a color.
1478 The border-color is used for the border that is drawn by the X server.
1479 Note that this does not fully take effect if done before
1480 F has an x-window; it must be redone when the window is created.
1482 Note: this is done in two routines because of the way X10 works.
1484 Note: under X11, this is normally the province of the window manager,
1485 and so emacs' border colors may be overridden. */
1488 x_set_border_color (f
, arg
, oldval
)
1490 Lisp_Object arg
, oldval
;
1495 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1496 x_set_border_pixel (f
, pix
);
1497 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1502 x_set_cursor_type (f
, arg
, oldval
)
1504 Lisp_Object arg
, oldval
;
1506 set_frame_cursor_types (f
, arg
);
1508 /* Make sure the cursor gets redrawn. */
1509 cursor_type_changed
= 1;
1513 x_set_icon_type (f
, arg
, oldval
)
1515 Lisp_Object arg
, oldval
;
1521 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1524 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1529 result
= x_text_icon (f
,
1530 (char *) SDATA ((!NILP (f
->icon_name
)
1534 result
= x_bitmap_icon (f
, arg
);
1539 error ("No icon window available");
1542 XFlush (FRAME_X_DISPLAY (f
));
1547 x_set_icon_name (f
, arg
, oldval
)
1549 Lisp_Object arg
, oldval
;
1555 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1558 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1563 if (f
->output_data
.x
->icon_bitmap
!= 0)
1568 result
= x_text_icon (f
,
1569 (char *) SDATA ((!NILP (f
->icon_name
)
1578 error ("No icon window available");
1581 XFlush (FRAME_X_DISPLAY (f
));
1587 x_set_menu_bar_lines (f
, value
, oldval
)
1589 Lisp_Object value
, oldval
;
1592 #ifndef USE_X_TOOLKIT
1593 int olines
= FRAME_MENU_BAR_LINES (f
);
1596 /* Right now, menu bars don't work properly in minibuf-only frames;
1597 most of the commands try to apply themselves to the minibuffer
1598 frame itself, and get an error because you can't switch buffers
1599 in or split the minibuffer window. */
1600 if (FRAME_MINIBUF_ONLY_P (f
))
1603 if (INTEGERP (value
))
1604 nlines
= XINT (value
);
1608 /* Make sure we redisplay all windows in this frame. */
1609 windows_or_buffers_changed
++;
1611 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1612 FRAME_MENU_BAR_LINES (f
) = 0;
1615 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1616 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1617 /* Make sure next redisplay shows the menu bar. */
1618 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1622 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1623 free_frame_menubar (f
);
1624 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1626 f
->output_data
.x
->menubar_widget
= 0;
1628 #else /* not USE_X_TOOLKIT && not USE_GTK */
1629 FRAME_MENU_BAR_LINES (f
) = nlines
;
1630 change_window_heights (f
->root_window
, nlines
- olines
);
1631 #endif /* not USE_X_TOOLKIT */
1636 /* Set the number of lines used for the tool bar of frame F to VALUE.
1637 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1638 is the old number of tool bar lines. This function changes the
1639 height of all windows on frame F to match the new tool bar height.
1640 The frame's height doesn't change. */
1643 x_set_tool_bar_lines (f
, value
, oldval
)
1645 Lisp_Object value
, oldval
;
1647 int delta
, nlines
, root_height
;
1648 Lisp_Object root_window
;
1650 /* Treat tool bars like menu bars. */
1651 if (FRAME_MINIBUF_ONLY_P (f
))
1654 /* Use VALUE only if an integer >= 0. */
1655 if (INTEGERP (value
) && XINT (value
) >= 0)
1656 nlines
= XFASTINT (value
);
1661 FRAME_TOOL_BAR_LINES (f
) = 0;
1664 FRAME_EXTERNAL_TOOL_BAR (f
) = 1;
1665 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1666 /* Make sure next redisplay shows the tool bar. */
1667 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1668 update_frame_tool_bar (f
);
1672 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1673 free_frame_tool_bar (f
);
1674 FRAME_EXTERNAL_TOOL_BAR (f
) = 0;
1680 /* Make sure we redisplay all windows in this frame. */
1681 ++windows_or_buffers_changed
;
1683 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
1685 /* Don't resize the tool-bar to more than we have room for. */
1686 root_window
= FRAME_ROOT_WINDOW (f
);
1687 root_height
= WINDOW_TOTAL_LINES (XWINDOW (root_window
));
1688 if (root_height
- delta
< 1)
1690 delta
= root_height
- 1;
1691 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
1694 FRAME_TOOL_BAR_LINES (f
) = nlines
;
1695 change_window_heights (root_window
, delta
);
1698 /* We also have to make sure that the internal border at the top of
1699 the frame, below the menu bar or tool bar, is redrawn when the
1700 tool bar disappears. This is so because the internal border is
1701 below the tool bar if one is displayed, but is below the menu bar
1702 if there isn't a tool bar. The tool bar draws into the area
1703 below the menu bar. */
1704 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
1708 clear_current_matrices (f
);
1709 updating_frame
= NULL
;
1712 /* If the tool bar gets smaller, the internal border below it
1713 has to be cleared. It was formerly part of the display
1714 of the larger tool bar, and updating windows won't clear it. */
1717 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1718 int width
= FRAME_PIXEL_WIDTH (f
);
1719 int y
= nlines
* FRAME_LINE_HEIGHT (f
);
1722 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1723 0, y
, width
, height
, False
);
1726 if (WINDOWP (f
->tool_bar_window
))
1727 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1732 /* Set the foreground color for scroll bars on frame F to VALUE.
1733 VALUE should be a string, a color name. If it isn't a string or
1734 isn't a valid color name, do nothing. OLDVAL is the old value of
1735 the frame parameter. */
1738 x_set_scroll_bar_foreground (f
, value
, oldval
)
1740 Lisp_Object value
, oldval
;
1742 unsigned long pixel
;
1744 if (STRINGP (value
))
1745 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1749 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1750 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1752 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1753 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1755 /* Remove all scroll bars because they have wrong colors. */
1756 if (condemn_scroll_bars_hook
)
1757 (*condemn_scroll_bars_hook
) (f
);
1758 if (judge_scroll_bars_hook
)
1759 (*judge_scroll_bars_hook
) (f
);
1761 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1767 /* Set the background color for scroll bars on frame F to VALUE VALUE
1768 should be a string, a color name. If it isn't a string or isn't a
1769 valid color name, do nothing. OLDVAL is the old value of the frame
1773 x_set_scroll_bar_background (f
, value
, oldval
)
1775 Lisp_Object value
, oldval
;
1777 unsigned long pixel
;
1779 if (STRINGP (value
))
1780 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1784 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1785 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1787 #ifdef USE_TOOLKIT_SCROLL_BARS
1788 /* Scrollbar shadow colors. */
1789 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1791 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1792 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1794 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1796 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1797 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1799 #endif /* USE_TOOLKIT_SCROLL_BARS */
1801 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1802 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1804 /* Remove all scroll bars because they have wrong colors. */
1805 if (condemn_scroll_bars_hook
)
1806 (*condemn_scroll_bars_hook
) (f
);
1807 if (judge_scroll_bars_hook
)
1808 (*judge_scroll_bars_hook
) (f
);
1810 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1816 /* Encode Lisp string STRING as a text in a format appropriate for
1817 XICCC (X Inter Client Communication Conventions).
1819 If STRING contains only ASCII characters, do no conversion and
1820 return the string data of STRING. Otherwise, encode the text by
1821 CODING_SYSTEM, and return a newly allocated memory area which
1822 should be freed by `xfree' by a caller.
1824 SELECTIONP non-zero means the string is being encoded for an X
1825 selection, so it is safe to run pre-write conversions (which
1828 Store the byte length of resulting text in *TEXT_BYTES.
1830 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1831 which means that the `encoding' of the result can be `STRING'.
1832 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1833 the result should be `COMPOUND_TEXT'. */
1836 x_encode_text (string
, coding_system
, selectionp
, text_bytes
, stringp
)
1837 Lisp_Object string
, coding_system
;
1838 int *text_bytes
, *stringp
;
1841 unsigned char *str
= SDATA (string
);
1842 int chars
= SCHARS (string
);
1843 int bytes
= SBYTES (string
);
1847 struct coding_system coding
;
1848 extern Lisp_Object Qcompound_text_with_extensions
;
1850 charset_info
= find_charset_in_text (str
, chars
, bytes
, NULL
, Qnil
);
1851 if (charset_info
== 0)
1853 /* No multibyte character in OBJ. We need not encode it. */
1854 *text_bytes
= bytes
;
1859 setup_coding_system (coding_system
, &coding
);
1861 && SYMBOLP (coding
.pre_write_conversion
)
1862 && !NILP (Ffboundp (coding
.pre_write_conversion
)))
1864 string
= run_pre_post_conversion_on_str (string
, &coding
, 1);
1865 str
= SDATA (string
);
1866 chars
= SCHARS (string
);
1867 bytes
= SBYTES (string
);
1869 coding
.src_multibyte
= 1;
1870 coding
.dst_multibyte
= 0;
1871 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1872 if (coding
.type
== coding_type_iso2022
)
1873 coding
.flags
|= CODING_FLAG_ISO_SAFE
;
1874 /* We suppress producing escape sequences for composition. */
1875 coding
.composing
= COMPOSITION_DISABLED
;
1876 bufsize
= encoding_buffer_size (&coding
, bytes
);
1877 buf
= (unsigned char *) xmalloc (bufsize
);
1878 encode_coding (&coding
, str
, buf
, bytes
, bufsize
);
1879 *text_bytes
= coding
.produced
;
1880 *stringp
= (charset_info
== 1
1881 || (!EQ (coding_system
, Qcompound_text
)
1882 && !EQ (coding_system
, Qcompound_text_with_extensions
)));
1887 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1890 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1891 name; if NAME is a string, set F's name to NAME and set
1892 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1894 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1895 suggesting a new name, which lisp code should override; if
1896 F->explicit_name is set, ignore the new name; otherwise, set it. */
1899 x_set_name (f
, name
, explicit)
1904 /* Make sure that requests from lisp code override requests from
1905 Emacs redisplay code. */
1908 /* If we're switching from explicit to implicit, we had better
1909 update the mode lines and thereby update the title. */
1910 if (f
->explicit_name
&& NILP (name
))
1911 update_mode_lines
= 1;
1913 f
->explicit_name
= ! NILP (name
);
1915 else if (f
->explicit_name
)
1918 /* If NAME is nil, set the name to the x_id_name. */
1921 /* Check for no change needed in this very common case
1922 before we do any consing. */
1923 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1926 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1929 CHECK_STRING (name
);
1931 /* Don't change the name if it's already NAME. */
1932 if (! NILP (Fstring_equal (name
, f
->name
)))
1937 /* For setting the frame title, the title parameter should override
1938 the name parameter. */
1939 if (! NILP (f
->title
))
1942 if (FRAME_X_WINDOW (f
))
1947 XTextProperty text
, icon
;
1949 Lisp_Object coding_system
;
1951 /* Note: Encoding strategy
1953 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1954 text.encoding. But, there are non-internationalized window
1955 managers which don't support that encoding. So, if NAME
1956 contains only ASCII and 8859-1 characters, encode it by
1957 iso-latin-1, and use "STRING" in text.encoding hoping that
1958 such window managers at least analyze this format correctly,
1959 i.e. treat 8-bit bytes as 8859-1 characters.
1961 We may also be able to use "UTF8_STRING" in text.encoding
1962 in the future which can encode all Unicode characters.
1963 But, for the moment, there's no way to know that the
1964 current window manager supports it or not. */
1965 coding_system
= Qcompound_text
;
1966 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
1967 text
.encoding
= (stringp
? XA_STRING
1968 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1970 text
.nitems
= bytes
;
1972 if (NILP (f
->icon_name
))
1978 /* See the above comment "Note: Encoding strategy". */
1979 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
1981 icon
.encoding
= (stringp
? XA_STRING
1982 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1984 icon
.nitems
= bytes
;
1987 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1989 #else /* not USE_GTK */
1990 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1991 #endif /* not USE_GTK */
1993 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1995 if (!NILP (f
->icon_name
)
1996 && icon
.value
!= (unsigned char *) SDATA (f
->icon_name
))
1998 if (text
.value
!= (unsigned char *) SDATA (name
))
2001 #else /* not HAVE_X11R4 */
2002 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2004 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2006 #endif /* not HAVE_X11R4 */
2011 /* This function should be called when the user's lisp code has
2012 specified a name for the frame; the name will override any set by the
2015 x_explicitly_set_name (f
, arg
, oldval
)
2017 Lisp_Object arg
, oldval
;
2019 x_set_name (f
, arg
, 1);
2022 /* This function should be called by Emacs redisplay code to set the
2023 name; names set this way will never override names set by the user's
2026 x_implicitly_set_name (f
, arg
, oldval
)
2028 Lisp_Object arg
, oldval
;
2030 x_set_name (f
, arg
, 0);
2033 /* Change the title of frame F to NAME.
2034 If NAME is nil, use the frame name as the title.
2036 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2037 name; if NAME is a string, set F's name to NAME and set
2038 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2040 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2041 suggesting a new name, which lisp code should override; if
2042 F->explicit_name is set, ignore the new name; otherwise, set it. */
2045 x_set_title (f
, name
, old_name
)
2047 Lisp_Object name
, old_name
;
2049 /* Don't change the title if it's already NAME. */
2050 if (EQ (name
, f
->title
))
2053 update_mode_lines
= 1;
2060 CHECK_STRING (name
);
2062 if (FRAME_X_WINDOW (f
))
2067 XTextProperty text
, icon
;
2069 Lisp_Object coding_system
;
2071 coding_system
= Qcompound_text
;
2072 /* See the comment "Note: Encoding strategy" in x_set_name. */
2073 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
2074 text
.encoding
= (stringp
? XA_STRING
2075 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
2077 text
.nitems
= bytes
;
2079 if (NILP (f
->icon_name
))
2085 /* See the comment "Note: Encoding strategy" in x_set_name. */
2086 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
2088 icon
.encoding
= (stringp
? XA_STRING
2089 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
2091 icon
.nitems
= bytes
;
2095 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
2097 #else /* not USE_GTK */
2098 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
2099 #endif /* not USE_GTK */
2101 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
2104 if (!NILP (f
->icon_name
)
2105 && icon
.value
!= (unsigned char *) SDATA (f
->icon_name
))
2107 if (text
.value
!= (unsigned char *) SDATA (name
))
2110 #else /* not HAVE_X11R4 */
2111 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2113 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2115 #endif /* not HAVE_X11R4 */
2121 x_set_scroll_bar_default_width (f
)
2124 int wid
= FRAME_COLUMN_WIDTH (f
);
2126 #ifdef USE_TOOLKIT_SCROLL_BARS
2127 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
2128 int width
= 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
2129 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (width
+ wid
- 1) / wid
;
2130 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = width
;
2132 /* Make the actual width at least 14 pixels and a multiple of a
2134 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
2136 /* Use all of that space (aside from required margins) for the
2138 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 0;
2143 /* Record in frame F the specified or default value according to ALIST
2144 of the parameter named PROP (a Lisp symbol). If no value is
2145 specified for PROP, look for an X default for XPROP on the frame
2146 named NAME. If that is not found either, use the value DEFLT. */
2149 x_default_scroll_bar_color_parameter (f
, alist
, prop
, xprop
, xclass
,
2158 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2161 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
2162 if (EQ (tem
, Qunbound
))
2164 #ifdef USE_TOOLKIT_SCROLL_BARS
2166 /* See if an X resource for the scroll bar color has been
2168 tem
= display_x_get_resource (dpyinfo
,
2169 build_string (foreground_p
2173 build_string ("verticalScrollBar"),
2177 /* If nothing has been specified, scroll bars will use a
2178 toolkit-dependent default. Because these defaults are
2179 difficult to get at without actually creating a scroll
2180 bar, use nil to indicate that no color has been
2185 #else /* not USE_TOOLKIT_SCROLL_BARS */
2189 #endif /* not USE_TOOLKIT_SCROLL_BARS */
2192 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2198 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2201 XSetWMProtocols (dpy
, w
, protocols
, count
)
2208 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2209 if (prop
== None
) return False
;
2210 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2211 (unsigned char *) protocols
, count
);
2214 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2216 #ifdef USE_X_TOOLKIT
2218 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2219 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2220 already be present because of the toolkit (Motif adds some of them,
2221 for example, but Xt doesn't). */
2224 hack_wm_protocols (f
, widget
)
2228 Display
*dpy
= XtDisplay (widget
);
2229 Window w
= XtWindow (widget
);
2230 int need_delete
= 1;
2236 Atom type
, *atoms
= 0;
2238 unsigned long nitems
= 0;
2239 unsigned long bytes_after
;
2241 if ((XGetWindowProperty (dpy
, w
,
2242 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2243 (long)0, (long)100, False
, XA_ATOM
,
2244 &type
, &format
, &nitems
, &bytes_after
,
2245 (unsigned char **) &atoms
)
2247 && format
== 32 && type
== XA_ATOM
)
2251 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2253 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2255 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2258 if (atoms
) XFree ((char *) atoms
);
2264 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2266 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2268 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2270 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2271 XA_ATOM
, 32, PropModeAppend
,
2272 (unsigned char *) props
, count
);
2280 /* Support routines for XIC (X Input Context). */
2284 static XFontSet xic_create_xfontset
P_ ((struct frame
*, char *));
2285 static XIMStyle best_xim_style
P_ ((XIMStyles
*, XIMStyles
*));
2288 /* Supported XIM styles, ordered by preference. */
2290 static XIMStyle supported_xim_styles
[] =
2292 XIMPreeditPosition
| XIMStatusArea
,
2293 XIMPreeditPosition
| XIMStatusNothing
,
2294 XIMPreeditPosition
| XIMStatusNone
,
2295 XIMPreeditNothing
| XIMStatusArea
,
2296 XIMPreeditNothing
| XIMStatusNothing
,
2297 XIMPreeditNothing
| XIMStatusNone
,
2298 XIMPreeditNone
| XIMStatusArea
,
2299 XIMPreeditNone
| XIMStatusNothing
,
2300 XIMPreeditNone
| XIMStatusNone
,
2305 /* Create an X fontset on frame F with base font name
2309 xic_create_xfontset (f
, base_fontname
)
2311 char *base_fontname
;
2314 char **missing_list
;
2318 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
2319 base_fontname
, &missing_list
,
2320 &missing_count
, &def_string
);
2322 XFreeStringList (missing_list
);
2324 /* No need to free def_string. */
2329 /* Value is the best input style, given user preferences USER (already
2330 checked to be supported by Emacs), and styles supported by the
2331 input method XIM. */
2334 best_xim_style (user
, xim
)
2340 for (i
= 0; i
< user
->count_styles
; ++i
)
2341 for (j
= 0; j
< xim
->count_styles
; ++j
)
2342 if (user
->supported_styles
[i
] == xim
->supported_styles
[j
])
2343 return user
->supported_styles
[i
];
2345 /* Return the default style. */
2346 return XIMPreeditNothing
| XIMStatusNothing
;
2349 /* Create XIC for frame F. */
2351 static XIMStyle xic_style
;
2354 create_frame_xic (f
)
2359 XFontSet xfs
= NULL
;
2364 xim
= FRAME_X_XIM (f
);
2369 XVaNestedList preedit_attr
;
2370 XVaNestedList status_attr
;
2371 char *base_fontname
;
2374 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2375 spot
.x
= 0; spot
.y
= 1;
2376 /* Create X fontset. */
2377 fontset
= FRAME_FONTSET (f
);
2379 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2382 /* Determine the base fontname from the ASCII font name of
2384 char *ascii_font
= (char *) SDATA (fontset_ascii (fontset
));
2385 char *p
= ascii_font
;
2388 for (i
= 0; *p
; p
++)
2391 /* As the font name doesn't conform to XLFD, we can't
2392 modify it to get a suitable base fontname for the
2394 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2397 int len
= strlen (ascii_font
) + 1;
2400 for (i
= 0, p
= ascii_font
; i
< 8; p
++)
2409 base_fontname
= (char *) alloca (len
);
2410 bzero (base_fontname
, len
);
2411 strcpy (base_fontname
, "-*-*-");
2412 bcopy (p1
, base_fontname
+ 5, p
- p1
);
2413 strcat (base_fontname
, "*-*-*-*-*-*-*");
2416 xfs
= xic_create_xfontset (f
, base_fontname
);
2418 /* Determine XIC style. */
2421 XIMStyles supported_list
;
2422 supported_list
.count_styles
= (sizeof supported_xim_styles
2423 / sizeof supported_xim_styles
[0]);
2424 supported_list
.supported_styles
= supported_xim_styles
;
2425 xic_style
= best_xim_style (&supported_list
,
2426 FRAME_X_XIM_STYLES (f
));
2429 preedit_attr
= XVaCreateNestedList (0,
2432 FRAME_FOREGROUND_PIXEL (f
),
2434 FRAME_BACKGROUND_PIXEL (f
),
2435 (xic_style
& XIMPreeditPosition
2440 status_attr
= XVaCreateNestedList (0,
2446 FRAME_FOREGROUND_PIXEL (f
),
2448 FRAME_BACKGROUND_PIXEL (f
),
2451 xic
= XCreateIC (xim
,
2452 XNInputStyle
, xic_style
,
2453 XNClientWindow
, FRAME_X_WINDOW(f
),
2454 XNFocusWindow
, FRAME_X_WINDOW(f
),
2455 XNStatusAttributes
, status_attr
,
2456 XNPreeditAttributes
, preedit_attr
,
2458 XFree (preedit_attr
);
2459 XFree (status_attr
);
2462 FRAME_XIC (f
) = xic
;
2463 FRAME_XIC_STYLE (f
) = xic_style
;
2464 FRAME_XIC_FONTSET (f
) = xfs
;
2468 /* Destroy XIC and free XIC fontset of frame F, if any. */
2474 if (FRAME_XIC (f
) == NULL
)
2477 XDestroyIC (FRAME_XIC (f
));
2478 if (FRAME_XIC_FONTSET (f
))
2479 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2481 FRAME_XIC (f
) = NULL
;
2482 FRAME_XIC_FONTSET (f
) = NULL
;
2486 /* Place preedit area for XIC of window W's frame to specified
2487 pixel position X/Y. X and Y are relative to window W. */
2490 xic_set_preeditarea (w
, x
, y
)
2494 struct frame
*f
= XFRAME (w
->frame
);
2498 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2499 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2500 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2501 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2506 /* Place status area for XIC in bottom right corner of frame F.. */
2509 xic_set_statusarea (f
)
2512 XIC xic
= FRAME_XIC (f
);
2517 /* Negotiate geometry of status area. If input method has existing
2518 status area, use its current size. */
2519 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2520 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2521 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2524 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2525 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2528 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2530 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2531 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2535 area
.width
= needed
->width
;
2536 area
.height
= needed
->height
;
2537 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2538 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2539 - FRAME_MENUBAR_HEIGHT (f
)
2540 - FRAME_TOOLBAR_HEIGHT (f
)
2541 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2544 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2545 XSetICValues(xic
, XNStatusAttributes
, attr
, NULL
);
2550 /* Set X fontset for XIC of frame F, using base font name
2551 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2554 xic_set_xfontset (f
, base_fontname
)
2556 char *base_fontname
;
2561 xfs
= xic_create_xfontset (f
, base_fontname
);
2563 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2564 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2565 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2566 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2567 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2570 if (FRAME_XIC_FONTSET (f
))
2571 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2572 FRAME_XIC_FONTSET (f
) = xfs
;
2575 #endif /* HAVE_X_I18N */
2579 #ifdef USE_X_TOOLKIT
2581 /* Create and set up the X widget for frame F. */
2584 x_window (f
, window_prompting
, minibuffer_only
)
2586 long window_prompting
;
2587 int minibuffer_only
;
2589 XClassHint class_hints
;
2590 XSetWindowAttributes attributes
;
2591 unsigned long attribute_mask
;
2592 Widget shell_widget
;
2594 Widget frame_widget
;
2600 /* Use the resource name as the top-level widget name
2601 for looking up resources. Make a non-Lisp copy
2602 for the window manager, so GC relocation won't bother it.
2604 Elsewhere we specify the window name for the window manager. */
2607 char *str
= (char *) SDATA (Vx_resource_name
);
2608 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2609 strcpy (f
->namebuf
, str
);
2613 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2614 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2615 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2616 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2617 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2618 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2619 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2620 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2621 applicationShellWidgetClass
,
2622 FRAME_X_DISPLAY (f
), al
, ac
);
2624 f
->output_data
.x
->widget
= shell_widget
;
2625 /* maybe_set_screen_title_format (shell_widget); */
2627 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2628 (widget_value
*) NULL
,
2629 shell_widget
, False
,
2633 (lw_callback
) NULL
);
2636 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2637 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2638 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2639 XtSetValues (pane_widget
, al
, ac
);
2640 f
->output_data
.x
->column_widget
= pane_widget
;
2642 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2643 the emacs screen when changing menubar. This reduces flickering. */
2646 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2647 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2648 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2649 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2650 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2651 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2652 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2653 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2654 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2657 f
->output_data
.x
->edit_widget
= frame_widget
;
2659 XtManageChild (frame_widget
);
2661 /* Do some needed geometry management. */
2664 char *tem
, shell_position
[32];
2667 int extra_borders
= 0;
2669 = (f
->output_data
.x
->menubar_widget
2670 ? (f
->output_data
.x
->menubar_widget
->core
.height
2671 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2674 #if 0 /* Experimentally, we now get the right results
2675 for -geometry -0-0 without this. 24 Aug 96, rms. */
2676 if (FRAME_EXTERNAL_MENU_BAR (f
))
2679 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2680 menubar_size
+= ibw
;
2684 f
->output_data
.x
->menubar_height
= menubar_size
;
2687 /* Motif seems to need this amount added to the sizes
2688 specified for the shell widget. The Athena/Lucid widgets don't.
2689 Both conclusions reached experimentally. -- rms. */
2690 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2691 &extra_borders
, NULL
);
2695 /* Convert our geometry parameters into a geometry string
2697 Note that we do not specify here whether the position
2698 is a user-specified or program-specified one.
2699 We pass that information later, in x_wm_set_size_hints. */
2701 int left
= f
->left_pos
;
2702 int xneg
= window_prompting
& XNegative
;
2703 int top
= f
->top_pos
;
2704 int yneg
= window_prompting
& YNegative
;
2710 if (window_prompting
& USPosition
)
2711 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2712 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2713 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2714 (xneg
? '-' : '+'), left
,
2715 (yneg
? '-' : '+'), top
);
2717 sprintf (shell_position
, "=%dx%d",
2718 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2719 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2722 len
= strlen (shell_position
) + 1;
2723 /* We don't free this because we don't know whether
2724 it is safe to free it while the frame exists.
2725 It isn't worth the trouble of arranging to free it
2726 when the frame is deleted. */
2727 tem
= (char *) xmalloc (len
);
2728 strncpy (tem
, shell_position
, len
);
2729 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2730 XtSetValues (shell_widget
, al
, ac
);
2733 XtManageChild (pane_widget
);
2734 XtRealizeWidget (shell_widget
);
2736 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2738 validate_x_resource_name ();
2740 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2741 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2742 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2745 FRAME_XIC (f
) = NULL
;
2747 create_frame_xic (f
);
2750 f
->output_data
.x
->wm_hints
.input
= True
;
2751 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2752 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2753 &f
->output_data
.x
->wm_hints
);
2755 hack_wm_protocols (f
, shell_widget
);
2758 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2761 /* Do a stupid property change to force the server to generate a
2762 PropertyNotify event so that the event_stream server timestamp will
2763 be initialized to something relevant to the time we created the window.
2765 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2766 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2767 XA_ATOM
, 32, PropModeAppend
,
2768 (unsigned char*) NULL
, 0);
2770 /* Make all the standard events reach the Emacs frame. */
2771 attributes
.event_mask
= STANDARD_EVENT_SET
;
2776 /* XIM server might require some X events. */
2777 unsigned long fevent
= NoEventMask
;
2778 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2779 attributes
.event_mask
|= fevent
;
2781 #endif /* HAVE_X_I18N */
2783 attribute_mask
= CWEventMask
;
2784 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2785 attribute_mask
, &attributes
);
2787 XtMapWidget (frame_widget
);
2789 /* x_set_name normally ignores requests to set the name if the
2790 requested name is the same as the current name. This is the one
2791 place where that assumption isn't correct; f->name is set, but
2792 the X server hasn't been told. */
2795 int explicit = f
->explicit_name
;
2797 f
->explicit_name
= 0;
2800 x_set_name (f
, name
, explicit);
2803 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2804 f
->output_data
.x
->text_cursor
);
2808 /* This is a no-op, except under Motif. Make sure main areas are
2809 set to something reasonable, in case we get an error later. */
2810 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2813 #else /* not USE_X_TOOLKIT */
2819 if (! xg_create_frame_widgets (f
))
2820 error ("Unable to create window");
2823 FRAME_XIC (f
) = NULL
;
2827 create_frame_xic (f
);
2830 /* XIM server might require some X events. */
2831 unsigned long fevent
= NoEventMask
;
2832 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2834 if (fevent
!= NoEventMask
)
2836 XSetWindowAttributes attributes
;
2837 XWindowAttributes wattr
;
2838 unsigned long attribute_mask
;
2840 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2842 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2843 attribute_mask
= CWEventMask
;
2844 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2845 attribute_mask
, &attributes
);
2853 #else /*! USE_GTK */
2854 /* Create and set up the X window for frame F. */
2861 XClassHint class_hints
;
2862 XSetWindowAttributes attributes
;
2863 unsigned long attribute_mask
;
2865 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2866 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2867 attributes
.bit_gravity
= StaticGravity
;
2868 attributes
.backing_store
= NotUseful
;
2869 attributes
.save_under
= True
;
2870 attributes
.event_mask
= STANDARD_EVENT_SET
;
2871 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2872 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2877 = XCreateWindow (FRAME_X_DISPLAY (f
),
2878 f
->output_data
.x
->parent_desc
,
2881 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2883 CopyFromParent
, /* depth */
2884 InputOutput
, /* class */
2886 attribute_mask
, &attributes
);
2891 create_frame_xic (f
);
2894 /* XIM server might require some X events. */
2895 unsigned long fevent
= NoEventMask
;
2896 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2897 attributes
.event_mask
|= fevent
;
2898 attribute_mask
= CWEventMask
;
2899 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2900 attribute_mask
, &attributes
);
2903 #endif /* HAVE_X_I18N */
2905 validate_x_resource_name ();
2907 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2908 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2909 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2911 /* The menubar is part of the ordinary display;
2912 it does not count in addition to the height of the window. */
2913 f
->output_data
.x
->menubar_height
= 0;
2915 /* This indicates that we use the "Passive Input" input model.
2916 Unless we do this, we don't get the Focus{In,Out} events that we
2917 need to draw the cursor correctly. Accursed bureaucrats.
2918 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2920 f
->output_data
.x
->wm_hints
.input
= True
;
2921 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2922 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2923 &f
->output_data
.x
->wm_hints
);
2924 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2926 /* Request "save yourself" and "delete window" commands from wm. */
2929 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2930 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2931 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2934 /* x_set_name normally ignores requests to set the name if the
2935 requested name is the same as the current name. This is the one
2936 place where that assumption isn't correct; f->name is set, but
2937 the X server hasn't been told. */
2940 int explicit = f
->explicit_name
;
2942 f
->explicit_name
= 0;
2945 x_set_name (f
, name
, explicit);
2948 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2949 f
->output_data
.x
->text_cursor
);
2953 if (FRAME_X_WINDOW (f
) == 0)
2954 error ("Unable to create window");
2957 #endif /* not USE_GTK */
2958 #endif /* not USE_X_TOOLKIT */
2960 /* Handle the icon stuff for this window. Perhaps later we might
2961 want an x_set_icon_position which can be called interactively as
2969 Lisp_Object icon_x
, icon_y
;
2970 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2972 /* Set the position of the icon. Note that twm groups all
2973 icons in an icon window. */
2974 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2975 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2976 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2978 CHECK_NUMBER (icon_x
);
2979 CHECK_NUMBER (icon_y
);
2981 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2982 error ("Both left and top icon corners of icon must be specified");
2986 if (! EQ (icon_x
, Qunbound
))
2987 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2989 /* Start up iconic or window? */
2990 x_wm_set_window_state
2991 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2996 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
3003 /* Make the GCs needed for this window, setting the
3004 background, border and mouse colors; also create the
3005 mouse cursor and the gray border tile. */
3007 static char cursor_bits
[] =
3009 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3010 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3011 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3012 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3019 XGCValues gc_values
;
3023 /* Create the GCs of this frame.
3024 Note that many default values are used. */
3027 gc_values
.font
= FRAME_FONT (f
)->fid
;
3028 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
3029 gc_values
.background
= f
->output_data
.x
->background_pixel
;
3030 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
3031 f
->output_data
.x
->normal_gc
3032 = XCreateGC (FRAME_X_DISPLAY (f
),
3034 GCLineWidth
| GCFont
| GCForeground
| GCBackground
,
3037 /* Reverse video style. */
3038 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3039 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
3040 f
->output_data
.x
->reverse_gc
3041 = XCreateGC (FRAME_X_DISPLAY (f
),
3043 GCFont
| GCForeground
| GCBackground
| GCLineWidth
,
3046 /* Cursor has cursor-color background, background-color foreground. */
3047 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3048 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
3049 gc_values
.fill_style
= FillOpaqueStippled
;
3051 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
3052 FRAME_X_DISPLAY_INFO (f
)->root_window
,
3053 cursor_bits
, 16, 16);
3054 f
->output_data
.x
->cursor_gc
3055 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3056 (GCFont
| GCForeground
| GCBackground
3057 | GCFillStyle
/* | GCStipple */ | GCLineWidth
),
3061 f
->output_data
.x
->white_relief
.gc
= 0;
3062 f
->output_data
.x
->black_relief
.gc
= 0;
3064 /* Create the gray border tile used when the pointer is not in
3065 the frame. Since this depends on the frame's pixel values,
3066 this must be done on a per-frame basis. */
3067 f
->output_data
.x
->border_tile
3068 = (XCreatePixmapFromBitmapData
3069 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
3070 gray_bits
, gray_width
, gray_height
,
3071 f
->output_data
.x
->foreground_pixel
,
3072 f
->output_data
.x
->background_pixel
,
3073 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
3079 /* Free what was was allocated in x_make_gc. */
3085 Display
*dpy
= FRAME_X_DISPLAY (f
);
3089 if (f
->output_data
.x
->normal_gc
)
3091 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
3092 f
->output_data
.x
->normal_gc
= 0;
3095 if (f
->output_data
.x
->reverse_gc
)
3097 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
3098 f
->output_data
.x
->reverse_gc
= 0;
3101 if (f
->output_data
.x
->cursor_gc
)
3103 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
3104 f
->output_data
.x
->cursor_gc
= 0;
3107 if (f
->output_data
.x
->border_tile
)
3109 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
3110 f
->output_data
.x
->border_tile
= 0;
3117 /* Handler for signals raised during x_create_frame and
3118 x_create_top_frame. FRAME is the frame which is partially
3122 unwind_create_frame (frame
)
3125 struct frame
*f
= XFRAME (frame
);
3127 /* If frame is ``official'', nothing to do. */
3128 if (!CONSP (Vframe_list
) || !EQ (XCAR (Vframe_list
), frame
))
3131 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3134 x_free_frame_resources (f
);
3136 /* Check that reference counts are indeed correct. */
3137 xassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
3138 xassert (dpyinfo
->image_cache
->refcount
== image_cache_refcount
);
3146 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3148 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
3149 Returns an Emacs frame object.
3150 ALIST is an alist of frame parameters.
3151 If the parameters specify that the frame should not have a minibuffer,
3152 and do not specify a specific minibuffer window to use,
3153 then `default-minibuffer-frame' must be a frame whose minibuffer can
3154 be shared by the new frame.
3156 This function is an internal primitive--use `make-frame' instead. */)
3161 Lisp_Object frame
, tem
;
3163 int minibuffer_only
= 0;
3164 long window_prompting
= 0;
3166 int count
= SPECPDL_INDEX ();
3167 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3168 Lisp_Object display
;
3169 struct x_display_info
*dpyinfo
= NULL
;
3175 /* Use this general default value to start with
3176 until we know if this frame has a specified name. */
3177 Vx_resource_name
= Vinvocation_name
;
3179 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3180 if (EQ (display
, Qunbound
))
3182 dpyinfo
= check_x_display_info (display
);
3184 kb
= dpyinfo
->kboard
;
3186 kb
= &the_only_kboard
;
3189 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3191 && ! EQ (name
, Qunbound
)
3193 error ("Invalid frame name--not a string or nil");
3196 Vx_resource_name
= name
;
3198 /* See if parent window is specified. */
3199 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3200 if (EQ (parent
, Qunbound
))
3202 if (! NILP (parent
))
3203 CHECK_NUMBER (parent
);
3205 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3206 /* No need to protect DISPLAY because that's not used after passing
3207 it to make_frame_without_minibuffer. */
3209 GCPRO4 (parms
, parent
, name
, frame
);
3210 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3212 if (EQ (tem
, Qnone
) || NILP (tem
))
3213 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3214 else if (EQ (tem
, Qonly
))
3216 f
= make_minibuffer_frame ();
3217 minibuffer_only
= 1;
3219 else if (WINDOWP (tem
))
3220 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3224 XSETFRAME (frame
, f
);
3226 /* Note that X Windows does support scroll bars. */
3227 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3229 f
->output_method
= output_x_window
;
3230 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3231 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3232 f
->output_data
.x
->icon_bitmap
= -1;
3233 FRAME_FONTSET (f
) = -1;
3234 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3235 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3236 #ifdef USE_TOOLKIT_SCROLL_BARS
3237 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3238 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3239 #endif /* USE_TOOLKIT_SCROLL_BARS */
3240 record_unwind_protect (unwind_create_frame
, frame
);
3243 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3245 if (! STRINGP (f
->icon_name
))
3246 f
->icon_name
= Qnil
;
3248 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3250 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
3251 dpyinfo_refcount
= dpyinfo
->reference_count
;
3252 #endif /* GLYPH_DEBUG */
3254 FRAME_KBOARD (f
) = kb
;
3257 /* These colors will be set anyway later, but it's important
3258 to get the color reference counts right, so initialize them! */
3261 struct gcpro gcpro1
;
3263 /* Function x_decode_color can signal an error. Make
3264 sure to initialize color slots so that we won't try
3265 to free colors we haven't allocated. */
3266 f
->output_data
.x
->foreground_pixel
= -1;
3267 f
->output_data
.x
->background_pixel
= -1;
3268 f
->output_data
.x
->cursor_pixel
= -1;
3269 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3270 f
->output_data
.x
->border_pixel
= -1;
3271 f
->output_data
.x
->mouse_pixel
= -1;
3273 black
= build_string ("black");
3275 f
->output_data
.x
->foreground_pixel
3276 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3277 f
->output_data
.x
->background_pixel
3278 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3279 f
->output_data
.x
->cursor_pixel
3280 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3281 f
->output_data
.x
->cursor_foreground_pixel
3282 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3283 f
->output_data
.x
->border_pixel
3284 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3285 f
->output_data
.x
->mouse_pixel
3286 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3290 /* Specify the parent under which to make this X window. */
3294 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3295 f
->output_data
.x
->explicit_parent
= 1;
3299 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3300 f
->output_data
.x
->explicit_parent
= 0;
3303 /* Set the name; the functions to which we pass f expect the name to
3305 if (EQ (name
, Qunbound
) || NILP (name
))
3307 f
->name
= build_string (dpyinfo
->x_id_name
);
3308 f
->explicit_name
= 0;
3313 f
->explicit_name
= 1;
3314 /* use the frame's title when getting resources for this frame. */
3315 specbind (Qx_resource_name
, name
);
3318 /* Extract the window parameters from the supplied values
3319 that are needed to determine window geometry. */
3323 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3326 /* First, try whatever font the caller has specified. */
3329 tem
= Fquery_fontset (font
, Qnil
);
3331 font
= x_new_fontset (f
, SDATA (tem
));
3333 font
= x_new_font (f
, SDATA (font
));
3336 /* Try out a font which we hope has bold and italic variations. */
3337 if (!STRINGP (font
))
3338 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
3339 if (!STRINGP (font
))
3340 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3341 if (! STRINGP (font
))
3342 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3343 if (! STRINGP (font
))
3344 /* This was formerly the first thing tried, but it finds too many fonts
3345 and takes too long. */
3346 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3347 /* If those didn't work, look for something which will at least work. */
3348 if (! STRINGP (font
))
3349 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3351 if (! STRINGP (font
))
3352 font
= build_string ("fixed");
3354 x_default_parameter (f
, parms
, Qfont
, font
,
3355 "font", "Font", RES_TYPE_STRING
);
3359 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3360 whereby it fails to get any font. */
3361 xlwmenu_default_font
= FRAME_FONT (f
);
3364 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3365 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3367 /* This defaults to 1 in order to match xterm. We recognize either
3368 internalBorderWidth or internalBorder (which is what xterm calls
3370 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3374 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3375 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3376 if (! EQ (value
, Qunbound
))
3377 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3380 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3381 "internalBorderWidth", "internalBorderWidth",
3383 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3384 "verticalScrollBars", "ScrollBars",
3387 /* Also do the stuff which must be set before the window exists. */
3388 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3389 "foreground", "Foreground", RES_TYPE_STRING
);
3390 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3391 "background", "Background", RES_TYPE_STRING
);
3392 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3393 "pointerColor", "Foreground", RES_TYPE_STRING
);
3394 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3395 "cursorColor", "Foreground", RES_TYPE_STRING
);
3396 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3397 "borderColor", "BorderColor", RES_TYPE_STRING
);
3398 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3399 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3400 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3401 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3402 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3403 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3404 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3405 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3407 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3408 "scrollBarForeground",
3409 "ScrollBarForeground", 1);
3410 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3411 "scrollBarBackground",
3412 "ScrollBarBackground", 0);
3414 /* Init faces before x_default_parameter is called for scroll-bar
3415 parameters because that function calls x_set_scroll_bar_width,
3416 which calls change_frame_size, which calls Fset_window_buffer,
3417 which runs hooks, which call Fvertical_motion. At the end, we
3418 end up in init_iterator with a null face cache, which should not
3420 init_frame_faces (f
);
3422 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3423 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3424 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (1),
3425 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3426 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3427 "bufferPredicate", "BufferPredicate",
3429 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3430 "title", "Title", RES_TYPE_STRING
);
3431 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3432 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3433 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3434 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3436 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3438 /* Compute the size of the X window. */
3439 window_prompting
= x_figure_window_size (f
, parms
, 1);
3441 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3442 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3444 /* Create the X widget or window. */
3445 #ifdef USE_X_TOOLKIT
3446 x_window (f
, window_prompting
, minibuffer_only
);
3454 /* Now consider the frame official. */
3455 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3456 Vframe_list
= Fcons (frame
, Vframe_list
);
3458 /* We need to do this after creating the X window, so that the
3459 icon-creation functions can say whose icon they're describing. */
3460 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3461 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
3463 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3464 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3465 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3466 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3467 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3468 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3469 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3470 "scrollBarWidth", "ScrollBarWidth",
3473 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3474 Change will not be effected unless different from the current
3476 width
= FRAME_COLS (f
);
3477 height
= FRAME_LINES (f
);
3479 SET_FRAME_COLS (f
, 0);
3480 FRAME_LINES (f
) = 0;
3481 change_frame_size (f
, height
, width
, 1, 0, 0);
3483 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3484 /* Create the menu bar. */
3485 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3487 /* If this signals an error, we haven't set size hints for the
3488 frame and we didn't make it visible. */
3489 initialize_frame_menubar (f
);
3492 /* This is a no-op, except under Motif where it arranges the
3493 main window for the widgets on it. */
3494 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3495 f
->output_data
.x
->menubar_widget
,
3496 f
->output_data
.x
->edit_widget
);
3497 #endif /* not USE_GTK */
3499 #endif /* USE_X_TOOLKIT || USE_GTK */
3501 /* Tell the server what size and position, etc, we want, and how
3502 badly we want them. This should be done after we have the menu
3503 bar so that its size can be taken into account. */
3505 x_wm_set_size_hint (f
, window_prompting
, 0);
3508 /* Make the window appear on the frame and enable display, unless
3509 the caller says not to. However, with explicit parent, Emacs
3510 cannot control visibility, so don't try. */
3511 if (! f
->output_data
.x
->explicit_parent
)
3513 Lisp_Object visibility
;
3515 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3517 if (EQ (visibility
, Qunbound
))
3520 if (EQ (visibility
, Qicon
))
3521 x_iconify_frame (f
);
3522 else if (! NILP (visibility
))
3523 x_make_frame_visible (f
);
3525 /* Must have been Qnil. */
3529 /* Set the WM leader property. GTK does this itself, so this is not
3530 needed when using GTK. */
3531 if (dpyinfo
->client_leader_window
!= 0)
3534 XChangeProperty (FRAME_X_DISPLAY (f
),
3535 FRAME_OUTER_WINDOW (f
),
3536 dpyinfo
->Xatom_wm_client_leader
,
3537 XA_WINDOW
, 32, PropModeReplace
,
3538 (char *) &dpyinfo
->client_leader_window
, 1);
3544 /* Make sure windows on this frame appear in calls to next-window
3545 and similar functions. */
3546 Vwindow_list
= Qnil
;
3548 return unbind_to (count
, frame
);
3552 /* FRAME is used only to get a handle on the X display. We don't pass the
3553 display info directly because we're called from frame.c, which doesn't
3554 know about that structure. */
3557 x_get_focus_frame (frame
)
3558 struct frame
*frame
;
3560 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3562 if (! dpyinfo
->x_focus_frame
)
3565 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3570 /* In certain situations, when the window manager follows a
3571 click-to-focus policy, there seems to be no way around calling
3572 XSetInputFocus to give another frame the input focus .
3574 In an ideal world, XSetInputFocus should generally be avoided so
3575 that applications don't interfere with the window manager's focus
3576 policy. But I think it's okay to use when it's clearly done
3577 following a user-command. */
3579 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
3580 doc
: /* Set the input focus to FRAME.
3581 FRAME nil means use the selected frame. */)
3585 struct frame
*f
= check_x_frame (frame
);
3586 Display
*dpy
= FRAME_X_DISPLAY (f
);
3590 count
= x_catch_errors (dpy
);
3591 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3592 RevertToParent
, CurrentTime
);
3593 x_uncatch_errors (dpy
, count
);
3600 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3601 doc
: /* Internal function called by `color-defined-p', which see. */)
3603 Lisp_Object color
, frame
;
3606 FRAME_PTR f
= check_x_frame (frame
);
3608 CHECK_STRING (color
);
3610 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3616 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3617 doc
: /* Internal function called by `color-values', which see. */)
3619 Lisp_Object color
, frame
;
3622 FRAME_PTR f
= check_x_frame (frame
);
3624 CHECK_STRING (color
);
3626 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3630 rgb
[0] = make_number (foo
.red
);
3631 rgb
[1] = make_number (foo
.green
);
3632 rgb
[2] = make_number (foo
.blue
);
3633 return Flist (3, rgb
);
3639 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3640 doc
: /* Internal function called by `display-color-p', which see. */)
3642 Lisp_Object display
;
3644 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3646 if (dpyinfo
->n_planes
<= 2)
3649 switch (dpyinfo
->visual
->class)
3662 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3664 doc
: /* Return t if the X display supports shades of gray.
3665 Note that color displays do support shades of gray.
3666 The optional argument DISPLAY specifies which display to ask about.
3667 DISPLAY should be either a frame or a display name (a string).
3668 If omitted or nil, that stands for the selected frame's display. */)
3670 Lisp_Object display
;
3672 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3674 if (dpyinfo
->n_planes
<= 1)
3677 switch (dpyinfo
->visual
->class)
3692 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3694 doc
: /* Returns the width in pixels of the X display DISPLAY.
3695 The optional argument DISPLAY specifies which display to ask about.
3696 DISPLAY should be either a frame or a display name (a string).
3697 If omitted or nil, that stands for the selected frame's display. */)
3699 Lisp_Object display
;
3701 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3703 return make_number (dpyinfo
->width
);
3706 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3707 Sx_display_pixel_height
, 0, 1, 0,
3708 doc
: /* Returns the height in pixels of the X display DISPLAY.
3709 The optional argument DISPLAY specifies which display to ask about.
3710 DISPLAY should be either a frame or a display name (a string).
3711 If omitted or nil, that stands for the selected frame's display. */)
3713 Lisp_Object display
;
3715 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3717 return make_number (dpyinfo
->height
);
3720 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3722 doc
: /* Returns the number of bitplanes of the X display DISPLAY.
3723 The optional argument DISPLAY specifies which display to ask about.
3724 DISPLAY should be either a frame or a display name (a string).
3725 If omitted or nil, that stands for the selected frame's display. */)
3727 Lisp_Object display
;
3729 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3731 return make_number (dpyinfo
->n_planes
);
3734 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3736 doc
: /* Returns the number of color cells of the X display DISPLAY.
3737 The optional argument DISPLAY specifies which display to ask about.
3738 DISPLAY should be either a frame or a display name (a string).
3739 If omitted or nil, that stands for the selected frame's display. */)
3741 Lisp_Object display
;
3743 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3745 return make_number (DisplayCells (dpyinfo
->display
,
3746 XScreenNumberOfScreen (dpyinfo
->screen
)));
3749 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3750 Sx_server_max_request_size
,
3752 doc
: /* Returns the maximum request size of the X server of display DISPLAY.
3753 The optional argument DISPLAY specifies which display to ask about.
3754 DISPLAY should be either a frame or a display name (a string).
3755 If omitted or nil, that stands for the selected frame's display. */)
3757 Lisp_Object display
;
3759 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3761 return make_number (MAXREQUEST (dpyinfo
->display
));
3764 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3765 doc
: /* Returns the vendor ID string of the X server of display DISPLAY.
3766 The optional argument DISPLAY specifies which display to ask about.
3767 DISPLAY should be either a frame or a display name (a string).
3768 If omitted or nil, that stands for the selected frame's display. */)
3770 Lisp_Object display
;
3772 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3773 char *vendor
= ServerVendor (dpyinfo
->display
);
3775 if (! vendor
) vendor
= "";
3776 return build_string (vendor
);
3779 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3780 doc
: /* Returns the version numbers of the X server of display DISPLAY.
3781 The value is a list of three integers: the major and minor
3782 version numbers of the X Protocol in use, and the vendor-specific release
3783 number. See also the function `x-server-vendor'.
3785 The optional argument DISPLAY specifies which display to ask about.
3786 DISPLAY should be either a frame or a display name (a string).
3787 If omitted or nil, that stands for the selected frame's display. */)
3789 Lisp_Object display
;
3791 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3792 Display
*dpy
= dpyinfo
->display
;
3794 return Fcons (make_number (ProtocolVersion (dpy
)),
3795 Fcons (make_number (ProtocolRevision (dpy
)),
3796 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3799 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3800 doc
: /* Return the number of screens on the X server of display DISPLAY.
3801 The optional argument DISPLAY specifies which display to ask about.
3802 DISPLAY should be either a frame or a display name (a string).
3803 If omitted or nil, that stands for the selected frame's display. */)
3805 Lisp_Object display
;
3807 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3809 return make_number (ScreenCount (dpyinfo
->display
));
3812 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3813 doc
: /* Return the height in millimeters of the X display DISPLAY.
3814 The optional argument DISPLAY specifies which display to ask about.
3815 DISPLAY should be either a frame or a display name (a string).
3816 If omitted or nil, that stands for the selected frame's display. */)
3818 Lisp_Object display
;
3820 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3822 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3825 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3826 doc
: /* Return the width in millimeters of the X display DISPLAY.
3827 The optional argument DISPLAY specifies which display to ask about.
3828 DISPLAY should be either a frame or a display name (a string).
3829 If omitted or nil, that stands for the selected frame's display. */)
3831 Lisp_Object display
;
3833 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3835 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3838 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3839 Sx_display_backing_store
, 0, 1, 0,
3840 doc
: /* Returns an indication of whether X display DISPLAY does backing store.
3841 The value may be `always', `when-mapped', or `not-useful'.
3842 The optional argument DISPLAY specifies which display to ask about.
3843 DISPLAY should be either a frame or a display name (a string).
3844 If omitted or nil, that stands for the selected frame's display. */)
3846 Lisp_Object display
;
3848 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3851 switch (DoesBackingStore (dpyinfo
->screen
))
3854 result
= intern ("always");
3858 result
= intern ("when-mapped");
3862 result
= intern ("not-useful");
3866 error ("Strange value for BackingStore parameter of screen");
3873 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3874 Sx_display_visual_class
, 0, 1, 0,
3875 doc
: /* Return the visual class of the X display DISPLAY.
3876 The value is one of the symbols `static-gray', `gray-scale',
3877 `static-color', `pseudo-color', `true-color', or `direct-color'.
3879 The optional argument DISPLAY specifies which display to ask about.
3880 DISPLAY should be either a frame or a display name (a string).
3881 If omitted or nil, that stands for the selected frame's display. */)
3883 Lisp_Object display
;
3885 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3888 switch (dpyinfo
->visual
->class)
3891 result
= intern ("static-gray");
3894 result
= intern ("gray-scale");
3897 result
= intern ("static-color");
3900 result
= intern ("pseudo-color");
3903 result
= intern ("true-color");
3906 result
= intern ("direct-color");
3909 error ("Display has an unknown visual class");
3916 DEFUN ("x-display-save-under", Fx_display_save_under
,
3917 Sx_display_save_under
, 0, 1, 0,
3918 doc
: /* Returns t if the X display DISPLAY supports the save-under feature.
3919 The optional argument DISPLAY specifies which display to ask about.
3920 DISPLAY should be either a frame or a display name (a string).
3921 If omitted or nil, that stands for the selected frame's display. */)
3923 Lisp_Object display
;
3925 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3927 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3935 register struct frame
*f
;
3937 return FRAME_PIXEL_WIDTH (f
);
3942 register struct frame
*f
;
3944 return FRAME_PIXEL_HEIGHT (f
);
3949 register struct frame
*f
;
3951 return FRAME_COLUMN_WIDTH (f
);
3956 register struct frame
*f
;
3958 return FRAME_LINE_HEIGHT (f
);
3963 register struct frame
*f
;
3965 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
3970 /************************************************************************
3972 ************************************************************************/
3975 /* Mapping visual names to visuals. */
3977 static struct visual_class
3984 {"StaticGray", StaticGray
},
3985 {"GrayScale", GrayScale
},
3986 {"StaticColor", StaticColor
},
3987 {"PseudoColor", PseudoColor
},
3988 {"TrueColor", TrueColor
},
3989 {"DirectColor", DirectColor
},
3994 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3996 /* Value is the screen number of screen SCR. This is a substitute for
3997 the X function with the same name when that doesn't exist. */
4000 XScreenNumberOfScreen (scr
)
4001 register Screen
*scr
;
4003 Display
*dpy
= scr
->display
;
4006 for (i
= 0; i
< dpy
->nscreens
; ++i
)
4007 if (scr
== dpy
->screens
+ i
)
4013 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4016 /* Select the visual that should be used on display DPYINFO. Set
4017 members of DPYINFO appropriately. Called from x_term_init. */
4020 select_visual (dpyinfo
)
4021 struct x_display_info
*dpyinfo
;
4023 Display
*dpy
= dpyinfo
->display
;
4024 Screen
*screen
= dpyinfo
->screen
;
4027 /* See if a visual is specified. */
4028 value
= display_x_get_resource (dpyinfo
,
4029 build_string ("visualClass"),
4030 build_string ("VisualClass"),
4032 if (STRINGP (value
))
4034 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4035 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4036 depth, a decimal number. NAME is compared with case ignored. */
4037 char *s
= (char *) alloca (SBYTES (value
) + 1);
4042 strcpy (s
, SDATA (value
));
4043 dash
= index (s
, '-');
4046 dpyinfo
->n_planes
= atoi (dash
+ 1);
4050 /* We won't find a matching visual with depth 0, so that
4051 an error will be printed below. */
4052 dpyinfo
->n_planes
= 0;
4054 /* Determine the visual class. */
4055 for (i
= 0; visual_classes
[i
].name
; ++i
)
4056 if (xstricmp (s
, visual_classes
[i
].name
) == 0)
4058 class = visual_classes
[i
].class;
4062 /* Look up a matching visual for the specified class. */
4064 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4065 dpyinfo
->n_planes
, class, &vinfo
))
4066 fatal ("Invalid visual specification `%s'", SDATA (value
));
4068 dpyinfo
->visual
= vinfo
.visual
;
4073 XVisualInfo
*vinfo
, vinfo_template
;
4075 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4078 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4080 vinfo_template
.visualid
= dpyinfo
->visual
->visualid
;
4082 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4083 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4084 &vinfo_template
, &n_visuals
);
4086 fatal ("Can't get proper X visual info");
4088 dpyinfo
->n_planes
= vinfo
->depth
;
4089 XFree ((char *) vinfo
);
4094 /* Return the X display structure for the display named NAME.
4095 Open a new connection if necessary. */
4097 struct x_display_info
*
4098 x_display_info_for_name (name
)
4102 struct x_display_info
*dpyinfo
;
4104 CHECK_STRING (name
);
4106 if (! EQ (Vwindow_system
, intern ("x")))
4107 error ("Not using X Windows");
4109 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4111 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4114 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4119 /* Use this general default value to start with. */
4120 Vx_resource_name
= Vinvocation_name
;
4122 validate_x_resource_name ();
4124 dpyinfo
= x_term_init (name
, (char *)0,
4125 (char *) SDATA (Vx_resource_name
));
4128 error ("Cannot connect to X server %s", SDATA (name
));
4131 XSETFASTINT (Vwindow_system_version
, 11);
4137 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4139 doc
: /* Open a connection to an X server.
4140 DISPLAY is the name of the display to connect to.
4141 Optional second arg XRM-STRING is a string of resources in xrdb format.
4142 If the optional third arg MUST-SUCCEED is non-nil,
4143 terminate Emacs if we can't open the connection. */)
4144 (display
, xrm_string
, must_succeed
)
4145 Lisp_Object display
, xrm_string
, must_succeed
;
4147 unsigned char *xrm_option
;
4148 struct x_display_info
*dpyinfo
;
4150 CHECK_STRING (display
);
4151 if (! NILP (xrm_string
))
4152 CHECK_STRING (xrm_string
);
4154 if (! EQ (Vwindow_system
, intern ("x")))
4155 error ("Not using X Windows");
4157 if (! NILP (xrm_string
))
4158 xrm_option
= (unsigned char *) SDATA (xrm_string
);
4160 xrm_option
= (unsigned char *) 0;
4162 validate_x_resource_name ();
4164 /* This is what opens the connection and sets x_current_display.
4165 This also initializes many symbols, such as those used for input. */
4166 dpyinfo
= x_term_init (display
, xrm_option
,
4167 (char *) SDATA (Vx_resource_name
));
4171 if (!NILP (must_succeed
))
4172 fatal ("Cannot connect to X server %s.\n\
4173 Check the DISPLAY environment variable or use `-d'.\n\
4174 Also use the `xauth' program to verify that you have the proper\n\
4175 authorization information needed to connect the X server.\n\
4176 An insecure way to solve the problem may be to use `xhost'.\n",
4179 error ("Cannot connect to X server %s", SDATA (display
));
4184 XSETFASTINT (Vwindow_system_version
, 11);
4188 DEFUN ("x-close-connection", Fx_close_connection
,
4189 Sx_close_connection
, 1, 1, 0,
4190 doc
: /* Close the connection to DISPLAY's X server.
4191 For DISPLAY, specify either a frame or a display name (a string).
4192 If DISPLAY is nil, that stands for the selected frame's display. */)
4194 Lisp_Object display
;
4196 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4199 if (dpyinfo
->reference_count
> 0)
4200 error ("Display still has frames on it");
4203 /* Free the fonts in the font table. */
4204 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4205 if (dpyinfo
->font_table
[i
].name
)
4207 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
4208 xfree (dpyinfo
->font_table
[i
].full_name
);
4209 xfree (dpyinfo
->font_table
[i
].name
);
4210 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4213 x_destroy_all_bitmaps (dpyinfo
);
4214 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4216 #ifdef USE_X_TOOLKIT
4217 XtCloseDisplay (dpyinfo
->display
);
4219 XCloseDisplay (dpyinfo
->display
);
4222 x_delete_display (dpyinfo
);
4228 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4229 doc
: /* Return the list of display names that Emacs has connections to. */)
4232 Lisp_Object tail
, result
;
4235 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
4236 result
= Fcons (XCAR (XCAR (tail
)), result
);
4241 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4242 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4243 If ON is nil, allow buffering of requests.
4244 Turning on synchronization prohibits the Xlib routines from buffering
4245 requests and seriously degrades performance, but makes debugging much
4247 The optional second argument DISPLAY specifies which display to act on.
4248 DISPLAY should be either a frame or a display name (a string).
4249 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4251 Lisp_Object display
, on
;
4253 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4255 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4260 /* Wait for responses to all X commands issued so far for frame F. */
4267 XSync (FRAME_X_DISPLAY (f
), False
);
4272 /***********************************************************************
4274 ***********************************************************************/
4276 /* Value is the number of elements of vector VECTOR. */
4278 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
4280 /* List of supported image types. Use define_image_type to add new
4281 types. Use lookup_image_type to find a type for a given symbol. */
4283 static struct image_type
*image_types
;
4285 /* The symbol `image' which is the car of the lists used to represent
4288 extern Lisp_Object Qimage
;
4290 /* The symbol `xbm' which is used as the type symbol for XBM images. */
4296 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
4297 extern Lisp_Object QCdata
, QCtype
;
4298 Lisp_Object QCascent
, QCmargin
, QCrelief
;
4299 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
4300 Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
;
4302 /* Other symbols. */
4304 Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
4306 /* Time in seconds after which images should be removed from the cache
4307 if not displayed. */
4309 Lisp_Object Vimage_cache_eviction_delay
;
4311 /* Function prototypes. */
4313 static void define_image_type
P_ ((struct image_type
*type
));
4314 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
4315 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
4316 static void x_laplace
P_ ((struct frame
*, struct image
*));
4317 static void x_emboss
P_ ((struct frame
*, struct image
*));
4318 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
4322 /* Define a new image type from TYPE. This adds a copy of TYPE to
4323 image_types and adds the symbol *TYPE->type to Vimage_types. */
4326 define_image_type (type
)
4327 struct image_type
*type
;
4329 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
4330 The initialized data segment is read-only. */
4331 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
4332 bcopy (type
, p
, sizeof *p
);
4333 p
->next
= image_types
;
4335 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
4339 /* Look up image type SYMBOL, and return a pointer to its image_type
4340 structure. Value is null if SYMBOL is not a known image type. */
4342 static INLINE
struct image_type
*
4343 lookup_image_type (symbol
)
4346 struct image_type
*type
;
4348 for (type
= image_types
; type
; type
= type
->next
)
4349 if (EQ (symbol
, *type
->type
))
4356 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
4357 valid image specification is a list whose car is the symbol
4358 `image', and whose rest is a property list. The property list must
4359 contain a value for key `:type'. That value must be the name of a
4360 supported image type. The rest of the property list depends on the
4364 valid_image_p (object
)
4369 if (CONSP (object
) && EQ (XCAR (object
), Qimage
))
4373 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
4374 if (EQ (XCAR (tem
), QCtype
))
4377 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
4379 struct image_type
*type
;
4380 type
= lookup_image_type (XCAR (tem
));
4382 valid_p
= type
->valid_p (object
);
4393 /* Log error message with format string FORMAT and argument ARG.
4394 Signaling an error, e.g. when an image cannot be loaded, is not a
4395 good idea because this would interrupt redisplay, and the error
4396 message display would lead to another redisplay. This function
4397 therefore simply displays a message. */
4400 image_error (format
, arg1
, arg2
)
4402 Lisp_Object arg1
, arg2
;
4404 add_to_log (format
, arg1
, arg2
);
4409 /***********************************************************************
4410 Image specifications
4411 ***********************************************************************/
4413 enum image_value_type
4415 IMAGE_DONT_CHECK_VALUE_TYPE
,
4417 IMAGE_STRING_OR_NIL_VALUE
,
4419 IMAGE_POSITIVE_INTEGER_VALUE
,
4420 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
4421 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
4423 IMAGE_INTEGER_VALUE
,
4424 IMAGE_FUNCTION_VALUE
,
4429 /* Structure used when parsing image specifications. */
4431 struct image_keyword
4433 /* Name of keyword. */
4436 /* The type of value allowed. */
4437 enum image_value_type type
;
4439 /* Non-zero means key must be present. */
4442 /* Used to recognize duplicate keywords in a property list. */
4445 /* The value that was found. */
4450 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
4452 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
4455 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
4456 has the format (image KEYWORD VALUE ...). One of the keyword/
4457 value pairs must be `:type TYPE'. KEYWORDS is a vector of
4458 image_keywords structures of size NKEYWORDS describing other
4459 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
4462 parse_image_spec (spec
, keywords
, nkeywords
, type
)
4464 struct image_keyword
*keywords
;
4471 if (!CONSP (spec
) || !EQ (XCAR (spec
), Qimage
))
4474 plist
= XCDR (spec
);
4475 while (CONSP (plist
))
4477 Lisp_Object key
, value
;
4479 /* First element of a pair must be a symbol. */
4481 plist
= XCDR (plist
);
4485 /* There must follow a value. */
4488 value
= XCAR (plist
);
4489 plist
= XCDR (plist
);
4491 /* Find key in KEYWORDS. Error if not found. */
4492 for (i
= 0; i
< nkeywords
; ++i
)
4493 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
4499 /* Record that we recognized the keyword. If a keywords
4500 was found more than once, it's an error. */
4501 keywords
[i
].value
= value
;
4502 ++keywords
[i
].count
;
4504 if (keywords
[i
].count
> 1)
4507 /* Check type of value against allowed type. */
4508 switch (keywords
[i
].type
)
4510 case IMAGE_STRING_VALUE
:
4511 if (!STRINGP (value
))
4515 case IMAGE_STRING_OR_NIL_VALUE
:
4516 if (!STRINGP (value
) && !NILP (value
))
4520 case IMAGE_SYMBOL_VALUE
:
4521 if (!SYMBOLP (value
))
4525 case IMAGE_POSITIVE_INTEGER_VALUE
:
4526 if (!INTEGERP (value
) || XINT (value
) <= 0)
4530 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
4531 if (INTEGERP (value
) && XINT (value
) >= 0)
4534 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
4535 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
4539 case IMAGE_ASCENT_VALUE
:
4540 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
4542 else if (INTEGERP (value
)
4543 && XINT (value
) >= 0
4544 && XINT (value
) <= 100)
4548 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
4549 if (!INTEGERP (value
) || XINT (value
) < 0)
4553 case IMAGE_DONT_CHECK_VALUE_TYPE
:
4556 case IMAGE_FUNCTION_VALUE
:
4557 value
= indirect_function (value
);
4559 || COMPILEDP (value
)
4560 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
4564 case IMAGE_NUMBER_VALUE
:
4565 if (!INTEGERP (value
) && !FLOATP (value
))
4569 case IMAGE_INTEGER_VALUE
:
4570 if (!INTEGERP (value
))
4574 case IMAGE_BOOL_VALUE
:
4575 if (!NILP (value
) && !EQ (value
, Qt
))
4584 if (EQ (key
, QCtype
) && !EQ (type
, value
))
4588 /* Check that all mandatory fields are present. */
4589 for (i
= 0; i
< nkeywords
; ++i
)
4590 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
4593 return NILP (plist
);
4597 /* Return the value of KEY in image specification SPEC. Value is nil
4598 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
4599 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
4602 image_spec_value (spec
, key
, found
)
4603 Lisp_Object spec
, key
;
4608 xassert (valid_image_p (spec
));
4610 for (tail
= XCDR (spec
);
4611 CONSP (tail
) && CONSP (XCDR (tail
));
4612 tail
= XCDR (XCDR (tail
)))
4614 if (EQ (XCAR (tail
), key
))
4618 return XCAR (XCDR (tail
));
4628 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
4629 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
4630 PIXELS non-nil means return the size in pixels, otherwise return the
4631 size in canonical character units.
4632 FRAME is the frame on which the image will be displayed. FRAME nil
4633 or omitted means use the selected frame. */)
4634 (spec
, pixels
, frame
)
4635 Lisp_Object spec
, pixels
, frame
;
4640 if (valid_image_p (spec
))
4642 struct frame
*f
= check_x_frame (frame
);
4643 int id
= lookup_image (f
, spec
);
4644 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4645 int width
= img
->width
+ 2 * img
->hmargin
;
4646 int height
= img
->height
+ 2 * img
->vmargin
;
4649 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
4650 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
4652 size
= Fcons (make_number (width
), make_number (height
));
4655 error ("Invalid image specification");
4661 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
4662 doc
: /* Return t if image SPEC has a mask bitmap.
4663 FRAME is the frame on which the image will be displayed. FRAME nil
4664 or omitted means use the selected frame. */)
4666 Lisp_Object spec
, frame
;
4671 if (valid_image_p (spec
))
4673 struct frame
*f
= check_x_frame (frame
);
4674 int id
= lookup_image (f
, spec
);
4675 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4680 error ("Invalid image specification");
4687 /***********************************************************************
4688 Image type independent image structures
4689 ***********************************************************************/
4691 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
4692 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
4695 /* Allocate and return a new image structure for image specification
4696 SPEC. SPEC has a hash value of HASH. */
4698 static struct image
*
4699 make_image (spec
, hash
)
4703 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
4705 xassert (valid_image_p (spec
));
4706 bzero (img
, sizeof *img
);
4707 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
4708 xassert (img
->type
!= NULL
);
4710 img
->data
.lisp_val
= Qnil
;
4711 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
4717 /* Free image IMG which was used on frame F, including its resources. */
4726 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4728 /* Remove IMG from the hash table of its cache. */
4730 img
->prev
->next
= img
->next
;
4732 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
4735 img
->next
->prev
= img
->prev
;
4737 c
->images
[img
->id
] = NULL
;
4739 /* Free resources, then free IMG. */
4740 img
->type
->free (f
, img
);
4746 /* Prepare image IMG for display on frame F. Must be called before
4747 drawing an image. */
4750 prepare_image_for_display (f
, img
)
4756 /* We're about to display IMG, so set its timestamp to `now'. */
4758 img
->timestamp
= EMACS_SECS (t
);
4760 /* If IMG doesn't have a pixmap yet, load it now, using the image
4761 type dependent loader function. */
4762 if (img
->pixmap
== None
&& !img
->load_failed_p
)
4763 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
4767 /* Value is the number of pixels for the ascent of image IMG when
4768 drawn in face FACE. */
4771 image_ascent (img
, face
)
4775 int height
= img
->height
+ img
->vmargin
;
4778 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
4781 /* This expression is arranged so that if the image can't be
4782 exactly centered, it will be moved slightly up. This is
4783 because a typical font is `top-heavy' (due to the presence
4784 uppercase letters), so the image placement should err towards
4785 being top-heavy too. It also just generally looks better. */
4786 ascent
= (height
+ face
->font
->ascent
- face
->font
->descent
+ 1) / 2;
4788 ascent
= height
/ 2;
4791 ascent
= height
* img
->ascent
/ 100.0;
4797 /* Image background colors. */
4799 static unsigned long
4800 four_corners_best (ximg
, width
, height
)
4802 unsigned long width
, height
;
4804 unsigned long corners
[4], best
;
4807 /* Get the colors at the corners of ximg. */
4808 corners
[0] = XGetPixel (ximg
, 0, 0);
4809 corners
[1] = XGetPixel (ximg
, width
- 1, 0);
4810 corners
[2] = XGetPixel (ximg
, width
- 1, height
- 1);
4811 corners
[3] = XGetPixel (ximg
, 0, height
- 1);
4813 /* Choose the most frequently found color as background. */
4814 for (i
= best_count
= 0; i
< 4; ++i
)
4818 for (j
= n
= 0; j
< 4; ++j
)
4819 if (corners
[i
] == corners
[j
])
4823 best
= corners
[i
], best_count
= n
;
4829 /* Return the `background' field of IMG. If IMG doesn't have one yet,
4830 it is guessed heuristically. If non-zero, XIMG is an existing XImage
4831 object to use for the heuristic. */
4834 image_background (img
, f
, ximg
)
4839 if (! img
->background_valid
)
4840 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4842 int free_ximg
= !ximg
;
4845 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4846 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4848 img
->background
= four_corners_best (ximg
, img
->width
, img
->height
);
4851 XDestroyImage (ximg
);
4853 img
->background_valid
= 1;
4856 return img
->background
;
4859 /* Return the `background_transparent' field of IMG. If IMG doesn't
4860 have one yet, it is guessed heuristically. If non-zero, MASK is an
4861 existing XImage object to use for the heuristic. */
4864 image_background_transparent (img
, f
, mask
)
4869 if (! img
->background_transparent_valid
)
4870 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4874 int free_mask
= !mask
;
4877 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
4878 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4880 img
->background_transparent
4881 = !four_corners_best (mask
, img
->width
, img
->height
);
4884 XDestroyImage (mask
);
4887 img
->background_transparent
= 0;
4889 img
->background_transparent_valid
= 1;
4892 return img
->background_transparent
;
4896 /***********************************************************************
4897 Helper functions for X image types
4898 ***********************************************************************/
4900 static void x_clear_image_1
P_ ((struct frame
*, struct image
*, int,
4902 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
4903 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
4905 Lisp_Object color_name
,
4906 unsigned long dflt
));
4909 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
4910 free the pixmap if any. MASK_P non-zero means clear the mask
4911 pixmap if any. COLORS_P non-zero means free colors allocated for
4912 the image, if any. */
4915 x_clear_image_1 (f
, img
, pixmap_p
, mask_p
, colors_p
)
4918 int pixmap_p
, mask_p
, colors_p
;
4920 if (pixmap_p
&& img
->pixmap
)
4922 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
4924 img
->background_valid
= 0;
4927 if (mask_p
&& img
->mask
)
4929 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4931 img
->background_transparent_valid
= 0;
4934 if (colors_p
&& img
->ncolors
)
4936 x_free_colors (f
, img
->colors
, img
->ncolors
);
4937 xfree (img
->colors
);
4943 /* Free X resources of image IMG which is used on frame F. */
4946 x_clear_image (f
, img
)
4951 x_clear_image_1 (f
, img
, 1, 1, 1);
4956 /* Allocate color COLOR_NAME for image IMG on frame F. If color
4957 cannot be allocated, use DFLT. Add a newly allocated color to
4958 IMG->colors, so that it can be freed again. Value is the pixel
4961 static unsigned long
4962 x_alloc_image_color (f
, img
, color_name
, dflt
)
4965 Lisp_Object color_name
;
4969 unsigned long result
;
4971 xassert (STRINGP (color_name
));
4973 if (x_defined_color (f
, SDATA (color_name
), &color
, 1))
4975 /* This isn't called frequently so we get away with simply
4976 reallocating the color vector to the needed size, here. */
4979 (unsigned long *) xrealloc (img
->colors
,
4980 img
->ncolors
* sizeof *img
->colors
);
4981 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
4982 result
= color
.pixel
;
4992 /***********************************************************************
4994 ***********************************************************************/
4996 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
4997 static void postprocess_image
P_ ((struct frame
*, struct image
*));
5000 /* Return a new, initialized image cache that is allocated from the
5001 heap. Call free_image_cache to free an image cache. */
5003 struct image_cache
*
5006 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
5009 bzero (c
, sizeof *c
);
5011 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
5012 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
5013 c
->buckets
= (struct image
**) xmalloc (size
);
5014 bzero (c
->buckets
, size
);
5019 /* Free image cache of frame F. Be aware that X frames share images
5023 free_image_cache (f
)
5026 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5031 /* Cache should not be referenced by any frame when freed. */
5032 xassert (c
->refcount
== 0);
5034 for (i
= 0; i
< c
->used
; ++i
)
5035 free_image (f
, c
->images
[i
]);
5039 FRAME_X_IMAGE_CACHE (f
) = NULL
;
5044 /* Clear image cache of frame F. FORCE_P non-zero means free all
5045 images. FORCE_P zero means clear only images that haven't been
5046 displayed for some time. Should be called from time to time to
5047 reduce the number of loaded images. If image-eviction-seconds is
5048 non-nil, this frees images in the cache which weren't displayed for
5049 at least that many seconds. */
5052 clear_image_cache (f
, force_p
)
5056 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5058 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
5065 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
5067 /* Block input so that we won't be interrupted by a SIGIO
5068 while being in an inconsistent state. */
5071 for (i
= nfreed
= 0; i
< c
->used
; ++i
)
5073 struct image
*img
= c
->images
[i
];
5075 && (force_p
|| img
->timestamp
< old
))
5077 free_image (f
, img
);
5082 /* We may be clearing the image cache because, for example,
5083 Emacs was iconified for a longer period of time. In that
5084 case, current matrices may still contain references to
5085 images freed above. So, clear these matrices. */
5088 Lisp_Object tail
, frame
;
5090 FOR_EACH_FRAME (tail
, frame
)
5092 struct frame
*f
= XFRAME (frame
);
5094 && FRAME_X_IMAGE_CACHE (f
) == c
)
5095 clear_current_matrices (f
);
5098 ++windows_or_buffers_changed
;
5106 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
5108 doc
: /* Clear the image cache of FRAME.
5109 FRAME nil or omitted means use the selected frame.
5110 FRAME t means clear the image caches of all frames. */)
5118 FOR_EACH_FRAME (tail
, frame
)
5119 if (FRAME_X_P (XFRAME (frame
)))
5120 clear_image_cache (XFRAME (frame
), 1);
5123 clear_image_cache (check_x_frame (frame
), 1);
5129 /* Compute masks and transform image IMG on frame F, as specified
5130 by the image's specification, */
5133 postprocess_image (f
, img
)
5137 /* Manipulation of the image's mask. */
5140 Lisp_Object conversion
, spec
;
5145 /* `:heuristic-mask t'
5147 means build a mask heuristically.
5148 `:heuristic-mask (R G B)'
5149 `:mask (heuristic (R G B))'
5150 means build a mask from color (R G B) in the
5153 means remove a mask, if any. */
5155 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
5157 x_build_heuristic_mask (f
, img
, mask
);
5162 mask
= image_spec_value (spec
, QCmask
, &found_p
);
5164 if (EQ (mask
, Qheuristic
))
5165 x_build_heuristic_mask (f
, img
, Qt
);
5166 else if (CONSP (mask
)
5167 && EQ (XCAR (mask
), Qheuristic
))
5169 if (CONSP (XCDR (mask
)))
5170 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
5172 x_build_heuristic_mask (f
, img
, XCDR (mask
));
5174 else if (NILP (mask
) && found_p
&& img
->mask
)
5176 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
5182 /* Should we apply an image transformation algorithm? */
5183 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
5184 if (EQ (conversion
, Qdisabled
))
5185 x_disable_image (f
, img
);
5186 else if (EQ (conversion
, Qlaplace
))
5188 else if (EQ (conversion
, Qemboss
))
5190 else if (CONSP (conversion
)
5191 && EQ (XCAR (conversion
), Qedge_detection
))
5194 tem
= XCDR (conversion
);
5196 x_edge_detection (f
, img
,
5197 Fplist_get (tem
, QCmatrix
),
5198 Fplist_get (tem
, QCcolor_adjustment
));
5204 /* Return the id of image with Lisp specification SPEC on frame F.
5205 SPEC must be a valid Lisp image specification (see valid_image_p). */
5208 lookup_image (f
, spec
)
5212 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5216 struct gcpro gcpro1
;
5219 /* F must be a window-system frame, and SPEC must be a valid image
5221 xassert (FRAME_WINDOW_P (f
));
5222 xassert (valid_image_p (spec
));
5226 /* Look up SPEC in the hash table of the image cache. */
5227 hash
= sxhash (spec
, 0);
5228 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5230 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
5231 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
5234 /* If not found, create a new image and cache it. */
5237 extern Lisp_Object Qpostscript
;
5240 img
= make_image (spec
, hash
);
5241 cache_image (f
, img
);
5242 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5244 /* If we can't load the image, and we don't have a width and
5245 height, use some arbitrary width and height so that we can
5246 draw a rectangle for it. */
5247 if (img
->load_failed_p
)
5251 value
= image_spec_value (spec
, QCwidth
, NULL
);
5252 img
->width
= (INTEGERP (value
)
5253 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
5254 value
= image_spec_value (spec
, QCheight
, NULL
);
5255 img
->height
= (INTEGERP (value
)
5256 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
5260 /* Handle image type independent image attributes
5261 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
5262 `:background COLOR'. */
5263 Lisp_Object ascent
, margin
, relief
, bg
;
5265 ascent
= image_spec_value (spec
, QCascent
, NULL
);
5266 if (INTEGERP (ascent
))
5267 img
->ascent
= XFASTINT (ascent
);
5268 else if (EQ (ascent
, Qcenter
))
5269 img
->ascent
= CENTERED_IMAGE_ASCENT
;
5271 margin
= image_spec_value (spec
, QCmargin
, NULL
);
5272 if (INTEGERP (margin
) && XINT (margin
) >= 0)
5273 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
5274 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
5275 && INTEGERP (XCDR (margin
)))
5277 if (XINT (XCAR (margin
)) > 0)
5278 img
->hmargin
= XFASTINT (XCAR (margin
));
5279 if (XINT (XCDR (margin
)) > 0)
5280 img
->vmargin
= XFASTINT (XCDR (margin
));
5283 relief
= image_spec_value (spec
, QCrelief
, NULL
);
5284 if (INTEGERP (relief
))
5286 img
->relief
= XINT (relief
);
5287 img
->hmargin
+= abs (img
->relief
);
5288 img
->vmargin
+= abs (img
->relief
);
5291 if (! img
->background_valid
)
5293 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
5297 = x_alloc_image_color (f
, img
, bg
,
5298 FRAME_BACKGROUND_PIXEL (f
));
5299 img
->background_valid
= 1;
5303 /* Do image transformations and compute masks, unless we
5304 don't have the image yet. */
5305 if (!EQ (*img
->type
->type
, Qpostscript
))
5306 postprocess_image (f
, img
);
5310 xassert (!interrupt_input_blocked
);
5313 /* We're using IMG, so set its timestamp to `now'. */
5314 EMACS_GET_TIME (now
);
5315 img
->timestamp
= EMACS_SECS (now
);
5319 /* Value is the image id. */
5324 /* Cache image IMG in the image cache of frame F. */
5327 cache_image (f
, img
)
5331 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5334 /* Find a free slot in c->images. */
5335 for (i
= 0; i
< c
->used
; ++i
)
5336 if (c
->images
[i
] == NULL
)
5339 /* If no free slot found, maybe enlarge c->images. */
5340 if (i
== c
->used
&& c
->used
== c
->size
)
5343 c
->images
= (struct image
**) xrealloc (c
->images
,
5344 c
->size
* sizeof *c
->images
);
5347 /* Add IMG to c->images, and assign IMG an id. */
5353 /* Add IMG to the cache's hash table. */
5354 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5355 img
->next
= c
->buckets
[i
];
5357 img
->next
->prev
= img
;
5359 c
->buckets
[i
] = img
;
5363 /* Call FN on every image in the image cache of frame F. Used to mark
5364 Lisp Objects in the image cache. */
5367 forall_images_in_image_cache (f
, fn
)
5369 void (*fn
) P_ ((struct image
*img
));
5371 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
))
5373 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5377 for (i
= 0; i
< c
->used
; ++i
)
5386 /***********************************************************************
5388 ***********************************************************************/
5390 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
5391 XImage
**, Pixmap
*));
5392 static void x_destroy_x_image
P_ ((XImage
*));
5393 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
5396 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
5397 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
5398 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
5399 via xmalloc. Print error messages via image_error if an error
5400 occurs. Value is non-zero if successful. */
5403 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
5405 int width
, height
, depth
;
5409 Display
*display
= FRAME_X_DISPLAY (f
);
5410 Screen
*screen
= FRAME_X_SCREEN (f
);
5411 Window window
= FRAME_X_WINDOW (f
);
5413 xassert (interrupt_input_blocked
);
5416 depth
= DefaultDepthOfScreen (screen
);
5417 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
5418 depth
, ZPixmap
, 0, NULL
, width
, height
,
5419 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
5422 image_error ("Unable to allocate X image", Qnil
, Qnil
);
5426 /* Allocate image raster. */
5427 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
5429 /* Allocate a pixmap of the same size. */
5430 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
5431 if (*pixmap
== None
)
5433 x_destroy_x_image (*ximg
);
5435 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
5443 /* Destroy XImage XIMG. Free XIMG->data. */
5446 x_destroy_x_image (ximg
)
5449 xassert (interrupt_input_blocked
);
5454 XDestroyImage (ximg
);
5459 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
5460 are width and height of both the image and pixmap. */
5463 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
5471 xassert (interrupt_input_blocked
);
5472 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
5473 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
5474 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5479 /***********************************************************************
5481 ***********************************************************************/
5483 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
5484 static char *slurp_file
P_ ((char *, int *));
5487 /* Find image file FILE. Look in data-directory, then
5488 x-bitmap-file-path. Value is the full name of the file found, or
5489 nil if not found. */
5492 x_find_image_file (file
)
5495 Lisp_Object file_found
, search_path
;
5496 struct gcpro gcpro1
, gcpro2
;
5500 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
5501 GCPRO2 (file_found
, search_path
);
5503 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
5504 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
5516 /* Read FILE into memory. Value is a pointer to a buffer allocated
5517 with xmalloc holding FILE's contents. Value is null if an error
5518 occurred. *SIZE is set to the size of the file. */
5521 slurp_file (file
, size
)
5529 if (stat (file
, &st
) == 0
5530 && (fp
= fopen (file
, "r")) != NULL
5531 && (buf
= (char *) xmalloc (st
.st_size
),
5532 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5553 /***********************************************************************
5555 ***********************************************************************/
5557 static int xbm_scan
P_ ((char **, char *, char *, int *));
5558 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
5559 static int xbm_load_image
P_ ((struct frame
*f
, struct image
*img
,
5561 static int xbm_image_p
P_ ((Lisp_Object object
));
5562 static int xbm_read_bitmap_data
P_ ((char *, char *, int *, int *,
5564 static int xbm_file_p
P_ ((Lisp_Object
));
5567 /* Indices of image specification fields in xbm_format, below. */
5569 enum xbm_keyword_index
5587 /* Vector of image_keyword structures describing the format
5588 of valid XBM image specifications. */
5590 static struct image_keyword xbm_format
[XBM_LAST
] =
5592 {":type", IMAGE_SYMBOL_VALUE
, 1},
5593 {":file", IMAGE_STRING_VALUE
, 0},
5594 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5595 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5596 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5597 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
5598 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
5599 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5600 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5601 {":relief", IMAGE_INTEGER_VALUE
, 0},
5602 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5603 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5604 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5607 /* Structure describing the image type XBM. */
5609 static struct image_type xbm_type
=
5618 /* Tokens returned from xbm_scan. */
5627 /* Return non-zero if OBJECT is a valid XBM-type image specification.
5628 A valid specification is a list starting with the symbol `image'
5629 The rest of the list is a property list which must contain an
5632 If the specification specifies a file to load, it must contain
5633 an entry `:file FILENAME' where FILENAME is a string.
5635 If the specification is for a bitmap loaded from memory it must
5636 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
5637 WIDTH and HEIGHT are integers > 0. DATA may be:
5639 1. a string large enough to hold the bitmap data, i.e. it must
5640 have a size >= (WIDTH + 7) / 8 * HEIGHT
5642 2. a bool-vector of size >= WIDTH * HEIGHT
5644 3. a vector of strings or bool-vectors, one for each line of the
5647 4. A string containing an in-memory XBM file. WIDTH and HEIGHT
5648 may not be specified in this case because they are defined in the
5651 Both the file and data forms may contain the additional entries
5652 `:background COLOR' and `:foreground COLOR'. If not present,
5653 foreground and background of the frame on which the image is
5654 displayed is used. */
5657 xbm_image_p (object
)
5660 struct image_keyword kw
[XBM_LAST
];
5662 bcopy (xbm_format
, kw
, sizeof kw
);
5663 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
5666 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
5668 if (kw
[XBM_FILE
].count
)
5670 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
5673 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
5675 /* In-memory XBM file. */
5676 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
5684 /* Entries for `:width', `:height' and `:data' must be present. */
5685 if (!kw
[XBM_WIDTH
].count
5686 || !kw
[XBM_HEIGHT
].count
5687 || !kw
[XBM_DATA
].count
)
5690 data
= kw
[XBM_DATA
].value
;
5691 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
5692 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
5694 /* Check type of data, and width and height against contents of
5700 /* Number of elements of the vector must be >= height. */
5701 if (XVECTOR (data
)->size
< height
)
5704 /* Each string or bool-vector in data must be large enough
5705 for one line of the image. */
5706 for (i
= 0; i
< height
; ++i
)
5708 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
5713 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
5716 else if (BOOL_VECTOR_P (elt
))
5718 if (XBOOL_VECTOR (elt
)->size
< width
)
5725 else if (STRINGP (data
))
5728 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
5731 else if (BOOL_VECTOR_P (data
))
5733 if (XBOOL_VECTOR (data
)->size
< width
* height
)
5744 /* Scan a bitmap file. FP is the stream to read from. Value is
5745 either an enumerator from enum xbm_token, or a character for a
5746 single-character token, or 0 at end of file. If scanning an
5747 identifier, store the lexeme of the identifier in SVAL. If
5748 scanning a number, store its value in *IVAL. */
5751 xbm_scan (s
, end
, sval
, ival
)
5760 /* Skip white space. */
5761 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5766 else if (isdigit (c
))
5768 int value
= 0, digit
;
5770 if (c
== '0' && *s
< end
)
5773 if (c
== 'x' || c
== 'X')
5780 else if (c
>= 'a' && c
<= 'f')
5781 digit
= c
- 'a' + 10;
5782 else if (c
>= 'A' && c
<= 'F')
5783 digit
= c
- 'A' + 10;
5786 value
= 16 * value
+ digit
;
5789 else if (isdigit (c
))
5793 && (c
= *(*s
)++, isdigit (c
)))
5794 value
= 8 * value
+ c
- '0';
5801 && (c
= *(*s
)++, isdigit (c
)))
5802 value
= 10 * value
+ c
- '0';
5810 else if (isalpha (c
) || c
== '_')
5814 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
5821 else if (c
== '/' && **s
== '*')
5823 /* C-style comment. */
5825 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
5838 /* Replacement for XReadBitmapFileData which isn't available under old
5839 X versions. CONTENTS is a pointer to a buffer to parse; END is the
5840 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
5841 the image. Return in *DATA the bitmap data allocated with xmalloc.
5842 Value is non-zero if successful. DATA null means just test if
5843 CONTENTS looks like an in-memory XBM file. */
5846 xbm_read_bitmap_data (contents
, end
, width
, height
, data
)
5847 char *contents
, *end
;
5848 int *width
, *height
;
5849 unsigned char **data
;
5852 char buffer
[BUFSIZ
];
5855 int bytes_per_line
, i
, nbytes
;
5861 LA1 = xbm_scan (&s, end, buffer, &value)
5863 #define expect(TOKEN) \
5864 if (LA1 != (TOKEN)) \
5869 #define expect_ident(IDENT) \
5870 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
5875 *width
= *height
= -1;
5878 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
5880 /* Parse defines for width, height and hot-spots. */
5884 expect_ident ("define");
5885 expect (XBM_TK_IDENT
);
5887 if (LA1
== XBM_TK_NUMBER
);
5889 char *p
= strrchr (buffer
, '_');
5890 p
= p
? p
+ 1 : buffer
;
5891 if (strcmp (p
, "width") == 0)
5893 else if (strcmp (p
, "height") == 0)
5896 expect (XBM_TK_NUMBER
);
5899 if (*width
< 0 || *height
< 0)
5901 else if (data
== NULL
)
5904 /* Parse bits. Must start with `static'. */
5905 expect_ident ("static");
5906 if (LA1
== XBM_TK_IDENT
)
5908 if (strcmp (buffer
, "unsigned") == 0)
5911 expect_ident ("char");
5913 else if (strcmp (buffer
, "short") == 0)
5917 if (*width
% 16 && *width
% 16 < 9)
5920 else if (strcmp (buffer
, "char") == 0)
5928 expect (XBM_TK_IDENT
);
5934 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
5935 nbytes
= bytes_per_line
* *height
;
5936 p
= *data
= (char *) xmalloc (nbytes
);
5940 for (i
= 0; i
< nbytes
; i
+= 2)
5943 expect (XBM_TK_NUMBER
);
5946 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
5949 if (LA1
== ',' || LA1
== '}')
5957 for (i
= 0; i
< nbytes
; ++i
)
5960 expect (XBM_TK_NUMBER
);
5964 if (LA1
== ',' || LA1
== '}')
5989 /* Load XBM image IMG which will be displayed on frame F from buffer
5990 CONTENTS. END is the end of the buffer. Value is non-zero if
5994 xbm_load_image (f
, img
, contents
, end
)
5997 char *contents
, *end
;
6000 unsigned char *data
;
6003 rc
= xbm_read_bitmap_data (contents
, end
, &img
->width
, &img
->height
, &data
);
6006 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6007 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6008 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6011 xassert (img
->width
> 0 && img
->height
> 0);
6013 /* Get foreground and background colors, maybe allocate colors. */
6014 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
6016 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
6017 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
6020 background
= x_alloc_image_color (f
, img
, value
, background
);
6021 img
->background
= background
;
6022 img
->background_valid
= 1;
6026 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
6029 img
->width
, img
->height
,
6030 foreground
, background
,
6034 if (img
->pixmap
== None
)
6036 x_clear_image (f
, img
);
6037 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
6043 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6049 /* Value is non-zero if DATA looks like an in-memory XBM file. */
6056 return (STRINGP (data
)
6057 && xbm_read_bitmap_data (SDATA (data
),
6064 /* Fill image IMG which is used on frame F with pixmap data. Value is
6065 non-zero if successful. */
6073 Lisp_Object file_name
;
6075 xassert (xbm_image_p (img
->spec
));
6077 /* If IMG->spec specifies a file name, create a non-file spec from it. */
6078 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
6079 if (STRINGP (file_name
))
6084 struct gcpro gcpro1
;
6086 file
= x_find_image_file (file_name
);
6088 if (!STRINGP (file
))
6090 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
6095 contents
= slurp_file (SDATA (file
), &size
);
6096 if (contents
== NULL
)
6098 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6103 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
6108 struct image_keyword fmt
[XBM_LAST
];
6111 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6112 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6115 int in_memory_file_p
= 0;
6117 /* See if data looks like an in-memory XBM file. */
6118 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6119 in_memory_file_p
= xbm_file_p (data
);
6121 /* Parse the image specification. */
6122 bcopy (xbm_format
, fmt
, sizeof fmt
);
6123 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
6126 /* Get specified width, and height. */
6127 if (!in_memory_file_p
)
6129 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
6130 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
6131 xassert (img
->width
> 0 && img
->height
> 0);
6134 /* Get foreground and background colors, maybe allocate colors. */
6135 if (fmt
[XBM_FOREGROUND
].count
6136 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
6137 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
6139 if (fmt
[XBM_BACKGROUND
].count
6140 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
6141 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
6144 if (in_memory_file_p
)
6145 success_p
= xbm_load_image (f
, img
, SDATA (data
),
6154 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
6156 p
= bits
= (char *) alloca (nbytes
* img
->height
);
6157 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
6159 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
6161 bcopy (SDATA (line
), p
, nbytes
);
6163 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
6166 else if (STRINGP (data
))
6167 bits
= SDATA (data
);
6169 bits
= XBOOL_VECTOR (data
)->data
;
6171 /* Create the pixmap. */
6172 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6174 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
6177 img
->width
, img
->height
,
6178 foreground
, background
,
6184 image_error ("Unable to create pixmap for XBM image `%s'",
6186 x_clear_image (f
, img
);
6196 /***********************************************************************
6198 ***********************************************************************/
6202 static int xpm_image_p
P_ ((Lisp_Object object
));
6203 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
6204 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
6206 #include "X11/xpm.h"
6208 /* The symbol `xpm' identifying XPM-format images. */
6212 /* Indices of image specification fields in xpm_format, below. */
6214 enum xpm_keyword_index
6230 /* Vector of image_keyword structures describing the format
6231 of valid XPM image specifications. */
6233 static struct image_keyword xpm_format
[XPM_LAST
] =
6235 {":type", IMAGE_SYMBOL_VALUE
, 1},
6236 {":file", IMAGE_STRING_VALUE
, 0},
6237 {":data", IMAGE_STRING_VALUE
, 0},
6238 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6239 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6240 {":relief", IMAGE_INTEGER_VALUE
, 0},
6241 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6242 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6243 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6244 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6245 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6248 /* Structure describing the image type XBM. */
6250 static struct image_type xpm_type
=
6260 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
6261 functions for allocating image colors. Our own functions handle
6262 color allocation failures more gracefully than the ones on the XPM
6265 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
6266 #define ALLOC_XPM_COLORS
6269 #ifdef ALLOC_XPM_COLORS
6271 static void xpm_init_color_cache
P_ ((struct frame
*, XpmAttributes
*));
6272 static void xpm_free_color_cache
P_ ((void));
6273 static int xpm_lookup_color
P_ ((struct frame
*, char *, XColor
*));
6274 static int xpm_color_bucket
P_ ((char *));
6275 static struct xpm_cached_color
*xpm_cache_color
P_ ((struct frame
*, char *,
6278 /* An entry in a hash table used to cache color definitions of named
6279 colors. This cache is necessary to speed up XPM image loading in
6280 case we do color allocations ourselves. Without it, we would need
6281 a call to XParseColor per pixel in the image. */
6283 struct xpm_cached_color
6285 /* Next in collision chain. */
6286 struct xpm_cached_color
*next
;
6288 /* Color definition (RGB and pixel color). */
6295 /* The hash table used for the color cache, and its bucket vector
6298 #define XPM_COLOR_CACHE_BUCKETS 1001
6299 struct xpm_cached_color
**xpm_color_cache
;
6301 /* Initialize the color cache. */
6304 xpm_init_color_cache (f
, attrs
)
6306 XpmAttributes
*attrs
;
6308 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
6309 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
6310 memset (xpm_color_cache
, 0, nbytes
);
6311 init_color_table ();
6313 if (attrs
->valuemask
& XpmColorSymbols
)
6318 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
6319 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6320 attrs
->colorsymbols
[i
].value
, &color
))
6322 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
6324 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
6330 /* Free the color cache. */
6333 xpm_free_color_cache ()
6335 struct xpm_cached_color
*p
, *next
;
6338 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
6339 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
6345 xfree (xpm_color_cache
);
6346 xpm_color_cache
= NULL
;
6347 free_color_table ();
6351 /* Return the bucket index for color named COLOR_NAME in the color
6355 xpm_color_bucket (color_name
)
6361 for (s
= color_name
; *s
; ++s
)
6363 return h
%= XPM_COLOR_CACHE_BUCKETS
;
6367 /* On frame F, cache values COLOR for color with name COLOR_NAME.
6368 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
6371 static struct xpm_cached_color
*
6372 xpm_cache_color (f
, color_name
, color
, bucket
)
6379 struct xpm_cached_color
*p
;
6382 bucket
= xpm_color_bucket (color_name
);
6384 nbytes
= sizeof *p
+ strlen (color_name
);
6385 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
6386 strcpy (p
->name
, color_name
);
6388 p
->next
= xpm_color_cache
[bucket
];
6389 xpm_color_cache
[bucket
] = p
;
6394 /* Look up color COLOR_NAME for frame F in the color cache. If found,
6395 return the cached definition in *COLOR. Otherwise, make a new
6396 entry in the cache and allocate the color. Value is zero if color
6397 allocation failed. */
6400 xpm_lookup_color (f
, color_name
, color
)
6405 struct xpm_cached_color
*p
;
6406 int h
= xpm_color_bucket (color_name
);
6408 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
6409 if (strcmp (p
->name
, color_name
) == 0)
6414 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6417 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
6419 p
= xpm_cache_color (f
, color_name
, color
, h
);
6421 /* You get `opaque' at least from ImageMagick converting pbm to xpm
6422 with transparency, and it's useful. */
6423 else if (strcmp ("opaque", color_name
) == 0)
6425 bzero (color
, sizeof (XColor
)); /* Is this necessary/correct? */
6426 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
6427 p
= xpm_cache_color (f
, color_name
, color
, h
);
6434 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
6435 CLOSURE is a pointer to the frame on which we allocate the
6436 color. Return in *COLOR the allocated color. Value is non-zero
6440 xpm_alloc_color (dpy
, cmap
, color_name
, color
, closure
)
6447 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
6451 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
6452 is a pointer to the frame on which we allocate the color. Value is
6453 non-zero if successful. */
6456 xpm_free_colors (dpy
, cmap
, pixels
, npixels
, closure
)
6466 #endif /* ALLOC_XPM_COLORS */
6469 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
6470 for XPM images. Such a list must consist of conses whose car and
6474 xpm_valid_color_symbols_p (color_symbols
)
6475 Lisp_Object color_symbols
;
6477 while (CONSP (color_symbols
))
6479 Lisp_Object sym
= XCAR (color_symbols
);
6481 || !STRINGP (XCAR (sym
))
6482 || !STRINGP (XCDR (sym
)))
6484 color_symbols
= XCDR (color_symbols
);
6487 return NILP (color_symbols
);
6491 /* Value is non-zero if OBJECT is a valid XPM image specification. */
6494 xpm_image_p (object
)
6497 struct image_keyword fmt
[XPM_LAST
];
6498 bcopy (xpm_format
, fmt
, sizeof fmt
);
6499 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
6500 /* Either `:file' or `:data' must be present. */
6501 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
6502 /* Either no `:color-symbols' or it's a list of conses
6503 whose car and cdr are strings. */
6504 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
6505 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
6509 /* Load image IMG which will be displayed on frame F. Value is
6510 non-zero if successful. */
6518 XpmAttributes attrs
;
6519 Lisp_Object specified_file
, color_symbols
;
6521 /* Configure the XPM lib. Use the visual of frame F. Allocate
6522 close colors. Return colors allocated. */
6523 bzero (&attrs
, sizeof attrs
);
6524 attrs
.visual
= FRAME_X_VISUAL (f
);
6525 attrs
.colormap
= FRAME_X_COLORMAP (f
);
6526 attrs
.valuemask
|= XpmVisual
;
6527 attrs
.valuemask
|= XpmColormap
;
6529 #ifdef ALLOC_XPM_COLORS
6530 /* Allocate colors with our own functions which handle
6531 failing color allocation more gracefully. */
6532 attrs
.color_closure
= f
;
6533 attrs
.alloc_color
= xpm_alloc_color
;
6534 attrs
.free_colors
= xpm_free_colors
;
6535 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
6536 #else /* not ALLOC_XPM_COLORS */
6537 /* Let the XPM lib allocate colors. */
6538 attrs
.valuemask
|= XpmReturnAllocPixels
;
6539 #ifdef XpmAllocCloseColors
6540 attrs
.alloc_close_colors
= 1;
6541 attrs
.valuemask
|= XpmAllocCloseColors
;
6542 #else /* not XpmAllocCloseColors */
6543 attrs
.closeness
= 600;
6544 attrs
.valuemask
|= XpmCloseness
;
6545 #endif /* not XpmAllocCloseColors */
6546 #endif /* ALLOC_XPM_COLORS */
6548 /* If image specification contains symbolic color definitions, add
6549 these to `attrs'. */
6550 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
6551 if (CONSP (color_symbols
))
6554 XpmColorSymbol
*xpm_syms
;
6557 attrs
.valuemask
|= XpmColorSymbols
;
6559 /* Count number of symbols. */
6560 attrs
.numsymbols
= 0;
6561 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
6564 /* Allocate an XpmColorSymbol array. */
6565 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
6566 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
6567 bzero (xpm_syms
, size
);
6568 attrs
.colorsymbols
= xpm_syms
;
6570 /* Fill the color symbol array. */
6571 for (tail
= color_symbols
, i
= 0;
6573 ++i
, tail
= XCDR (tail
))
6575 Lisp_Object name
= XCAR (XCAR (tail
));
6576 Lisp_Object color
= XCDR (XCAR (tail
));
6577 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
6578 strcpy (xpm_syms
[i
].name
, SDATA (name
));
6579 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
6580 strcpy (xpm_syms
[i
].value
, SDATA (color
));
6584 /* Create a pixmap for the image, either from a file, or from a
6585 string buffer containing data in the same format as an XPM file. */
6586 #ifdef ALLOC_XPM_COLORS
6587 xpm_init_color_cache (f
, &attrs
);
6590 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6591 if (STRINGP (specified_file
))
6593 Lisp_Object file
= x_find_image_file (specified_file
);
6594 if (!STRINGP (file
))
6596 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6600 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6601 SDATA (file
), &img
->pixmap
, &img
->mask
,
6606 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
6607 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6609 &img
->pixmap
, &img
->mask
,
6613 if (rc
== XpmSuccess
)
6615 #ifdef ALLOC_XPM_COLORS
6616 img
->colors
= colors_in_color_table (&img
->ncolors
);
6617 #else /* not ALLOC_XPM_COLORS */
6620 img
->ncolors
= attrs
.nalloc_pixels
;
6621 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
6622 * sizeof *img
->colors
);
6623 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
6625 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
6626 #ifdef DEBUG_X_COLORS
6627 register_color (img
->colors
[i
]);
6630 #endif /* not ALLOC_XPM_COLORS */
6632 img
->width
= attrs
.width
;
6633 img
->height
= attrs
.height
;
6634 xassert (img
->width
> 0 && img
->height
> 0);
6636 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
6637 XpmFreeAttributes (&attrs
);
6644 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
6647 case XpmFileInvalid
:
6648 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
6652 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
6655 case XpmColorFailed
:
6656 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
6660 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
6665 #ifdef ALLOC_XPM_COLORS
6666 xpm_free_color_cache ();
6668 return rc
== XpmSuccess
;
6671 #endif /* HAVE_XPM != 0 */
6674 /***********************************************************************
6676 ***********************************************************************/
6678 /* An entry in the color table mapping an RGB color to a pixel color. */
6683 unsigned long pixel
;
6685 /* Next in color table collision list. */
6686 struct ct_color
*next
;
6689 /* The bucket vector size to use. Must be prime. */
6693 /* Value is a hash of the RGB color given by R, G, and B. */
6695 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
6697 /* The color hash table. */
6699 struct ct_color
**ct_table
;
6701 /* Number of entries in the color table. */
6703 int ct_colors_allocated
;
6705 /* Initialize the color table. */
6710 int size
= CT_SIZE
* sizeof (*ct_table
);
6711 ct_table
= (struct ct_color
**) xmalloc (size
);
6712 bzero (ct_table
, size
);
6713 ct_colors_allocated
= 0;
6717 /* Free memory associated with the color table. */
6723 struct ct_color
*p
, *next
;
6725 for (i
= 0; i
< CT_SIZE
; ++i
)
6726 for (p
= ct_table
[i
]; p
; p
= next
)
6737 /* Value is a pixel color for RGB color R, G, B on frame F. If an
6738 entry for that color already is in the color table, return the
6739 pixel color of that entry. Otherwise, allocate a new color for R,
6740 G, B, and make an entry in the color table. */
6742 static unsigned long
6743 lookup_rgb_color (f
, r
, g
, b
)
6747 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
6748 int i
= hash
% CT_SIZE
;
6751 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6752 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
6765 cmap
= FRAME_X_COLORMAP (f
);
6766 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6770 ++ct_colors_allocated
;
6772 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6776 p
->pixel
= color
.pixel
;
6777 p
->next
= ct_table
[i
];
6781 return FRAME_FOREGROUND_PIXEL (f
);
6788 /* Look up pixel color PIXEL which is used on frame F in the color
6789 table. If not already present, allocate it. Value is PIXEL. */
6791 static unsigned long
6792 lookup_pixel_color (f
, pixel
)
6794 unsigned long pixel
;
6796 int i
= pixel
% CT_SIZE
;
6799 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6800 if (p
->pixel
== pixel
)
6809 cmap
= FRAME_X_COLORMAP (f
);
6810 color
.pixel
= pixel
;
6811 x_query_color (f
, &color
);
6812 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6816 ++ct_colors_allocated
;
6818 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6823 p
->next
= ct_table
[i
];
6827 return FRAME_FOREGROUND_PIXEL (f
);
6834 /* Value is a vector of all pixel colors contained in the color table,
6835 allocated via xmalloc. Set *N to the number of colors. */
6837 static unsigned long *
6838 colors_in_color_table (n
)
6843 unsigned long *colors
;
6845 if (ct_colors_allocated
== 0)
6852 colors
= (unsigned long *) xmalloc (ct_colors_allocated
6854 *n
= ct_colors_allocated
;
6856 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
6857 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6858 colors
[j
++] = p
->pixel
;
6866 /***********************************************************************
6868 ***********************************************************************/
6870 static XColor
*x_to_xcolors
P_ ((struct frame
*, struct image
*, int));
6871 static void x_from_xcolors
P_ ((struct frame
*, struct image
*, XColor
*));
6872 static void x_detect_edges
P_ ((struct frame
*, struct image
*, int[9], int));
6874 /* Non-zero means draw a cross on images having `:conversion
6877 int cross_disabled_images
;
6879 /* Edge detection matrices for different edge-detection
6882 static int emboss_matrix
[9] = {
6884 2, -1, 0, /* y - 1 */
6886 0, 1, -2 /* y + 1 */
6889 static int laplace_matrix
[9] = {
6891 1, 0, 0, /* y - 1 */
6893 0, 0, -1 /* y + 1 */
6896 /* Value is the intensity of the color whose red/green/blue values
6899 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
6902 /* On frame F, return an array of XColor structures describing image
6903 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
6904 non-zero means also fill the red/green/blue members of the XColor
6905 structures. Value is a pointer to the array of XColors structures,
6906 allocated with xmalloc; it must be freed by the caller. */
6909 x_to_xcolors (f
, img
, rgb_p
)
6918 colors
= (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *colors
);
6920 /* Get the X image IMG->pixmap. */
6921 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
6922 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
6924 /* Fill the `pixel' members of the XColor array. I wished there
6925 were an easy and portable way to circumvent XGetPixel. */
6927 for (y
= 0; y
< img
->height
; ++y
)
6931 for (x
= 0; x
< img
->width
; ++x
, ++p
)
6932 p
->pixel
= XGetPixel (ximg
, x
, y
);
6935 x_query_colors (f
, row
, img
->width
);
6938 XDestroyImage (ximg
);
6943 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
6944 RGB members are set. F is the frame on which this all happens.
6945 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
6948 x_from_xcolors (f
, img
, colors
)
6958 init_color_table ();
6960 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
6963 for (y
= 0; y
< img
->height
; ++y
)
6964 for (x
= 0; x
< img
->width
; ++x
, ++p
)
6966 unsigned long pixel
;
6967 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
6968 XPutPixel (oimg
, x
, y
, pixel
);
6972 x_clear_image_1 (f
, img
, 1, 0, 1);
6974 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
6975 x_destroy_x_image (oimg
);
6976 img
->pixmap
= pixmap
;
6977 img
->colors
= colors_in_color_table (&img
->ncolors
);
6978 free_color_table ();
6982 /* On frame F, perform edge-detection on image IMG.
6984 MATRIX is a nine-element array specifying the transformation
6985 matrix. See emboss_matrix for an example.
6987 COLOR_ADJUST is a color adjustment added to each pixel of the
6991 x_detect_edges (f
, img
, matrix
, color_adjust
)
6994 int matrix
[9], color_adjust
;
6996 XColor
*colors
= x_to_xcolors (f
, img
, 1);
7000 for (i
= sum
= 0; i
< 9; ++i
)
7001 sum
+= abs (matrix
[i
]);
7003 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
7005 new = (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *new);
7007 for (y
= 0; y
< img
->height
; ++y
)
7009 p
= COLOR (new, 0, y
);
7010 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7011 p
= COLOR (new, img
->width
- 1, y
);
7012 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7015 for (x
= 1; x
< img
->width
- 1; ++x
)
7017 p
= COLOR (new, x
, 0);
7018 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7019 p
= COLOR (new, x
, img
->height
- 1);
7020 p
->red
= p
->green
= p
->blue
= 0xffff/2;
7023 for (y
= 1; y
< img
->height
- 1; ++y
)
7025 p
= COLOR (new, 1, y
);
7027 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
7029 int r
, g
, b
, y1
, x1
;
7032 for (y1
= y
- 1; y1
< y
+ 2; ++y1
)
7033 for (x1
= x
- 1; x1
< x
+ 2; ++x1
, ++i
)
7036 XColor
*t
= COLOR (colors
, x1
, y1
);
7037 r
+= matrix
[i
] * t
->red
;
7038 g
+= matrix
[i
] * t
->green
;
7039 b
+= matrix
[i
] * t
->blue
;
7042 r
= (r
/ sum
+ color_adjust
) & 0xffff;
7043 g
= (g
/ sum
+ color_adjust
) & 0xffff;
7044 b
= (b
/ sum
+ color_adjust
) & 0xffff;
7045 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
7050 x_from_xcolors (f
, img
, new);
7056 /* Perform the pre-defined `emboss' edge-detection on image IMG
7064 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
7068 /* Perform the pre-defined `laplace' edge-detection on image IMG
7076 x_detect_edges (f
, img
, laplace_matrix
, 45000);
7080 /* Perform edge-detection on image IMG on frame F, with specified
7081 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
7083 MATRIX must be either
7085 - a list of at least 9 numbers in row-major form
7086 - a vector of at least 9 numbers
7088 COLOR_ADJUST nil means use a default; otherwise it must be a
7092 x_edge_detection (f
, img
, matrix
, color_adjust
)
7095 Lisp_Object matrix
, color_adjust
;
7103 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
7104 ++i
, matrix
= XCDR (matrix
))
7105 trans
[i
] = XFLOATINT (XCAR (matrix
));
7107 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
7109 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
7110 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
7113 if (NILP (color_adjust
))
7114 color_adjust
= make_number (0xffff / 2);
7116 if (i
== 9 && NUMBERP (color_adjust
))
7117 x_detect_edges (f
, img
, trans
, (int) XFLOATINT (color_adjust
));
7121 /* Transform image IMG on frame F so that it looks disabled. */
7124 x_disable_image (f
, img
)
7128 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7130 if (dpyinfo
->n_planes
>= 2)
7132 /* Color (or grayscale). Convert to gray, and equalize. Just
7133 drawing such images with a stipple can look very odd, so
7134 we're using this method instead. */
7135 XColor
*colors
= x_to_xcolors (f
, img
, 1);
7137 const int h
= 15000;
7138 const int l
= 30000;
7140 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
7144 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
7145 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
7146 p
->red
= p
->green
= p
->blue
= i2
;
7149 x_from_xcolors (f
, img
, colors
);
7152 /* Draw a cross over the disabled image, if we must or if we
7154 if (dpyinfo
->n_planes
< 2 || cross_disabled_images
)
7156 Display
*dpy
= FRAME_X_DISPLAY (f
);
7159 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
7160 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
7161 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
7162 img
->width
- 1, img
->height
- 1);
7163 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
7169 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
7170 XSetForeground (dpy
, gc
, WHITE_PIX_DEFAULT (f
));
7171 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
7172 img
->width
- 1, img
->height
- 1);
7173 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
7181 /* Build a mask for image IMG which is used on frame F. FILE is the
7182 name of an image file, for error messages. HOW determines how to
7183 determine the background color of IMG. If it is a list '(R G B)',
7184 with R, G, and B being integers >= 0, take that as the color of the
7185 background. Otherwise, determine the background color of IMG
7186 heuristically. Value is non-zero if successful. */
7189 x_build_heuristic_mask (f
, img
, how
)
7194 Display
*dpy
= FRAME_X_DISPLAY (f
);
7195 XImage
*ximg
, *mask_img
;
7196 int x
, y
, rc
, use_img_background
;
7197 unsigned long bg
= 0;
7201 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
7203 img
->background_transparent_valid
= 0;
7206 /* Create an image and pixmap serving as mask. */
7207 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
7208 &mask_img
, &img
->mask
);
7212 /* Get the X image of IMG->pixmap. */
7213 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
7216 /* Determine the background color of ximg. If HOW is `(R G B)'
7217 take that as color. Otherwise, use the image's background color. */
7218 use_img_background
= 1;
7224 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
7226 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
7230 if (i
== 3 && NILP (how
))
7232 char color_name
[30];
7233 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
7234 bg
= x_alloc_image_color (f
, img
, build_string (color_name
), 0);
7235 use_img_background
= 0;
7239 if (use_img_background
)
7240 bg
= four_corners_best (ximg
, img
->width
, img
->height
);
7242 /* Set all bits in mask_img to 1 whose color in ximg is different
7243 from the background color bg. */
7244 for (y
= 0; y
< img
->height
; ++y
)
7245 for (x
= 0; x
< img
->width
; ++x
)
7246 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
7248 /* Fill in the background_transparent field while we have the mask handy. */
7249 image_background_transparent (img
, f
, mask_img
);
7251 /* Put mask_img into img->mask. */
7252 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
7253 x_destroy_x_image (mask_img
);
7254 XDestroyImage (ximg
);
7261 /***********************************************************************
7262 PBM (mono, gray, color)
7263 ***********************************************************************/
7265 static int pbm_image_p
P_ ((Lisp_Object object
));
7266 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
7267 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
7269 /* The symbol `pbm' identifying images of this type. */
7273 /* Indices of image specification fields in gs_format, below. */
7275 enum pbm_keyword_index
7291 /* Vector of image_keyword structures describing the format
7292 of valid user-defined image specifications. */
7294 static struct image_keyword pbm_format
[PBM_LAST
] =
7296 {":type", IMAGE_SYMBOL_VALUE
, 1},
7297 {":file", IMAGE_STRING_VALUE
, 0},
7298 {":data", IMAGE_STRING_VALUE
, 0},
7299 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7300 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7301 {":relief", IMAGE_INTEGER_VALUE
, 0},
7302 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7303 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7304 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7305 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
7306 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7309 /* Structure describing the image type `pbm'. */
7311 static struct image_type pbm_type
=
7321 /* Return non-zero if OBJECT is a valid PBM image specification. */
7324 pbm_image_p (object
)
7327 struct image_keyword fmt
[PBM_LAST
];
7329 bcopy (pbm_format
, fmt
, sizeof fmt
);
7331 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
7334 /* Must specify either :data or :file. */
7335 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
7339 /* Scan a decimal number from *S and return it. Advance *S while
7340 reading the number. END is the end of the string. Value is -1 at
7344 pbm_scan_number (s
, end
)
7345 unsigned char **s
, *end
;
7347 int c
= 0, val
= -1;
7351 /* Skip white-space. */
7352 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
7357 /* Skip comment to end of line. */
7358 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
7361 else if (isdigit (c
))
7363 /* Read decimal number. */
7365 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
7366 val
= 10 * val
+ c
- '0';
7377 /* Load PBM image IMG for use on frame F. */
7385 int width
, height
, max_color_idx
= 0;
7387 Lisp_Object file
, specified_file
;
7388 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
7389 struct gcpro gcpro1
;
7390 unsigned char *contents
= NULL
;
7391 unsigned char *end
, *p
;
7394 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7398 if (STRINGP (specified_file
))
7400 file
= x_find_image_file (specified_file
);
7401 if (!STRINGP (file
))
7403 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7408 contents
= slurp_file (SDATA (file
), &size
);
7409 if (contents
== NULL
)
7411 image_error ("Error reading `%s'", file
, Qnil
);
7417 end
= contents
+ size
;
7422 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7424 end
= p
+ SBYTES (data
);
7427 /* Check magic number. */
7428 if (end
- p
< 2 || *p
++ != 'P')
7430 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7440 raw_p
= 0, type
= PBM_MONO
;
7444 raw_p
= 0, type
= PBM_GRAY
;
7448 raw_p
= 0, type
= PBM_COLOR
;
7452 raw_p
= 1, type
= PBM_MONO
;
7456 raw_p
= 1, type
= PBM_GRAY
;
7460 raw_p
= 1, type
= PBM_COLOR
;
7464 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7468 /* Read width, height, maximum color-component. Characters
7469 starting with `#' up to the end of a line are ignored. */
7470 width
= pbm_scan_number (&p
, end
);
7471 height
= pbm_scan_number (&p
, end
);
7473 if (type
!= PBM_MONO
)
7475 max_color_idx
= pbm_scan_number (&p
, end
);
7476 if (raw_p
&& max_color_idx
> 255)
7477 max_color_idx
= 255;
7482 || (type
!= PBM_MONO
&& max_color_idx
< 0))
7485 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7486 &ximg
, &img
->pixmap
))
7489 /* Initialize the color hash table. */
7490 init_color_table ();
7492 if (type
== PBM_MONO
)
7495 struct image_keyword fmt
[PBM_LAST
];
7496 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
7497 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
7499 /* Parse the image specification. */
7500 bcopy (pbm_format
, fmt
, sizeof fmt
);
7501 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
7503 /* Get foreground and background colors, maybe allocate colors. */
7504 if (fmt
[PBM_FOREGROUND
].count
7505 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
7506 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
7507 if (fmt
[PBM_BACKGROUND
].count
7508 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
7510 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
7511 img
->background
= bg
;
7512 img
->background_valid
= 1;
7515 for (y
= 0; y
< height
; ++y
)
7516 for (x
= 0; x
< width
; ++x
)
7526 g
= pbm_scan_number (&p
, end
);
7528 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
7533 for (y
= 0; y
< height
; ++y
)
7534 for (x
= 0; x
< width
; ++x
)
7538 if (type
== PBM_GRAY
)
7539 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
7548 r
= pbm_scan_number (&p
, end
);
7549 g
= pbm_scan_number (&p
, end
);
7550 b
= pbm_scan_number (&p
, end
);
7553 if (r
< 0 || g
< 0 || b
< 0)
7557 XDestroyImage (ximg
);
7558 image_error ("Invalid pixel value in image `%s'",
7563 /* RGB values are now in the range 0..max_color_idx.
7564 Scale this to the range 0..0xffff supported by X. */
7565 r
= (double) r
* 65535 / max_color_idx
;
7566 g
= (double) g
* 65535 / max_color_idx
;
7567 b
= (double) b
* 65535 / max_color_idx
;
7568 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7572 /* Store in IMG->colors the colors allocated for the image, and
7573 free the color table. */
7574 img
->colors
= colors_in_color_table (&img
->ncolors
);
7575 free_color_table ();
7577 /* Maybe fill in the background field while we have ximg handy. */
7578 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7579 IMAGE_BACKGROUND (img
, f
, ximg
);
7581 /* Put the image into a pixmap. */
7582 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7583 x_destroy_x_image (ximg
);
7586 img
->height
= height
;
7595 /***********************************************************************
7597 ***********************************************************************/
7601 #if defined HAVE_LIBPNG_PNG_H
7602 # include <libpng/png.h>
7607 /* Function prototypes. */
7609 static int png_image_p
P_ ((Lisp_Object object
));
7610 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
7612 /* The symbol `png' identifying images of this type. */
7616 /* Indices of image specification fields in png_format, below. */
7618 enum png_keyword_index
7633 /* Vector of image_keyword structures describing the format
7634 of valid user-defined image specifications. */
7636 static struct image_keyword png_format
[PNG_LAST
] =
7638 {":type", IMAGE_SYMBOL_VALUE
, 1},
7639 {":data", IMAGE_STRING_VALUE
, 0},
7640 {":file", IMAGE_STRING_VALUE
, 0},
7641 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7642 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7643 {":relief", IMAGE_INTEGER_VALUE
, 0},
7644 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7645 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7646 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7647 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7650 /* Structure describing the image type `png'. */
7652 static struct image_type png_type
=
7662 /* Return non-zero if OBJECT is a valid PNG image specification. */
7665 png_image_p (object
)
7668 struct image_keyword fmt
[PNG_LAST
];
7669 bcopy (png_format
, fmt
, sizeof fmt
);
7671 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
7674 /* Must specify either the :data or :file keyword. */
7675 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
7679 /* Error and warning handlers installed when the PNG library
7683 my_png_error (png_ptr
, msg
)
7684 png_struct
*png_ptr
;
7687 xassert (png_ptr
!= NULL
);
7688 image_error ("PNG error: %s", build_string (msg
), Qnil
);
7689 longjmp (png_ptr
->jmpbuf
, 1);
7694 my_png_warning (png_ptr
, msg
)
7695 png_struct
*png_ptr
;
7698 xassert (png_ptr
!= NULL
);
7699 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
7702 /* Memory source for PNG decoding. */
7704 struct png_memory_storage
7706 unsigned char *bytes
; /* The data */
7707 size_t len
; /* How big is it? */
7708 int index
; /* Where are we? */
7712 /* Function set as reader function when reading PNG image from memory.
7713 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
7714 bytes from the input to DATA. */
7717 png_read_from_memory (png_ptr
, data
, length
)
7718 png_structp png_ptr
;
7722 struct png_memory_storage
*tbr
7723 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
7725 if (length
> tbr
->len
- tbr
->index
)
7726 png_error (png_ptr
, "Read error");
7728 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
7729 tbr
->index
= tbr
->index
+ length
;
7732 /* Load PNG image IMG for use on frame F. Value is non-zero if
7740 Lisp_Object file
, specified_file
;
7741 Lisp_Object specified_data
;
7743 XImage
*ximg
, *mask_img
= NULL
;
7744 struct gcpro gcpro1
;
7745 png_struct
*png_ptr
= NULL
;
7746 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
7747 FILE *volatile fp
= NULL
;
7749 png_byte
* volatile pixels
= NULL
;
7750 png_byte
** volatile rows
= NULL
;
7751 png_uint_32 width
, height
;
7752 int bit_depth
, color_type
, interlace_type
;
7754 png_uint_32 row_bytes
;
7756 double screen_gamma
;
7757 struct png_memory_storage tbr
; /* Data to be read */
7759 /* Find out what file to load. */
7760 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7761 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7765 if (NILP (specified_data
))
7767 file
= x_find_image_file (specified_file
);
7768 if (!STRINGP (file
))
7770 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7775 /* Open the image file. */
7776 fp
= fopen (SDATA (file
), "rb");
7779 image_error ("Cannot open image file `%s'", file
, Qnil
);
7785 /* Check PNG signature. */
7786 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
7787 || !png_check_sig (sig
, sizeof sig
))
7789 image_error ("Not a PNG file: `%s'", file
, Qnil
);
7797 /* Read from memory. */
7798 tbr
.bytes
= SDATA (specified_data
);
7799 tbr
.len
= SBYTES (specified_data
);
7802 /* Check PNG signature. */
7803 if (tbr
.len
< sizeof sig
7804 || !png_check_sig (tbr
.bytes
, sizeof sig
))
7806 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
7811 /* Need to skip past the signature. */
7812 tbr
.bytes
+= sizeof (sig
);
7815 /* Initialize read and info structs for PNG lib. */
7816 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
7817 my_png_error
, my_png_warning
);
7820 if (fp
) fclose (fp
);
7825 info_ptr
= png_create_info_struct (png_ptr
);
7828 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
7829 if (fp
) fclose (fp
);
7834 end_info
= png_create_info_struct (png_ptr
);
7837 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
7838 if (fp
) fclose (fp
);
7843 /* Set error jump-back. We come back here when the PNG library
7844 detects an error. */
7845 if (setjmp (png_ptr
->jmpbuf
))
7849 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7852 if (fp
) fclose (fp
);
7857 /* Read image info. */
7858 if (!NILP (specified_data
))
7859 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
7861 png_init_io (png_ptr
, fp
);
7863 png_set_sig_bytes (png_ptr
, sizeof sig
);
7864 png_read_info (png_ptr
, info_ptr
);
7865 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
7866 &interlace_type
, NULL
, NULL
);
7868 /* If image contains simply transparency data, we prefer to
7869 construct a clipping mask. */
7870 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
7875 /* This function is easier to write if we only have to handle
7876 one data format: RGB or RGBA with 8 bits per channel. Let's
7877 transform other formats into that format. */
7879 /* Strip more than 8 bits per channel. */
7880 if (bit_depth
== 16)
7881 png_set_strip_16 (png_ptr
);
7883 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
7885 png_set_expand (png_ptr
);
7887 /* Convert grayscale images to RGB. */
7888 if (color_type
== PNG_COLOR_TYPE_GRAY
7889 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
7890 png_set_gray_to_rgb (png_ptr
);
7892 screen_gamma
= (f
->gamma
? 1 / f
->gamma
/ 0.45455 : 2.2);
7894 #if 0 /* Avoid double gamma correction for PNG images. */
7895 { /* Tell the PNG lib to handle gamma correction for us. */
7898 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
7899 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
7900 /* The libpng documentation says this is right in this case. */
7901 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7904 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
7905 /* Image contains gamma information. */
7906 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
7908 /* Use the standard default for the image gamma. */
7909 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7913 /* Handle alpha channel by combining the image with a background
7914 color. Do this only if a real alpha channel is supplied. For
7915 simple transparency, we prefer a clipping mask. */
7918 png_color_16
*image_bg
;
7919 Lisp_Object specified_bg
7920 = image_spec_value (img
->spec
, QCbackground
, NULL
);
7922 if (STRINGP (specified_bg
))
7923 /* The user specified `:background', use that. */
7926 if (x_defined_color (f
, SDATA (specified_bg
), &color
, 0))
7928 png_color_16 user_bg
;
7930 bzero (&user_bg
, sizeof user_bg
);
7931 user_bg
.red
= color
.red
;
7932 user_bg
.green
= color
.green
;
7933 user_bg
.blue
= color
.blue
;
7935 png_set_background (png_ptr
, &user_bg
,
7936 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7939 else if (png_get_bKGD (png_ptr
, info_ptr
, &image_bg
))
7940 /* Image contains a background color with which to
7941 combine the image. */
7942 png_set_background (png_ptr
, image_bg
,
7943 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
7946 /* Image does not contain a background color with which
7947 to combine the image data via an alpha channel. Use
7948 the frame's background instead. */
7951 png_color_16 frame_background
;
7953 cmap
= FRAME_X_COLORMAP (f
);
7954 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7955 x_query_color (f
, &color
);
7957 bzero (&frame_background
, sizeof frame_background
);
7958 frame_background
.red
= color
.red
;
7959 frame_background
.green
= color
.green
;
7960 frame_background
.blue
= color
.blue
;
7962 png_set_background (png_ptr
, &frame_background
,
7963 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7967 /* Update info structure. */
7968 png_read_update_info (png_ptr
, info_ptr
);
7970 /* Get number of channels. Valid values are 1 for grayscale images
7971 and images with a palette, 2 for grayscale images with transparency
7972 information (alpha channel), 3 for RGB images, and 4 for RGB
7973 images with alpha channel, i.e. RGBA. If conversions above were
7974 sufficient we should only have 3 or 4 channels here. */
7975 channels
= png_get_channels (png_ptr
, info_ptr
);
7976 xassert (channels
== 3 || channels
== 4);
7978 /* Number of bytes needed for one row of the image. */
7979 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
7981 /* Allocate memory for the image. */
7982 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
7983 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
7984 for (i
= 0; i
< height
; ++i
)
7985 rows
[i
] = pixels
+ i
* row_bytes
;
7987 /* Read the entire image. */
7988 png_read_image (png_ptr
, rows
);
7989 png_read_end (png_ptr
, info_ptr
);
7996 /* Create the X image and pixmap. */
7997 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
8001 /* Create an image and pixmap serving as mask if the PNG image
8002 contains an alpha channel. */
8005 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
8006 &mask_img
, &img
->mask
))
8008 x_destroy_x_image (ximg
);
8009 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
8014 /* Fill the X image and mask from PNG data. */
8015 init_color_table ();
8017 for (y
= 0; y
< height
; ++y
)
8019 png_byte
*p
= rows
[y
];
8021 for (x
= 0; x
< width
; ++x
)
8028 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
8030 /* An alpha channel, aka mask channel, associates variable
8031 transparency with an image. Where other image formats
8032 support binary transparency---fully transparent or fully
8033 opaque---PNG allows up to 254 levels of partial transparency.
8034 The PNG library implements partial transparency by combining
8035 the image with a specified background color.
8037 I'm not sure how to handle this here nicely: because the
8038 background on which the image is displayed may change, for
8039 real alpha channel support, it would be necessary to create
8040 a new image for each possible background.
8042 What I'm doing now is that a mask is created if we have
8043 boolean transparency information. Otherwise I'm using
8044 the frame's background color to combine the image with. */
8049 XPutPixel (mask_img
, x
, y
, *p
> 0);
8055 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8056 /* Set IMG's background color from the PNG image, unless the user
8060 if (png_get_bKGD (png_ptr
, info_ptr
, &bg
))
8062 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
8063 img
->background_valid
= 1;
8067 /* Remember colors allocated for this image. */
8068 img
->colors
= colors_in_color_table (&img
->ncolors
);
8069 free_color_table ();
8072 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
8077 img
->height
= height
;
8079 /* Maybe fill in the background field while we have ximg handy. */
8080 IMAGE_BACKGROUND (img
, f
, ximg
);
8082 /* Put the image into the pixmap, then free the X image and its buffer. */
8083 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8084 x_destroy_x_image (ximg
);
8086 /* Same for the mask. */
8089 /* Fill in the background_transparent field while we have the mask
8091 image_background_transparent (img
, f
, mask_img
);
8093 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
8094 x_destroy_x_image (mask_img
);
8101 #endif /* HAVE_PNG != 0 */
8105 /***********************************************************************
8107 ***********************************************************************/
8111 /* Work around a warning about HAVE_STDLIB_H being redefined in
8113 #ifdef HAVE_STDLIB_H
8114 #define HAVE_STDLIB_H_1
8115 #undef HAVE_STDLIB_H
8116 #endif /* HAVE_STLIB_H */
8118 #include <jpeglib.h>
8122 #ifdef HAVE_STLIB_H_1
8123 #define HAVE_STDLIB_H 1
8126 static int jpeg_image_p
P_ ((Lisp_Object object
));
8127 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
8129 /* The symbol `jpeg' identifying images of this type. */
8133 /* Indices of image specification fields in gs_format, below. */
8135 enum jpeg_keyword_index
8144 JPEG_HEURISTIC_MASK
,
8150 /* Vector of image_keyword structures describing the format
8151 of valid user-defined image specifications. */
8153 static struct image_keyword jpeg_format
[JPEG_LAST
] =
8155 {":type", IMAGE_SYMBOL_VALUE
, 1},
8156 {":data", IMAGE_STRING_VALUE
, 0},
8157 {":file", IMAGE_STRING_VALUE
, 0},
8158 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8159 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8160 {":relief", IMAGE_INTEGER_VALUE
, 0},
8161 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8162 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8163 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8164 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8167 /* Structure describing the image type `jpeg'. */
8169 static struct image_type jpeg_type
=
8179 /* Return non-zero if OBJECT is a valid JPEG image specification. */
8182 jpeg_image_p (object
)
8185 struct image_keyword fmt
[JPEG_LAST
];
8187 bcopy (jpeg_format
, fmt
, sizeof fmt
);
8189 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
8192 /* Must specify either the :data or :file keyword. */
8193 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
8197 struct my_jpeg_error_mgr
8199 struct jpeg_error_mgr pub
;
8200 jmp_buf setjmp_buffer
;
8205 my_error_exit (cinfo
)
8208 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
8209 longjmp (mgr
->setjmp_buffer
, 1);
8213 /* Init source method for JPEG data source manager. Called by
8214 jpeg_read_header() before any data is actually read. See
8215 libjpeg.doc from the JPEG lib distribution. */
8218 our_init_source (cinfo
)
8219 j_decompress_ptr cinfo
;
8224 /* Fill input buffer method for JPEG data source manager. Called
8225 whenever more data is needed. We read the whole image in one step,
8226 so this only adds a fake end of input marker at the end. */
8229 our_fill_input_buffer (cinfo
)
8230 j_decompress_ptr cinfo
;
8232 /* Insert a fake EOI marker. */
8233 struct jpeg_source_mgr
*src
= cinfo
->src
;
8234 static JOCTET buffer
[2];
8236 buffer
[0] = (JOCTET
) 0xFF;
8237 buffer
[1] = (JOCTET
) JPEG_EOI
;
8239 src
->next_input_byte
= buffer
;
8240 src
->bytes_in_buffer
= 2;
8245 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
8246 is the JPEG data source manager. */
8249 our_skip_input_data (cinfo
, num_bytes
)
8250 j_decompress_ptr cinfo
;
8253 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8257 if (num_bytes
> src
->bytes_in_buffer
)
8258 ERREXIT (cinfo
, JERR_INPUT_EOF
);
8260 src
->bytes_in_buffer
-= num_bytes
;
8261 src
->next_input_byte
+= num_bytes
;
8266 /* Method to terminate data source. Called by
8267 jpeg_finish_decompress() after all data has been processed. */
8270 our_term_source (cinfo
)
8271 j_decompress_ptr cinfo
;
8276 /* Set up the JPEG lib for reading an image from DATA which contains
8277 LEN bytes. CINFO is the decompression info structure created for
8278 reading the image. */
8281 jpeg_memory_src (cinfo
, data
, len
)
8282 j_decompress_ptr cinfo
;
8286 struct jpeg_source_mgr
*src
;
8288 if (cinfo
->src
== NULL
)
8290 /* First time for this JPEG object? */
8291 cinfo
->src
= (struct jpeg_source_mgr
*)
8292 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
8293 sizeof (struct jpeg_source_mgr
));
8294 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8295 src
->next_input_byte
= data
;
8298 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8299 src
->init_source
= our_init_source
;
8300 src
->fill_input_buffer
= our_fill_input_buffer
;
8301 src
->skip_input_data
= our_skip_input_data
;
8302 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
8303 src
->term_source
= our_term_source
;
8304 src
->bytes_in_buffer
= len
;
8305 src
->next_input_byte
= data
;
8309 /* Load image IMG for use on frame F. Patterned after example.c
8310 from the JPEG lib. */
8317 struct jpeg_decompress_struct cinfo
;
8318 struct my_jpeg_error_mgr mgr
;
8319 Lisp_Object file
, specified_file
;
8320 Lisp_Object specified_data
;
8321 FILE * volatile fp
= NULL
;
8323 int row_stride
, x
, y
;
8324 XImage
*ximg
= NULL
;
8326 unsigned long *colors
;
8328 struct gcpro gcpro1
;
8330 /* Open the JPEG file. */
8331 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8332 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8336 if (NILP (specified_data
))
8338 file
= x_find_image_file (specified_file
);
8339 if (!STRINGP (file
))
8341 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8346 fp
= fopen (SDATA (file
), "r");
8349 image_error ("Cannot open `%s'", file
, Qnil
);
8355 /* Customize libjpeg's error handling to call my_error_exit when an
8356 error is detected. This function will perform a longjmp. */
8357 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
8358 mgr
.pub
.error_exit
= my_error_exit
;
8360 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
8364 /* Called from my_error_exit. Display a JPEG error. */
8365 char buffer
[JMSG_LENGTH_MAX
];
8366 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
8367 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
8368 build_string (buffer
));
8371 /* Close the input file and destroy the JPEG object. */
8373 fclose ((FILE *) fp
);
8374 jpeg_destroy_decompress (&cinfo
);
8376 /* If we already have an XImage, free that. */
8377 x_destroy_x_image (ximg
);
8379 /* Free pixmap and colors. */
8380 x_clear_image (f
, img
);
8386 /* Create the JPEG decompression object. Let it read from fp.
8387 Read the JPEG image header. */
8388 jpeg_create_decompress (&cinfo
);
8390 if (NILP (specified_data
))
8391 jpeg_stdio_src (&cinfo
, (FILE *) fp
);
8393 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
8394 SBYTES (specified_data
));
8396 jpeg_read_header (&cinfo
, TRUE
);
8398 /* Customize decompression so that color quantization will be used.
8399 Start decompression. */
8400 cinfo
.quantize_colors
= TRUE
;
8401 jpeg_start_decompress (&cinfo
);
8402 width
= img
->width
= cinfo
.output_width
;
8403 height
= img
->height
= cinfo
.output_height
;
8405 /* Create X image and pixmap. */
8406 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8407 longjmp (mgr
.setjmp_buffer
, 2);
8409 /* Allocate colors. When color quantization is used,
8410 cinfo.actual_number_of_colors has been set with the number of
8411 colors generated, and cinfo.colormap is a two-dimensional array
8412 of color indices in the range 0..cinfo.actual_number_of_colors.
8413 No more than 255 colors will be generated. */
8417 if (cinfo
.out_color_components
> 2)
8418 ir
= 0, ig
= 1, ib
= 2;
8419 else if (cinfo
.out_color_components
> 1)
8420 ir
= 0, ig
= 1, ib
= 0;
8422 ir
= 0, ig
= 0, ib
= 0;
8424 /* Use the color table mechanism because it handles colors that
8425 cannot be allocated nicely. Such colors will be replaced with
8426 a default color, and we don't have to care about which colors
8427 can be freed safely, and which can't. */
8428 init_color_table ();
8429 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
8432 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
8434 /* Multiply RGB values with 255 because X expects RGB values
8435 in the range 0..0xffff. */
8436 int r
= cinfo
.colormap
[ir
][i
] << 8;
8437 int g
= cinfo
.colormap
[ig
][i
] << 8;
8438 int b
= cinfo
.colormap
[ib
][i
] << 8;
8439 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8442 /* Remember those colors actually allocated. */
8443 img
->colors
= colors_in_color_table (&img
->ncolors
);
8444 free_color_table ();
8448 row_stride
= width
* cinfo
.output_components
;
8449 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
8451 for (y
= 0; y
< height
; ++y
)
8453 jpeg_read_scanlines (&cinfo
, buffer
, 1);
8454 for (x
= 0; x
< cinfo
.output_width
; ++x
)
8455 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
8459 jpeg_finish_decompress (&cinfo
);
8460 jpeg_destroy_decompress (&cinfo
);
8462 fclose ((FILE *) fp
);
8464 /* Maybe fill in the background field while we have ximg handy. */
8465 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8466 IMAGE_BACKGROUND (img
, f
, ximg
);
8468 /* Put the image into the pixmap. */
8469 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8470 x_destroy_x_image (ximg
);
8475 #endif /* HAVE_JPEG */
8479 /***********************************************************************
8481 ***********************************************************************/
8487 static int tiff_image_p
P_ ((Lisp_Object object
));
8488 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
8490 /* The symbol `tiff' identifying images of this type. */
8494 /* Indices of image specification fields in tiff_format, below. */
8496 enum tiff_keyword_index
8505 TIFF_HEURISTIC_MASK
,
8511 /* Vector of image_keyword structures describing the format
8512 of valid user-defined image specifications. */
8514 static struct image_keyword tiff_format
[TIFF_LAST
] =
8516 {":type", IMAGE_SYMBOL_VALUE
, 1},
8517 {":data", IMAGE_STRING_VALUE
, 0},
8518 {":file", IMAGE_STRING_VALUE
, 0},
8519 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8520 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8521 {":relief", IMAGE_INTEGER_VALUE
, 0},
8522 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8523 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8524 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8525 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8528 /* Structure describing the image type `tiff'. */
8530 static struct image_type tiff_type
=
8540 /* Return non-zero if OBJECT is a valid TIFF image specification. */
8543 tiff_image_p (object
)
8546 struct image_keyword fmt
[TIFF_LAST
];
8547 bcopy (tiff_format
, fmt
, sizeof fmt
);
8549 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
8552 /* Must specify either the :data or :file keyword. */
8553 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
8557 /* Reading from a memory buffer for TIFF images Based on the PNG
8558 memory source, but we have to provide a lot of extra functions.
8561 We really only need to implement read and seek, but I am not
8562 convinced that the TIFF library is smart enough not to destroy
8563 itself if we only hand it the function pointers we need to
8568 unsigned char *bytes
;
8576 tiff_read_from_memory (data
, buf
, size
)
8581 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8583 if (size
> src
->len
- src
->index
)
8585 bcopy (src
->bytes
+ src
->index
, buf
, size
);
8592 tiff_write_from_memory (data
, buf
, size
)
8602 tiff_seek_in_memory (data
, off
, whence
)
8607 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8612 case SEEK_SET
: /* Go from beginning of source. */
8616 case SEEK_END
: /* Go from end of source. */
8617 idx
= src
->len
+ off
;
8620 case SEEK_CUR
: /* Go from current position. */
8621 idx
= src
->index
+ off
;
8624 default: /* Invalid `whence'. */
8628 if (idx
> src
->len
|| idx
< 0)
8637 tiff_close_memory (data
)
8646 tiff_mmap_memory (data
, pbase
, psize
)
8651 /* It is already _IN_ memory. */
8657 tiff_unmap_memory (data
, base
, size
)
8662 /* We don't need to do this. */
8667 tiff_size_of_memory (data
)
8670 return ((tiff_memory_source
*) data
)->len
;
8675 tiff_error_handler (title
, format
, ap
)
8676 const char *title
, *format
;
8682 len
= sprintf (buf
, "TIFF error: %s ", title
);
8683 vsprintf (buf
+ len
, format
, ap
);
8684 add_to_log (buf
, Qnil
, Qnil
);
8689 tiff_warning_handler (title
, format
, ap
)
8690 const char *title
, *format
;
8696 len
= sprintf (buf
, "TIFF warning: %s ", title
);
8697 vsprintf (buf
+ len
, format
, ap
);
8698 add_to_log (buf
, Qnil
, Qnil
);
8702 /* Load TIFF image IMG for use on frame F. Value is non-zero if
8710 Lisp_Object file
, specified_file
;
8711 Lisp_Object specified_data
;
8713 int width
, height
, x
, y
;
8717 struct gcpro gcpro1
;
8718 tiff_memory_source memsrc
;
8720 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8721 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8725 TIFFSetErrorHandler (tiff_error_handler
);
8726 TIFFSetWarningHandler (tiff_warning_handler
);
8728 if (NILP (specified_data
))
8730 /* Read from a file */
8731 file
= x_find_image_file (specified_file
);
8732 if (!STRINGP (file
))
8734 image_error ("Cannot find image file `%s'", file
, Qnil
);
8739 /* Try to open the image file. */
8740 tiff
= TIFFOpen (SDATA (file
), "r");
8743 image_error ("Cannot open `%s'", file
, Qnil
);
8750 /* Memory source! */
8751 memsrc
.bytes
= SDATA (specified_data
);
8752 memsrc
.len
= SBYTES (specified_data
);
8755 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
8756 (TIFFReadWriteProc
) tiff_read_from_memory
,
8757 (TIFFReadWriteProc
) tiff_write_from_memory
,
8758 tiff_seek_in_memory
,
8760 tiff_size_of_memory
,
8766 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
8772 /* Get width and height of the image, and allocate a raster buffer
8773 of width x height 32-bit values. */
8774 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
8775 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
8776 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
8778 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
8782 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
8788 /* Create the X image and pixmap. */
8789 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8796 /* Initialize the color table. */
8797 init_color_table ();
8799 /* Process the pixel raster. Origin is in the lower-left corner. */
8800 for (y
= 0; y
< height
; ++y
)
8802 uint32
*row
= buf
+ y
* width
;
8804 for (x
= 0; x
< width
; ++x
)
8806 uint32 abgr
= row
[x
];
8807 int r
= TIFFGetR (abgr
) << 8;
8808 int g
= TIFFGetG (abgr
) << 8;
8809 int b
= TIFFGetB (abgr
) << 8;
8810 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
8814 /* Remember the colors allocated for the image. Free the color table. */
8815 img
->colors
= colors_in_color_table (&img
->ncolors
);
8816 free_color_table ();
8819 img
->height
= height
;
8821 /* Maybe fill in the background field while we have ximg handy. */
8822 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8823 IMAGE_BACKGROUND (img
, f
, ximg
);
8825 /* Put the image into the pixmap, then free the X image and its buffer. */
8826 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8827 x_destroy_x_image (ximg
);
8834 #endif /* HAVE_TIFF != 0 */
8838 /***********************************************************************
8840 ***********************************************************************/
8844 #include <gif_lib.h>
8846 static int gif_image_p
P_ ((Lisp_Object object
));
8847 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
8849 /* The symbol `gif' identifying images of this type. */
8853 /* Indices of image specification fields in gif_format, below. */
8855 enum gif_keyword_index
8871 /* Vector of image_keyword structures describing the format
8872 of valid user-defined image specifications. */
8874 static struct image_keyword gif_format
[GIF_LAST
] =
8876 {":type", IMAGE_SYMBOL_VALUE
, 1},
8877 {":data", IMAGE_STRING_VALUE
, 0},
8878 {":file", IMAGE_STRING_VALUE
, 0},
8879 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8880 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8881 {":relief", IMAGE_INTEGER_VALUE
, 0},
8882 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8883 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8884 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8885 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8886 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8889 /* Structure describing the image type `gif'. */
8891 static struct image_type gif_type
=
8901 /* Return non-zero if OBJECT is a valid GIF image specification. */
8904 gif_image_p (object
)
8907 struct image_keyword fmt
[GIF_LAST
];
8908 bcopy (gif_format
, fmt
, sizeof fmt
);
8910 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
8913 /* Must specify either the :data or :file keyword. */
8914 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
8918 /* Reading a GIF image from memory
8919 Based on the PNG memory stuff to a certain extent. */
8923 unsigned char *bytes
;
8930 /* Make the current memory source available to gif_read_from_memory.
8931 It's done this way because not all versions of libungif support
8932 a UserData field in the GifFileType structure. */
8933 static gif_memory_source
*current_gif_memory_src
;
8936 gif_read_from_memory (file
, buf
, len
)
8941 gif_memory_source
*src
= current_gif_memory_src
;
8943 if (len
> src
->len
- src
->index
)
8946 bcopy (src
->bytes
+ src
->index
, buf
, len
);
8952 /* Load GIF image IMG for use on frame F. Value is non-zero if
8960 Lisp_Object file
, specified_file
;
8961 Lisp_Object specified_data
;
8962 int rc
, width
, height
, x
, y
, i
;
8964 ColorMapObject
*gif_color_map
;
8965 unsigned long pixel_colors
[256];
8967 struct gcpro gcpro1
;
8969 int ino
, image_left
, image_top
, image_width
, image_height
;
8970 gif_memory_source memsrc
;
8971 unsigned char *raster
;
8973 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8974 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8978 if (NILP (specified_data
))
8980 file
= x_find_image_file (specified_file
);
8981 if (!STRINGP (file
))
8983 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8988 /* Open the GIF file. */
8989 gif
= DGifOpenFileName (SDATA (file
));
8992 image_error ("Cannot open `%s'", file
, Qnil
);
8999 /* Read from memory! */
9000 current_gif_memory_src
= &memsrc
;
9001 memsrc
.bytes
= SDATA (specified_data
);
9002 memsrc
.len
= SBYTES (specified_data
);
9005 gif
= DGifOpen(&memsrc
, gif_read_from_memory
);
9008 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
9014 /* Read entire contents. */
9015 rc
= DGifSlurp (gif
);
9016 if (rc
== GIF_ERROR
)
9018 image_error ("Error reading `%s'", img
->spec
, Qnil
);
9019 DGifCloseFile (gif
);
9024 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
9025 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
9026 if (ino
>= gif
->ImageCount
)
9028 image_error ("Invalid image number `%s' in image `%s'",
9030 DGifCloseFile (gif
);
9035 width
= img
->width
= max (gif
->SWidth
, gif
->Image
.Left
+ gif
->Image
.Width
);
9036 height
= img
->height
= max (gif
->SHeight
, gif
->Image
.Top
+ gif
->Image
.Height
);
9038 /* Create the X image and pixmap. */
9039 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
9041 DGifCloseFile (gif
);
9046 /* Allocate colors. */
9047 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
9049 gif_color_map
= gif
->SColorMap
;
9050 init_color_table ();
9051 bzero (pixel_colors
, sizeof pixel_colors
);
9053 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
9055 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
9056 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
9057 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
9058 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
9061 img
->colors
= colors_in_color_table (&img
->ncolors
);
9062 free_color_table ();
9064 /* Clear the part of the screen image that are not covered by
9065 the image from the GIF file. Full animated GIF support
9066 requires more than can be done here (see the gif89 spec,
9067 disposal methods). Let's simply assume that the part
9068 not covered by a sub-image is in the frame's background color. */
9069 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
9070 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
9071 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
9072 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
9074 for (y
= 0; y
< image_top
; ++y
)
9075 for (x
= 0; x
< width
; ++x
)
9076 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9078 for (y
= image_top
+ image_height
; y
< height
; ++y
)
9079 for (x
= 0; x
< width
; ++x
)
9080 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9082 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
9084 for (x
= 0; x
< image_left
; ++x
)
9085 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9086 for (x
= image_left
+ image_width
; x
< width
; ++x
)
9087 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9090 /* Read the GIF image into the X image. We use a local variable
9091 `raster' here because RasterBits below is a char *, and invites
9092 problems with bytes >= 0x80. */
9093 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
9095 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
9097 static int interlace_start
[] = {0, 4, 2, 1};
9098 static int interlace_increment
[] = {8, 8, 4, 2};
9100 int row
= interlace_start
[0];
9104 for (y
= 0; y
< image_height
; y
++)
9106 if (row
>= image_height
)
9108 row
= interlace_start
[++pass
];
9109 while (row
>= image_height
)
9110 row
= interlace_start
[++pass
];
9113 for (x
= 0; x
< image_width
; x
++)
9115 int i
= raster
[(y
* image_width
) + x
];
9116 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
9120 row
+= interlace_increment
[pass
];
9125 for (y
= 0; y
< image_height
; ++y
)
9126 for (x
= 0; x
< image_width
; ++x
)
9128 int i
= raster
[y
* image_width
+ x
];
9129 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
9133 DGifCloseFile (gif
);
9135 /* Maybe fill in the background field while we have ximg handy. */
9136 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
9137 IMAGE_BACKGROUND (img
, f
, ximg
);
9139 /* Put the image into the pixmap, then free the X image and its buffer. */
9140 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
9141 x_destroy_x_image (ximg
);
9147 #endif /* HAVE_GIF != 0 */
9151 /***********************************************************************
9153 ***********************************************************************/
9155 static int gs_image_p
P_ ((Lisp_Object object
));
9156 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
9157 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
9159 /* The symbol `postscript' identifying images of this type. */
9161 Lisp_Object Qpostscript
;
9163 /* Keyword symbols. */
9165 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
9167 /* Indices of image specification fields in gs_format, below. */
9169 enum gs_keyword_index
9187 /* Vector of image_keyword structures describing the format
9188 of valid user-defined image specifications. */
9190 static struct image_keyword gs_format
[GS_LAST
] =
9192 {":type", IMAGE_SYMBOL_VALUE
, 1},
9193 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9194 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9195 {":file", IMAGE_STRING_VALUE
, 1},
9196 {":loader", IMAGE_FUNCTION_VALUE
, 0},
9197 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
9198 {":ascent", IMAGE_ASCENT_VALUE
, 0},
9199 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
9200 {":relief", IMAGE_INTEGER_VALUE
, 0},
9201 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9202 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9203 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9204 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
9207 /* Structure describing the image type `ghostscript'. */
9209 static struct image_type gs_type
=
9219 /* Free X resources of Ghostscript image IMG which is used on frame F. */
9222 gs_clear_image (f
, img
)
9226 /* IMG->data.ptr_val may contain a recorded colormap. */
9227 xfree (img
->data
.ptr_val
);
9228 x_clear_image (f
, img
);
9232 /* Return non-zero if OBJECT is a valid Ghostscript image
9239 struct image_keyword fmt
[GS_LAST
];
9243 bcopy (gs_format
, fmt
, sizeof fmt
);
9245 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
9248 /* Bounding box must be a list or vector containing 4 integers. */
9249 tem
= fmt
[GS_BOUNDING_BOX
].value
;
9252 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
9253 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
9258 else if (VECTORP (tem
))
9260 if (XVECTOR (tem
)->size
!= 4)
9262 for (i
= 0; i
< 4; ++i
)
9263 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
9273 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
9282 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
9283 struct gcpro gcpro1
, gcpro2
;
9285 double in_width
, in_height
;
9286 Lisp_Object pixel_colors
= Qnil
;
9288 /* Compute pixel size of pixmap needed from the given size in the
9289 image specification. Sizes in the specification are in pt. 1 pt
9290 = 1/72 in, xdpi and ydpi are stored in the frame's X display
9292 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
9293 in_width
= XFASTINT (pt_width
) / 72.0;
9294 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
9295 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
9296 in_height
= XFASTINT (pt_height
) / 72.0;
9297 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
9299 /* Create the pixmap. */
9300 xassert (img
->pixmap
== None
);
9301 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9302 img
->width
, img
->height
,
9303 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
9307 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
9311 /* Call the loader to fill the pixmap. It returns a process object
9312 if successful. We do not record_unwind_protect here because
9313 other places in redisplay like calling window scroll functions
9314 don't either. Let the Lisp loader use `unwind-protect' instead. */
9315 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
9317 sprintf (buffer
, "%lu %lu",
9318 (unsigned long) FRAME_X_WINDOW (f
),
9319 (unsigned long) img
->pixmap
);
9320 window_and_pixmap_id
= build_string (buffer
);
9322 sprintf (buffer
, "%lu %lu",
9323 FRAME_FOREGROUND_PIXEL (f
),
9324 FRAME_BACKGROUND_PIXEL (f
));
9325 pixel_colors
= build_string (buffer
);
9327 XSETFRAME (frame
, f
);
9328 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
9330 loader
= intern ("gs-load-image");
9332 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
9333 make_number (img
->width
),
9334 make_number (img
->height
),
9335 window_and_pixmap_id
,
9338 return PROCESSP (img
->data
.lisp_val
);
9342 /* Kill the Ghostscript process that was started to fill PIXMAP on
9343 frame F. Called from XTread_socket when receiving an event
9344 telling Emacs that Ghostscript has finished drawing. */
9347 x_kill_gs_process (pixmap
, f
)
9351 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
9355 /* Find the image containing PIXMAP. */
9356 for (i
= 0; i
< c
->used
; ++i
)
9357 if (c
->images
[i
]->pixmap
== pixmap
)
9360 /* Should someone in between have cleared the image cache, for
9361 instance, give up. */
9365 /* Kill the GS process. We should have found PIXMAP in the image
9366 cache and its image should contain a process object. */
9368 xassert (PROCESSP (img
->data
.lisp_val
));
9369 Fkill_process (img
->data
.lisp_val
, Qnil
);
9370 img
->data
.lisp_val
= Qnil
;
9372 /* On displays with a mutable colormap, figure out the colors
9373 allocated for the image by looking at the pixels of an XImage for
9375 class = FRAME_X_VISUAL (f
)->class;
9376 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
9382 /* Try to get an XImage for img->pixmep. */
9383 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
9384 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
9389 /* Initialize the color table. */
9390 init_color_table ();
9392 /* For each pixel of the image, look its color up in the
9393 color table. After having done so, the color table will
9394 contain an entry for each color used by the image. */
9395 for (y
= 0; y
< img
->height
; ++y
)
9396 for (x
= 0; x
< img
->width
; ++x
)
9398 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
9399 lookup_pixel_color (f
, pixel
);
9402 /* Record colors in the image. Free color table and XImage. */
9403 img
->colors
= colors_in_color_table (&img
->ncolors
);
9404 free_color_table ();
9405 XDestroyImage (ximg
);
9407 #if 0 /* This doesn't seem to be the case. If we free the colors
9408 here, we get a BadAccess later in x_clear_image when
9409 freeing the colors. */
9410 /* We have allocated colors once, but Ghostscript has also
9411 allocated colors on behalf of us. So, to get the
9412 reference counts right, free them once. */
9414 x_free_colors (f
, img
->colors
, img
->ncolors
);
9418 image_error ("Cannot get X image of `%s'; colors will not be freed",
9424 /* Now that we have the pixmap, compute mask and transform the
9425 image if requested. */
9427 postprocess_image (f
, img
);
9433 /***********************************************************************
9435 ***********************************************************************/
9437 DEFUN ("x-change-window-property", Fx_change_window_property
,
9438 Sx_change_window_property
, 2, 3, 0,
9439 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
9440 PROP and VALUE must be strings. FRAME nil or omitted means use the
9441 selected frame. Value is VALUE. */)
9442 (prop
, value
, frame
)
9443 Lisp_Object frame
, prop
, value
;
9445 struct frame
*f
= check_x_frame (frame
);
9448 CHECK_STRING (prop
);
9449 CHECK_STRING (value
);
9452 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9453 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9454 prop_atom
, XA_STRING
, 8, PropModeReplace
,
9455 SDATA (value
), SCHARS (value
));
9457 /* Make sure the property is set when we return. */
9458 XFlush (FRAME_X_DISPLAY (f
));
9465 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
9466 Sx_delete_window_property
, 1, 2, 0,
9467 doc
: /* Remove window property PROP from X window of FRAME.
9468 FRAME nil or omitted means use the selected frame. Value is PROP. */)
9470 Lisp_Object prop
, frame
;
9472 struct frame
*f
= check_x_frame (frame
);
9475 CHECK_STRING (prop
);
9477 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9478 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
9480 /* Make sure the property is removed when we return. */
9481 XFlush (FRAME_X_DISPLAY (f
));
9488 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
9490 doc
: /* Value is the value of window property PROP on FRAME.
9491 If FRAME is nil or omitted, use the selected frame. Value is nil
9492 if FRAME hasn't a property with name PROP or if PROP has no string
9495 Lisp_Object prop
, frame
;
9497 struct frame
*f
= check_x_frame (frame
);
9500 Lisp_Object prop_value
= Qnil
;
9501 char *tmp_data
= NULL
;
9504 unsigned long actual_size
, bytes_remaining
;
9506 CHECK_STRING (prop
);
9508 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9509 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9510 prop_atom
, 0, 0, False
, XA_STRING
,
9511 &actual_type
, &actual_format
, &actual_size
,
9512 &bytes_remaining
, (unsigned char **) &tmp_data
);
9515 int size
= bytes_remaining
;
9520 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9521 prop_atom
, 0, bytes_remaining
,
9523 &actual_type
, &actual_format
,
9524 &actual_size
, &bytes_remaining
,
9525 (unsigned char **) &tmp_data
);
9526 if (rc
== Success
&& tmp_data
)
9527 prop_value
= make_string (tmp_data
, size
);
9538 /***********************************************************************
9540 ***********************************************************************/
9542 /* If non-null, an asynchronous timer that, when it expires, displays
9543 an hourglass cursor on all frames. */
9545 static struct atimer
*hourglass_atimer
;
9547 /* Non-zero means an hourglass cursor is currently shown. */
9549 static int hourglass_shown_p
;
9551 /* Number of seconds to wait before displaying an hourglass cursor. */
9553 static Lisp_Object Vhourglass_delay
;
9555 /* Default number of seconds to wait before displaying an hourglass
9558 #define DEFAULT_HOURGLASS_DELAY 1
9560 /* Function prototypes. */
9562 static void show_hourglass
P_ ((struct atimer
*));
9563 static void hide_hourglass
P_ ((void));
9566 /* Cancel a currently active hourglass timer, and start a new one. */
9572 int secs
, usecs
= 0;
9574 cancel_hourglass ();
9576 if (INTEGERP (Vhourglass_delay
)
9577 && XINT (Vhourglass_delay
) > 0)
9578 secs
= XFASTINT (Vhourglass_delay
);
9579 else if (FLOATP (Vhourglass_delay
)
9580 && XFLOAT_DATA (Vhourglass_delay
) > 0)
9583 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
9584 secs
= XFASTINT (tem
);
9585 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
9588 secs
= DEFAULT_HOURGLASS_DELAY
;
9590 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
9591 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
9592 show_hourglass
, NULL
);
9596 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
9602 if (hourglass_atimer
)
9604 cancel_atimer (hourglass_atimer
);
9605 hourglass_atimer
= NULL
;
9608 if (hourglass_shown_p
)
9613 /* Timer function of hourglass_atimer. TIMER is equal to
9616 Display an hourglass pointer on all frames by mapping the frames'
9617 hourglass_window. Set the hourglass_p flag in the frames'
9618 output_data.x structure to indicate that an hourglass cursor is
9619 shown on the frames. */
9622 show_hourglass (timer
)
9623 struct atimer
*timer
;
9625 /* The timer implementation will cancel this timer automatically
9626 after this function has run. Set hourglass_atimer to null
9627 so that we know the timer doesn't have to be canceled. */
9628 hourglass_atimer
= NULL
;
9630 if (!hourglass_shown_p
)
9632 Lisp_Object rest
, frame
;
9636 FOR_EACH_FRAME (rest
, frame
)
9638 struct frame
*f
= XFRAME (frame
);
9640 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
9642 Display
*dpy
= FRAME_X_DISPLAY (f
);
9644 #ifdef USE_X_TOOLKIT
9645 if (f
->output_data
.x
->widget
)
9647 if (FRAME_OUTER_WINDOW (f
))
9650 f
->output_data
.x
->hourglass_p
= 1;
9652 if (!f
->output_data
.x
->hourglass_window
)
9654 unsigned long mask
= CWCursor
;
9655 XSetWindowAttributes attrs
;
9657 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
9659 f
->output_data
.x
->hourglass_window
9660 = XCreateWindow (dpy
, FRAME_OUTER_WINDOW (f
),
9661 0, 0, 32000, 32000, 0, 0,
9667 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
9673 hourglass_shown_p
= 1;
9679 /* Hide the hourglass pointer on all frames, if it is currently
9685 if (hourglass_shown_p
)
9687 Lisp_Object rest
, frame
;
9690 FOR_EACH_FRAME (rest
, frame
)
9692 struct frame
*f
= XFRAME (frame
);
9695 /* Watch out for newly created frames. */
9696 && f
->output_data
.x
->hourglass_window
)
9698 XUnmapWindow (FRAME_X_DISPLAY (f
),
9699 f
->output_data
.x
->hourglass_window
);
9700 /* Sync here because XTread_socket looks at the
9701 hourglass_p flag that is reset to zero below. */
9702 XSync (FRAME_X_DISPLAY (f
), False
);
9703 f
->output_data
.x
->hourglass_p
= 0;
9707 hourglass_shown_p
= 0;
9714 /***********************************************************************
9716 ***********************************************************************/
9718 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
9719 Lisp_Object
, Lisp_Object
));
9720 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
9721 Lisp_Object
, int, int, int *, int *));
9723 /* The frame of a currently visible tooltip. */
9725 Lisp_Object tip_frame
;
9727 /* If non-nil, a timer started that hides the last tooltip when it
9730 Lisp_Object tip_timer
;
9733 /* If non-nil, a vector of 3 elements containing the last args
9734 with which x-show-tip was called. See there. */
9736 Lisp_Object last_show_tip_args
;
9738 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
9740 Lisp_Object Vx_max_tooltip_size
;
9744 unwind_create_tip_frame (frame
)
9747 Lisp_Object deleted
;
9749 deleted
= unwind_create_frame (frame
);
9750 if (EQ (deleted
, Qt
))
9760 /* Create a frame for a tooltip on the display described by DPYINFO.
9761 PARMS is a list of frame parameters. TEXT is the string to
9762 display in the tip frame. Value is the frame.
9764 Note that functions called here, esp. x_default_parameter can
9765 signal errors, for instance when a specified color name is
9766 undefined. We have to make sure that we're in a consistent state
9767 when this happens. */
9770 x_create_tip_frame (dpyinfo
, parms
, text
)
9771 struct x_display_info
*dpyinfo
;
9772 Lisp_Object parms
, text
;
9775 Lisp_Object frame
, tem
;
9777 long window_prompting
= 0;
9779 int count
= SPECPDL_INDEX ();
9780 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9782 int face_change_count_before
= face_change_count
;
9784 struct buffer
*old_buffer
;
9788 /* Use this general default value to start with until we know if
9789 this frame has a specified name. */
9790 Vx_resource_name
= Vinvocation_name
;
9793 kb
= dpyinfo
->kboard
;
9795 kb
= &the_only_kboard
;
9798 /* Get the name of the frame to use for resource lookup. */
9799 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
9801 && !EQ (name
, Qunbound
)
9803 error ("Invalid frame name--not a string or nil");
9804 Vx_resource_name
= name
;
9807 GCPRO3 (parms
, name
, frame
);
9809 XSETFRAME (frame
, f
);
9811 buffer
= Fget_buffer_create (build_string (" *tip*"));
9812 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
9813 old_buffer
= current_buffer
;
9814 set_buffer_internal_1 (XBUFFER (buffer
));
9815 current_buffer
->truncate_lines
= Qnil
;
9818 set_buffer_internal_1 (old_buffer
);
9820 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
9821 record_unwind_protect (unwind_create_tip_frame
, frame
);
9823 /* By setting the output method, we're essentially saying that
9824 the frame is live, as per FRAME_LIVE_P. If we get a signal
9825 from this point on, x_destroy_window might screw up reference
9827 f
->output_method
= output_x_window
;
9828 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
9829 bzero (f
->output_data
.x
, sizeof (struct x_output
));
9830 f
->output_data
.x
->icon_bitmap
= -1;
9831 FRAME_FONTSET (f
) = -1;
9832 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
9833 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
9834 #ifdef USE_TOOLKIT_SCROLL_BARS
9835 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
9836 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
9837 #endif /* USE_TOOLKIT_SCROLL_BARS */
9838 f
->icon_name
= Qnil
;
9839 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
9841 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
9842 dpyinfo_refcount
= dpyinfo
->reference_count
;
9843 #endif /* GLYPH_DEBUG */
9845 FRAME_KBOARD (f
) = kb
;
9847 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
9848 f
->output_data
.x
->explicit_parent
= 0;
9850 /* These colors will be set anyway later, but it's important
9851 to get the color reference counts right, so initialize them! */
9854 struct gcpro gcpro1
;
9856 black
= build_string ("black");
9858 f
->output_data
.x
->foreground_pixel
9859 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9860 f
->output_data
.x
->background_pixel
9861 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9862 f
->output_data
.x
->cursor_pixel
9863 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9864 f
->output_data
.x
->cursor_foreground_pixel
9865 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9866 f
->output_data
.x
->border_pixel
9867 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9868 f
->output_data
.x
->mouse_pixel
9869 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9873 /* Set the name; the functions to which we pass f expect the name to
9875 if (EQ (name
, Qunbound
) || NILP (name
))
9877 f
->name
= build_string (dpyinfo
->x_id_name
);
9878 f
->explicit_name
= 0;
9883 f
->explicit_name
= 1;
9884 /* use the frame's title when getting resources for this frame. */
9885 specbind (Qx_resource_name
, name
);
9888 /* Extract the window parameters from the supplied values that are
9889 needed to determine window geometry. */
9893 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
9896 /* First, try whatever font the caller has specified. */
9899 tem
= Fquery_fontset (font
, Qnil
);
9901 font
= x_new_fontset (f
, SDATA (tem
));
9903 font
= x_new_font (f
, SDATA (font
));
9906 /* Try out a font which we hope has bold and italic variations. */
9907 if (!STRINGP (font
))
9908 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
9909 if (!STRINGP (font
))
9910 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9911 if (! STRINGP (font
))
9912 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9913 if (! STRINGP (font
))
9914 /* This was formerly the first thing tried, but it finds too many fonts
9915 and takes too long. */
9916 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
9917 /* If those didn't work, look for something which will at least work. */
9918 if (! STRINGP (font
))
9919 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
9921 if (! STRINGP (font
))
9922 font
= build_string ("fixed");
9924 x_default_parameter (f
, parms
, Qfont
, font
,
9925 "font", "Font", RES_TYPE_STRING
);
9928 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
9929 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
9931 /* This defaults to 2 in order to match xterm. We recognize either
9932 internalBorderWidth or internalBorder (which is what xterm calls
9934 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9938 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
9939 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
9940 if (! EQ (value
, Qunbound
))
9941 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
9945 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
9946 "internalBorderWidth", "internalBorderWidth",
9949 /* Also do the stuff which must be set before the window exists. */
9950 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
9951 "foreground", "Foreground", RES_TYPE_STRING
);
9952 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
9953 "background", "Background", RES_TYPE_STRING
);
9954 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
9955 "pointerColor", "Foreground", RES_TYPE_STRING
);
9956 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
9957 "cursorColor", "Foreground", RES_TYPE_STRING
);
9958 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
9959 "borderColor", "BorderColor", RES_TYPE_STRING
);
9961 /* Init faces before x_default_parameter is called for scroll-bar
9962 parameters because that function calls x_set_scroll_bar_width,
9963 which calls change_frame_size, which calls Fset_window_buffer,
9964 which runs hooks, which call Fvertical_motion. At the end, we
9965 end up in init_iterator with a null face cache, which should not
9967 init_frame_faces (f
);
9969 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
9971 window_prompting
= x_figure_window_size (f
, parms
, 0);
9974 XSetWindowAttributes attrs
;
9978 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
9979 if (DoesSaveUnders (dpyinfo
->screen
))
9980 mask
|= CWSaveUnder
;
9982 /* Window managers look at the override-redirect flag to determine
9983 whether or net to give windows a decoration (Xlib spec, chapter
9985 attrs
.override_redirect
= True
;
9986 attrs
.save_under
= True
;
9987 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
9988 /* Arrange for getting MapNotify and UnmapNotify events. */
9989 attrs
.event_mask
= StructureNotifyMask
;
9991 = FRAME_X_WINDOW (f
)
9992 = XCreateWindow (FRAME_X_DISPLAY (f
),
9993 FRAME_X_DISPLAY_INFO (f
)->root_window
,
9994 /* x, y, width, height */
9998 CopyFromParent
, InputOutput
, CopyFromParent
,
10005 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
10006 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
10007 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
10008 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
10009 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
10010 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
10012 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
10013 Change will not be effected unless different from the current
10014 FRAME_LINES (f). */
10015 width
= FRAME_COLS (f
);
10016 height
= FRAME_LINES (f
);
10017 SET_FRAME_COLS (f
, 0);
10018 FRAME_LINES (f
) = 0;
10019 change_frame_size (f
, height
, width
, 1, 0, 0);
10021 /* Add `tooltip' frame parameter's default value. */
10022 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
10023 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
10026 /* Set up faces after all frame parameters are known. This call
10027 also merges in face attributes specified for new frames.
10029 Frame parameters may be changed if .Xdefaults contains
10030 specifications for the default font. For example, if there is an
10031 `Emacs.default.attributeBackground: pink', the `background-color'
10032 attribute of the frame get's set, which let's the internal border
10033 of the tooltip frame appear in pink. Prevent this. */
10035 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
10037 /* Set tip_frame here, so that */
10039 call1 (Qface_set_after_frame_default
, frame
);
10041 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
10042 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
10050 /* It is now ok to make the frame official even if we get an error
10051 below. And the frame needs to be on Vframe_list or making it
10052 visible won't work. */
10053 Vframe_list
= Fcons (frame
, Vframe_list
);
10055 /* Now that the frame is official, it counts as a reference to
10057 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
10059 /* Setting attributes of faces of the tooltip frame from resources
10060 and similar will increment face_change_count, which leads to the
10061 clearing of all current matrices. Since this isn't necessary
10062 here, avoid it by resetting face_change_count to the value it
10063 had before we created the tip frame. */
10064 face_change_count
= face_change_count_before
;
10066 /* Discard the unwind_protect. */
10067 return unbind_to (count
, frame
);
10071 /* Compute where to display tip frame F. PARMS is the list of frame
10072 parameters for F. DX and DY are specified offsets from the current
10073 location of the mouse. WIDTH and HEIGHT are the width and height
10074 of the tooltip. Return coordinates relative to the root window of
10075 the display in *ROOT_X, and *ROOT_Y. */
10078 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
10080 Lisp_Object parms
, dx
, dy
;
10082 int *root_x
, *root_y
;
10084 Lisp_Object left
, top
;
10086 Window root
, child
;
10089 /* User-specified position? */
10090 left
= Fcdr (Fassq (Qleft
, parms
));
10091 top
= Fcdr (Fassq (Qtop
, parms
));
10093 /* Move the tooltip window where the mouse pointer is. Resize and
10095 if (!INTEGERP (left
) || !INTEGERP (top
))
10098 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
10099 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
10103 if (INTEGERP (top
))
10104 *root_y
= XINT (top
);
10105 else if (*root_y
+ XINT (dy
) - height
< 0)
10106 *root_y
-= XINT (dy
);
10110 *root_y
+= XINT (dy
);
10113 if (INTEGERP (left
))
10114 *root_x
= XINT (left
);
10115 else if (*root_x
+ XINT (dx
) + width
<= FRAME_X_DISPLAY_INFO (f
)->width
)
10116 /* It fits to the right of the pointer. */
10117 *root_x
+= XINT (dx
);
10118 else if (width
+ XINT (dx
) <= *root_x
)
10119 /* It fits to the left of the pointer. */
10120 *root_x
-= width
+ XINT (dx
);
10122 /* Put it left-justified on the screen--it ought to fit that way. */
10127 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
10128 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
10129 A tooltip window is a small X window displaying a string.
10131 FRAME nil or omitted means use the selected frame.
10133 PARMS is an optional list of frame parameters which can be used to
10134 change the tooltip's appearance.
10136 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
10137 means use the default timeout of 5 seconds.
10139 If the list of frame parameters PARAMS contains a `left' parameters,
10140 the tooltip is displayed at that x-position. Otherwise it is
10141 displayed at the mouse position, with offset DX added (default is 5 if
10142 DX isn't specified). Likewise for the y-position; if a `top' frame
10143 parameter is specified, it determines the y-position of the tooltip
10144 window, otherwise it is displayed at the mouse position, with offset
10145 DY added (default is -10).
10147 A tooltip's maximum size is specified by `x-max-tooltip-size'.
10148 Text larger than the specified size is clipped. */)
10149 (string
, frame
, parms
, timeout
, dx
, dy
)
10150 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
10154 int root_x
, root_y
;
10155 struct buffer
*old_buffer
;
10156 struct text_pos pos
;
10157 int i
, width
, height
;
10158 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
10159 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
10160 int count
= SPECPDL_INDEX ();
10162 specbind (Qinhibit_redisplay
, Qt
);
10164 GCPRO4 (string
, parms
, frame
, timeout
);
10166 CHECK_STRING (string
);
10167 f
= check_x_frame (frame
);
10168 if (NILP (timeout
))
10169 timeout
= make_number (5);
10171 CHECK_NATNUM (timeout
);
10174 dx
= make_number (5);
10179 dy
= make_number (-10);
10183 if (NILP (last_show_tip_args
))
10184 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
10186 if (!NILP (tip_frame
))
10188 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
10189 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
10190 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
10192 if (EQ (frame
, last_frame
)
10193 && !NILP (Fequal (last_string
, string
))
10194 && !NILP (Fequal (last_parms
, parms
)))
10196 struct frame
*f
= XFRAME (tip_frame
);
10198 /* Only DX and DY have changed. */
10199 if (!NILP (tip_timer
))
10201 Lisp_Object timer
= tip_timer
;
10203 call1 (Qcancel_timer
, timer
);
10207 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
10208 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
10209 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10216 /* Hide a previous tip, if any. */
10219 ASET (last_show_tip_args
, 0, string
);
10220 ASET (last_show_tip_args
, 1, frame
);
10221 ASET (last_show_tip_args
, 2, parms
);
10223 /* Add default values to frame parameters. */
10224 if (NILP (Fassq (Qname
, parms
)))
10225 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
10226 if (NILP (Fassq (Qinternal_border_width
, parms
)))
10227 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
10228 if (NILP (Fassq (Qborder_width
, parms
)))
10229 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
10230 if (NILP (Fassq (Qborder_color
, parms
)))
10231 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
10232 if (NILP (Fassq (Qbackground_color
, parms
)))
10233 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
10236 /* Create a frame for the tooltip, and record it in the global
10237 variable tip_frame. */
10238 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
10239 f
= XFRAME (frame
);
10241 /* Set up the frame's root window. */
10242 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
10243 w
->left_col
= w
->top_line
= make_number (0);
10245 if (CONSP (Vx_max_tooltip_size
)
10246 && INTEGERP (XCAR (Vx_max_tooltip_size
))
10247 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
10248 && INTEGERP (XCDR (Vx_max_tooltip_size
))
10249 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
10251 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
10252 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
10256 w
->total_cols
= make_number (80);
10257 w
->total_lines
= make_number (40);
10260 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
10262 w
->pseudo_window_p
= 1;
10264 /* Display the tooltip text in a temporary buffer. */
10265 old_buffer
= current_buffer
;
10266 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
10267 current_buffer
->truncate_lines
= Qnil
;
10268 clear_glyph_matrix (w
->desired_matrix
);
10269 clear_glyph_matrix (w
->current_matrix
);
10270 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
10271 try_window (FRAME_ROOT_WINDOW (f
), pos
);
10273 /* Compute width and height of the tooltip. */
10274 width
= height
= 0;
10275 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
10277 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
10278 struct glyph
*last
;
10281 /* Stop at the first empty row at the end. */
10282 if (!row
->enabled_p
|| !row
->displays_text_p
)
10285 /* Let the row go over the full width of the frame. */
10286 row
->full_width_p
= 1;
10288 /* There's a glyph at the end of rows that is used to place
10289 the cursor there. Don't include the width of this glyph. */
10290 if (row
->used
[TEXT_AREA
])
10292 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
10293 row_width
= row
->pixel_width
- last
->pixel_width
;
10296 row_width
= row
->pixel_width
;
10298 height
+= row
->height
;
10299 width
= max (width
, row_width
);
10302 /* Add the frame's internal border to the width and height the X
10303 window should have. */
10304 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10305 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10307 /* Move the tooltip window where the mouse pointer is. Resize and
10309 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
10312 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10313 root_x
, root_y
, width
, height
);
10314 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
10317 /* Draw into the window. */
10318 w
->must_be_updated_p
= 1;
10319 update_single_window (w
, 1);
10321 /* Restore original current buffer. */
10322 set_buffer_internal_1 (old_buffer
);
10323 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
10326 /* Let the tip disappear after timeout seconds. */
10327 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
10328 intern ("x-hide-tip"));
10331 return unbind_to (count
, Qnil
);
10335 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
10336 doc
: /* Hide the current tooltip window, if there is any.
10337 Value is t if tooltip was open, nil otherwise. */)
10341 Lisp_Object deleted
, frame
, timer
;
10342 struct gcpro gcpro1
, gcpro2
;
10344 /* Return quickly if nothing to do. */
10345 if (NILP (tip_timer
) && NILP (tip_frame
))
10350 GCPRO2 (frame
, timer
);
10351 tip_frame
= tip_timer
= deleted
= Qnil
;
10353 count
= SPECPDL_INDEX ();
10354 specbind (Qinhibit_redisplay
, Qt
);
10355 specbind (Qinhibit_quit
, Qt
);
10358 call1 (Qcancel_timer
, timer
);
10360 if (FRAMEP (frame
))
10362 Fdelete_frame (frame
, Qnil
);
10366 /* Bloodcurdling hack alert: The Lucid menu bar widget's
10367 redisplay procedure is not called when a tip frame over menu
10368 items is unmapped. Redisplay the menu manually... */
10370 struct frame
*f
= SELECTED_FRAME ();
10371 Widget w
= f
->output_data
.x
->menubar_widget
;
10372 extern void xlwmenu_redisplay
P_ ((Widget
));
10374 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
10378 xlwmenu_redisplay (w
);
10382 #endif /* USE_LUCID */
10386 return unbind_to (count
, deleted
);
10391 /***********************************************************************
10392 File selection dialog
10393 ***********************************************************************/
10397 /* Callback for "OK" and "Cancel" on file selection dialog. */
10400 file_dialog_cb (widget
, client_data
, call_data
)
10402 XtPointer call_data
, client_data
;
10404 int *result
= (int *) client_data
;
10405 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
10406 *result
= cb
->reason
;
10410 /* Callback for unmapping a file selection dialog. This is used to
10411 capture the case where a dialog is closed via a window manager's
10412 closer button, for example. Using a XmNdestroyCallback didn't work
10416 file_dialog_unmap_cb (widget
, client_data
, call_data
)
10418 XtPointer call_data
, client_data
;
10420 int *result
= (int *) client_data
;
10421 *result
= XmCR_CANCEL
;
10425 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10426 doc
: /* Read file name, prompting with PROMPT in directory DIR.
10427 Use a file selection dialog.
10428 Select DEFAULT-FILENAME in the dialog's file selection box, if
10429 specified. Don't let the user enter a file name in the file
10430 selection dialog's entry field, if MUSTMATCH is non-nil. */)
10431 (prompt
, dir
, default_filename
, mustmatch
)
10432 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10435 struct frame
*f
= SELECTED_FRAME ();
10436 Lisp_Object file
= Qnil
;
10437 Widget dialog
, text
, list
, help
;
10440 extern XtAppContext Xt_app_con
;
10441 XmString dir_xmstring
, pattern_xmstring
;
10442 int count
= SPECPDL_INDEX ();
10443 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10445 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10446 CHECK_STRING (prompt
);
10447 CHECK_STRING (dir
);
10449 /* Prevent redisplay. */
10450 specbind (Qinhibit_redisplay
, Qt
);
10454 /* Create the dialog with PROMPT as title, using DIR as initial
10455 directory and using "*" as pattern. */
10456 dir
= Fexpand_file_name (dir
, Qnil
);
10457 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
10458 pattern_xmstring
= XmStringCreateLocalized ("*");
10460 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
10461 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
10462 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
10463 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
10464 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
10465 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
10467 XmStringFree (dir_xmstring
);
10468 XmStringFree (pattern_xmstring
);
10470 /* Add callbacks for OK and Cancel. */
10471 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
10472 (XtPointer
) &result
);
10473 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
10474 (XtPointer
) &result
);
10475 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
10476 (XtPointer
) &result
);
10478 /* Disable the help button since we can't display help. */
10479 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
10480 XtSetSensitive (help
, False
);
10482 /* Mark OK button as default. */
10483 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
10484 XmNshowAsDefault
, True
, NULL
);
10486 /* If MUSTMATCH is non-nil, disable the file entry field of the
10487 dialog, so that the user must select a file from the files list
10488 box. We can't remove it because we wouldn't have a way to get at
10489 the result file name, then. */
10490 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
10491 if (!NILP (mustmatch
))
10494 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
10495 XtSetSensitive (text
, False
);
10496 XtSetSensitive (label
, False
);
10499 /* Manage the dialog, so that list boxes get filled. */
10500 XtManageChild (dialog
);
10502 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
10503 must include the path for this to work. */
10504 list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
10505 if (STRINGP (default_filename
))
10507 XmString default_xmstring
;
10511 = XmStringCreateLocalized (SDATA (default_filename
));
10513 if (!XmListItemExists (list
, default_xmstring
))
10515 /* Add a new item if DEFAULT_FILENAME is not in the list. */
10516 XmListAddItem (list
, default_xmstring
, 0);
10520 item_pos
= XmListItemPos (list
, default_xmstring
);
10521 XmStringFree (default_xmstring
);
10523 /* Select the item and scroll it into view. */
10524 XmListSelectPos (list
, item_pos
, True
);
10525 XmListSetPos (list
, item_pos
);
10528 /* Process events until the user presses Cancel or OK. */
10530 while (result
== 0)
10533 XtAppNextEvent (Xt_app_con
, &event
);
10534 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
) );
10537 /* Get the result. */
10538 if (result
== XmCR_OK
)
10543 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
10544 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
10545 XmStringFree (text
);
10546 file
= build_string (data
);
10553 XtUnmanageChild (dialog
);
10554 XtDestroyWidget (dialog
);
10558 /* Make "Cancel" equivalent to C-g. */
10560 Fsignal (Qquit
, Qnil
);
10562 return unbind_to (count
, file
);
10565 #endif /* USE_MOTIF */
10569 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10570 "Read file name, prompting with PROMPT in directory DIR.\n\
10571 Use a file selection dialog.\n\
10572 Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
10573 specified. Don't let the user enter a file name in the file\n\
10574 selection dialog's entry field, if MUSTMATCH is non-nil.")
10575 (prompt
, dir
, default_filename
, mustmatch
)
10576 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10578 FRAME_PTR f
= SELECTED_FRAME ();
10580 Lisp_Object file
= Qnil
;
10581 int count
= specpdl_ptr
- specpdl
;
10582 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10586 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10587 CHECK_STRING (prompt
);
10588 CHECK_STRING (dir
);
10590 /* Prevent redisplay. */
10591 specbind (Qinhibit_redisplay
, Qt
);
10595 if (STRINGP (default_filename
))
10596 cdef_file
= SDATA (default_filename
);
10598 cdef_file
= SDATA (dir
);
10600 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
, ! NILP (mustmatch
));
10604 file
= build_string (fn
);
10611 /* Make "Cancel" equivalent to C-g. */
10613 Fsignal (Qquit
, Qnil
);
10615 return unbind_to (count
, file
);
10618 #endif /* USE_GTK */
10621 /***********************************************************************
10623 ***********************************************************************/
10625 #ifdef HAVE_XKBGETKEYBOARD
10626 #include <X11/XKBlib.h>
10627 #include <X11/keysym.h>
10630 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
10631 Sx_backspace_delete_keys_p
, 0, 1, 0,
10632 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
10633 FRAME nil means use the selected frame.
10634 Value is t if we know that both keys are present, and are mapped to the
10635 usual X keysyms. */)
10639 #ifdef HAVE_XKBGETKEYBOARD
10641 struct frame
*f
= check_x_frame (frame
);
10642 Display
*dpy
= FRAME_X_DISPLAY (f
);
10643 Lisp_Object have_keys
;
10644 int major
, minor
, op
, event
, error
;
10648 /* Check library version in case we're dynamically linked. */
10649 major
= XkbMajorVersion
;
10650 minor
= XkbMinorVersion
;
10651 if (!XkbLibraryVersion (&major
, &minor
))
10657 /* Check that the server supports XKB. */
10658 major
= XkbMajorVersion
;
10659 minor
= XkbMinorVersion
;
10660 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
10667 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
10670 int delete_keycode
= 0, backspace_keycode
= 0, i
;
10672 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
10674 for (i
= kb
->min_key_code
;
10675 (i
< kb
->max_key_code
10676 && (delete_keycode
== 0 || backspace_keycode
== 0));
10679 /* The XKB symbolic key names can be seen most easily in
10680 the PS file generated by `xkbprint -label name
10682 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
10683 delete_keycode
= i
;
10684 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
10685 backspace_keycode
= i
;
10688 XkbFreeNames (kb
, 0, True
);
10691 XkbFreeClientMap (kb
, 0, True
);
10694 && backspace_keycode
10695 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
10696 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
10701 #else /* not HAVE_XKBGETKEYBOARD */
10703 #endif /* not HAVE_XKBGETKEYBOARD */
10708 /***********************************************************************
10710 ***********************************************************************/
10712 /* Keep this list in the same order as frame_parms in frame.c.
10713 Use 0 for unsupported frame parameters. */
10715 frame_parm_handler x_frame_parm_handlers
[] =
10719 x_set_background_color
,
10720 x_set_border_color
,
10721 x_set_border_width
,
10722 x_set_cursor_color
,
10725 x_set_foreground_color
,
10728 x_set_internal_border_width
,
10729 x_set_menu_bar_lines
,
10731 x_explicitly_set_name
,
10732 x_set_scroll_bar_width
,
10734 x_set_unsplittable
,
10735 x_set_vertical_scroll_bars
,
10737 x_set_tool_bar_lines
,
10738 x_set_scroll_bar_foreground
,
10739 x_set_scroll_bar_background
,
10740 x_set_screen_gamma
,
10741 x_set_line_spacing
,
10742 x_set_fringe_width
,
10743 x_set_fringe_width
,
10751 /* This is zero if not using X windows. */
10754 /* The section below is built by the lisp expression at the top of the file,
10755 just above where these variables are declared. */
10756 /*&&& init symbols here &&&*/
10757 Qnone
= intern ("none");
10758 staticpro (&Qnone
);
10759 Qsuppress_icon
= intern ("suppress-icon");
10760 staticpro (&Qsuppress_icon
);
10761 Qundefined_color
= intern ("undefined-color");
10762 staticpro (&Qundefined_color
);
10763 Qcenter
= intern ("center");
10764 staticpro (&Qcenter
);
10765 Qcompound_text
= intern ("compound-text");
10766 staticpro (&Qcompound_text
);
10767 Qcancel_timer
= intern ("cancel-timer");
10768 staticpro (&Qcancel_timer
);
10769 /* This is the end of symbol initialization. */
10771 /* Text property `display' should be nonsticky by default. */
10772 Vtext_property_default_nonsticky
10773 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
10776 Qlaplace
= intern ("laplace");
10777 staticpro (&Qlaplace
);
10778 Qemboss
= intern ("emboss");
10779 staticpro (&Qemboss
);
10780 Qedge_detection
= intern ("edge-detection");
10781 staticpro (&Qedge_detection
);
10782 Qheuristic
= intern ("heuristic");
10783 staticpro (&Qheuristic
);
10784 QCmatrix
= intern (":matrix");
10785 staticpro (&QCmatrix
);
10786 QCcolor_adjustment
= intern (":color-adjustment");
10787 staticpro (&QCcolor_adjustment
);
10788 QCmask
= intern (":mask");
10789 staticpro (&QCmask
);
10791 Fput (Qundefined_color
, Qerror_conditions
,
10792 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
10793 Fput (Qundefined_color
, Qerror_message
,
10794 build_string ("Undefined color"));
10796 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images
,
10797 doc
: /* Non-nil means always draw a cross over disabled images.
10798 Disabled images are those having an `:conversion disabled' property.
10799 A cross is always drawn on black & white displays. */);
10800 cross_disabled_images
= 0;
10802 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
10803 doc
: /* List of directories to search for window system bitmap files. */);
10804 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
10806 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
10807 doc
: /* The shape of the pointer when over text.
10808 Changing the value does not affect existing frames
10809 unless you set the mouse color. */);
10810 Vx_pointer_shape
= Qnil
;
10812 #if 0 /* This doesn't really do anything. */
10813 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
10814 doc
: /* The shape of the pointer when not over text.
10815 This variable takes effect when you create a new frame
10816 or when you set the mouse color. */);
10818 Vx_nontext_pointer_shape
= Qnil
;
10820 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
10821 doc
: /* The shape of the pointer when Emacs is busy.
10822 This variable takes effect when you create a new frame
10823 or when you set the mouse color. */);
10824 Vx_hourglass_pointer_shape
= Qnil
;
10826 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
10827 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
10828 display_hourglass_p
= 1;
10830 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
10831 doc
: /* *Seconds to wait before displaying an hourglass pointer.
10832 Value must be an integer or float. */);
10833 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
10835 #if 0 /* This doesn't really do anything. */
10836 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
10837 doc
: /* The shape of the pointer when over the mode line.
10838 This variable takes effect when you create a new frame
10839 or when you set the mouse color. */);
10841 Vx_mode_pointer_shape
= Qnil
;
10843 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
10844 &Vx_sensitive_text_pointer_shape
,
10845 doc
: /* The shape of the pointer when over mouse-sensitive text.
10846 This variable takes effect when you create a new frame
10847 or when you set the mouse color. */);
10848 Vx_sensitive_text_pointer_shape
= Qnil
;
10850 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
10851 &Vx_window_horizontal_drag_shape
,
10852 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
10853 This variable takes effect when you create a new frame
10854 or when you set the mouse color. */);
10855 Vx_window_horizontal_drag_shape
= Qnil
;
10857 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
10858 doc
: /* A string indicating the foreground color of the cursor box. */);
10859 Vx_cursor_fore_pixel
= Qnil
;
10861 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
10862 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
10863 Text larger than this is clipped. */);
10864 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
10866 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
10867 doc
: /* Non-nil if no X window manager is in use.
10868 Emacs doesn't try to figure this out; this is always nil
10869 unless you set it to something else. */);
10870 /* We don't have any way to find this out, so set it to nil
10871 and maybe the user would like to set it to t. */
10872 Vx_no_window_manager
= Qnil
;
10874 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
10875 &Vx_pixel_size_width_font_regexp
,
10876 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
10878 Since Emacs gets width of a font matching with this regexp from
10879 PIXEL_SIZE field of the name, font finding mechanism gets faster for
10880 such a font. This is especially effective for such large fonts as
10881 Chinese, Japanese, and Korean. */);
10882 Vx_pixel_size_width_font_regexp
= Qnil
;
10884 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
10885 doc
: /* Time after which cached images are removed from the cache.
10886 When an image has not been displayed this many seconds, remove it
10887 from the image cache. Value must be an integer or nil with nil
10888 meaning don't clear the cache. */);
10889 Vimage_cache_eviction_delay
= make_number (30 * 60);
10891 #ifdef USE_X_TOOLKIT
10892 Fprovide (intern ("x-toolkit"), Qnil
);
10894 Fprovide (intern ("motif"), Qnil
);
10896 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
10897 doc
: /* Version info for LessTif/Motif. */);
10898 Vmotif_version_string
= build_string (XmVERSION_STRING
);
10899 #endif /* USE_MOTIF */
10900 #endif /* USE_X_TOOLKIT */
10902 /* X window properties. */
10903 defsubr (&Sx_change_window_property
);
10904 defsubr (&Sx_delete_window_property
);
10905 defsubr (&Sx_window_property
);
10907 defsubr (&Sxw_display_color_p
);
10908 defsubr (&Sx_display_grayscale_p
);
10909 defsubr (&Sxw_color_defined_p
);
10910 defsubr (&Sxw_color_values
);
10911 defsubr (&Sx_server_max_request_size
);
10912 defsubr (&Sx_server_vendor
);
10913 defsubr (&Sx_server_version
);
10914 defsubr (&Sx_display_pixel_width
);
10915 defsubr (&Sx_display_pixel_height
);
10916 defsubr (&Sx_display_mm_width
);
10917 defsubr (&Sx_display_mm_height
);
10918 defsubr (&Sx_display_screens
);
10919 defsubr (&Sx_display_planes
);
10920 defsubr (&Sx_display_color_cells
);
10921 defsubr (&Sx_display_visual_class
);
10922 defsubr (&Sx_display_backing_store
);
10923 defsubr (&Sx_display_save_under
);
10924 defsubr (&Sx_create_frame
);
10925 defsubr (&Sx_open_connection
);
10926 defsubr (&Sx_close_connection
);
10927 defsubr (&Sx_display_list
);
10928 defsubr (&Sx_synchronize
);
10929 defsubr (&Sx_focus_frame
);
10930 defsubr (&Sx_backspace_delete_keys_p
);
10932 /* Setting callback functions for fontset handler. */
10933 get_font_info_func
= x_get_font_info
;
10935 #if 0 /* This function pointer doesn't seem to be used anywhere.
10936 And the pointer assigned has the wrong type, anyway. */
10937 list_fonts_func
= x_list_fonts
;
10940 load_font_func
= x_load_font
;
10941 find_ccl_program_func
= x_find_ccl_program
;
10942 query_font_func
= x_query_font
;
10943 set_frame_fontset_func
= x_set_font
;
10944 check_window_system_func
= check_x
;
10947 Qxbm
= intern ("xbm");
10949 QCconversion
= intern (":conversion");
10950 staticpro (&QCconversion
);
10951 QCheuristic_mask
= intern (":heuristic-mask");
10952 staticpro (&QCheuristic_mask
);
10953 QCcolor_symbols
= intern (":color-symbols");
10954 staticpro (&QCcolor_symbols
);
10955 QCascent
= intern (":ascent");
10956 staticpro (&QCascent
);
10957 QCmargin
= intern (":margin");
10958 staticpro (&QCmargin
);
10959 QCrelief
= intern (":relief");
10960 staticpro (&QCrelief
);
10961 Qpostscript
= intern ("postscript");
10962 staticpro (&Qpostscript
);
10963 QCloader
= intern (":loader");
10964 staticpro (&QCloader
);
10965 QCbounding_box
= intern (":bounding-box");
10966 staticpro (&QCbounding_box
);
10967 QCpt_width
= intern (":pt-width");
10968 staticpro (&QCpt_width
);
10969 QCpt_height
= intern (":pt-height");
10970 staticpro (&QCpt_height
);
10971 QCindex
= intern (":index");
10972 staticpro (&QCindex
);
10973 Qpbm
= intern ("pbm");
10977 Qxpm
= intern ("xpm");
10982 Qjpeg
= intern ("jpeg");
10983 staticpro (&Qjpeg
);
10987 Qtiff
= intern ("tiff");
10988 staticpro (&Qtiff
);
10992 Qgif
= intern ("gif");
10997 Qpng
= intern ("png");
11001 defsubr (&Sclear_image_cache
);
11002 defsubr (&Simage_size
);
11003 defsubr (&Simage_mask_p
);
11005 hourglass_atimer
= NULL
;
11006 hourglass_shown_p
= 0;
11008 defsubr (&Sx_show_tip
);
11009 defsubr (&Sx_hide_tip
);
11011 staticpro (&tip_timer
);
11013 staticpro (&tip_frame
);
11015 last_show_tip_args
= Qnil
;
11016 staticpro (&last_show_tip_args
);
11019 defsubr (&Sx_file_dialog
);
11027 image_types
= NULL
;
11028 Vimage_types
= Qnil
;
11030 define_image_type (&xbm_type
);
11031 define_image_type (&gs_type
);
11032 define_image_type (&pbm_type
);
11035 define_image_type (&xpm_type
);
11039 define_image_type (&jpeg_type
);
11043 define_image_type (&tiff_type
);
11047 define_image_type (&gif_type
);
11051 define_image_type (&png_type
);
11055 #endif /* HAVE_X_WINDOWS */