aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog40
-rw-r--r--src/w32fns.c1254
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 @@
12001-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
12001-10-21 Miles Bader <miles@gnu.org> 412001-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));
687void x_set_unsplittable P_ ((struct frame *, Lisp_Object, Lisp_Object)); 687void x_set_unsplittable P_ ((struct frame *, Lisp_Object, Lisp_Object));
688void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object)); 688void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
689static void x_set_screen_gamma P_ ((struct frame *, Lisp_Object, Lisp_Object)); 689static void x_set_screen_gamma P_ ((struct frame *, Lisp_Object, Lisp_Object));
690static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,
691 Lisp_Object));
690 692
691static struct x_frame_parm_table x_frame_parms[] = 693static 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;
7680extern Lisp_Object QCdata; 7702extern Lisp_Object QCdata;
7681Lisp_Object QCtype, QCascent, QCmargin, QCrelief; 7703Lisp_Object QCtype, QCascent, QCmargin, QCrelief;
7682Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; 7704Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
7683Lisp_Object QCindex; 7705Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
7684 7706
7685/* Other symbols. */ 7707/* Other symbols. */
7686 7708
7687Lisp_Object Qlaplace; 7709Lisp_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));
7697static struct image_type *lookup_image_type P_ ((Lisp_Object symbol)); 7719static struct image_type *lookup_image_type P_ ((Lisp_Object symbol));
7698static void image_error P_ ((char *format, Lisp_Object, Lisp_Object)); 7720static void image_error P_ ((char *format, Lisp_Object, Lisp_Object));
7699static void x_laplace P_ ((struct frame *, struct image *)); 7721static void x_laplace P_ ((struct frame *, struct image *));
7722static void x_emboss P_ ((struct frame *, struct image *));
7700static int x_build_heuristic_mask P_ ((struct frame *, struct image *, 7723static 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
8197static void cache_image P_ ((struct frame *f, struct image *img)); 8237static void cache_image P_ ((struct frame *f, struct image *img));
8238static 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
8359static void
8360postprocess_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
8644static Lisp_Object x_find_image_file P_ ((Lisp_Object)); 8702static Lisp_Object x_find_image_file P_ ((Lisp_Object));
8703static 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
8739static char *
8740slurp_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
8864static int 8960static int
8865xbm_scan (fp, sval, ival) 8961xbm_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
8943static int 9055static int
8944xbm_read_bitmap_file_data (file, width, height, data) 9056xbm_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
9093static int 9204static int
9094xbm_load_image_from_file (f, img, specified_file) 9205xbm_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
9261static int
9262xbm_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. */
9849static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int));
9850static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *));
9851static 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 */ 9856int cross_disabled_images;
9713static void x_laplace_write_row P_ ((struct frame *, long *,
9714 int, XImage *, int));
9715static 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 9861static 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
9868static 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
9887static XColor *
9888x_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
9723static void 9926static void
9724x_laplace_read_row (f, cmap, colors, width, ximg, y) 9927x_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
9745static void 9969static void
9746x_laplace_write_row (f, pixels, width, ximg, y) 9970x_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
10038static void
10039x_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) 10071static void
10072x_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) 10103static void
10104x_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
11670static void
11671tiff_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
11684static void
11685tiff_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
12142Lisp_Object Qpostscript;
12143
11796#ifdef HAVE_GHOSTSCRIPT 12144#ifdef HAVE_GHOSTSCRIPT
11797static int gs_image_p P_ ((Lisp_Object object)); 12145static int gs_image_p P_ ((Lisp_Object object));
11798static int gs_load P_ ((struct frame *f, struct image *img)); 12146static 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
11803Lisp_Object Qpostscript;
11804
11805/* Keyword symbols. */ 12151/* Keyword symbols. */
11806 12152
11807Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height; 12153Lisp_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
12363static Lisp_Object x_create_tip_frame P_ ((struct w32_display_info *, 12716static Lisp_Object x_create_tip_frame P_ ((struct w32_display_info *,
12364 Lisp_Object)); 12717 Lisp_Object, Lisp_Object));
12718static 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
12368Lisp_Object tip_frame; 12723Lisp_Object tip_frame;
12369 12724
@@ -12373,6 +12728,16 @@ Lisp_Object tip_frame;
12373Lisp_Object tip_timer; 12728Lisp_Object tip_timer;
12374Window tip_window; 12729Window 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
12734Lisp_Object last_show_tip_args;
12735
12736/* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
12737
12738Lisp_Object Vx_max_tooltip_size;
12739
12740
12376static Lisp_Object 12741static Lisp_Object
12377unwind_create_tip_frame (frame) 12742unwind_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
12401static Lisp_Object 12767static Lisp_Object
12402x_create_tip_frame (dpyinfo, parms) 12768x_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
13062static void
13063compute_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. */
12643DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, 13111DEFUN ("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\
12658DX isn't specified). Likewise for the y-position; if a `top' frame\n\ 13126DX isn't specified). Likewise for the y-position; if a `top' frame\n\
12659parameter is specified, it determines the y-position of the tooltip\n\ 13127parameter is specified, it determines the y-position of the tooltip\n\
12660window, otherwise it is displayed at the mouse position, with offset\n\ 13128window, otherwise it is displayed at the mouse position, with offset\n\
12661DY added (default is 10).") 13129DY added (default is -10).\n\
13130\n\
13131A tooltip's maximum size is specified by `x-max-tooltip-size'.\n\
13132Text 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
12842DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0, 13319DEFUN ("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\
12844Value is t is tooltip was open, nil otherwise.") 13321Value 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\
12888Use a file selection dialog.\n\ 13365Use a file selection dialog.\n\
12889Select DEFAULT-FILENAME in the dialog's file selection box, if\n\ 13366Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
12890specified. Don't let the user enter a file name in the file\n\ 13367specified. Ensure that file exists if MUSTMATCH is non-nil.")
12891selection 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\
14225Text 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\
13734Emacs doesn't try to figure this out; this is always nil\n\ 14230Emacs doesn't try to figure this out; this is always nil\n\