diff options
| author | Jason Rumney | 2001-10-21 11:45:21 +0000 |
|---|---|---|
| committer | Jason Rumney | 2001-10-21 11:45:21 +0000 |
| commit | 3cf3436ebc2288e147aaeffbe7ba049b4bece990 (patch) | |
| tree | 513f0f5b2b7bd6fa28ce367ce9f8862f02ae3df7 | |
| parent | 292508513c425257dadc19e72a8c13d433134a5e (diff) | |
| download | emacs-3cf3436ebc2288e147aaeffbe7ba049b4bece990.tar.gz emacs-3cf3436ebc2288e147aaeffbe7ba049b4bece990.zip | |
(Fx_file_dialog): Pass a filter to GetOpenFileName.
Sync with xfns.c:
(x_laplace_read_row, x_laplace_write_row): Removed.
(postprocess_image): New function.
(lookup_image): Call it for all image types except PostScript.
(x_kill_gs_process): Call postprocess_image.
(tiff_error_handler, tiff_warning_handler): New functions.
(tiff_load): Install them as handlers.
(x_kill_gs_process): Recognize if someone has cleared the image
cache under us.
(valid_image_p): Protect better against invalid image
specifications. Previous code could signal an error.
(Fx_hide_tip, Fshow_tip): Doc fix.
(Fv_max_tooltip_size): New variable.
(syns_of_xfns): DEFVAR_LISP it.
(Fx_show_tip): Add parameter TEXT. Set the tip frame's root
window buffer to *tip* right after creating the frame. Set frame's
window_width. Use a maximum tooltip size specified by
Vx_max_tooltip_size, if that has valid contents.
(compute_tip_xy): Add parameters WIDTH and HEIGHT.
Make sure the tooltip is completely visible.
(x_create_tip_frame): Set tooltip buffer's truncate-lines to nil.
(Fx_create_frame): Adjust the frame's height for presence
of the tool bar before calling x_figure_window_size.
(x_set_tool_bar_lines): Clear the tool bar window's current matrix
when the window gets smaller.
(x_set_foreground_color): Set frame's cursor_pixel.
(x_set_foreground_color, x_set_background_color): Cleaned up.
(x_set_font): Handle case of x_new_fontset returning the same name
as before, although there was a change in fontsets.
| -rw-r--r-- | src/ChangeLog | 40 | ||||
| -rw-r--r-- | src/w32fns.c | 1254 |
2 files changed, 915 insertions, 379 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index ab5168940ad..1ab368efa0b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,43 @@ | |||
| 1 | 2001-10-21 Jason Rumney <jasonr@gnu.org> | ||
| 2 | |||
| 3 | * w32fns.c (Fx_file_dialog): Pass a filter to GetOpenFileName. | ||
| 4 | |||
| 5 | * w32menu.c (single_submenu, w32_menu_show) [!HAVE_MULTILINGUAL_MENU]: | ||
| 6 | Protect unibyte stings created by replacing their multibyte | ||
| 7 | equivalents in menu_items. | ||
| 8 | (w32_menu_show): Don't overwrite an item's name with its key | ||
| 9 | description in case the description is a multibyte string. | ||
| 10 | (single_submenu): Some cleanup. | ||
| 11 | |||
| 12 | * w32fns.c (x_laplace_read_row, x_laplace_write_row): Removed. | ||
| 13 | (postprocess_image): New function. | ||
| 14 | (lookup_image): Call it for all image types except PostScript. | ||
| 15 | (x_kill_gs_process): Call postprocess_image. | ||
| 16 | (tiff_error_handler, tiff_warning_handler): New functions. | ||
| 17 | (tiff_load): Install them as handlers. | ||
| 18 | (x_kill_gs_process): Recognize if someone has cleared the image | ||
| 19 | cache under us. | ||
| 20 | (valid_image_p): Protect better against invalid image | ||
| 21 | specifications. Previous code could signal an error. | ||
| 22 | (Fx_hide_tip, Fshow_tip): Doc fix. | ||
| 23 | (Fv_max_tooltip_size): New variable. | ||
| 24 | (syns_of_xfns): DEFVAR_LISP it. | ||
| 25 | (Fx_show_tip): Add parameter TEXT. Set the tip frame's root | ||
| 26 | window buffer to *tip* right after creating the frame. Set frame's | ||
| 27 | window_width. Use a maximum tooltip size specified by | ||
| 28 | Vx_max_tooltip_size, if that has valid contents. | ||
| 29 | (compute_tip_xy): Add parameters WIDTH and HEIGHT. | ||
| 30 | Make sure the tooltip is completely visible. | ||
| 31 | (x_create_tip_frame): Set tooltip buffer's truncate-lines to nil. | ||
| 32 | (Fx_create_frame): Adjust the frame's height for presence | ||
| 33 | of the tool bar before calling x_figure_window_size. | ||
| 34 | (x_set_tool_bar_lines): Clear the tool bar window's current matrix | ||
| 35 | when the window gets smaller. | ||
| 36 | (x_set_foreground_color): Set frame's cursor_pixel. | ||
| 37 | (x_set_foreground_color, x_set_background_color): Cleaned up. | ||
| 38 | (x_set_font): Handle case of x_new_fontset returning the same name | ||
| 39 | as before, although there was a change in fontsets. | ||
| 40 | |||
| 1 | 2001-10-21 Miles Bader <miles@gnu.org> | 41 | 2001-10-21 Miles Bader <miles@gnu.org> |
| 2 | 42 | ||
| 3 | * data.c (Fplus, Fminus, Fmax, Ftimes, Fquo, Flogand, Flogior) | 43 | * data.c (Fplus, Fminus, Fmax, Ftimes, Fquo, Flogand, Flogior) |
diff --git a/src/w32fns.c b/src/w32fns.c index 991ac7ac3af..a4ad1e49c20 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -687,6 +687,8 @@ void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object)); | |||
| 687 | void x_set_unsplittable P_ ((struct frame *, Lisp_Object, Lisp_Object)); | 687 | void x_set_unsplittable P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
| 688 | void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object)); | 688 | void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
| 689 | static void x_set_screen_gamma P_ ((struct frame *, Lisp_Object, Lisp_Object)); | 689 | static void x_set_screen_gamma P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
| 690 | static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object, | ||
| 691 | Lisp_Object)); | ||
| 690 | 692 | ||
| 691 | static struct x_frame_parm_table x_frame_parms[] = | 693 | static struct x_frame_parm_table x_frame_parms[] = |
| 692 | { | 694 | { |
| @@ -1956,11 +1958,18 @@ x_set_foreground_color (f, arg, oldval) | |||
| 1956 | struct frame *f; | 1958 | struct frame *f; |
| 1957 | Lisp_Object arg, oldval; | 1959 | Lisp_Object arg, oldval; |
| 1958 | { | 1960 | { |
| 1959 | FRAME_FOREGROUND_PIXEL (f) | 1961 | struct w32_output *x = f->output_data.w32; |
| 1960 | = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); | 1962 | PIX_TYPE fg, old_fg; |
| 1963 | |||
| 1964 | fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); | ||
| 1965 | old_fg = FRAME_FOREGROUND_PIXEL (f); | ||
| 1966 | FRAME_FOREGROUND_PIXEL (f) = fg; | ||
| 1961 | 1967 | ||
| 1962 | if (FRAME_W32_WINDOW (f) != 0) | 1968 | if (FRAME_W32_WINDOW (f) != 0) |
| 1963 | { | 1969 | { |
| 1970 | if (x->cursor_pixel == old_fg) | ||
| 1971 | x->cursor_pixel = fg; | ||
| 1972 | |||
| 1964 | update_face_from_frame_parameter (f, Qforeground_color, arg); | 1973 | update_face_from_frame_parameter (f, Qforeground_color, arg); |
| 1965 | if (FRAME_VISIBLE_P (f)) | 1974 | if (FRAME_VISIBLE_P (f)) |
| 1966 | redraw_frame (f); | 1975 | redraw_frame (f); |
| @@ -2367,6 +2376,7 @@ x_set_font (f, arg, oldval) | |||
| 2367 | Lisp_Object result; | 2376 | Lisp_Object result; |
| 2368 | Lisp_Object fontset_name; | 2377 | Lisp_Object fontset_name; |
| 2369 | Lisp_Object frame; | 2378 | Lisp_Object frame; |
| 2379 | int old_fontset = FRAME_FONTSET(f); | ||
| 2370 | 2380 | ||
| 2371 | CHECK_STRING (arg, 1); | 2381 | CHECK_STRING (arg, 1); |
| 2372 | 2382 | ||
| @@ -2384,8 +2394,16 @@ x_set_font (f, arg, oldval) | |||
| 2384 | error ("The characters of the given font have varying widths"); | 2394 | error ("The characters of the given font have varying widths"); |
| 2385 | else if (STRINGP (result)) | 2395 | else if (STRINGP (result)) |
| 2386 | { | 2396 | { |
| 2387 | if (!NILP (Fequal (result, oldval))) | 2397 | if (STRINGP (fontset_name)) |
| 2398 | { | ||
| 2399 | /* Fontset names are built from ASCII font names, so the | ||
| 2400 | names may be equal despite there was a change. */ | ||
| 2401 | if (old_fontset == FRAME_FONTSET (f)) | ||
| 2402 | return; | ||
| 2403 | } | ||
| 2404 | else if (!NILP (Fequal (result, oldval))) | ||
| 2388 | return; | 2405 | return; |
| 2406 | |||
| 2389 | store_frame_param (f, Qfont, result); | 2407 | store_frame_param (f, Qfont, result); |
| 2390 | recompute_basic_faces (f); | 2408 | recompute_basic_faces (f); |
| 2391 | } | 2409 | } |
| @@ -2602,6 +2620,9 @@ x_set_tool_bar_lines (f, value, oldval) | |||
| 2602 | release_frame_dc (f, hdc); | 2620 | release_frame_dc (f, hdc); |
| 2603 | } | 2621 | } |
| 2604 | UNBLOCK_INPUT; | 2622 | UNBLOCK_INPUT; |
| 2623 | |||
| 2624 | if (WINDOWP (f->tool_bar_window)) | ||
| 2625 | clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix); | ||
| 2605 | } | 2626 | } |
| 2606 | } | 2627 | } |
| 2607 | 2628 | ||
| @@ -5355,6 +5376,35 @@ This function is an internal primitive--use `make-frame' instead.") | |||
| 5355 | 5376 | ||
| 5356 | f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; | 5377 | f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; |
| 5357 | f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window; | 5378 | f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window; |
| 5379 | |||
| 5380 | /* Add the tool-bar height to the initial frame height so that the | ||
| 5381 | user gets a text display area of the size he specified with -g or | ||
| 5382 | via .Xdefaults. Later changes of the tool-bar height don't | ||
| 5383 | change the frame size. This is done so that users can create | ||
| 5384 | tall Emacs frames without having to guess how tall the tool-bar | ||
| 5385 | will get. */ | ||
| 5386 | if (FRAME_TOOL_BAR_LINES (f)) | ||
| 5387 | { | ||
| 5388 | int margin, relief, bar_height; | ||
| 5389 | |||
| 5390 | relief = (tool_bar_button_relief > 0 | ||
| 5391 | ? tool_bar_button_relief | ||
| 5392 | : DEFAULT_TOOL_BAR_BUTTON_RELIEF); | ||
| 5393 | |||
| 5394 | if (INTEGERP (Vtool_bar_button_margin) | ||
| 5395 | && XINT (Vtool_bar_button_margin) > 0) | ||
| 5396 | margin = XFASTINT (Vtool_bar_button_margin); | ||
| 5397 | else if (CONSP (Vtool_bar_button_margin) | ||
| 5398 | && INTEGERP (XCDR (Vtool_bar_button_margin)) | ||
| 5399 | && XINT (XCDR (Vtool_bar_button_margin)) > 0) | ||
| 5400 | margin = XFASTINT (XCDR (Vtool_bar_button_margin)); | ||
| 5401 | else | ||
| 5402 | margin = 0; | ||
| 5403 | |||
| 5404 | bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief; | ||
| 5405 | f->height += (bar_height + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f); | ||
| 5406 | } | ||
| 5407 | |||
| 5358 | window_prompting = x_figure_window_size (f, parms); | 5408 | window_prompting = x_figure_window_size (f, parms); |
| 5359 | 5409 | ||
| 5360 | if (window_prompting & XNegative) | 5410 | if (window_prompting & XNegative) |
| @@ -5406,34 +5456,6 @@ This function is an internal primitive--use `make-frame' instead.") | |||
| 5406 | width = f->width; | 5456 | width = f->width; |
| 5407 | height = f->height; | 5457 | height = f->height; |
| 5408 | 5458 | ||
| 5409 | /* Add the tool-bar height to the initial frame height so that the | ||
| 5410 | user gets a text display area of the size he specified with -g or | ||
| 5411 | via .Xdefaults. Later changes of the tool-bar height don't | ||
| 5412 | change the frame size. This is done so that users can create | ||
| 5413 | tall Emacs frames without having to guess how tall the tool-bar | ||
| 5414 | will get. */ | ||
| 5415 | if (FRAME_TOOL_BAR_LINES (f)) | ||
| 5416 | { | ||
| 5417 | int margin, relief, bar_height; | ||
| 5418 | |||
| 5419 | relief = (tool_bar_button_relief > 0 | ||
| 5420 | ? tool_bar_button_relief | ||
| 5421 | : DEFAULT_TOOL_BAR_BUTTON_RELIEF); | ||
| 5422 | |||
| 5423 | if (INTEGERP (Vtool_bar_button_margin) | ||
| 5424 | && XINT (Vtool_bar_button_margin) > 0) | ||
| 5425 | margin = XFASTINT (Vtool_bar_button_margin); | ||
| 5426 | else if (CONSP (Vtool_bar_button_margin) | ||
| 5427 | && INTEGERP (XCDR (Vtool_bar_button_margin)) | ||
| 5428 | && XINT (XCDR (Vtool_bar_button_margin)) > 0) | ||
| 5429 | margin = XFASTINT (XCDR (Vtool_bar_button_margin)); | ||
| 5430 | else | ||
| 5431 | margin = 0; | ||
| 5432 | |||
| 5433 | bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief; | ||
| 5434 | height += (bar_height + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f); | ||
| 5435 | } | ||
| 5436 | |||
| 5437 | f->height = 0; | 5459 | f->height = 0; |
| 5438 | SET_FRAME_WIDTH (f, 0); | 5460 | SET_FRAME_WIDTH (f, 0); |
| 5439 | change_frame_size (f, height, width, 1, 0, 0); | 5461 | change_frame_size (f, height, width, 1, 0, 0); |
| @@ -7680,11 +7702,11 @@ extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile; | |||
| 7680 | extern Lisp_Object QCdata; | 7702 | extern Lisp_Object QCdata; |
| 7681 | Lisp_Object QCtype, QCascent, QCmargin, QCrelief; | 7703 | Lisp_Object QCtype, QCascent, QCmargin, QCrelief; |
| 7682 | Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; | 7704 | Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; |
| 7683 | Lisp_Object QCindex; | 7705 | Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask; |
| 7684 | 7706 | ||
| 7685 | /* Other symbols. */ | 7707 | /* Other symbols. */ |
| 7686 | 7708 | ||
| 7687 | Lisp_Object Qlaplace; | 7709 | Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic; |
| 7688 | 7710 | ||
| 7689 | /* Time in seconds after which images should be removed from the cache | 7711 | /* Time in seconds after which images should be removed from the cache |
| 7690 | if not displayed. */ | 7712 | if not displayed. */ |
| @@ -7697,6 +7719,7 @@ static void define_image_type P_ ((struct image_type *type)); | |||
| 7697 | static struct image_type *lookup_image_type P_ ((Lisp_Object symbol)); | 7719 | static struct image_type *lookup_image_type P_ ((Lisp_Object symbol)); |
| 7698 | static void image_error P_ ((char *format, Lisp_Object, Lisp_Object)); | 7720 | static void image_error P_ ((char *format, Lisp_Object, Lisp_Object)); |
| 7699 | static void x_laplace P_ ((struct frame *, struct image *)); | 7721 | static void x_laplace P_ ((struct frame *, struct image *)); |
| 7722 | static void x_emboss P_ ((struct frame *, struct image *)); | ||
| 7700 | static int x_build_heuristic_mask P_ ((struct frame *, struct image *, | 7723 | static int x_build_heuristic_mask P_ ((struct frame *, struct image *, |
| 7701 | Lisp_Object)); | 7724 | Lisp_Object)); |
| 7702 | 7725 | ||
| @@ -7750,11 +7773,22 @@ valid_image_p (object) | |||
| 7750 | 7773 | ||
| 7751 | if (CONSP (object) && EQ (XCAR (object), Qimage)) | 7774 | if (CONSP (object) && EQ (XCAR (object), Qimage)) |
| 7752 | { | 7775 | { |
| 7753 | Lisp_Object symbol = Fplist_get (XCDR (object), QCtype); | 7776 | Lisp_Object tem; |
| 7754 | struct image_type *type = lookup_image_type (symbol); | 7777 | |
| 7755 | 7778 | for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem)) | |
| 7756 | if (type) | 7779 | if (EQ (XCAR (tem), QCtype)) |
| 7757 | valid_p = type->valid_p (object); | 7780 | { |
| 7781 | tem = XCDR (tem); | ||
| 7782 | if (CONSP (tem) && SYMBOLP (XCAR (tem))) | ||
| 7783 | { | ||
| 7784 | struct image_type *type; | ||
| 7785 | type = lookup_image_type (XCAR (tem)); | ||
| 7786 | if (type) | ||
| 7787 | valid_p = type->valid_p (object); | ||
| 7788 | } | ||
| 7789 | |||
| 7790 | break; | ||
| 7791 | } | ||
| 7758 | } | 7792 | } |
| 7759 | 7793 | ||
| 7760 | return valid_p; | 7794 | return valid_p; |
| @@ -7785,6 +7819,7 @@ enum image_value_type | |||
| 7785 | { | 7819 | { |
| 7786 | IMAGE_DONT_CHECK_VALUE_TYPE, | 7820 | IMAGE_DONT_CHECK_VALUE_TYPE, |
| 7787 | IMAGE_STRING_VALUE, | 7821 | IMAGE_STRING_VALUE, |
| 7822 | IMAGE_STRING_OR_NIL_VALUE, | ||
| 7788 | IMAGE_SYMBOL_VALUE, | 7823 | IMAGE_SYMBOL_VALUE, |
| 7789 | IMAGE_POSITIVE_INTEGER_VALUE, | 7824 | IMAGE_POSITIVE_INTEGER_VALUE, |
| 7790 | IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, | 7825 | IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, |
| @@ -7882,6 +7917,11 @@ parse_image_spec (spec, keywords, nkeywords, type) | |||
| 7882 | return 0; | 7917 | return 0; |
| 7883 | break; | 7918 | break; |
| 7884 | 7919 | ||
| 7920 | case IMAGE_STRING_OR_NIL_VALUE: | ||
| 7921 | if (!STRINGP (value) && !NILP (value)) | ||
| 7922 | return 0; | ||
| 7923 | break; | ||
| 7924 | |||
| 7885 | case IMAGE_SYMBOL_VALUE: | 7925 | case IMAGE_SYMBOL_VALUE: |
| 7886 | if (!SYMBOLP (value)) | 7926 | if (!SYMBOLP (value)) |
| 7887 | return 0; | 7927 | return 0; |
| @@ -8195,6 +8235,7 @@ x_alloc_image_color (f, img, color_name, dflt) | |||
| 8195 | ***********************************************************************/ | 8235 | ***********************************************************************/ |
| 8196 | 8236 | ||
| 8197 | static void cache_image P_ ((struct frame *f, struct image *img)); | 8237 | static void cache_image P_ ((struct frame *f, struct image *img)); |
| 8238 | static void postprocess_image P_ ((struct frame *, struct image *)); | ||
| 8198 | 8239 | ||
| 8199 | 8240 | ||
| 8200 | /* Return a new, initialized image cache that is allocated from the | 8241 | /* Return a new, initialized image cache that is allocated from the |
| @@ -8312,6 +8353,83 @@ FRAME t means clear the image caches of all frames.") | |||
| 8312 | } | 8353 | } |
| 8313 | 8354 | ||
| 8314 | 8355 | ||
| 8356 | /* Compute masks and transform image IMG on frame F, as specified | ||
| 8357 | by the image's specification, */ | ||
| 8358 | |||
| 8359 | static void | ||
| 8360 | postprocess_image (f, img) | ||
| 8361 | struct frame *f; | ||
| 8362 | struct image *img; | ||
| 8363 | { | ||
| 8364 | #if 0 /* TODO: image support. */ | ||
| 8365 | /* Manipulation of the image's mask. */ | ||
| 8366 | if (img->pixmap) | ||
| 8367 | { | ||
| 8368 | Lisp_Object conversion, spec; | ||
| 8369 | Lisp_Object mask; | ||
| 8370 | |||
| 8371 | spec = img->spec; | ||
| 8372 | |||
| 8373 | /* `:heuristic-mask t' | ||
| 8374 | `:mask heuristic' | ||
| 8375 | means build a mask heuristically. | ||
| 8376 | `:heuristic-mask (R G B)' | ||
| 8377 | `:mask (heuristic (R G B))' | ||
| 8378 | means build a mask from color (R G B) in the | ||
| 8379 | image. | ||
| 8380 | `:mask nil' | ||
| 8381 | means remove a mask, if any. */ | ||
| 8382 | |||
| 8383 | mask = image_spec_value (spec, QCheuristic_mask, NULL); | ||
| 8384 | if (!NILP (mask)) | ||
| 8385 | x_build_heuristic_mask (f, img, mask); | ||
| 8386 | else | ||
| 8387 | { | ||
| 8388 | int found_p; | ||
| 8389 | |||
| 8390 | mask = image_spec_value (spec, QCmask, &found_p); | ||
| 8391 | |||
| 8392 | if (EQ (mask, Qheuristic)) | ||
| 8393 | x_build_heuristic_mask (f, img, Qt); | ||
| 8394 | else if (CONSP (mask) | ||
| 8395 | && EQ (XCAR (mask), Qheuristic)) | ||
| 8396 | { | ||
| 8397 | if (CONSP (XCDR (mask))) | ||
| 8398 | x_build_heuristic_mask (f, img, XCAR (XCDR (mask))); | ||
| 8399 | else | ||
| 8400 | x_build_heuristic_mask (f, img, XCDR (mask)); | ||
| 8401 | } | ||
| 8402 | else if (NILP (mask) && found_p && img->mask) | ||
| 8403 | { | ||
| 8404 | XFreePixmap (FRAME_X_DISPLAY (f), img->mask); | ||
| 8405 | img->mask = NULL; | ||
| 8406 | } | ||
| 8407 | } | ||
| 8408 | |||
| 8409 | |||
| 8410 | /* Should we apply an image transformation algorithm? */ | ||
| 8411 | conversion = image_spec_value (spec, QCconversion, NULL); | ||
| 8412 | if (EQ (conversion, Qdisabled)) | ||
| 8413 | x_disable_image (f, img); | ||
| 8414 | else if (EQ (conversion, Qlaplace)) | ||
| 8415 | x_laplace (f, img); | ||
| 8416 | else if (EQ (conversion, Qemboss)) | ||
| 8417 | x_emboss (f, img); | ||
| 8418 | else if (CONSP (conversion) | ||
| 8419 | && EQ (XCAR (conversion), Qedge_detection)) | ||
| 8420 | { | ||
| 8421 | Lisp_Object tem; | ||
| 8422 | tem = XCDR (conversion); | ||
| 8423 | if (CONSP (tem)) | ||
| 8424 | x_edge_detection (f, img, | ||
| 8425 | Fplist_get (tem, QCmatrix), | ||
| 8426 | Fplist_get (tem, QCcolor_adjustment)); | ||
| 8427 | } | ||
| 8428 | } | ||
| 8429 | #endif | ||
| 8430 | } | ||
| 8431 | |||
| 8432 | |||
| 8315 | /* Return the id of image with Lisp specification SPEC on frame F. | 8433 | /* Return the id of image with Lisp specification SPEC on frame F. |
| 8316 | SPEC must be a valid Lisp image specification (see valid_image_p). */ | 8434 | SPEC must be a valid Lisp image specification (see valid_image_p). */ |
| 8317 | 8435 | ||
| @@ -8345,6 +8463,8 @@ lookup_image (f, spec) | |||
| 8345 | /* If not found, create a new image and cache it. */ | 8463 | /* If not found, create a new image and cache it. */ |
| 8346 | if (img == NULL) | 8464 | if (img == NULL) |
| 8347 | { | 8465 | { |
| 8466 | extern Lisp_Object Qpostscript; | ||
| 8467 | |||
| 8348 | BLOCK_INPUT; | 8468 | BLOCK_INPUT; |
| 8349 | img = make_image (spec, hash); | 8469 | img = make_image (spec, hash); |
| 8350 | cache_image (f, img); | 8470 | cache_image (f, img); |
| @@ -8396,74 +8516,12 @@ lookup_image (f, spec) | |||
| 8396 | img->vmargin += abs (img->relief); | 8516 | img->vmargin += abs (img->relief); |
| 8397 | } | 8517 | } |
| 8398 | 8518 | ||
| 8399 | #if 0 /* TODO: image mask and algorithm. */ | 8519 | /* Do image transformations and compute masks, unless we |
| 8400 | /* Manipulation of the image's mask. */ | 8520 | don't have the image yet. */ |
| 8401 | if (img->pixmap) | 8521 | if (!EQ (*img->type->type, Qpostscript)) |
| 8402 | { | 8522 | postprocess_image (f, img); |
| 8403 | /* `:heuristic-mask t' | ||
| 8404 | `:mask heuristic' | ||
| 8405 | means build a mask heuristically. | ||
| 8406 | `:heuristic-mask (R G B)' | ||
| 8407 | `:mask (heuristic (R G B))' | ||
| 8408 | means build a mask from color (R G B) in the | ||
| 8409 | image. | ||
| 8410 | `:mask nil' | ||
| 8411 | means remove a mask, if any. */ | ||
| 8412 | |||
| 8413 | Lisp_Object mask; | ||
| 8414 | |||
| 8415 | mask = image_spec_value (spec, QCheuristic_mask, NULL); | ||
| 8416 | if (!NILP (mask)) | ||
| 8417 | x_build_heuristic_mask (f, img, mask); | ||
| 8418 | else | ||
| 8419 | { | ||
| 8420 | int found_p; | ||
| 8421 | |||
| 8422 | mask = image_spec_value (spec, QCmask, &found_p); | ||
| 8423 | |||
| 8424 | if (EQ (mask, Qheuristic)) | ||
| 8425 | x_build_heuristic_mask (f, img, Qt); | ||
| 8426 | else if (CONSP (mask) | ||
| 8427 | && EQ (XCAR (mask), Qheuristic)) | ||
| 8428 | { | ||
| 8429 | if (CONSP (XCDR (mask))) | ||
| 8430 | x_build_heuristic_mask (f, img, XCAR (XCDR (mask))); | ||
| 8431 | else | ||
| 8432 | x_build_heuristic_mask (f, img, XCDR (mask)); | ||
| 8433 | } | ||
| 8434 | else if (NILP (mask) && found_p && img->mask) | ||
| 8435 | { | ||
| 8436 | XFreePixmap (FRAME_X_DISPLAY (f), img->mask); | ||
| 8437 | img->mask = None; | ||
| 8438 | } | ||
| 8439 | } | ||
| 8440 | } | ||
| 8441 | |||
| 8442 | /* Should we apply an image transformation algorithm? */ | ||
| 8443 | if (img->pixmap) | ||
| 8444 | { | ||
| 8445 | Lisp_Object conversion; | ||
| 8446 | |||
| 8447 | algorithm = image_spec_value (spec, QCconversion, NULL); | ||
| 8448 | if (EQ (conversion, Qdisabled)) | ||
| 8449 | x_disable_image (f, img); | ||
| 8450 | else if (EQ (conversion, Qlaplace)) | ||
| 8451 | x_laplace (f, img); | ||
| 8452 | else if (EQ (conversion, Qemboss)) | ||
| 8453 | x_emboss (f, img); | ||
| 8454 | else if (CONSP (conversion) | ||
| 8455 | && EQ (XCAR (conversion), Qedge_detection)) | ||
| 8456 | { | ||
| 8457 | Lisp_Object tem; | ||
| 8458 | tem = XCDR (conversion); | ||
| 8459 | if (CONSP (tem)) | ||
| 8460 | x_edge_detection (f, img, | ||
| 8461 | Fplist_get (tem, QCmatrix), | ||
| 8462 | Fplist_get (tem, QCcolor_adjustment)); | ||
| 8463 | } | ||
| 8464 | } | ||
| 8465 | #endif /* TODO. */ | ||
| 8466 | } | 8523 | } |
| 8524 | |||
| 8467 | UNBLOCK_INPUT; | 8525 | UNBLOCK_INPUT; |
| 8468 | xassert (!interrupt_input_blocked); | 8526 | xassert (!interrupt_input_blocked); |
| 8469 | } | 8527 | } |
| @@ -8638,10 +8696,12 @@ x_put_x_image (f, ximg, pixmap, width, height) | |||
| 8638 | 8696 | ||
| 8639 | 8697 | ||
| 8640 | /*********************************************************************** | 8698 | /*********************************************************************** |
| 8641 | Searching files | 8699 | File Handling |
| 8642 | ***********************************************************************/ | 8700 | ***********************************************************************/ |
| 8643 | 8701 | ||
| 8644 | static Lisp_Object x_find_image_file P_ ((Lisp_Object)); | 8702 | static Lisp_Object x_find_image_file P_ ((Lisp_Object)); |
| 8703 | static char *slurp_file P_ ((char *, int *)); | ||
| 8704 | |||
| 8645 | 8705 | ||
| 8646 | /* Find image file FILE. Look in data-directory, then | 8706 | /* Find image file FILE. Look in data-directory, then |
| 8647 | x-bitmap-file-path. Value is the full name of the file found, or | 8707 | x-bitmap-file-path. Value is the full name of the file found, or |
| @@ -8672,6 +8732,42 @@ x_find_image_file (file) | |||
| 8672 | } | 8732 | } |
| 8673 | 8733 | ||
| 8674 | 8734 | ||
| 8735 | /* Read FILE into memory. Value is a pointer to a buffer allocated | ||
| 8736 | with xmalloc holding FILE's contents. Value is null if an error | ||
| 8737 | occurred. *SIZE is set to the size of the file. */ | ||
| 8738 | |||
| 8739 | static char * | ||
| 8740 | slurp_file (file, size) | ||
| 8741 | char *file; | ||
| 8742 | int *size; | ||
| 8743 | { | ||
| 8744 | FILE *fp = NULL; | ||
| 8745 | char *buf = NULL; | ||
| 8746 | struct stat st; | ||
| 8747 | |||
| 8748 | if (stat (file, &st) == 0 | ||
| 8749 | && (fp = fopen (file, "r")) != NULL | ||
| 8750 | && (buf = (char *) xmalloc (st.st_size), | ||
| 8751 | fread (buf, 1, st.st_size, fp) == st.st_size)) | ||
| 8752 | { | ||
| 8753 | *size = st.st_size; | ||
| 8754 | fclose (fp); | ||
| 8755 | } | ||
| 8756 | else | ||
| 8757 | { | ||
| 8758 | if (fp) | ||
| 8759 | fclose (fp); | ||
| 8760 | if (buf) | ||
| 8761 | { | ||
| 8762 | xfree (buf); | ||
| 8763 | buf = NULL; | ||
| 8764 | } | ||
| 8765 | } | ||
| 8766 | |||
| 8767 | return buf; | ||
| 8768 | } | ||
| 8769 | |||
| 8770 | |||
| 8675 | 8771 | ||
| 8676 | /*********************************************************************** | 8772 | /*********************************************************************** |
| 8677 | XBM images | 8773 | XBM images |
| @@ -8714,8 +8810,8 @@ static struct image_keyword xbm_format[XBM_LAST] = | |||
| 8714 | {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0}, | 8810 | {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0}, |
| 8715 | {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0}, | 8811 | {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0}, |
| 8716 | {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, | 8812 | {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
| 8717 | {":foreground", IMAGE_STRING_VALUE, 0}, | 8813 | {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0}, |
| 8718 | {":background", IMAGE_STRING_VALUE, 0}, | 8814 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0}, |
| 8719 | {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, | 8815 | {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, |
| 8720 | {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, | 8816 | {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
| 8721 | {":relief", IMAGE_INTEGER_VALUE, 0}, | 8817 | {":relief", IMAGE_INTEGER_VALUE, 0}, |
| @@ -8862,30 +8958,33 @@ xbm_image_p (object) | |||
| 8862 | scanning a number, store its value in *IVAL. */ | 8958 | scanning a number, store its value in *IVAL. */ |
| 8863 | 8959 | ||
| 8864 | static int | 8960 | static int |
| 8865 | xbm_scan (fp, sval, ival) | 8961 | xbm_scan (s, end, sval, ival) |
| 8866 | FILE *fp; | 8962 | char **s, *end; |
| 8867 | char *sval; | 8963 | char *sval; |
| 8868 | int *ival; | 8964 | int *ival; |
| 8869 | { | 8965 | { |
| 8870 | int c; | 8966 | int c; |
| 8871 | 8967 | ||
| 8968 | loop: | ||
| 8969 | |||
| 8872 | /* Skip white space. */ | 8970 | /* Skip white space. */ |
| 8873 | while ((c = fgetc (fp)) != EOF && isspace (c)) | 8971 | while (*s < end &&(c = *(*s)++, isspace (c))) |
| 8874 | ; | 8972 | ; |
| 8875 | 8973 | ||
| 8876 | if (c == EOF) | 8974 | if (*s >= end) |
| 8877 | c = 0; | 8975 | c = 0; |
| 8878 | else if (isdigit (c)) | 8976 | else if (isdigit (c)) |
| 8879 | { | 8977 | { |
| 8880 | int value = 0, digit; | 8978 | int value = 0, digit; |
| 8881 | 8979 | ||
| 8882 | if (c == '0') | 8980 | if (c == '0' && *s < end) |
| 8883 | { | 8981 | { |
| 8884 | c = fgetc (fp); | 8982 | c = *(*s)++; |
| 8885 | if (c == 'x' || c == 'X') | 8983 | if (c == 'x' || c == 'X') |
| 8886 | { | 8984 | { |
| 8887 | while ((c = fgetc (fp)) != EOF) | 8985 | while (*s < end) |
| 8888 | { | 8986 | { |
| 8987 | c = *(*s)++; | ||
| 8889 | if (isdigit (c)) | 8988 | if (isdigit (c)) |
| 8890 | digit = c - '0'; | 8989 | digit = c - '0'; |
| 8891 | else if (c >= 'a' && c <= 'f') | 8990 | else if (c >= 'a' && c <= 'f') |
| @@ -8900,53 +8999,66 @@ xbm_scan (fp, sval, ival) | |||
| 8900 | else if (isdigit (c)) | 8999 | else if (isdigit (c)) |
| 8901 | { | 9000 | { |
| 8902 | value = c - '0'; | 9001 | value = c - '0'; |
| 8903 | while ((c = fgetc (fp)) != EOF | 9002 | while (*s < end |
| 8904 | && isdigit (c)) | 9003 | && (c = *(*s)++, isdigit (c))) |
| 8905 | value = 8 * value + c - '0'; | 9004 | value = 8 * value + c - '0'; |
| 8906 | } | 9005 | } |
| 8907 | } | 9006 | } |
| 8908 | else | 9007 | else |
| 8909 | { | 9008 | { |
| 8910 | value = c - '0'; | 9009 | value = c - '0'; |
| 8911 | while ((c = fgetc (fp)) != EOF | 9010 | while (*s < end |
| 8912 | && isdigit (c)) | 9011 | && (c = *(*s)++, isdigit (c))) |
| 8913 | value = 10 * value + c - '0'; | 9012 | value = 10 * value + c - '0'; |
| 8914 | } | 9013 | } |
| 8915 | 9014 | ||
| 8916 | if (c != EOF) | 9015 | if (*s < end) |
| 8917 | ungetc (c, fp); | 9016 | *s = *s - 1; |
| 8918 | *ival = value; | 9017 | *ival = value; |
| 8919 | c = XBM_TK_NUMBER; | 9018 | c = XBM_TK_NUMBER; |
| 8920 | } | 9019 | } |
| 8921 | else if (isalpha (c) || c == '_') | 9020 | else if (isalpha (c) || c == '_') |
| 8922 | { | 9021 | { |
| 8923 | *sval++ = c; | 9022 | *sval++ = c; |
| 8924 | while ((c = fgetc (fp)) != EOF | 9023 | while (*s < end |
| 8925 | && (isalnum (c) || c == '_')) | 9024 | && (c = *(*s)++, (isalnum (c) || c == '_'))) |
| 8926 | *sval++ = c; | 9025 | *sval++ = c; |
| 8927 | *sval = 0; | 9026 | *sval = 0; |
| 8928 | if (c != EOF) | 9027 | if (*s < end) |
| 8929 | ungetc (c, fp); | 9028 | *s = *s - 1; |
| 8930 | c = XBM_TK_IDENT; | 9029 | c = XBM_TK_IDENT; |
| 8931 | } | 9030 | } |
| 9031 | else if (c == '/' && **s == '*') | ||
| 9032 | { | ||
| 9033 | /* C-style comment. */ | ||
| 9034 | ++*s; | ||
| 9035 | while (**s && (**s != '*' || *(*s + 1) != '/')) | ||
| 9036 | ++*s; | ||
| 9037 | if (**s) | ||
| 9038 | { | ||
| 9039 | *s += 2; | ||
| 9040 | goto loop; | ||
| 9041 | } | ||
| 9042 | } | ||
| 8932 | 9043 | ||
| 8933 | return c; | 9044 | return c; |
| 8934 | } | 9045 | } |
| 8935 | 9046 | ||
| 8936 | 9047 | ||
| 8937 | /* Replacement for XReadBitmapFileData which isn't available under old | 9048 | /* Replacement for XReadBitmapFileData which isn't available under old |
| 8938 | X versions. FILE is the name of the bitmap file to read. Set | 9049 | X versions. CONTENTS is a pointer to a buffer to parse; END is the |
| 8939 | *WIDTH and *HEIGHT to the width and height of the image. Return in | 9050 | buffer's end. Set *WIDTH and *HEIGHT to the width and height of |
| 8940 | *DATA the bitmap data allocated with xmalloc. Value is non-zero if | 9051 | the image. Return in *DATA the bitmap data allocated with xmalloc. |
| 8941 | successful. */ | 9052 | Value is non-zero if successful. DATA null means just test if |
| 9053 | CONTENTS looks like an in-memory XBM file. */ | ||
| 8942 | 9054 | ||
| 8943 | static int | 9055 | static int |
| 8944 | xbm_read_bitmap_file_data (file, width, height, data) | 9056 | xbm_read_bitmap_data (contents, end, width, height, data) |
| 8945 | char *file; | 9057 | char *contents, *end; |
| 8946 | int *width, *height; | 9058 | int *width, *height; |
| 8947 | unsigned char **data; | 9059 | unsigned char **data; |
| 8948 | { | 9060 | { |
| 8949 | FILE *fp; | 9061 | char *s = contents; |
| 8950 | char buffer[BUFSIZ]; | 9062 | char buffer[BUFSIZ]; |
| 8951 | int padding_p = 0; | 9063 | int padding_p = 0; |
| 8952 | int v10 = 0; | 9064 | int v10 = 0; |
| @@ -8956,7 +9068,7 @@ xbm_read_bitmap_file_data (file, width, height, data) | |||
| 8956 | int LA1; | 9068 | int LA1; |
| 8957 | 9069 | ||
| 8958 | #define match() \ | 9070 | #define match() \ |
| 8959 | LA1 = xbm_scan (fp, buffer, &value) | 9071 | LA1 = xbm_scan (contents, end, buffer, &value) |
| 8960 | 9072 | ||
| 8961 | #define expect(TOKEN) \ | 9073 | #define expect(TOKEN) \ |
| 8962 | if (LA1 != (TOKEN)) \ | 9074 | if (LA1 != (TOKEN)) \ |
| @@ -8970,13 +9082,10 @@ xbm_read_bitmap_file_data (file, width, height, data) | |||
| 8970 | else \ | 9082 | else \ |
| 8971 | goto failure | 9083 | goto failure |
| 8972 | 9084 | ||
| 8973 | fp = fopen (file, "r"); | ||
| 8974 | if (fp == NULL) | ||
| 8975 | return 0; | ||
| 8976 | |||
| 8977 | *width = *height = -1; | 9085 | *width = *height = -1; |
| 8978 | *data = NULL; | 9086 | if (data) |
| 8979 | LA1 = xbm_scan (fp, buffer, &value); | 9087 | *data = NULL; |
| 9088 | LA1 = xbm_scan (&s, end, buffer, &value); | ||
| 8980 | 9089 | ||
| 8981 | /* Parse defines for width, height and hot-spots. */ | 9090 | /* Parse defines for width, height and hot-spots. */ |
| 8982 | while (LA1 == '#') | 9091 | while (LA1 == '#') |
| @@ -8999,6 +9108,8 @@ xbm_read_bitmap_file_data (file, width, height, data) | |||
| 8999 | 9108 | ||
| 9000 | if (*width < 0 || *height < 0) | 9109 | if (*width < 0 || *height < 0) |
| 9001 | goto failure; | 9110 | goto failure; |
| 9111 | else if (data == NULL) | ||
| 9112 | goto success; | ||
| 9002 | 9113 | ||
| 9003 | /* Parse bits. Must start with `static'. */ | 9114 | /* Parse bits. Must start with `static'. */ |
| 9004 | expect_ident ("static"); | 9115 | expect_ident ("static"); |
| @@ -9068,13 +9179,12 @@ xbm_read_bitmap_file_data (file, width, height, data) | |||
| 9068 | } | 9179 | } |
| 9069 | } | 9180 | } |
| 9070 | 9181 | ||
| 9071 | fclose (fp); | 9182 | success: |
| 9072 | return 1; | 9183 | return 1; |
| 9073 | 9184 | ||
| 9074 | failure: | 9185 | failure: |
| 9075 | 9186 | ||
| 9076 | fclose (fp); | 9187 | if (data && *data) |
| 9077 | if (*data) | ||
| 9078 | { | 9188 | { |
| 9079 | xfree (*data); | 9189 | xfree (*data); |
| 9080 | *data = NULL; | 9190 | *data = NULL; |
| @@ -9087,35 +9197,21 @@ xbm_read_bitmap_file_data (file, width, height, data) | |||
| 9087 | } | 9197 | } |
| 9088 | 9198 | ||
| 9089 | 9199 | ||
| 9090 | /* Load XBM image IMG which will be displayed on frame F from file | 9200 | /* Load XBM image IMG which will be displayed on frame F from buffer |
| 9091 | SPECIFIED_FILE. Value is non-zero if successful. */ | 9201 | CONTENTS. END is the end of the buffer. Value is non-zero if |
| 9202 | successful. */ | ||
| 9092 | 9203 | ||
| 9093 | static int | 9204 | static int |
| 9094 | xbm_load_image_from_file (f, img, specified_file) | 9205 | xbm_load_image (f, img, contents, end) |
| 9095 | struct frame *f; | 9206 | struct frame *f; |
| 9096 | struct image *img; | 9207 | struct image *img; |
| 9097 | Lisp_Object specified_file; | 9208 | char *contents, *end; |
| 9098 | { | 9209 | { |
| 9099 | int rc; | 9210 | int rc; |
| 9100 | unsigned char *data; | 9211 | unsigned char *data; |
| 9101 | int success_p = 0; | 9212 | int success_p = 0; |
| 9102 | Lisp_Object file; | ||
| 9103 | struct gcpro gcpro1; | ||
| 9104 | 9213 | ||
| 9105 | xassert (STRINGP (specified_file)); | 9214 | rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data); |
| 9106 | file = Qnil; | ||
| 9107 | GCPRO1 (file); | ||
| 9108 | |||
| 9109 | file = x_find_image_file (specified_file); | ||
| 9110 | if (!STRINGP (file)) | ||
| 9111 | { | ||
| 9112 | image_error ("Cannot find image file `%s'", specified_file, Qnil); | ||
| 9113 | UNGCPRO; | ||
| 9114 | return 0; | ||
| 9115 | } | ||
| 9116 | |||
| 9117 | rc = xbm_read_bitmap_file_data (XSTRING (file)->data, &img->width, | ||
| 9118 | &img->height, &data); | ||
| 9119 | if (rc) | 9215 | if (rc) |
| 9120 | { | 9216 | { |
| 9121 | int depth = one_w32_display_info.n_cbits; | 9217 | int depth = one_w32_display_info.n_cbits; |
| @@ -9135,7 +9231,6 @@ xbm_load_image_from_file (f, img, specified_file) | |||
| 9135 | background = x_alloc_image_color (f, img, value, background); | 9231 | background = x_alloc_image_color (f, img, value, background); |
| 9136 | 9232 | ||
| 9137 | #if 0 /* TODO : Port image display to W32 */ | 9233 | #if 0 /* TODO : Port image display to W32 */ |
| 9138 | BLOCK_INPUT; | ||
| 9139 | img->pixmap | 9234 | img->pixmap |
| 9140 | = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f), | 9235 | = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f), |
| 9141 | FRAME_W32_WINDOW (f), | 9236 | FRAME_W32_WINDOW (f), |
| @@ -9148,22 +9243,34 @@ xbm_load_image_from_file (f, img, specified_file) | |||
| 9148 | if (img->pixmap == 0) | 9243 | if (img->pixmap == 0) |
| 9149 | { | 9244 | { |
| 9150 | x_clear_image (f, img); | 9245 | x_clear_image (f, img); |
| 9151 | image_error ("Unable to create X pixmap for `%s'", file, Qnil); | 9246 | image_error ("Unable to create X pixmap for `%s'", img->spec, Qnil); |
| 9152 | } | 9247 | } |
| 9153 | else | 9248 | else |
| 9154 | success_p = 1; | 9249 | success_p = 1; |
| 9155 | |||
| 9156 | UNBLOCK_INPUT; | ||
| 9157 | #endif | 9250 | #endif |
| 9158 | } | 9251 | } |
| 9159 | else | 9252 | else |
| 9160 | image_error ("Error loading XBM image `%s'", img->spec, Qnil); | 9253 | image_error ("Error loading XBM image `%s'", img->spec, Qnil); |
| 9161 | 9254 | ||
| 9162 | UNGCPRO; | ||
| 9163 | return success_p; | 9255 | return success_p; |
| 9164 | } | 9256 | } |
| 9165 | 9257 | ||
| 9166 | 9258 | ||
| 9259 | /* Value is non-zero if DATA looks like an in-memory XBM file. */ | ||
| 9260 | |||
| 9261 | static int | ||
| 9262 | xbm_file_p (data) | ||
| 9263 | Lisp_Object data; | ||
| 9264 | { | ||
| 9265 | int w, h; | ||
| 9266 | return (STRINGP (data) | ||
| 9267 | && xbm_read_bitmap_data (XSTRING (data)->data, | ||
| 9268 | (XSTRING (data)->data | ||
| 9269 | + STRING_BYTES (XSTRING (data))), | ||
| 9270 | &w, &h, NULL)); | ||
| 9271 | } | ||
| 9272 | |||
| 9273 | |||
| 9167 | /* Fill image IMG which is used on frame F with pixmap data. Value is | 9274 | /* Fill image IMG which is used on frame F with pixmap data. Value is |
| 9168 | non-zero if successful. */ | 9275 | non-zero if successful. */ |
| 9169 | 9276 | ||
| @@ -9180,7 +9287,32 @@ xbm_load (f, img) | |||
| 9180 | /* If IMG->spec specifies a file name, create a non-file spec from it. */ | 9287 | /* If IMG->spec specifies a file name, create a non-file spec from it. */ |
| 9181 | file_name = image_spec_value (img->spec, QCfile, NULL); | 9288 | file_name = image_spec_value (img->spec, QCfile, NULL); |
| 9182 | if (STRINGP (file_name)) | 9289 | if (STRINGP (file_name)) |
| 9183 | success_p = xbm_load_image_from_file (f, img, file_name); | 9290 | { |
| 9291 | Lisp_Object file; | ||
| 9292 | char *contents; | ||
| 9293 | int size; | ||
| 9294 | struct gcpro gcpro1; | ||
| 9295 | |||
| 9296 | file = x_find_image_file (file_name); | ||
| 9297 | GCPRO1 (file); | ||
| 9298 | if (!STRINGP (file)) | ||
| 9299 | { | ||
| 9300 | image_error ("Cannot find image file `%s'", file_name, Qnil); | ||
| 9301 | UNGCPRO; | ||
| 9302 | return 0; | ||
| 9303 | } | ||
| 9304 | |||
| 9305 | contents = slurp_file (XSTRING (file)->data, &size); | ||
| 9306 | if (contents == NULL) | ||
| 9307 | { | ||
| 9308 | image_error ("Error loading XBM image `%s'", img->spec, Qnil); | ||
| 9309 | UNGCPRO; | ||
| 9310 | return 0; | ||
| 9311 | } | ||
| 9312 | |||
| 9313 | success_p = xbm_load_image (f, img, contents, contents + size); | ||
| 9314 | UNGCPRO; | ||
| 9315 | } | ||
| 9184 | else | 9316 | else |
| 9185 | { | 9317 | { |
| 9186 | struct image_keyword fmt[XBM_LAST]; | 9318 | struct image_keyword fmt[XBM_LAST]; |
| @@ -9190,6 +9322,11 @@ xbm_load (f, img) | |||
| 9190 | unsigned long background = FRAME_BACKGROUND_PIXEL (f); | 9322 | unsigned long background = FRAME_BACKGROUND_PIXEL (f); |
| 9191 | char *bits; | 9323 | char *bits; |
| 9192 | int parsed_p; | 9324 | int parsed_p; |
| 9325 | int in_memory_file_p = 0; | ||
| 9326 | |||
| 9327 | /* See if data looks like an in-memory XBM file. */ | ||
| 9328 | data = image_spec_value (img->spec, QCdata, NULL); | ||
| 9329 | in_memory_file_p = xbm_file_p (data); | ||
| 9193 | 9330 | ||
| 9194 | /* Parse the list specification. */ | 9331 | /* Parse the list specification. */ |
| 9195 | bcopy (xbm_format, fmt, sizeof fmt); | 9332 | bcopy (xbm_format, fmt, sizeof fmt); |
| @@ -9197,68 +9334,68 @@ xbm_load (f, img) | |||
| 9197 | xassert (parsed_p); | 9334 | xassert (parsed_p); |
| 9198 | 9335 | ||
| 9199 | /* Get specified width, and height. */ | 9336 | /* Get specified width, and height. */ |
| 9200 | img->width = XFASTINT (fmt[XBM_WIDTH].value); | 9337 | if (!in_memory_file_p) |
| 9201 | img->height = XFASTINT (fmt[XBM_HEIGHT].value); | 9338 | { |
| 9202 | xassert (img->width > 0 && img->height > 0); | 9339 | img->width = XFASTINT (fmt[XBM_WIDTH].value); |
| 9203 | 9340 | img->height = XFASTINT (fmt[XBM_HEIGHT].value); | |
| 9204 | BLOCK_INPUT; | 9341 | xassert (img->width > 0 && img->height > 0); |
| 9205 | 9342 | } | |
| 9206 | if (fmt[XBM_ASCENT].count) | ||
| 9207 | img->ascent = XFASTINT (fmt[XBM_ASCENT].value); | ||
| 9208 | |||
| 9209 | /* Get foreground and background colors, maybe allocate colors. */ | 9343 | /* Get foreground and background colors, maybe allocate colors. */ |
| 9210 | if (fmt[XBM_FOREGROUND].count) | 9344 | if (fmt[XBM_FOREGROUND].count |
| 9345 | && STRINGP (fmt[XBM_FOREGROUND].value)) | ||
| 9211 | foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value, | 9346 | foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value, |
| 9212 | foreground); | 9347 | foreground); |
| 9213 | if (fmt[XBM_BACKGROUND].count) | 9348 | if (fmt[XBM_BACKGROUND].count |
| 9349 | && STRINGP (fmt[XBM_BACKGROUND].value)) | ||
| 9214 | background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value, | 9350 | background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value, |
| 9215 | background); | 9351 | background); |
| 9216 | 9352 | ||
| 9217 | /* Set bits to the bitmap image data. */ | 9353 | if (in_memory_file_p) |
| 9218 | data = fmt[XBM_DATA].value; | 9354 | success_p = xbm_load_image (f, img, XSTRING (data)->data, |
| 9219 | if (VECTORP (data)) | 9355 | (XSTRING (data)->data |
| 9356 | + STRING_BYTES (XSTRING (data)))); | ||
| 9357 | else | ||
| 9220 | { | 9358 | { |
| 9221 | int i; | 9359 | if (VECTORP (data)) |
| 9222 | char *p; | 9360 | { |
| 9223 | int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR; | 9361 | int i; |
| 9362 | char *p; | ||
| 9363 | int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR; | ||
| 9224 | 9364 | ||
| 9225 | p = bits = (char *) alloca (nbytes * img->height); | 9365 | p = bits = (char *) alloca (nbytes * img->height); |
| 9226 | for (i = 0; i < img->height; ++i, p += nbytes) | 9366 | for (i = 0; i < img->height; ++i, p += nbytes) |
| 9367 | { | ||
| 9368 | Lisp_Object line = XVECTOR (data)->contents[i]; | ||
| 9369 | if (STRINGP (line)) | ||
| 9370 | bcopy (XSTRING (line)->data, p, nbytes); | ||
| 9371 | else | ||
| 9372 | bcopy (XBOOL_VECTOR (line)->data, p, nbytes); | ||
| 9373 | } | ||
| 9374 | } | ||
| 9375 | else if (STRINGP (data)) | ||
| 9376 | bits = XSTRING (data)->data; | ||
| 9377 | else | ||
| 9378 | bits = XBOOL_VECTOR (data)->data; | ||
| 9379 | #ifdef TODO /* image support. */ | ||
| 9380 | /* Create the pixmap. */ | ||
| 9381 | depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f)); | ||
| 9382 | img->pixmap | ||
| 9383 | = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f), | ||
| 9384 | FRAME_X_WINDOW (f), | ||
| 9385 | bits, | ||
| 9386 | img->width, img->height, | ||
| 9387 | foreground, background, | ||
| 9388 | depth); | ||
| 9389 | #endif | ||
| 9390 | if (img->pixmap) | ||
| 9391 | success_p = 1; | ||
| 9392 | else | ||
| 9227 | { | 9393 | { |
| 9228 | Lisp_Object line = XVECTOR (data)->contents[i]; | 9394 | image_error ("Unable to create pixmap for XBM image `%s'", |
| 9229 | if (STRINGP (line)) | 9395 | img->spec, Qnil); |
| 9230 | bcopy (XSTRING (line)->data, p, nbytes); | 9396 | x_clear_image (f, img); |
| 9231 | else | ||
| 9232 | bcopy (XBOOL_VECTOR (line)->data, p, nbytes); | ||
| 9233 | } | 9397 | } |
| 9234 | } | 9398 | } |
| 9235 | else if (STRINGP (data)) | ||
| 9236 | bits = XSTRING (data)->data; | ||
| 9237 | else | ||
| 9238 | bits = XBOOL_VECTOR (data)->data; | ||
| 9239 | |||
| 9240 | #if 0 /* TODO : W32 XPM code */ | ||
| 9241 | /* Create the pixmap. */ | ||
| 9242 | depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f)); | ||
| 9243 | img->pixmap | ||
| 9244 | = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f), | ||
| 9245 | FRAME_W32_WINDOW (f), | ||
| 9246 | bits, | ||
| 9247 | img->width, img->height, | ||
| 9248 | foreground, background, | ||
| 9249 | depth); | ||
| 9250 | #endif /* TODO */ | ||
| 9251 | |||
| 9252 | if (img->pixmap) | ||
| 9253 | success_p = 1; | ||
| 9254 | else | ||
| 9255 | { | ||
| 9256 | image_error ("Unable to create pixmap for XBM image `%s'", | ||
| 9257 | img->spec, Qnil); | ||
| 9258 | x_clear_image (f, img); | ||
| 9259 | } | ||
| 9260 | |||
| 9261 | UNBLOCK_INPUT; | ||
| 9262 | } | 9399 | } |
| 9263 | 9400 | ||
| 9264 | return success_p; | 9401 | return success_p; |
| @@ -9708,54 +9845,204 @@ colors_in_color_table (n) | |||
| 9708 | /*********************************************************************** | 9845 | /*********************************************************************** |
| 9709 | Algorithms | 9846 | Algorithms |
| 9710 | ***********************************************************************/ | 9847 | ***********************************************************************/ |
| 9848 | #if 0 /* TODO: image support. */ | ||
| 9849 | static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int)); | ||
| 9850 | static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *)); | ||
| 9851 | static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int)); | ||
| 9852 | |||
| 9853 | /* Non-zero means draw a cross on images having `:conversion | ||
| 9854 | disabled'. */ | ||
| 9711 | 9855 | ||
| 9712 | #if 0 /* TODO : W32 versions of low level algorithms */ | 9856 | int cross_disabled_images; |
| 9713 | static void x_laplace_write_row P_ ((struct frame *, long *, | ||
| 9714 | int, XImage *, int)); | ||
| 9715 | static void x_laplace_read_row P_ ((struct frame *, Colormap, | ||
| 9716 | XColor *, int, XImage *, int)); | ||
| 9717 | 9857 | ||
| 9858 | /* Edge detection matrices for different edge-detection | ||
| 9859 | strategies. */ | ||
| 9718 | 9860 | ||
| 9719 | /* Fill COLORS with RGB colors from row Y of image XIMG. F is the | 9861 | static int emboss_matrix[9] = { |
| 9720 | frame we operate on, CMAP is the color-map in effect, and WIDTH is | 9862 | /* x - 1 x x + 1 */ |
| 9721 | the width of one row in the image. */ | 9863 | 2, -1, 0, /* y - 1 */ |
| 9864 | -1, 0, 1, /* y */ | ||
| 9865 | 0, 1, -2 /* y + 1 */ | ||
| 9866 | }; | ||
| 9867 | |||
| 9868 | static int laplace_matrix[9] = { | ||
| 9869 | /* x - 1 x x + 1 */ | ||
| 9870 | 1, 0, 0, /* y - 1 */ | ||
| 9871 | 0, 0, 0, /* y */ | ||
| 9872 | 0, 0, -1 /* y + 1 */ | ||
| 9873 | }; | ||
| 9874 | |||
| 9875 | /* Value is the intensity of the color whose red/green/blue values | ||
| 9876 | are R, G, and B. */ | ||
| 9877 | |||
| 9878 | #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6) | ||
| 9879 | |||
| 9880 | |||
| 9881 | /* On frame F, return an array of XColor structures describing image | ||
| 9882 | IMG->pixmap. Each XColor structure has its pixel color set. RGB_P | ||
| 9883 | non-zero means also fill the red/green/blue members of the XColor | ||
| 9884 | structures. Value is a pointer to the array of XColors structures, | ||
| 9885 | allocated with xmalloc; it must be freed by the caller. */ | ||
| 9886 | |||
| 9887 | static XColor * | ||
| 9888 | x_to_xcolors (f, img, rgb_p) | ||
| 9889 | struct frame *f; | ||
| 9890 | struct image *img; | ||
| 9891 | int rgb_p; | ||
| 9892 | { | ||
| 9893 | int x, y; | ||
| 9894 | XColor *colors, *p; | ||
| 9895 | XImage *ximg; | ||
| 9896 | |||
| 9897 | colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors); | ||
| 9898 | |||
| 9899 | /* Get the X image IMG->pixmap. */ | ||
| 9900 | ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, | ||
| 9901 | 0, 0, img->width, img->height, ~0, ZPixmap); | ||
| 9902 | |||
| 9903 | /* Fill the `pixel' members of the XColor array. I wished there | ||
| 9904 | were an easy and portable way to circumvent XGetPixel. */ | ||
| 9905 | p = colors; | ||
| 9906 | for (y = 0; y < img->height; ++y) | ||
| 9907 | { | ||
| 9908 | XColor *row = p; | ||
| 9909 | |||
| 9910 | for (x = 0; x < img->width; ++x, ++p) | ||
| 9911 | p->pixel = XGetPixel (ximg, x, y); | ||
| 9912 | |||
| 9913 | if (rgb_p) | ||
| 9914 | x_query_colors (f, row, img->width); | ||
| 9915 | } | ||
| 9916 | |||
| 9917 | XDestroyImage (ximg); | ||
| 9918 | return colors; | ||
| 9919 | } | ||
| 9920 | |||
| 9921 | |||
| 9922 | /* Create IMG->pixmap from an array COLORS of XColor structures, whose | ||
| 9923 | RGB members are set. F is the frame on which this all happens. | ||
| 9924 | COLORS will be freed; an existing IMG->pixmap will be freed, too. */ | ||
| 9722 | 9925 | ||
| 9723 | static void | 9926 | static void |
| 9724 | x_laplace_read_row (f, cmap, colors, width, ximg, y) | 9927 | x_from_xcolors (f, img, colors) |
| 9725 | struct frame *f; | 9928 | struct frame *f; |
| 9726 | Colormap cmap; | 9929 | struct image *img; |
| 9727 | XColor *colors; | 9930 | XColor *colors; |
| 9728 | int width; | ||
| 9729 | XImage *ximg; | ||
| 9730 | int y; | ||
| 9731 | { | 9931 | { |
| 9732 | int x; | 9932 | int x, y; |
| 9933 | XImage *oimg; | ||
| 9934 | Pixmap pixmap; | ||
| 9935 | XColor *p; | ||
| 9936 | |||
| 9937 | init_color_table (); | ||
| 9938 | |||
| 9939 | x_create_x_image_and_pixmap (f, img->width, img->height, 0, | ||
| 9940 | &oimg, &pixmap); | ||
| 9941 | p = colors; | ||
| 9942 | for (y = 0; y < img->height; ++y) | ||
| 9943 | for (x = 0; x < img->width; ++x, ++p) | ||
| 9944 | { | ||
| 9945 | unsigned long pixel; | ||
| 9946 | pixel = lookup_rgb_color (f, p->red, p->green, p->blue); | ||
| 9947 | XPutPixel (oimg, x, y, pixel); | ||
| 9948 | } | ||
| 9733 | 9949 | ||
| 9734 | for (x = 0; x < width; ++x) | 9950 | xfree (colors); |
| 9735 | colors[x].pixel = XGetPixel (ximg, x, y); | 9951 | x_clear_image_1 (f, img, 1, 0, 1); |
| 9736 | 9952 | ||
| 9737 | XQueryColors (NULL, cmap, colors, width); | 9953 | x_put_x_image (f, oimg, pixmap, img->width, img->height); |
| 9954 | x_destroy_x_image (oimg); | ||
| 9955 | img->pixmap = pixmap; | ||
| 9956 | img->colors = colors_in_color_table (&img->ncolors); | ||
| 9957 | free_color_table (); | ||
| 9738 | } | 9958 | } |
| 9739 | 9959 | ||
| 9740 | 9960 | ||
| 9741 | /* Write row Y of image XIMG. PIXELS is an array of WIDTH longs | 9961 | /* On frame F, perform edge-detection on image IMG. |
| 9742 | containing the pixel colors to write. F is the frame we are | 9962 | |
| 9743 | working on. */ | 9963 | MATRIX is a nine-element array specifying the transformation |
| 9964 | matrix. See emboss_matrix for an example. | ||
| 9965 | |||
| 9966 | COLOR_ADJUST is a color adjustment added to each pixel of the | ||
| 9967 | outgoing image. */ | ||
| 9744 | 9968 | ||
| 9745 | static void | 9969 | static void |
| 9746 | x_laplace_write_row (f, pixels, width, ximg, y) | 9970 | x_detect_edges (f, img, matrix, color_adjust) |
| 9747 | struct frame *f; | 9971 | struct frame *f; |
| 9748 | long *pixels; | 9972 | struct image *img; |
| 9749 | int width; | 9973 | int matrix[9], color_adjust; |
| 9750 | XImage *ximg; | ||
| 9751 | int y; | ||
| 9752 | { | 9974 | { |
| 9753 | int x; | 9975 | XColor *colors = x_to_xcolors (f, img, 1); |
| 9976 | XColor *new, *p; | ||
| 9977 | int x, y, i, sum; | ||
| 9978 | |||
| 9979 | for (i = sum = 0; i < 9; ++i) | ||
| 9980 | sum += abs (matrix[i]); | ||
| 9981 | |||
| 9982 | #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X)) | ||
| 9983 | |||
| 9984 | new = (XColor *) xmalloc (img->width * img->height * sizeof *new); | ||
| 9985 | |||
| 9986 | for (y = 0; y < img->height; ++y) | ||
| 9987 | { | ||
| 9988 | p = COLOR (new, 0, y); | ||
| 9989 | p->red = p->green = p->blue = 0xffff/2; | ||
| 9990 | p = COLOR (new, img->width - 1, y); | ||
| 9991 | p->red = p->green = p->blue = 0xffff/2; | ||
| 9992 | } | ||
| 9754 | 9993 | ||
| 9755 | for (x = 0; x < width; ++x) | 9994 | for (x = 1; x < img->width - 1; ++x) |
| 9756 | XPutPixel (ximg, x, y, pixels[x]); | 9995 | { |
| 9996 | p = COLOR (new, x, 0); | ||
| 9997 | p->red = p->green = p->blue = 0xffff/2; | ||
| 9998 | p = COLOR (new, x, img->height - 1); | ||
| 9999 | p->red = p->green = p->blue = 0xffff/2; | ||
| 10000 | } | ||
| 10001 | |||
| 10002 | for (y = 1; y < img->height - 1; ++y) | ||
| 10003 | { | ||
| 10004 | p = COLOR (new, 1, y); | ||
| 10005 | |||
| 10006 | for (x = 1; x < img->width - 1; ++x, ++p) | ||
| 10007 | { | ||
| 10008 | int r, g, b, y1, x1; | ||
| 10009 | |||
| 10010 | r = g = b = i = 0; | ||
| 10011 | for (y1 = y - 1; y1 < y + 2; ++y1) | ||
| 10012 | for (x1 = x - 1; x1 < x + 2; ++x1, ++i) | ||
| 10013 | if (matrix[i]) | ||
| 10014 | { | ||
| 10015 | XColor *t = COLOR (colors, x1, y1); | ||
| 10016 | r += matrix[i] * t->red; | ||
| 10017 | g += matrix[i] * t->green; | ||
| 10018 | b += matrix[i] * t->blue; | ||
| 10019 | } | ||
| 10020 | |||
| 10021 | r = (r / sum + color_adjust) & 0xffff; | ||
| 10022 | g = (g / sum + color_adjust) & 0xffff; | ||
| 10023 | b = (b / sum + color_adjust) & 0xffff; | ||
| 10024 | p->red = p->green = p->blue = COLOR_INTENSITY (r, g, b); | ||
| 10025 | } | ||
| 10026 | } | ||
| 10027 | |||
| 10028 | xfree (colors); | ||
| 10029 | x_from_xcolors (f, img, new); | ||
| 10030 | |||
| 10031 | #undef COLOR | ||
| 10032 | } | ||
| 10033 | |||
| 10034 | |||
| 10035 | /* Perform the pre-defined `emboss' edge-detection on image IMG | ||
| 10036 | on frame F. */ | ||
| 10037 | |||
| 10038 | static void | ||
| 10039 | x_emboss (f, img) | ||
| 10040 | struct frame *f; | ||
| 10041 | struct image *img; | ||
| 10042 | { | ||
| 10043 | x_detect_edges (f, img, emboss_matrix, 0xffff / 2); | ||
| 9757 | } | 10044 | } |
| 9758 | #endif | 10045 | |
| 9759 | 10046 | ||
| 9760 | /* Transform image IMG which is used on frame F with a Laplace | 10047 | /* Transform image IMG which is used on frame F with a Laplace |
| 9761 | edge-detection algorithm. The result is an image that can be used | 10048 | edge-detection algorithm. The result is an image that can be used |
| @@ -9766,85 +10053,108 @@ x_laplace (f, img) | |||
| 9766 | struct frame *f; | 10053 | struct frame *f; |
| 9767 | struct image *img; | 10054 | struct image *img; |
| 9768 | { | 10055 | { |
| 9769 | #if 0 /* TODO : W32 version */ | 10056 | x_detect_edges (f, img, laplace_matrix, 45000); |
| 9770 | Colormap cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f)); | 10057 | } |
| 9771 | XImage *ximg, *oimg; | ||
| 9772 | XColor *in[3]; | ||
| 9773 | long *out; | ||
| 9774 | Pixmap pixmap; | ||
| 9775 | int x, y, i; | ||
| 9776 | long pixel; | ||
| 9777 | int in_y, out_y, rc; | ||
| 9778 | int mv2 = 45000; | ||
| 9779 | 10058 | ||
| 9780 | BLOCK_INPUT; | ||
| 9781 | 10059 | ||
| 9782 | /* Get the X image IMG->pixmap. */ | 10060 | /* Perform edge-detection on image IMG on frame F, with specified |
| 9783 | ximg = XGetImage (NULL, img->pixmap, | 10061 | transformation matrix MATRIX and color-adjustment COLOR_ADJUST. |
| 9784 | 0, 0, img->width, img->height, ~0, ZPixmap); | ||
| 9785 | |||
| 9786 | /* Allocate 3 input rows, and one output row of colors. */ | ||
| 9787 | for (i = 0; i < 3; ++i) | ||
| 9788 | in[i] = (XColor *) alloca (img->width * sizeof (XColor)); | ||
| 9789 | out = (long *) alloca (img->width * sizeof (long)); | ||
| 9790 | 10062 | ||
| 9791 | /* Create an X image for output. */ | 10063 | MATRIX must be either |
| 9792 | rc = x_create_x_image_and_pixmap (f, img->width, img->height, 0, | ||
| 9793 | &oimg, &pixmap); | ||
| 9794 | 10064 | ||
| 9795 | /* Fill first two rows. */ | 10065 | - a list of at least 9 numbers in row-major form |
| 9796 | x_laplace_read_row (f, cmap, in[0], img->width, ximg, 0); | 10066 | - a vector of at least 9 numbers |
| 9797 | x_laplace_read_row (f, cmap, in[1], img->width, ximg, 1); | ||
| 9798 | in_y = 2; | ||
| 9799 | 10067 | ||
| 9800 | /* Write first row, all zeros. */ | 10068 | COLOR_ADJUST nil means use a default; otherwise it must be a |
| 9801 | init_color_table (); | 10069 | number. */ |
| 9802 | pixel = lookup_rgb_color (f, 0, 0, 0); | ||
| 9803 | for (x = 0; x < img->width; ++x) | ||
| 9804 | out[x] = pixel; | ||
| 9805 | x_laplace_write_row (f, out, img->width, oimg, 0); | ||
| 9806 | out_y = 1; | ||
| 9807 | 10070 | ||
| 9808 | for (y = 2; y < img->height; ++y) | 10071 | static void |
| 10072 | x_edge_detection (f, img, matrix, color_adjust) | ||
| 10073 | struct frame *f; | ||
| 10074 | struct image *img; | ||
| 10075 | Lisp_Object matrix, color_adjust; | ||
| 10076 | { | ||
| 10077 | int i = 0; | ||
| 10078 | int trans[9]; | ||
| 10079 | |||
| 10080 | if (CONSP (matrix)) | ||
| 9809 | { | 10081 | { |
| 9810 | int rowa = y % 3; | 10082 | for (i = 0; |
| 9811 | int rowb = (y + 2) % 3; | 10083 | i < 9 && CONSP (matrix) && NUMBERP (XCAR (matrix)); |
| 10084 | ++i, matrix = XCDR (matrix)) | ||
| 10085 | trans[i] = XFLOATINT (XCAR (matrix)); | ||
| 10086 | } | ||
| 10087 | else if (VECTORP (matrix) && ASIZE (matrix) >= 9) | ||
| 10088 | { | ||
| 10089 | for (i = 0; i < 9 && NUMBERP (AREF (matrix, i)); ++i) | ||
| 10090 | trans[i] = XFLOATINT (AREF (matrix, i)); | ||
| 10091 | } | ||
| 10092 | |||
| 10093 | if (NILP (color_adjust)) | ||
| 10094 | color_adjust = make_number (0xffff / 2); | ||
| 10095 | |||
| 10096 | if (i == 9 && NUMBERP (color_adjust)) | ||
| 10097 | x_detect_edges (f, img, trans, (int) XFLOATINT (color_adjust)); | ||
| 10098 | } | ||
| 10099 | |||
| 9812 | 10100 | ||
| 9813 | x_laplace_read_row (f, cmap, in[rowa], img->width, ximg, in_y++); | 10101 | /* Transform image IMG on frame F so that it looks disabled. */ |
| 9814 | 10102 | ||
| 9815 | for (x = 0; x < img->width - 2; ++x) | 10103 | static void |
| 10104 | x_disable_image (f, img) | ||
| 10105 | struct frame *f; | ||
| 10106 | struct image *img; | ||
| 10107 | { | ||
| 10108 | struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | ||
| 10109 | |||
| 10110 | if (dpyinfo->n_planes >= 2) | ||
| 10111 | { | ||
| 10112 | /* Color (or grayscale). Convert to gray, and equalize. Just | ||
| 10113 | drawing such images with a stipple can look very odd, so | ||
| 10114 | we're using this method instead. */ | ||
| 10115 | XColor *colors = x_to_xcolors (f, img, 1); | ||
| 10116 | XColor *p, *end; | ||
| 10117 | const int h = 15000; | ||
| 10118 | const int l = 30000; | ||
| 10119 | |||
| 10120 | for (p = colors, end = colors + img->width * img->height; | ||
| 10121 | p < end; | ||
| 10122 | ++p) | ||
| 9816 | { | 10123 | { |
| 9817 | int r = in[rowa][x].red + mv2 - in[rowb][x + 2].red; | 10124 | int i = COLOR_INTENSITY (p->red, p->green, p->blue); |
| 9818 | int g = in[rowa][x].green + mv2 - in[rowb][x + 2].green; | 10125 | int i2 = (0xffff - h - l) * i / 0xffff + l; |
| 9819 | int b = in[rowa][x].blue + mv2 - in[rowb][x + 2].blue; | 10126 | p->red = p->green = p->blue = i2; |
| 9820 | |||
| 9821 | out[x + 1] = lookup_rgb_color (f, r & 0xffff, g & 0xffff, | ||
| 9822 | b & 0xffff); | ||
| 9823 | } | 10127 | } |
| 9824 | 10128 | ||
| 9825 | x_laplace_write_row (f, out, img->width, oimg, out_y++); | 10129 | x_from_xcolors (f, img, colors); |
| 9826 | } | 10130 | } |
| 9827 | 10131 | ||
| 9828 | /* Write last line, all zeros. */ | 10132 | /* Draw a cross over the disabled image, if we must or if we |
| 9829 | for (x = 0; x < img->width; ++x) | 10133 | should. */ |
| 9830 | out[x] = pixel; | 10134 | if (dpyinfo->n_planes < 2 || cross_disabled_images) |
| 9831 | x_laplace_write_row (f, out, img->width, oimg, out_y); | 10135 | { |
| 10136 | Display *dpy = FRAME_X_DISPLAY (f); | ||
| 10137 | GC gc; | ||
| 9832 | 10138 | ||
| 9833 | /* Free the input image, and free resources of IMG. */ | 10139 | gc = XCreateGC (dpy, img->pixmap, 0, NULL); |
| 9834 | XDestroyImage (ximg); | 10140 | XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f)); |
| 9835 | x_clear_image (f, img); | 10141 | XDrawLine (dpy, img->pixmap, gc, 0, 0, |
| 9836 | 10142 | img->width - 1, img->height - 1); | |
| 9837 | /* Put the output image into pixmap, and destroy it. */ | 10143 | XDrawLine (dpy, img->pixmap, gc, 0, img->height - 1, |
| 9838 | x_put_x_image (f, oimg, pixmap, img->width, img->height); | 10144 | img->width - 1, 0); |
| 9839 | x_destroy_x_image (oimg); | 10145 | XFreeGC (dpy, gc); |
| 9840 | 10146 | ||
| 9841 | /* Remember new pixmap and colors in IMG. */ | 10147 | if (img->mask) |
| 9842 | img->pixmap = pixmap; | 10148 | { |
| 9843 | img->colors = colors_in_color_table (&img->ncolors); | 10149 | gc = XCreateGC (dpy, img->mask, 0, NULL); |
| 9844 | free_color_table (); | 10150 | XSetForeground (dpy, gc, WHITE_PIX_DEFAULT (f)); |
| 9845 | 10151 | XDrawLine (dpy, img->mask, gc, 0, 0, | |
| 9846 | UNBLOCK_INPUT; | 10152 | img->width - 1, img->height - 1); |
| 9847 | #endif /* TODO */ | 10153 | XDrawLine (dpy, img->mask, gc, 0, img->height - 1, |
| 10154 | img->width - 1, 0); | ||
| 10155 | XFreeGC (dpy, gc); | ||
| 10156 | } | ||
| 10157 | } | ||
| 9848 | } | 10158 | } |
| 9849 | 10159 | ||
| 9850 | 10160 | ||
| @@ -9861,7 +10171,6 @@ x_build_heuristic_mask (f, img, how) | |||
| 9861 | struct image *img; | 10171 | struct image *img; |
| 9862 | Lisp_Object how; | 10172 | Lisp_Object how; |
| 9863 | { | 10173 | { |
| 9864 | #if 0 /* TODO : W32 version */ | ||
| 9865 | Display *dpy = FRAME_W32_DISPLAY (f); | 10174 | Display *dpy = FRAME_W32_DISPLAY (f); |
| 9866 | XImage *ximg, *mask_img; | 10175 | XImage *ximg, *mask_img; |
| 9867 | int x, y, rc, look_at_corners_p; | 10176 | int x, y, rc, look_at_corners_p; |
| @@ -9953,11 +10262,10 @@ x_build_heuristic_mask (f, img, how) | |||
| 9953 | XDestroyImage (ximg); | 10262 | XDestroyImage (ximg); |
| 9954 | 10263 | ||
| 9955 | UNBLOCK_INPUT; | 10264 | UNBLOCK_INPUT; |
| 9956 | #endif /* TODO */ | ||
| 9957 | 10265 | ||
| 9958 | return 1; | 10266 | return 1; |
| 9959 | } | 10267 | } |
| 9960 | 10268 | #endif /* TODO */ | |
| 9961 | 10269 | ||
| 9962 | 10270 | ||
| 9963 | /*********************************************************************** | 10271 | /*********************************************************************** |
| @@ -10000,7 +10308,10 @@ static struct image_keyword pbm_format[PBM_LAST] = | |||
| 10000 | {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, | 10308 | {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
| 10001 | {":relief", IMAGE_INTEGER_VALUE, 0}, | 10309 | {":relief", IMAGE_INTEGER_VALUE, 0}, |
| 10002 | {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, | 10310 | {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
| 10003 | {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} | 10311 | {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
| 10312 | {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, | ||
| 10313 | {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0}, | ||
| 10314 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} | ||
| 10004 | }; | 10315 | }; |
| 10005 | 10316 | ||
| 10006 | /* Structure describing the image type `pbm'. */ | 10317 | /* Structure describing the image type `pbm'. */ |
| @@ -10140,7 +10451,7 @@ pbm_load (f, img) | |||
| 10140 | return 0; | 10451 | return 0; |
| 10141 | } | 10452 | } |
| 10142 | 10453 | ||
| 10143 | contents = pbm_read_file (file, &size); | 10454 | contents = slurp_file (XSTRING (file)->data, &size); |
| 10144 | if (contents == NULL) | 10455 | if (contents == NULL) |
| 10145 | { | 10456 | { |
| 10146 | image_error ("Error reading `%s'", file, Qnil); | 10457 | image_error ("Error reading `%s'", file, Qnil); |
| @@ -10217,20 +10528,31 @@ pbm_load (f, img) | |||
| 10217 | || (type != PBM_MONO && max_color_idx < 0)) | 10528 | || (type != PBM_MONO && max_color_idx < 0)) |
| 10218 | goto error; | 10529 | goto error; |
| 10219 | 10530 | ||
| 10220 | BLOCK_INPUT; | ||
| 10221 | if (!x_create_x_image_and_pixmap (f, width, height, 0, | 10531 | if (!x_create_x_image_and_pixmap (f, width, height, 0, |
| 10222 | &ximg, &img->pixmap)) | 10532 | &ximg, &img->pixmap)) |
| 10223 | { | 10533 | goto error; |
| 10224 | UNBLOCK_INPUT; | 10534 | |
| 10225 | goto error; | ||
| 10226 | } | ||
| 10227 | |||
| 10228 | /* Initialize the color hash table. */ | 10535 | /* Initialize the color hash table. */ |
| 10229 | init_color_table (); | 10536 | init_color_table (); |
| 10230 | 10537 | ||
| 10231 | if (type == PBM_MONO) | 10538 | if (type == PBM_MONO) |
| 10232 | { | 10539 | { |
| 10233 | int c = 0, g; | 10540 | int c = 0, g; |
| 10541 | struct image_keyword fmt[PBM_LAST]; | ||
| 10542 | unsigned long fg = FRAME_FOREGROUND_PIXEL (f); | ||
| 10543 | unsigned long bg = FRAME_BACKGROUND_PIXEL (f); | ||
| 10544 | |||
| 10545 | /* Parse the image specification. */ | ||
| 10546 | bcopy (pbm_format, fmt, sizeof fmt); | ||
| 10547 | parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm); | ||
| 10548 | |||
| 10549 | /* Get foreground and background colors, maybe allocate colors. */ | ||
| 10550 | if (fmt[PBM_FOREGROUND].count | ||
| 10551 | && STRINGP (fmt[PBM_FOREGROUND].value)) | ||
| 10552 | fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg); | ||
| 10553 | if (fmt[PBM_BACKGROUND].count | ||
| 10554 | && STRINGP (fmt[PBM_BACKGROUND].value)) | ||
| 10555 | bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg); | ||
| 10234 | 10556 | ||
| 10235 | for (y = 0; y < height; ++y) | 10557 | for (y = 0; y < height; ++y) |
| 10236 | for (x = 0; x < width; ++x) | 10558 | for (x = 0; x < width; ++x) |
| @@ -10245,9 +10567,7 @@ pbm_load (f, img) | |||
| 10245 | else | 10567 | else |
| 10246 | g = pbm_scan_number (&p, end); | 10568 | g = pbm_scan_number (&p, end); |
| 10247 | 10569 | ||
| 10248 | XPutPixel (ximg, x, y, (g | 10570 | XPutPixel (ximg, x, y, g ? fg : bg); |
| 10249 | ? FRAME_FOREGROUND_PIXEL (f) | ||
| 10250 | : FRAME_BACKGROUND_PIXEL (f))); | ||
| 10251 | } | 10571 | } |
| 10252 | } | 10572 | } |
| 10253 | else | 10573 | else |
| @@ -10277,7 +10597,6 @@ pbm_load (f, img) | |||
| 10277 | xfree (ximg->data); | 10597 | xfree (ximg->data); |
| 10278 | ximg->data = NULL; | 10598 | ximg->data = NULL; |
| 10279 | XDestroyImage (ximg); | 10599 | XDestroyImage (ximg); |
| 10280 | UNBLOCK_INPUT; | ||
| 10281 | image_error ("Invalid pixel value in image `%s'", | 10600 | image_error ("Invalid pixel value in image `%s'", |
| 10282 | img->spec, Qnil); | 10601 | img->spec, Qnil); |
| 10283 | goto error; | 10602 | goto error; |
| @@ -10300,7 +10619,6 @@ pbm_load (f, img) | |||
| 10300 | /* Put the image into a pixmap. */ | 10619 | /* Put the image into a pixmap. */ |
| 10301 | x_put_x_image (f, ximg, img->pixmap, width, height); | 10620 | x_put_x_image (f, ximg, img->pixmap, width, height); |
| 10302 | x_destroy_x_image (ximg); | 10621 | x_destroy_x_image (ximg); |
| 10303 | UNBLOCK_INPUT; | ||
| 10304 | 10622 | ||
| 10305 | img->width = width; | 10623 | img->width = width; |
| 10306 | img->height = height; | 10624 | img->height = height; |
| @@ -11348,6 +11666,35 @@ tiff_size_of_memory (data) | |||
| 11348 | return ((tiff_memory_source *) data)->len; | 11666 | return ((tiff_memory_source *) data)->len; |
| 11349 | } | 11667 | } |
| 11350 | 11668 | ||
| 11669 | |||
| 11670 | static void | ||
| 11671 | tiff_error_handler (title, format, ap) | ||
| 11672 | const char *title, *format; | ||
| 11673 | va_list ap; | ||
| 11674 | { | ||
| 11675 | char buf[512]; | ||
| 11676 | int len; | ||
| 11677 | |||
| 11678 | len = sprintf (buf, "TIFF error: %s ", title); | ||
| 11679 | vsprintf (buf + len, format, ap); | ||
| 11680 | add_to_log (buf, Qnil, Qnil); | ||
| 11681 | } | ||
| 11682 | |||
| 11683 | |||
| 11684 | static void | ||
| 11685 | tiff_warning_handler (title, format, ap) | ||
| 11686 | const char *title, *format; | ||
| 11687 | va_list ap; | ||
| 11688 | { | ||
| 11689 | char buf[512]; | ||
| 11690 | int len; | ||
| 11691 | |||
| 11692 | len = sprintf (buf, "TIFF warning: %s ", title); | ||
| 11693 | vsprintf (buf + len, format, ap); | ||
| 11694 | add_to_log (buf, Qnil, Qnil); | ||
| 11695 | } | ||
| 11696 | |||
| 11697 | |||
| 11351 | /* Load TIFF image IMG for use on frame F. Value is non-zero if | 11698 | /* Load TIFF image IMG for use on frame F. Value is non-zero if |
| 11352 | successful. */ | 11699 | successful. */ |
| 11353 | 11700 | ||
| @@ -11371,25 +11718,28 @@ tiff_load (f, img) | |||
| 11371 | file = Qnil; | 11718 | file = Qnil; |
| 11372 | GCPRO1 (file); | 11719 | GCPRO1 (file); |
| 11373 | 11720 | ||
| 11721 | TIFFSetErrorHandler (tiff_error_handler); | ||
| 11722 | TIFFSetWarningHandler (tiff_warning_handler); | ||
| 11723 | |||
| 11374 | if (NILP (specified_data)) | 11724 | if (NILP (specified_data)) |
| 11375 | { | 11725 | { |
| 11376 | /* Read from a file */ | 11726 | /* Read from a file */ |
| 11377 | file = x_find_image_file (specified_file); | 11727 | file = x_find_image_file (specified_file); |
| 11378 | if (!STRINGP (file)) | 11728 | if (!STRINGP (file)) |
| 11379 | { | 11729 | { |
| 11380 | image_error ("Cannot find image file `%s'", file, Qnil); | 11730 | image_error ("Cannot find image file `%s'", file, Qnil); |
| 11381 | UNGCPRO; | 11731 | UNGCPRO; |
| 11382 | return 0; | 11732 | return 0; |
| 11383 | } | 11733 | } |
| 11384 | 11734 | ||
| 11385 | /* Try to open the image file. */ | 11735 | /* Try to open the image file. */ |
| 11386 | tiff = TIFFOpen (XSTRING (file)->data, "r"); | 11736 | tiff = TIFFOpen (XSTRING (file)->data, "r"); |
| 11387 | if (tiff == NULL) | 11737 | if (tiff == NULL) |
| 11388 | { | 11738 | { |
| 11389 | image_error ("Cannot open `%s'", file, Qnil); | 11739 | image_error ("Cannot open `%s'", file, Qnil); |
| 11390 | UNGCPRO; | 11740 | UNGCPRO; |
| 11391 | return 0; | 11741 | return 0; |
| 11392 | } | 11742 | } |
| 11393 | } | 11743 | } |
| 11394 | else | 11744 | else |
| 11395 | { | 11745 | { |
| @@ -11431,12 +11781,9 @@ tiff_load (f, img) | |||
| 11431 | return 0; | 11781 | return 0; |
| 11432 | } | 11782 | } |
| 11433 | 11783 | ||
| 11434 | BLOCK_INPUT; | ||
| 11435 | |||
| 11436 | /* Create the X image and pixmap. */ | 11784 | /* Create the X image and pixmap. */ |
| 11437 | if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) | 11785 | if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) |
| 11438 | { | 11786 | { |
| 11439 | UNBLOCK_INPUT; | ||
| 11440 | xfree (buf); | 11787 | xfree (buf); |
| 11441 | UNGCPRO; | 11788 | UNGCPRO; |
| 11442 | return 0; | 11789 | return 0; |
| @@ -11468,7 +11815,6 @@ tiff_load (f, img) | |||
| 11468 | x_put_x_image (f, ximg, img->pixmap, width, height); | 11815 | x_put_x_image (f, ximg, img->pixmap, width, height); |
| 11469 | x_destroy_x_image (ximg); | 11816 | x_destroy_x_image (ximg); |
| 11470 | xfree (buf); | 11817 | xfree (buf); |
| 11471 | UNBLOCK_INPUT; | ||
| 11472 | 11818 | ||
| 11473 | img->width = width; | 11819 | img->width = width; |
| 11474 | img->height = height; | 11820 | img->height = height; |
| @@ -11793,6 +12139,8 @@ gif_load (f, img) | |||
| 11793 | Ghostscript | 12139 | Ghostscript |
| 11794 | ***********************************************************************/ | 12140 | ***********************************************************************/ |
| 11795 | 12141 | ||
| 12142 | Lisp_Object Qpostscript; | ||
| 12143 | |||
| 11796 | #ifdef HAVE_GHOSTSCRIPT | 12144 | #ifdef HAVE_GHOSTSCRIPT |
| 11797 | static int gs_image_p P_ ((Lisp_Object object)); | 12145 | static int gs_image_p P_ ((Lisp_Object object)); |
| 11798 | static int gs_load P_ ((struct frame *f, struct image *img)); | 12146 | static int gs_load P_ ((struct frame *f, struct image *img)); |
| @@ -11800,8 +12148,6 @@ static void gs_clear_image P_ ((struct frame *f, struct image *img)); | |||
| 11800 | 12148 | ||
| 11801 | /* The symbol `postscript' identifying images of this type. */ | 12149 | /* The symbol `postscript' identifying images of this type. */ |
| 11802 | 12150 | ||
| 11803 | Lisp_Object Qpostscript; | ||
| 11804 | |||
| 11805 | /* Keyword symbols. */ | 12151 | /* Keyword symbols. */ |
| 11806 | 12152 | ||
| 11807 | Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height; | 12153 | Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height; |
| @@ -11999,9 +12345,13 @@ x_kill_gs_process (pixmap, f) | |||
| 11999 | if (c->images[i]->pixmap == pixmap) | 12345 | if (c->images[i]->pixmap == pixmap) |
| 12000 | break; | 12346 | break; |
| 12001 | 12347 | ||
| 12348 | /* Should someone in between have cleared the image cache, for | ||
| 12349 | instance, give up. */ | ||
| 12350 | if (i == c->used) | ||
| 12351 | return; | ||
| 12352 | |||
| 12002 | /* Kill the GS process. We should have found PIXMAP in the image | 12353 | /* Kill the GS process. We should have found PIXMAP in the image |
| 12003 | cache and its image should contain a process object. */ | 12354 | cache and its image should contain a process object. */ |
| 12004 | xassert (i < c->used); | ||
| 12005 | img = c->images[i]; | 12355 | img = c->images[i]; |
| 12006 | xassert (PROCESSP (img->data.lisp_val)); | 12356 | xassert (PROCESSP (img->data.lisp_val)); |
| 12007 | Fkill_process (img->data.lisp_val, Qnil); | 12357 | Fkill_process (img->data.lisp_val, Qnil); |
| @@ -12049,11 +12399,8 @@ x_kill_gs_process (pixmap, f) | |||
| 12049 | allocated colors on behalf of us. So, to get the | 12399 | allocated colors on behalf of us. So, to get the |
| 12050 | reference counts right, free them once. */ | 12400 | reference counts right, free them once. */ |
| 12051 | if (img->ncolors) | 12401 | if (img->ncolors) |
| 12052 | { | 12402 | x_free_colors (FRAME_W32_DISPLAY (f), cmap, |
| 12053 | Colormap cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f)); | ||
| 12054 | XFreeColors (FRAME_W32_DISPLAY (f), cmap, | ||
| 12055 | img->colors, img->ncolors, 0); | 12403 | img->colors, img->ncolors, 0); |
| 12056 | } | ||
| 12057 | #endif | 12404 | #endif |
| 12058 | } | 12405 | } |
| 12059 | else | 12406 | else |
| @@ -12062,6 +12409,12 @@ x_kill_gs_process (pixmap, f) | |||
| 12062 | 12409 | ||
| 12063 | UNBLOCK_INPUT; | 12410 | UNBLOCK_INPUT; |
| 12064 | } | 12411 | } |
| 12412 | |||
| 12413 | /* Now that we have the pixmap, compute mask and transform the | ||
| 12414 | image if requested. */ | ||
| 12415 | BLOCK_INPUT; | ||
| 12416 | postprocess_image (f, img); | ||
| 12417 | UNBLOCK_INPUT; | ||
| 12065 | } | 12418 | } |
| 12066 | 12419 | ||
| 12067 | #endif /* HAVE_GHOSTSCRIPT */ | 12420 | #endif /* HAVE_GHOSTSCRIPT */ |
| @@ -12361,9 +12714,11 @@ hide_hourglass () | |||
| 12361 | ***********************************************************************/ | 12714 | ***********************************************************************/ |
| 12362 | 12715 | ||
| 12363 | static Lisp_Object x_create_tip_frame P_ ((struct w32_display_info *, | 12716 | static Lisp_Object x_create_tip_frame P_ ((struct w32_display_info *, |
| 12364 | Lisp_Object)); | 12717 | Lisp_Object, Lisp_Object)); |
| 12718 | static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object, | ||
| 12719 | Lisp_Object, int, int, int *, int *)); | ||
| 12365 | 12720 | ||
| 12366 | /* The frame of a currently visible tooltip, or null. */ | 12721 | /* The frame of a currently visible tooltip. */ |
| 12367 | 12722 | ||
| 12368 | Lisp_Object tip_frame; | 12723 | Lisp_Object tip_frame; |
| 12369 | 12724 | ||
| @@ -12373,6 +12728,16 @@ Lisp_Object tip_frame; | |||
| 12373 | Lisp_Object tip_timer; | 12728 | Lisp_Object tip_timer; |
| 12374 | Window tip_window; | 12729 | Window tip_window; |
| 12375 | 12730 | ||
| 12731 | /* If non-nil, a vector of 3 elements containing the last args | ||
| 12732 | with which x-show-tip was called. See there. */ | ||
| 12733 | |||
| 12734 | Lisp_Object last_show_tip_args; | ||
| 12735 | |||
| 12736 | /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */ | ||
| 12737 | |||
| 12738 | Lisp_Object Vx_max_tooltip_size; | ||
| 12739 | |||
| 12740 | |||
| 12376 | static Lisp_Object | 12741 | static Lisp_Object |
| 12377 | unwind_create_tip_frame (frame) | 12742 | unwind_create_tip_frame (frame) |
| 12378 | Lisp_Object frame; | 12743 | Lisp_Object frame; |
| @@ -12391,7 +12756,8 @@ unwind_create_tip_frame (frame) | |||
| 12391 | 12756 | ||
| 12392 | 12757 | ||
| 12393 | /* Create a frame for a tooltip on the display described by DPYINFO. | 12758 | /* Create a frame for a tooltip on the display described by DPYINFO. |
| 12394 | PARMS is a list of frame parameters. Value is the frame. | 12759 | PARMS is a list of frame parameters. TEXT is the string to |
| 12760 | display in the tip frame. Value is the frame. | ||
| 12395 | 12761 | ||
| 12396 | Note that functions called here, esp. x_default_parameter can | 12762 | Note that functions called here, esp. x_default_parameter can |
| 12397 | signal errors, for instance when a specified color name is | 12763 | signal errors, for instance when a specified color name is |
| @@ -12399,9 +12765,9 @@ unwind_create_tip_frame (frame) | |||
| 12399 | when this happens. */ | 12765 | when this happens. */ |
| 12400 | 12766 | ||
| 12401 | static Lisp_Object | 12767 | static Lisp_Object |
| 12402 | x_create_tip_frame (dpyinfo, parms) | 12768 | x_create_tip_frame (dpyinfo, parms, text) |
| 12403 | struct w32_display_info *dpyinfo; | 12769 | struct w32_display_info *dpyinfo; |
| 12404 | Lisp_Object parms; | 12770 | Lisp_Object parms, text; |
| 12405 | { | 12771 | { |
| 12406 | #if 0 /* TODO : w32 version */ | 12772 | #if 0 /* TODO : w32 version */ |
| 12407 | struct frame *f; | 12773 | struct frame *f; |
| @@ -12412,6 +12778,9 @@ x_create_tip_frame (dpyinfo, parms) | |||
| 12412 | int count = BINDING_STACK_SIZE (); | 12778 | int count = BINDING_STACK_SIZE (); |
| 12413 | struct gcpro gcpro1, gcpro2, gcpro3; | 12779 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 12414 | struct kboard *kb; | 12780 | struct kboard *kb; |
| 12781 | int face_change_count_before = face_change_count; | ||
| 12782 | Lisp_Object buffer; | ||
| 12783 | struct buffer *old_buffer; | ||
| 12415 | 12784 | ||
| 12416 | check_x (); | 12785 | check_x (); |
| 12417 | 12786 | ||
| @@ -12437,9 +12806,23 @@ x_create_tip_frame (dpyinfo, parms) | |||
| 12437 | GCPRO3 (parms, name, frame); | 12806 | GCPRO3 (parms, name, frame); |
| 12438 | f = make_frame (1); | 12807 | f = make_frame (1); |
| 12439 | XSETFRAME (frame, f); | 12808 | XSETFRAME (frame, f); |
| 12809 | |||
| 12810 | buffer = Fget_buffer_create (build_string (" *tip*")); | ||
| 12811 | Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer); | ||
| 12812 | old_buffer = current_buffer; | ||
| 12813 | set_buffer_internal_1 (XBUFFER (buffer)); | ||
| 12814 | current_buffer->truncate_lines = Qnil; | ||
| 12815 | Ferase_buffer (); | ||
| 12816 | Finsert (1, &text); | ||
| 12817 | set_buffer_internal_1 (old_buffer); | ||
| 12818 | |||
| 12440 | FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; | 12819 | FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; |
| 12441 | record_unwind_protect (unwind_create_tip_frame, frame); | 12820 | record_unwind_protect (unwind_create_tip_frame, frame); |
| 12442 | 12821 | ||
| 12822 | /* By setting the output method, we're essentially saying that | ||
| 12823 | the frame is live, as per FRAME_LIVE_P. If we get a signal | ||
| 12824 | from this point on, x_destroy_window might screw up reference | ||
| 12825 | counts etc. */ | ||
| 12443 | f->output_method = output_w32; | 12826 | f->output_method = output_w32; |
| 12444 | f->output_data.w32 = | 12827 | f->output_data.w32 = |
| 12445 | (struct w32_output *) xmalloc (sizeof (struct w32_output)); | 12828 | (struct w32_output *) xmalloc (sizeof (struct w32_output)); |
| @@ -12580,7 +12963,10 @@ x_create_tip_frame (dpyinfo, parms) | |||
| 12580 | unsigned long mask; | 12963 | unsigned long mask; |
| 12581 | 12964 | ||
| 12582 | BLOCK_INPUT; | 12965 | BLOCK_INPUT; |
| 12583 | mask = CWBackPixel | CWOverrideRedirect | CWSaveUnder | CWEventMask; | 12966 | mask = CWBackPixel | CWOverrideRedirect | CWEventMask; |
| 12967 | if (DoesSaveUnders (dpyinfo->screen)) | ||
| 12968 | mask |= CWSaveUnder; | ||
| 12969 | |||
| 12584 | /* Window managers looks at the override-redirect flag to | 12970 | /* Window managers looks at the override-redirect flag to |
| 12585 | determine whether or net to give windows a decoration (Xlib | 12971 | determine whether or net to give windows a decoration (Xlib |
| 12586 | 3.2.8). */ | 12972 | 3.2.8). */ |
| @@ -12620,6 +13006,26 @@ x_create_tip_frame (dpyinfo, parms) | |||
| 12620 | SET_FRAME_WIDTH (f, 0); | 13006 | SET_FRAME_WIDTH (f, 0); |
| 12621 | change_frame_size (f, height, width, 1, 0, 0); | 13007 | change_frame_size (f, height, width, 1, 0, 0); |
| 12622 | 13008 | ||
| 13009 | /* Set up faces after all frame parameters are known. This call | ||
| 13010 | also merges in face attributes specified for new frames. | ||
| 13011 | |||
| 13012 | Frame parameters may be changed if .Xdefaults contains | ||
| 13013 | specifications for the default font. For example, if there is an | ||
| 13014 | `Emacs.default.attributeBackground: pink', the `background-color' | ||
| 13015 | attribute of the frame get's set, which let's the internal border | ||
| 13016 | of the tooltip frame appear in pink. Prevent this. */ | ||
| 13017 | { | ||
| 13018 | Lisp_Object bg = Fframe_parameter (frame, Qbackground_color); | ||
| 13019 | |||
| 13020 | /* Set tip_frame here, so that */ | ||
| 13021 | tip_frame = frame; | ||
| 13022 | call1 (Qface_set_after_frame_default, frame); | ||
| 13023 | |||
| 13024 | if (!EQ (bg, Fframe_parameter (frame, Qbackground_color))) | ||
| 13025 | Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg), | ||
| 13026 | Qnil)); | ||
| 13027 | } | ||
| 13028 | |||
| 12623 | f->no_split = 1; | 13029 | f->no_split = 1; |
| 12624 | 13030 | ||
| 12625 | UNGCPRO; | 13031 | UNGCPRO; |
| @@ -12628,17 +13034,79 @@ x_create_tip_frame (dpyinfo, parms) | |||
| 12628 | below. And the frame needs to be on Vframe_list or making it | 13034 | below. And the frame needs to be on Vframe_list or making it |
| 12629 | visible won't work. */ | 13035 | visible won't work. */ |
| 12630 | Vframe_list = Fcons (frame, Vframe_list); | 13036 | Vframe_list = Fcons (frame, Vframe_list); |
| 12631 | tip_frame = frame; | ||
| 12632 | 13037 | ||
| 12633 | /* Now that the frame is official, it counts as a reference to | 13038 | /* Now that the frame is official, it counts as a reference to |
| 12634 | its display. */ | 13039 | its display. */ |
| 12635 | FRAME_W32_DISPLAY_INFO (f)->reference_count++; | 13040 | FRAME_W32_DISPLAY_INFO (f)->reference_count++; |
| 12636 | 13041 | ||
| 13042 | /* Setting attributes of faces of the tooltip frame from resources | ||
| 13043 | and similar will increment face_change_count, which leads to the | ||
| 13044 | clearing of all current matrices. Since this isn't necessary | ||
| 13045 | here, avoid it by resetting face_change_count to the value it | ||
| 13046 | had before we created the tip frame. */ | ||
| 13047 | face_change_count = face_change_count_before; | ||
| 13048 | |||
| 13049 | /* Discard the unwind_protect. */ | ||
| 12637 | return unbind_to (count, frame); | 13050 | return unbind_to (count, frame); |
| 12638 | #endif /* TODO */ | 13051 | #endif /* TODO */ |
| 12639 | return Qnil; | 13052 | return Qnil; |
| 12640 | } | 13053 | } |
| 12641 | 13054 | ||
| 13055 | |||
| 13056 | /* Compute where to display tip frame F. PARMS is the list of frame | ||
| 13057 | parameters for F. DX and DY are specified offsets from the current | ||
| 13058 | location of the mouse. WIDTH and HEIGHT are the width and height | ||
| 13059 | of the tooltip. Return coordinates relative to the root window of | ||
| 13060 | the display in *ROOT_X, and *ROOT_Y. */ | ||
| 13061 | |||
| 13062 | static void | ||
| 13063 | compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y) | ||
| 13064 | struct frame *f; | ||
| 13065 | Lisp_Object parms, dx, dy; | ||
| 13066 | int width, height; | ||
| 13067 | int *root_x, *root_y; | ||
| 13068 | { | ||
| 13069 | #ifdef TODO /* Tool tips not supported. */ | ||
| 13070 | Lisp_Object left, top; | ||
| 13071 | int win_x, win_y; | ||
| 13072 | Window root, child; | ||
| 13073 | unsigned pmask; | ||
| 13074 | |||
| 13075 | /* User-specified position? */ | ||
| 13076 | left = Fcdr (Fassq (Qleft, parms)); | ||
| 13077 | top = Fcdr (Fassq (Qtop, parms)); | ||
| 13078 | |||
| 13079 | /* Move the tooltip window where the mouse pointer is. Resize and | ||
| 13080 | show it. */ | ||
| 13081 | if (!INTEGERP (left) && !INTEGERP (top)) | ||
| 13082 | { | ||
| 13083 | BLOCK_INPUT; | ||
| 13084 | XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window, | ||
| 13085 | &root, &child, root_x, root_y, &win_x, &win_y, &pmask); | ||
| 13086 | UNBLOCK_INPUT; | ||
| 13087 | } | ||
| 13088 | |||
| 13089 | if (INTEGERP (top)) | ||
| 13090 | *root_y = XINT (top); | ||
| 13091 | else if (*root_y + XINT (dy) - height < 0) | ||
| 13092 | *root_y -= XINT (dy); | ||
| 13093 | else | ||
| 13094 | { | ||
| 13095 | *root_y -= height; | ||
| 13096 | *root_y += XINT (dy); | ||
| 13097 | } | ||
| 13098 | |||
| 13099 | if (INTEGERP (left)) | ||
| 13100 | *root_x = XINT (left); | ||
| 13101 | else if (*root_x + XINT (dx) + width > FRAME_X_DISPLAY_INFO (f)->width) | ||
| 13102 | *root_x -= width + XINT (dx); | ||
| 13103 | else | ||
| 13104 | *root_x += XINT (dx); | ||
| 13105 | |||
| 13106 | #endif /* Tooltip support. */ | ||
| 13107 | } | ||
| 13108 | |||
| 13109 | |||
| 12642 | #ifdef TODO /* Tooltip support not complete. */ | 13110 | #ifdef TODO /* Tooltip support not complete. */ |
| 12643 | DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, | 13111 | DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, |
| 12644 | "Show STRING in a \"tooltip\" window on frame FRAME.\n\ | 13112 | "Show STRING in a \"tooltip\" window on frame FRAME.\n\ |
| @@ -12658,19 +13126,20 @@ displayed at the mouse position, with offset DX added (default is 5 if\n\ | |||
| 12658 | DX isn't specified). Likewise for the y-position; if a `top' frame\n\ | 13126 | DX isn't specified). Likewise for the y-position; if a `top' frame\n\ |
| 12659 | parameter is specified, it determines the y-position of the tooltip\n\ | 13127 | parameter is specified, it determines the y-position of the tooltip\n\ |
| 12660 | window, otherwise it is displayed at the mouse position, with offset\n\ | 13128 | window, otherwise it is displayed at the mouse position, with offset\n\ |
| 12661 | DY added (default is 10).") | 13129 | DY added (default is -10).\n\ |
| 13130 | \n\ | ||
| 13131 | A tooltip's maximum size is specified by `x-max-tooltip-size'.\n\ | ||
| 13132 | Text larger than the specified size is clipped.") | ||
| 12662 | (string, frame, parms, timeout, dx, dy) | 13133 | (string, frame, parms, timeout, dx, dy) |
| 12663 | Lisp_Object string, frame, parms, timeout, dx, dy; | 13134 | Lisp_Object string, frame, parms, timeout, dx, dy; |
| 12664 | { | 13135 | { |
| 12665 | struct frame *f; | 13136 | struct frame *f; |
| 12666 | struct window *w; | 13137 | struct window *w; |
| 12667 | Window root, child; | 13138 | Lisp_Object buffer, top, left, max_width, max_height; |
| 12668 | Lisp_Object buffer, top, left; | 13139 | int root_x, root_y; |
| 12669 | struct buffer *old_buffer; | 13140 | struct buffer *old_buffer; |
| 12670 | struct text_pos pos; | 13141 | struct text_pos pos; |
| 12671 | int i, width, height; | 13142 | int i, width, height; |
| 12672 | int root_x, root_y, win_x, win_y; | ||
| 12673 | unsigned pmask; | ||
| 12674 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 13143 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 12675 | int old_windows_or_buffers_changed = windows_or_buffers_changed; | 13144 | int old_windows_or_buffers_changed = windows_or_buffers_changed; |
| 12676 | int count = specpdl_ptr - specpdl; | 13145 | int count = specpdl_ptr - specpdl; |
| @@ -12753,23 +13222,33 @@ DY added (default is 10).") | |||
| 12753 | frame = x_create_tip_frame (FRAME_W32_DISPLAY_INFO (f), parms); | 13222 | frame = x_create_tip_frame (FRAME_W32_DISPLAY_INFO (f), parms); |
| 12754 | f = XFRAME (frame); | 13223 | f = XFRAME (frame); |
| 12755 | 13224 | ||
| 12756 | /* Set up the frame's root window. Currently we use a size of 80 | 13225 | /* Set up the frame's root window. */ |
| 12757 | columns x 40 lines. If someone wants to show a larger tip, he | ||
| 12758 | will loose. I don't think this is a realistic case. */ | ||
| 12759 | w = XWINDOW (FRAME_ROOT_WINDOW (f)); | 13226 | w = XWINDOW (FRAME_ROOT_WINDOW (f)); |
| 12760 | w->left = w->top = make_number (0); | 13227 | w->left = w->top = make_number (0); |
| 12761 | w->width = make_number (80); | 13228 | |
| 12762 | w->height = make_number (40); | 13229 | if (CONSP (Vx_max_tooltip_size) |
| 13230 | && INTEGERP (XCAR (Vx_max_tooltip_size)) | ||
| 13231 | && XINT (XCAR (Vx_max_tooltip_size)) > 0 | ||
| 13232 | && INTEGERP (XCDR (Vx_max_tooltip_size)) | ||
| 13233 | && XINT (XCDR (Vx_max_tooltip_size)) > 0) | ||
| 13234 | { | ||
| 13235 | w->width = XCAR (Vx_max_tooltip_size); | ||
| 13236 | w->height = XCDR (Vx_max_tooltip_size); | ||
| 13237 | } | ||
| 13238 | else | ||
| 13239 | { | ||
| 13240 | w->width = make_number (80); | ||
| 13241 | w->height = make_number (40); | ||
| 13242 | } | ||
| 13243 | |||
| 13244 | f->window_width = XINT (w->width); | ||
| 12763 | adjust_glyphs (f); | 13245 | adjust_glyphs (f); |
| 12764 | w->pseudo_window_p = 1; | 13246 | w->pseudo_window_p = 1; |
| 12765 | 13247 | ||
| 12766 | /* Display the tooltip text in a temporary buffer. */ | 13248 | /* Display the tooltip text in a temporary buffer. */ |
| 12767 | buffer = Fget_buffer_create (build_string (" *tip*")); | ||
| 12768 | Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer); | ||
| 12769 | old_buffer = current_buffer; | 13249 | old_buffer = current_buffer; |
| 12770 | set_buffer_internal_1 (XBUFFER (buffer)); | 13250 | set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer)); |
| 12771 | Ferase_buffer (); | 13251 | current_buffer->truncate_lines = Qnil; |
| 12772 | Finsert (1, &string); | ||
| 12773 | clear_glyph_matrix (w->desired_matrix); | 13252 | clear_glyph_matrix (w->desired_matrix); |
| 12774 | clear_glyph_matrix (w->current_matrix); | 13253 | clear_glyph_matrix (w->current_matrix); |
| 12775 | SET_TEXT_POS (pos, BEGV, BEGV_BYTE); | 13254 | SET_TEXT_POS (pos, BEGV, BEGV_BYTE); |
| @@ -12811,15 +13290,13 @@ DY added (default is 10).") | |||
| 12811 | 13290 | ||
| 12812 | /* Move the tooltip window where the mouse pointer is. Resize and | 13291 | /* Move the tooltip window where the mouse pointer is. Resize and |
| 12813 | show it. */ | 13292 | show it. */ |
| 12814 | compute_tip_xy (f, parms, dx, dy, &root_x, &root_y); | 13293 | compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y); |
| 12815 | 13294 | ||
| 12816 | #if 0 /* TODO : W32 specifics */ | ||
| 12817 | BLOCK_INPUT; | 13295 | BLOCK_INPUT; |
| 12818 | XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 13296 | XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 12819 | root_x, root_y - height, width, height); | 13297 | root_x, root_y - height, width, height); |
| 12820 | XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); | 13298 | XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); |
| 12821 | UNBLOCK_INPUT; | 13299 | UNBLOCK_INPUT; |
| 12822 | #endif /* TODO */ | ||
| 12823 | 13300 | ||
| 12824 | /* Draw into the window. */ | 13301 | /* Draw into the window. */ |
| 12825 | w->must_be_updated_p = 1; | 13302 | w->must_be_updated_p = 1; |
| @@ -12841,7 +13318,7 @@ DY added (default is 10).") | |||
| 12841 | 13318 | ||
| 12842 | DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0, | 13319 | DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0, |
| 12843 | "Hide the current tooltip window, if there is any.\n\ | 13320 | "Hide the current tooltip window, if there is any.\n\ |
| 12844 | Value is t is tooltip was open, nil otherwise.") | 13321 | Value is t if tooltip was open, nil otherwise.") |
| 12845 | () | 13322 | () |
| 12846 | { | 13323 | { |
| 12847 | int count; | 13324 | int count; |
| @@ -12887,8 +13364,7 @@ DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, | |||
| 12887 | "Read file name, prompting with PROMPT in directory DIR.\n\ | 13364 | "Read file name, prompting with PROMPT in directory DIR.\n\ |
| 12888 | Use a file selection dialog.\n\ | 13365 | Use a file selection dialog.\n\ |
| 12889 | Select DEFAULT-FILENAME in the dialog's file selection box, if\n\ | 13366 | Select DEFAULT-FILENAME in the dialog's file selection box, if\n\ |
| 12890 | specified. Don't let the user enter a file name in the file\n\ | 13367 | specified. Ensure that file exists if MUSTMATCH is non-nil.") |
| 12891 | selection dialog's entry field, if MUSTMATCH is non-nil.") | ||
| 12892 | (prompt, dir, default_filename, mustmatch) | 13368 | (prompt, dir, default_filename, mustmatch) |
| 12893 | Lisp_Object prompt, dir, default_filename, mustmatch; | 13369 | Lisp_Object prompt, dir, default_filename, mustmatch; |
| 12894 | { | 13370 | { |
| @@ -12949,6 +13425,9 @@ selection dialog's entry field, if MUSTMATCH is non-nil.") | |||
| 12949 | bzero (&file_details, sizeof (file_details)); | 13425 | bzero (&file_details, sizeof (file_details)); |
| 12950 | file_details.lStructSize = sizeof (file_details); | 13426 | file_details.lStructSize = sizeof (file_details); |
| 12951 | file_details.hwndOwner = FRAME_W32_WINDOW (f); | 13427 | file_details.hwndOwner = FRAME_W32_WINDOW (f); |
| 13428 | /* Undocumented Bug in Common File Dialog: | ||
| 13429 | If a filter is not specified, shell links are not resolved. */ | ||
| 13430 | file_details.lpstrFilter = "ALL Files (*.*)\0*.*\0\0"; | ||
| 12952 | file_details.lpstrFile = filename; | 13431 | file_details.lpstrFile = filename; |
| 12953 | file_details.nMaxFile = sizeof (filename); | 13432 | file_details.nMaxFile = sizeof (filename); |
| 12954 | file_details.lpstrInitialDir = init_dir; | 13433 | file_details.lpstrInitialDir = init_dir; |
| @@ -13547,6 +14026,18 @@ syms_of_w32fns () | |||
| 13547 | 14026 | ||
| 13548 | Qlaplace = intern ("laplace"); | 14027 | Qlaplace = intern ("laplace"); |
| 13549 | staticpro (&Qlaplace); | 14028 | staticpro (&Qlaplace); |
| 14029 | Qemboss = intern ("emboss"); | ||
| 14030 | staticpro (&Qemboss); | ||
| 14031 | Qedge_detection = intern ("edge-detection"); | ||
| 14032 | staticpro (&Qedge_detection); | ||
| 14033 | Qheuristic = intern ("heuristic"); | ||
| 14034 | staticpro (&Qheuristic); | ||
| 14035 | QCmatrix = intern (":matrix"); | ||
| 14036 | staticpro (&QCmatrix); | ||
| 14037 | QCcolor_adjustment = intern (":color-adjustment"); | ||
| 14038 | staticpro (&QCcolor_adjustment); | ||
| 14039 | QCmask = intern (":mask"); | ||
| 14040 | staticpro (&QCmask); | ||
| 13550 | 14041 | ||
| 13551 | Qface_set_after_frame_default = intern ("face-set-after-frame-default"); | 14042 | Qface_set_after_frame_default = intern ("face-set-after-frame-default"); |
| 13552 | staticpro (&Qface_set_after_frame_default); | 14043 | staticpro (&Qface_set_after_frame_default); |
| @@ -13729,6 +14220,11 @@ or when you set the mouse color."); | |||
| 13729 | "A string indicating the foreground color of the cursor box."); | 14220 | "A string indicating the foreground color of the cursor box."); |
| 13730 | Vx_cursor_fore_pixel = Qnil; | 14221 | Vx_cursor_fore_pixel = Qnil; |
| 13731 | 14222 | ||
| 14223 | DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size, | ||
| 14224 | "Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).\n\ | ||
| 14225 | Text larger than this is clipped."); | ||
| 14226 | Vx_max_tooltip_size = Fcons (make_number (80), make_number (40)); | ||
| 14227 | |||
| 13732 | DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager, | 14228 | DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager, |
| 13733 | "Non-nil if no window manager is in use.\n\ | 14229 | "Non-nil if no window manager is in use.\n\ |
| 13734 | Emacs doesn't try to figure this out; this is always nil\n\ | 14230 | Emacs doesn't try to figure this out; this is always nil\n\ |