Commit 3cf3436e authored by Jason Rumney's avatar Jason Rumney

(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.
parent 29250851
2001-10-21 Jason Rumney <jasonr@gnu.org>
* w32fns.c (Fx_file_dialog): Pass a filter to GetOpenFileName.
* w32menu.c (single_submenu, w32_menu_show) [!HAVE_MULTILINGUAL_MENU]:
Protect unibyte stings created by replacing their multibyte
equivalents in menu_items.
(w32_menu_show): Don't overwrite an item's name with its key
description in case the description is a multibyte string.
(single_submenu): Some cleanup.
* w32fns.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.
2001-10-21 Miles Bader <miles@gnu.org>
* data.c (Fplus, Fminus, Fmax, Ftimes, Fquo, Flogand, Flogior)
......
......@@ -687,6 +687,8 @@ void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_unsplittable P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
static void x_set_screen_gamma P_ ((struct frame *, Lisp_Object, Lisp_Object));
static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,
Lisp_Object));
static struct x_frame_parm_table x_frame_parms[] =
{
......@@ -1956,11 +1958,18 @@ x_set_foreground_color (f, arg, oldval)
struct frame *f;
Lisp_Object arg, oldval;
{
FRAME_FOREGROUND_PIXEL (f)
= x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
struct w32_output *x = f->output_data.w32;
PIX_TYPE fg, old_fg;
fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
old_fg = FRAME_FOREGROUND_PIXEL (f);
FRAME_FOREGROUND_PIXEL (f) = fg;
if (FRAME_W32_WINDOW (f) != 0)
{
if (x->cursor_pixel == old_fg)
x->cursor_pixel = fg;
update_face_from_frame_parameter (f, Qforeground_color, arg);
if (FRAME_VISIBLE_P (f))
redraw_frame (f);
......@@ -2367,6 +2376,7 @@ x_set_font (f, arg, oldval)
Lisp_Object result;
Lisp_Object fontset_name;
Lisp_Object frame;
int old_fontset = FRAME_FONTSET(f);
CHECK_STRING (arg, 1);
......@@ -2384,8 +2394,16 @@ x_set_font (f, arg, oldval)
error ("The characters of the given font have varying widths");
else if (STRINGP (result))
{
if (!NILP (Fequal (result, oldval)))
if (STRINGP (fontset_name))
{
/* Fontset names are built from ASCII font names, so the
names may be equal despite there was a change. */
if (old_fontset == FRAME_FONTSET (f))
return;
}
else if (!NILP (Fequal (result, oldval)))
return;
store_frame_param (f, Qfont, result);
recompute_basic_faces (f);
}
......@@ -2602,6 +2620,9 @@ x_set_tool_bar_lines (f, value, oldval)
release_frame_dc (f, hdc);
}
UNBLOCK_INPUT;
if (WINDOWP (f->tool_bar_window))
clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
}
}
......@@ -5355,6 +5376,35 @@ This function is an internal primitive--use `make-frame' instead.")
f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;
f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
/* Add the tool-bar height to the initial frame height so that the
user gets a text display area of the size he specified with -g or
via .Xdefaults. Later changes of the tool-bar height don't
change the frame size. This is done so that users can create
tall Emacs frames without having to guess how tall the tool-bar
will get. */
if (FRAME_TOOL_BAR_LINES (f))
{
int margin, relief, bar_height;
relief = (tool_bar_button_relief > 0
? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF);
if (INTEGERP (Vtool_bar_button_margin)
&& XINT (Vtool_bar_button_margin) > 0)
margin = XFASTINT (Vtool_bar_button_margin);
else if (CONSP (Vtool_bar_button_margin)
&& INTEGERP (XCDR (Vtool_bar_button_margin))
&& XINT (XCDR (Vtool_bar_button_margin)) > 0)
margin = XFASTINT (XCDR (Vtool_bar_button_margin));
else
margin = 0;
bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
f->height += (bar_height + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
}
window_prompting = x_figure_window_size (f, parms);
if (window_prompting & XNegative)
......@@ -5406,34 +5456,6 @@ This function is an internal primitive--use `make-frame' instead.")
width = f->width;
height = f->height;
/* Add the tool-bar height to the initial frame height so that the
user gets a text display area of the size he specified with -g or
via .Xdefaults. Later changes of the tool-bar height don't
change the frame size. This is done so that users can create
tall Emacs frames without having to guess how tall the tool-bar
will get. */
if (FRAME_TOOL_BAR_LINES (f))
{
int margin, relief, bar_height;
relief = (tool_bar_button_relief > 0
? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF);
if (INTEGERP (Vtool_bar_button_margin)
&& XINT (Vtool_bar_button_margin) > 0)
margin = XFASTINT (Vtool_bar_button_margin);
else if (CONSP (Vtool_bar_button_margin)
&& INTEGERP (XCDR (Vtool_bar_button_margin))
&& XINT (XCDR (Vtool_bar_button_margin)) > 0)
margin = XFASTINT (XCDR (Vtool_bar_button_margin));
else
margin = 0;
bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
height += (bar_height + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
}
f->height = 0;
SET_FRAME_WIDTH (f, 0);
change_frame_size (f, height, width, 1, 0, 0);
......@@ -7680,11 +7702,11 @@ extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
extern Lisp_Object QCdata;
Lisp_Object QCtype, QCascent, QCmargin, QCrelief;
Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
Lisp_Object QCindex;
Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
/* Other symbols. */
Lisp_Object Qlaplace;
Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic;
/* Time in seconds after which images should be removed from the cache
if not displayed. */
......@@ -7697,6 +7719,7 @@ static void define_image_type P_ ((struct image_type *type));
static struct image_type *lookup_image_type P_ ((Lisp_Object symbol));
static void image_error P_ ((char *format, Lisp_Object, Lisp_Object));
static void x_laplace P_ ((struct frame *, struct image *));
static void x_emboss P_ ((struct frame *, struct image *));
static int x_build_heuristic_mask P_ ((struct frame *, struct image *,
Lisp_Object));
......@@ -7750,13 +7773,24 @@ valid_image_p (object)
if (CONSP (object) && EQ (XCAR (object), Qimage))
{
Lisp_Object symbol = Fplist_get (XCDR (object), QCtype);
struct image_type *type = lookup_image_type (symbol);
Lisp_Object tem;
for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem))
if (EQ (XCAR (tem), QCtype))
{
tem = XCDR (tem);
if (CONSP (tem) && SYMBOLP (XCAR (tem)))
{
struct image_type *type;
type = lookup_image_type (XCAR (tem));
if (type)
valid_p = type->valid_p (object);
}
break;
}
}
return valid_p;
}
......@@ -7785,6 +7819,7 @@ enum image_value_type
{
IMAGE_DONT_CHECK_VALUE_TYPE,
IMAGE_STRING_VALUE,
IMAGE_STRING_OR_NIL_VALUE,
IMAGE_SYMBOL_VALUE,
IMAGE_POSITIVE_INTEGER_VALUE,
IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
......@@ -7882,6 +7917,11 @@ parse_image_spec (spec, keywords, nkeywords, type)
return 0;
break;
case IMAGE_STRING_OR_NIL_VALUE:
if (!STRINGP (value) && !NILP (value))
return 0;
break;
case IMAGE_SYMBOL_VALUE:
if (!SYMBOLP (value))
return 0;
......@@ -8195,6 +8235,7 @@ x_alloc_image_color (f, img, color_name, dflt)
***********************************************************************/
static void cache_image P_ ((struct frame *f, struct image *img));
static void postprocess_image P_ ((struct frame *, struct image *));
/* 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.")
}
/* Compute masks and transform image IMG on frame F, as specified
by the image's specification, */
static void
postprocess_image (f, img)
struct frame *f;
struct image *img;
{
#if 0 /* TODO: image support. */
/* Manipulation of the image's mask. */
if (img->pixmap)
{
Lisp_Object conversion, spec;
Lisp_Object mask;
spec = img->spec;
/* `:heuristic-mask t'
`:mask heuristic'
means build a mask heuristically.
`:heuristic-mask (R G B)'
`:mask (heuristic (R G B))'
means build a mask from color (R G B) in the
image.
`:mask nil'
means remove a mask, if any. */
mask = image_spec_value (spec, QCheuristic_mask, NULL);
if (!NILP (mask))
x_build_heuristic_mask (f, img, mask);
else
{
int found_p;
mask = image_spec_value (spec, QCmask, &found_p);
if (EQ (mask, Qheuristic))
x_build_heuristic_mask (f, img, Qt);
else if (CONSP (mask)
&& EQ (XCAR (mask), Qheuristic))
{
if (CONSP (XCDR (mask)))
x_build_heuristic_mask (f, img, XCAR (XCDR (mask)));
else
x_build_heuristic_mask (f, img, XCDR (mask));
}
else if (NILP (mask) && found_p && img->mask)
{
XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
img->mask = NULL;
}
}
/* Should we apply an image transformation algorithm? */
conversion = image_spec_value (spec, QCconversion, NULL);
if (EQ (conversion, Qdisabled))
x_disable_image (f, img);
else if (EQ (conversion, Qlaplace))
x_laplace (f, img);
else if (EQ (conversion, Qemboss))
x_emboss (f, img);
else if (CONSP (conversion)
&& EQ (XCAR (conversion), Qedge_detection))
{
Lisp_Object tem;
tem = XCDR (conversion);
if (CONSP (tem))
x_edge_detection (f, img,
Fplist_get (tem, QCmatrix),
Fplist_get (tem, QCcolor_adjustment));
}
}
#endif
}
/* Return the id of image with Lisp specification SPEC on frame F.
SPEC must be a valid Lisp image specification (see valid_image_p). */
......@@ -8345,6 +8463,8 @@ lookup_image (f, spec)
/* If not found, create a new image and cache it. */
if (img == NULL)
{
extern Lisp_Object Qpostscript;
BLOCK_INPUT;
img = make_image (spec, hash);
cache_image (f, img);
......@@ -8396,74 +8516,12 @@ lookup_image (f, spec)
img->vmargin += abs (img->relief);
}
#if 0 /* TODO: image mask and algorithm. */
/* Manipulation of the image's mask. */
if (img->pixmap)
{
/* `:heuristic-mask t'
`:mask heuristic'
means build a mask heuristically.
`:heuristic-mask (R G B)'
`:mask (heuristic (R G B))'
means build a mask from color (R G B) in the
image.
`:mask nil'
means remove a mask, if any. */
Lisp_Object mask;
mask = image_spec_value (spec, QCheuristic_mask, NULL);
if (!NILP (mask))
x_build_heuristic_mask (f, img, mask);
else
{
int found_p;
mask = image_spec_value (spec, QCmask, &found_p);
if (EQ (mask, Qheuristic))
x_build_heuristic_mask (f, img, Qt);
else if (CONSP (mask)
&& EQ (XCAR (mask), Qheuristic))
{
if (CONSP (XCDR (mask)))
x_build_heuristic_mask (f, img, XCAR (XCDR (mask)));
else
x_build_heuristic_mask (f, img, XCDR (mask));
}
else if (NILP (mask) && found_p && img->mask)
{
XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
img->mask = None;
}
}
/* Do image transformations and compute masks, unless we
don't have the image yet. */
if (!EQ (*img->type->type, Qpostscript))
postprocess_image (f, img);
}
/* Should we apply an image transformation algorithm? */
if (img->pixmap)
{
Lisp_Object conversion;
algorithm = image_spec_value (spec, QCconversion, NULL);
if (EQ (conversion, Qdisabled))
x_disable_image (f, img);
else if (EQ (conversion, Qlaplace))
x_laplace (f, img);
else if (EQ (conversion, Qemboss))
x_emboss (f, img);
else if (CONSP (conversion)
&& EQ (XCAR (conversion), Qedge_detection))
{
Lisp_Object tem;
tem = XCDR (conversion);
if (CONSP (tem))
x_edge_detection (f, img,
Fplist_get (tem, QCmatrix),
Fplist_get (tem, QCcolor_adjustment));
}
}
#endif /* TODO. */
}
UNBLOCK_INPUT;
xassert (!interrupt_input_blocked);
}
......@@ -8638,10 +8696,12 @@ x_put_x_image (f, ximg, pixmap, width, height)
/***********************************************************************
Searching files
File Handling
***********************************************************************/
static Lisp_Object x_find_image_file P_ ((Lisp_Object));
static char *slurp_file P_ ((char *, int *));
/* Find image file FILE. Look in data-directory, then
x-bitmap-file-path. Value is the full name of the file found, or
......@@ -8672,6 +8732,42 @@ x_find_image_file (file)
}
/* Read FILE into memory. Value is a pointer to a buffer allocated
with xmalloc holding FILE's contents. Value is null if an error
occurred. *SIZE is set to the size of the file. */
static char *
slurp_file (file, size)
char *file;
int *size;
{
FILE *fp = NULL;
char *buf = NULL;
struct stat st;
if (stat (file, &st) == 0
&& (fp = fopen (file, "r")) != NULL
&& (buf = (char *) xmalloc (st.st_size),
fread (buf, 1, st.st_size, fp) == st.st_size))
{
*size = st.st_size;
fclose (fp);
}
else
{
if (fp)
fclose (fp);
if (buf)
{
xfree (buf);
buf = NULL;
}
}
return buf;
}
/***********************************************************************
XBM images
......@@ -8714,8 +8810,8 @@ static struct image_keyword xbm_format[XBM_LAST] =
{":width", IMAGE_POSITIVE_INTEGER_VALUE, 0},
{":height", IMAGE_POSITIVE_INTEGER_VALUE, 0},
{":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":foreground", IMAGE_STRING_VALUE, 0},
{":background", IMAGE_STRING_VALUE, 0},
{":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
{":background", IMAGE_STRING_OR_NIL_VALUE, 0},
{":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
......@@ -8862,30 +8958,33 @@ xbm_image_p (object)
scanning a number, store its value in *IVAL. */
static int
xbm_scan (fp, sval, ival)
FILE *fp;
xbm_scan (s, end, sval, ival)
char **s, *end;
char *sval;
int *ival;
{
int c;
loop:
/* Skip white space. */
while ((c = fgetc (fp)) != EOF && isspace (c))
while (*s < end &&(c = *(*s)++, isspace (c)))
;
if (c == EOF)
if (*s >= end)
c = 0;
else if (isdigit (c))
{
int value = 0, digit;
if (c == '0')
if (c == '0' && *s < end)
{
c = fgetc (fp);
c = *(*s)++;
if (c == 'x' || c == 'X')
{
while ((c = fgetc (fp)) != EOF)
while (*s < end)
{
c = *(*s)++;
if (isdigit (c))
digit = c - '0';
else if (c >= 'a' && c <= 'f')
......@@ -8900,53 +8999,66 @@ xbm_scan (fp, sval, ival)
else if (isdigit (c))
{
value = c - '0';
while ((c = fgetc (fp)) != EOF
&& isdigit (c))
while (*s < end
&& (c = *(*s)++, isdigit (c)))
value = 8 * value + c - '0';
}
}
else
{
value = c - '0';
while ((c = fgetc (fp)) != EOF
&& isdigit (c))
while (*s < end
&& (c = *(*s)++, isdigit (c)))
value = 10 * value + c - '0';
}
if (c != EOF)
ungetc (c, fp);
if (*s < end)
*s = *s - 1;
*ival = value;
c = XBM_TK_NUMBER;
}
else if (isalpha (c) || c == '_')
{
*sval++ = c;
while ((c = fgetc (fp)) != EOF
&& (isalnum (c) || c == '_'))
while (*s < end
&& (c = *(*s)++, (isalnum (c) || c == '_')))
*sval++ = c;
*sval = 0;
if (c != EOF)
ungetc (c, fp);
if (*s < end)
*s = *s - 1;
c = XBM_TK_IDENT;
}
else if (c == '/' && **s == '*')
{
/* C-style comment. */
++*s;
while (**s && (**s != '*' || *(*s + 1) != '/'))
++*s;
if (**s)
{
*s += 2;
goto loop;
}
}
return c;
}
/* Replacement for XReadBitmapFileData which isn't available under old
X versions. FILE is the name of the bitmap file to read. Set
*WIDTH and *HEIGHT to the width and height of the image. Return in
*DATA the bitmap data allocated with xmalloc. Value is non-zero if
successful. */
X versions. CONTENTS is a pointer to a buffer to parse; END is the
buffer's end. Set *WIDTH and *HEIGHT to the width and height of
the image. Return in *DATA the bitmap data allocated with xmalloc.
Value is non-zero if successful. DATA null means just test if
CONTENTS looks like an in-memory XBM file. */
static int
xbm_read_bitmap_file_data (file, width, height, data)
char *file;
xbm_read_bitmap_data (contents, end, width, height, data)
char *contents, *end;
int *width, *height;
unsigned char **data;
{
FILE *fp;
char *s = contents;
char buffer[BUFSIZ];
int padding_p = 0;
int v10 = 0;
......@@ -8956,7 +9068,7 @@ xbm_read_bitmap_file_data (file, width, height, data)
int LA1;
#define match() \
LA1 = xbm_scan (fp, buffer, &value)
LA1 = xbm_scan (contents, end, buffer, &value)
#define expect(TOKEN) \
if (LA1 != (TOKEN)) \
......@@ -8970,13 +9082,10 @@ xbm_read_bitmap_file_data (file, width, height, data)
else \
goto failure
fp = fopen (file, "r");
if (fp == NULL)
return 0;
*width = *height = -1;
if (data)
*data = NULL;
LA1 = xbm_scan (fp, buffer, &value);
LA1 = xbm_scan (&s, end, buffer, &value);
/* Parse defines for width, height and hot-spots. */
while (LA1 == '#')
......@@ -8999,6 +9108,8 @@ xbm_read_bitmap_file_data (file, width, height, data)
if (*width < 0 || *height < 0)
goto failure;
else if (data == NULL)
goto success;
/* Parse bits. Must start with `static'. */
expect_ident ("static");
......@@ -9068,13 +9179,12 @@ xbm_read_bitmap_file_data (file, width, height, data)
}
}
fclose (fp);
success:
return 1;
failure:
fclose (fp);
if (*data)
if (data && *data)
{
xfree (*data);
*data = NULL;
......@@ -9087,35 +9197,21 @@ xbm_read_bitmap_file_data (file, width, height, data)
}
/* Load XBM image IMG which will be displayed on frame F from file
SPECIFIED_FILE. Value is non-zero if successful. */
/* Load XBM image IMG which will be displayed on frame F from buffer
CONTENTS. END is the end of the buffer. Value is non-zero if
successful. */
static int
xbm_load_image_from_file (f, img, specified_file)
xbm_load_image (f, img, contents, end)
struct frame *f;
struct image *img;
Lisp_Object specified_file;
char *contents, *end;
{
int rc;
unsigned char *data;
int success_p = 0;
Lisp_Object file;
struct gcpro gcpro1;
xassert (STRINGP (specified_file));
file = Qnil;
GCPRO1 (file);
file = x_find_image_file (specified_file);
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", specified_file, Qnil);
UNGCPRO;
return 0;
}
rc = xbm_read_bitmap_file_data (XSTRING (file)->data, &img->width,
&img->height, &data);
rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data);
if (rc)
{
int depth = one_w32_display_info.n_cbits;