/* Functions for the X window system.
- Copyright (C) 1989, 92, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 01, 02
Free Software Foundation.
This file is part of GNU Emacs.
#include <stdio.h>
#include <math.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
/* This makes the fields of a Display accessible, in Xlib header files. */
#define XLIB_ILLEGAL_ACCESS
#include "keyboard.h"
#include "blockinput.h"
#include <epaths.h>
+#include "character.h"
#include "charset.h"
#include "coding.h"
#include "fontset.h"
Lisp_Object Qscreen_gamma, Qline_spacing, Qcenter;
Lisp_Object Qcompound_text, Qcancel_timer;
Lisp_Object Qwait_for_wm;
+Lisp_Object Qfullscreen;
+Lisp_Object Qfullwidth;
+Lisp_Object Qfullheight;
+Lisp_Object Qfullboth;
/* The below are defined in frame.c. */
if (NILP (frame))
frame = selected_frame;
- CHECK_LIVE_FRAME (frame, 0);
+ CHECK_LIVE_FRAME (frame);
f = XFRAME (frame);
if (! FRAME_X_P (f))
error ("Non-X frame used");
{
FRAME_PTR f;
- CHECK_LIVE_FRAME (frame, 0);
+ CHECK_LIVE_FRAME (frame);
f = XFRAME (frame);
if (! FRAME_X_P (f))
error ("Non-X frame used");
void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
static void x_set_line_spacing P_ ((struct frame *, Lisp_Object, Lisp_Object));
static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
+static void x_set_fullscreen P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
+static void x_set_fringe_width P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_font P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_border_width P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_internal_border_width P_ ((struct frame *, Lisp_Object,
static struct x_frame_parm_table x_frame_parms[] =
{
- "auto-raise", x_set_autoraise,
- "auto-lower", x_set_autolower,
- "background-color", x_set_background_color,
- "border-color", x_set_border_color,
- "border-width", x_set_border_width,
- "cursor-color", x_set_cursor_color,
- "cursor-type", x_set_cursor_type,
- "font", x_set_font,
- "foreground-color", x_set_foreground_color,
- "icon-name", x_set_icon_name,
- "icon-type", x_set_icon_type,
- "internal-border-width", x_set_internal_border_width,
- "menu-bar-lines", x_set_menu_bar_lines,
- "mouse-color", x_set_mouse_color,
- "name", x_explicitly_set_name,
- "scroll-bar-width", x_set_scroll_bar_width,
- "title", x_set_title,
- "unsplittable", x_set_unsplittable,
- "vertical-scroll-bars", x_set_vertical_scroll_bars,
- "visibility", x_set_visibility,
- "tool-bar-lines", x_set_tool_bar_lines,
- "scroll-bar-foreground", x_set_scroll_bar_foreground,
- "scroll-bar-background", x_set_scroll_bar_background,
- "screen-gamma", x_set_screen_gamma,
- "line-spacing", x_set_line_spacing,
- "wait-for-wm", x_set_wait_for_wm
+ {"auto-raise", x_set_autoraise},
+ {"auto-lower", x_set_autolower},
+ {"background-color", x_set_background_color},
+ {"border-color", x_set_border_color},
+ {"border-width", x_set_border_width},
+ {"cursor-color", x_set_cursor_color},
+ {"cursor-type", x_set_cursor_type},
+ {"font", x_set_font},
+ {"foreground-color", x_set_foreground_color},
+ {"icon-name", x_set_icon_name},
+ {"icon-type", x_set_icon_type},
+ {"internal-border-width", x_set_internal_border_width},
+ {"menu-bar-lines", x_set_menu_bar_lines},
+ {"mouse-color", x_set_mouse_color},
+ {"name", x_explicitly_set_name},
+ {"scroll-bar-width", x_set_scroll_bar_width},
+ {"title", x_set_title},
+ {"unsplittable", x_set_unsplittable},
+ {"vertical-scroll-bars", x_set_vertical_scroll_bars},
+ {"visibility", x_set_visibility},
+ {"tool-bar-lines", x_set_tool_bar_lines},
+ {"scroll-bar-foreground", x_set_scroll_bar_foreground},
+ {"scroll-bar-background", x_set_scroll_bar_background},
+ {"screen-gamma", x_set_screen_gamma},
+ {"line-spacing", x_set_line_spacing},
+ {"left-fringe", x_set_fringe_width},
+ {"right-fringe", x_set_fringe_width},
+ {"wait-for-wm", x_set_wait_for_wm},
+ {"fullscreen", x_set_fullscreen},
+
};
/* Attach the `x-frame-parameter' properties to
make_number (i));
}
\f
+
+/* Really try to move where we want to be in case of fullscreen. Some WMs
+ moves the window where we tell them. Some (mwm, twm) moves the outer
+ window manager window there instead.
+ Try to compensate for those WM here. */
+static void
+x_fullscreen_move (f, new_top, new_left)
+ struct frame *f;
+ int new_top;
+ int new_left;
+{
+ if (new_top != f->output_data.x->top_pos
+ || new_left != f->output_data.x->left_pos)
+ {
+ int move_x = new_left + f->output_data.x->x_pixels_outer_diff;
+ int move_y = new_top + f->output_data.x->y_pixels_outer_diff;
+
+ f->output_data.x->want_fullscreen |= FULLSCREEN_MOVE_WAIT;
+ x_set_offset (f, move_x, move_y, 1);
+ }
+}
+
/* Change the parameters of frame F as specified by ALIST.
If a parameter is not specially recognized, do nothing special;
otherwise call the `x_set_...' function for that parameter.
int i, p;
int left_no_change = 0, top_no_change = 0;
int icon_left_no_change = 0, icon_top_no_change = 0;
+ int fullscreen_is_being_set = 0;
struct gcpro gcpro1, gcpro2;
/* Process foreground_color and background_color before anything else.
They are independent of other properties, but other properties (e.g.,
cursor_color) are dependent upon them. */
+ /* Process default font as well, since fringe widths depends on it. */
+ /* Also, process fullscreen, width and height depend upon that */
for (p = 0; p < i; p++)
{
Lisp_Object prop, val;
prop = parms[p];
val = values[p];
- if (EQ (prop, Qforeground_color) || EQ (prop, Qbackground_color))
+ if (EQ (prop, Qforeground_color)
+ || EQ (prop, Qbackground_color)
+ || EQ (prop, Qfont)
+ || EQ (prop, Qfullscreen))
{
register Lisp_Object param_index, old_value;
- param_index = Fget (prop, Qx_frame_parameter);
old_value = get_frame_param (f, prop);
- store_frame_param (f, prop, val);
- if (NATNUMP (param_index)
- && (XFASTINT (param_index)
- < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
- (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);
+ fullscreen_is_being_set |= EQ (prop, Qfullscreen);
+
+ if (NILP (Fequal (val, old_value)))
+ {
+ store_frame_param (f, prop, val);
+
+ param_index = Fget (prop, Qx_frame_parameter);
+ if (NATNUMP (param_index)
+ && (XFASTINT (param_index)
+ < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
+ (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);
+ }
}
}
icon_top = val;
else if (EQ (prop, Qicon_left))
icon_left = val;
- else if (EQ (prop, Qforeground_color) || EQ (prop, Qbackground_color))
+ else if (EQ (prop, Qforeground_color)
+ || EQ (prop, Qbackground_color)
+ || EQ (prop, Qfont)
+ || EQ (prop, Qfullscreen))
/* Processed above. */
continue;
else
{
register Lisp_Object param_index, old_value;
- param_index = Fget (prop, Qx_frame_parameter);
old_value = get_frame_param (f, prop);
+
store_frame_param (f, prop, val);
- if (NATNUMP (param_index)
+
+ param_index = Fget (prop, Qx_frame_parameter);
+ if (NATNUMP (param_index)
&& (XFASTINT (param_index)
< sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
(*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);
XSETINT (icon_top, 0);
}
+ if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
+ {
+ /* If the frame is visible already and the fullscreen parameter is
+ being set, it is too late to set WM manager hints to specify
+ size and position.
+ Here we first get the width, height and position that applies to
+ fullscreen. We then move the frame to the appropriate
+ position. Resize of the frame is taken care of in the code after
+ this if-statement. */
+ int new_left, new_top;
+
+ x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
+ x_fullscreen_move (f, new_top, new_left);
+ }
+
/* Don't set these parameters unless they've been explicitly
specified. The window might be mapped or resized while we're in
this function, and we don't want to override that unless the lisp
FRAME_PTR f;
int *xptr, *yptr;
{
- int win_x, win_y;
- Window child;
+ int win_x, win_y, outer_x, outer_y;
+ int real_x = 0, real_y = 0;
+ int had_errors = 0;
+ Window win = f->output_data.x->parent_desc;
- /* This is pretty gross, but seems to be the easiest way out of
- the problem that arises when restarting window-managers. */
+ int count;
-#ifdef USE_X_TOOLKIT
- Window outer = (f->output_data.x->widget
- ? XtWindow (f->output_data.x->widget)
- : FRAME_X_WINDOW (f));
-#else
- Window outer = f->output_data.x->window_desc;
-#endif
- Window tmp_root_window;
- Window *tmp_children;
- unsigned int tmp_nchildren;
+ BLOCK_INPUT;
+
+ count = x_catch_errors (FRAME_X_DISPLAY (f));
- while (1)
+ if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
+ win = FRAME_OUTER_WINDOW (f);
+
+ /* This loop traverses up the containment tree until we hit the root
+ window. Window managers may intersect many windows between our window
+ and the root window. The window we find just before the root window
+ should be the outer WM window. */
+ for (;;)
{
- int count = x_catch_errors (FRAME_X_DISPLAY (f));
- Window outer_window;
+ Window wm_window, rootw;
+ Window *tmp_children;
+ unsigned int tmp_nchildren;
- XQueryTree (FRAME_X_DISPLAY (f), outer, &tmp_root_window,
- &f->output_data.x->parent_desc,
- &tmp_children, &tmp_nchildren);
+ XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
+ &wm_window, &tmp_children, &tmp_nchildren);
XFree ((char *) tmp_children);
- win_x = win_y = 0;
+ had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
- /* Find the position of the outside upper-left corner of
- the inner window, with respect to the outer window. */
- if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
- outer_window = f->output_data.x->parent_desc;
- else
- outer_window = outer;
+ if (wm_window == rootw || had_errors)
+ break;
+ win = wm_window;
+ }
+
+ if (! had_errors)
+ {
+ int ign;
+ Window child, rootw;
+
+ /* Get the real coordinates for the WM window upper left corner */
+ XGetGeometry (FRAME_X_DISPLAY (f), win,
+ &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
+
+ /* Translate real coordinates to coordinates relative to our
+ window. For our window, the upper left corner is 0, 0.
+ Since the upper left corner of the WM window is outside
+ our window, win_x and win_y will be negative:
+
+ ------------------ ---> x
+ | title |
+ | ----------------- v y
+ | | our window
+ */
XTranslateCoordinates (FRAME_X_DISPLAY (f),
/* From-window, to-window. */
- outer_window,
FRAME_X_DISPLAY_INFO (f)->root_window,
+ FRAME_X_WINDOW (f),
/* From-position, to-position. */
- 0, 0, &win_x, &win_y,
+ real_x, real_y, &win_x, &win_y,
/* Child of win. */
&child);
- /* It is possible for the window returned by the XQueryNotify
- to become invalid by the time we call XTranslateCoordinates.
- That can happen when you restart some window managers.
- If so, we get an error in XTranslateCoordinates.
- Detect that and try the whole thing over. */
- if (! x_had_errors_p (FRAME_X_DISPLAY (f)))
+ if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
{
- x_uncatch_errors (FRAME_X_DISPLAY (f), count);
- break;
+ outer_x = win_x;
+ outer_y = win_y;
}
+ else
+ {
+ XTranslateCoordinates (FRAME_X_DISPLAY (f),
- x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+ /* From-window, to-window. */
+ FRAME_X_DISPLAY_INFO (f)->root_window,
+ FRAME_OUTER_WINDOW (f),
+
+ /* From-position, to-position. */
+ real_x, real_y, &outer_x, &outer_y,
+
+ /* Child of win. */
+ &child);
}
- *xptr = win_x;
- *yptr = win_y;
+ had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
+ }
+
+ x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+
+ UNBLOCK_INPUT;
+
+ if (had_errors) return;
+
+ f->output_data.x->x_pixels_diff = -win_x;
+ f->output_data.x->y_pixels_diff = -win_y;
+ f->output_data.x->x_pixels_outer_diff = -outer_x;
+ f->output_data.x->y_pixels_outer_diff = -outer_y;
+
+ *xptr = real_x;
+ *yptr = real_y;
}
/* Insert a description of internally-recorded parameters of frame X
make_number (f->output_data.x->border_width));
store_in_alist (alistptr, Qinternal_border_width,
make_number (f->output_data.x->internal_border_width));
+ store_in_alist (alistptr, Qleft_fringe,
+ make_number (f->output_data.x->left_fringe_width));
+ store_in_alist (alistptr, Qright_fringe,
+ make_number (f->output_data.x->right_fringe_width));
+ store_in_alist (alistptr, Qscroll_bar_width,
+ make_number (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
+ ? FRAME_SCROLL_BAR_PIXEL_WIDTH(f)
+ : 0));
sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
store_in_alist (alistptr, Qwindow_id,
build_string (buf));
{
XColor cdef;
- CHECK_STRING (color_name, 0);
+ CHECK_STRING (color_name);
#if 0 /* Don't do this. It's wrong when we're not using the default
colormap, it makes freeing difficult, and it's probably not
}
+/* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
+ the previous value of that parameter, NEW_VALUE is the new value. */
+
+static void
+x_set_fullscreen (f, new_value, old_value)
+ struct frame *f;
+ Lisp_Object new_value, old_value;
+{
+ if (NILP (new_value))
+ f->output_data.x->want_fullscreen = FULLSCREEN_NONE;
+ else if (EQ (new_value, Qfullboth))
+ f->output_data.x->want_fullscreen = FULLSCREEN_BOTH;
+ else if (EQ (new_value, Qfullwidth))
+ f->output_data.x->want_fullscreen = FULLSCREEN_WIDTH;
+ else if (EQ (new_value, Qfullheight))
+ f->output_data.x->want_fullscreen = FULLSCREEN_HEIGHT;
+}
+
+
/* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
the previous value of that parameter, NEW_VALUE is the new
value. */
if (!NILP (Vx_pointer_shape))
{
- CHECK_NUMBER (Vx_pointer_shape, 0);
+ CHECK_NUMBER (Vx_pointer_shape);
cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
}
else
if (!NILP (Vx_nontext_pointer_shape))
{
- CHECK_NUMBER (Vx_nontext_pointer_shape, 0);
+ CHECK_NUMBER (Vx_nontext_pointer_shape);
nontext_cursor
= XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
}
if (!NILP (Vx_hourglass_pointer_shape))
{
- CHECK_NUMBER (Vx_hourglass_pointer_shape, 0);
+ CHECK_NUMBER (Vx_hourglass_pointer_shape);
hourglass_cursor
= XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
}
x_check_errors (dpy, "bad nontext pointer cursor: %s");
if (!NILP (Vx_mode_pointer_shape))
{
- CHECK_NUMBER (Vx_mode_pointer_shape, 0);
+ CHECK_NUMBER (Vx_mode_pointer_shape);
mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
}
else
if (!NILP (Vx_sensitive_text_pointer_shape))
{
- CHECK_NUMBER (Vx_sensitive_text_pointer_shape, 0);
+ CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
cross_cursor
= XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
}
if (!NILP (Vx_window_horizontal_drag_shape))
{
- CHECK_NUMBER (Vx_window_horizontal_drag_shape, 0);
+ CHECK_NUMBER (Vx_window_horizontal_drag_shape);
horizontal_drag_cursor
= XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
}
{
int pix;
- CHECK_STRING (arg, 0);
+ CHECK_STRING (arg);
pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
x_set_border_pixel (f, pix);
update_face_from_frame_parameter (f, Qborder_color, arg);
Lisp_Object frame;
int old_fontset = f->output_data.x->fontset;
- CHECK_STRING (arg, 1);
+ CHECK_STRING (arg);
fontset_name = Fquery_fontset (arg, Qnil);
BLOCK_INPUT;
result = (STRINGP (fontset_name)
? x_new_fontset (f, XSTRING (fontset_name)->data)
- : x_new_font (f, XSTRING (arg)->data));
+ : x_new_fontset (f, XSTRING (arg)->data));
UNBLOCK_INPUT;
if (EQ (result, Qnil))
if (old_fontset == f->output_data.x->fontset)
return;
}
- else if (!NILP (Fequal (result, oldval)))
+ store_frame_param (f, Qfont, result);
+ if (!NILP (Fequal (result, oldval)))
return;
- store_frame_param (f, Qfont, result);
recompute_basic_faces (f);
}
else
}
}
+static void
+x_set_fringe_width (f, new_value, old_value)
+ struct frame *f;
+ Lisp_Object new_value, old_value;
+{
+ x_compute_fringe_widths (f, 1);
+}
+
void
x_set_border_width (f, arg, oldval)
struct frame *f;
Lisp_Object arg, oldval;
{
- CHECK_NUMBER (arg, 0);
+ CHECK_NUMBER (arg);
if (XINT (arg) == f->output_data.x->border_width)
return;
{
int old = f->output_data.x->internal_border_width;
- CHECK_NUMBER (arg, 0);
+ CHECK_NUMBER (arg);
f->output_data.x->internal_border_width = XINT (arg);
if (f->output_data.x->internal_border_width < 0)
f->output_data.x->internal_border_width = 0;
SET_FRAME_GARBAGED (f);
do_pending_window_change (0);
}
+ else
+ SET_FRAME_GARBAGED (f);
}
void
CODING_SYSTEM, and return a newly allocated memory area which
should be freed by `xfree' by a caller.
+ SELECTIONP non-zero means the string is being encoded for an X
+ selection, so it is safe to run pre-write conversions (which
+ may run Lisp code).
+
Store the byte length of resulting text in *TEXT_BYTES.
If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
the result should be `COMPOUND_TEXT'. */
unsigned char *
-x_encode_text (string, coding_system, text_bytes, stringp)
+x_encode_text (string, coding_system, selectionp, text_bytes, stringp)
Lisp_Object string, coding_system;
int *text_bytes, *stringp;
+ int selectionp;
{
- unsigned char *str = XSTRING (string)->data;
- int chars = XSTRING (string)->size;
- int bytes = STRING_BYTES (XSTRING (string));
- int charset_info;
- int bufsize;
- unsigned char *buf;
+ int result = string_xstring_p (string);
struct coding_system coding;
- charset_info = find_charset_in_text (str, chars, bytes, NULL, Qnil);
- if (charset_info == 0)
+ if (result == 0)
{
/* No multibyte character in OBJ. We need not encode it. */
- *text_bytes = bytes;
+ *text_bytes = STRING_BYTES (XSTRING (string));
*stringp = 1;
- return str;
+ return XSTRING (string)->data;
}
setup_coding_system (coding_system, &coding);
- coding.src_multibyte = 1;
- coding.dst_multibyte = 0;
- coding.mode |= CODING_MODE_LAST_BLOCK;
- if (coding.type == coding_type_iso2022)
- coding.flags |= CODING_FLAG_ISO_SAFE;
+ coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
/* We suppress producing escape sequences for composition. */
- coding.composing = COMPOSITION_DISABLED;
- bufsize = encoding_buffer_size (&coding, bytes);
- buf = (unsigned char *) xmalloc (bufsize);
- encode_coding (&coding, str, buf, bytes, bufsize);
+ coding.common_flags &= ~CODING_ANNOTATION_MASK;
+ coding.dst_bytes = XSTRING (string)->size * 2;
+ coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
+ encode_coding_object (&coding, string, 0, 0,
+ XSTRING (string)->size,
+ STRING_BYTES (XSTRING (string)), Qnil);
*text_bytes = coding.produced;
- *stringp = (charset_info == 1 || !EQ (coding_system, Qcompound_text));
- return buf;
+ *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
+ return coding.destination;
}
\f
name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
}
else
- CHECK_STRING (name, 0);
+ CHECK_STRING (name);
/* Don't change the name if it's already NAME. */
if (! NILP (Fstring_equal (name, f->name)))
coding_system = Vlocale_coding_system;
if (NILP (coding_system))
coding_system = Qcompound_text;
- text.value = x_encode_text (name, coding_system, &bytes, &stringp);
+ text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
text.encoding = (stringp ? XA_STRING
: FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
text.format = 8;
}
else
{
- icon.value = x_encode_text (f->icon_name, coding_system,
+ icon.value = x_encode_text (f->icon_name, coding_system, 0,
&bytes, &stringp);
icon.encoding = (stringp ? XA_STRING
: FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
if (NILP (name))
name = f->name;
else
- CHECK_STRING (name, 0);
+ CHECK_STRING (name);
if (FRAME_X_WINDOW (f))
{
coding_system = Vlocale_coding_system;
if (NILP (coding_system))
coding_system = Qcompound_text;
- text.value = x_encode_text (name, coding_system, &bytes, &stringp);
+ text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
text.encoding = (stringp ? XA_STRING
: FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
text.format = 8;
}
else
{
- icon.value = x_encode_text (f->icon_name, coding_system,
+ icon.value = x_encode_text (f->icon_name, coding_system, 0,
&bytes, &stringp);
icon.encoding = (stringp ? XA_STRING
: FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
extern char *x_get_string_resource ();
DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
- doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
+ doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
class, where INSTANCE is the name under which Emacs was invoked, or
the name specified by the `-name' or `-rn' command-line arguments.
check_x ();
- CHECK_STRING (attribute, 0);
- CHECK_STRING (class, 0);
+ CHECK_STRING (attribute);
+ CHECK_STRING (class);
if (!NILP (component))
- CHECK_STRING (component, 1);
+ CHECK_STRING (component);
if (!NILP (subclass))
- CHECK_STRING (subclass, 2);
+ CHECK_STRING (subclass);
if (NILP (component) != NILP (subclass))
error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
char *name_key;
char *class_key;
- CHECK_STRING (attribute, 0);
- CHECK_STRING (class, 0);
+ CHECK_STRING (attribute);
+ CHECK_STRING (class);
if (!NILP (component))
- CHECK_STRING (component, 1);
+ CHECK_STRING (component);
if (!NILP (subclass))
- CHECK_STRING (subclass, 2);
+ CHECK_STRING (subclass);
if (NILP (component) != NILP (subclass))
error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
unsigned int width, height;
Lisp_Object result;
- CHECK_STRING (string, 0);
+ CHECK_STRING (string);
geometry = XParseGeometry ((char *) XSTRING (string)->data,
&x, &y, &width, &height);
{
if (!EQ (tem0, Qunbound))
{
- CHECK_NUMBER (tem0, 0);
+ CHECK_NUMBER (tem0);
f->height = XINT (tem0);
}
if (!EQ (tem1, Qunbound))
{
- CHECK_NUMBER (tem1, 0);
+ CHECK_NUMBER (tem1);
SET_FRAME_WIDTH (f, XINT (tem1));
}
if (!NILP (tem2) && !EQ (tem2, Qunbound))
= (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
? 0
: (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.x->font)));
- f->output_data.x->flags_areas_extra
- = FRAME_FLAGS_AREA_WIDTH (f);
+
+ x_compute_fringe_widths (f, 0);
+
f->output_data.x->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
f->output_data.x->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
f->output_data.x->top_pos = 0;
else
{
- CHECK_NUMBER (tem0, 0);
+ CHECK_NUMBER (tem0);
f->output_data.x->top_pos = XINT (tem0);
if (f->output_data.x->top_pos < 0)
window_prompting |= YNegative;
f->output_data.x->left_pos = 0;
else
{
- CHECK_NUMBER (tem1, 0);
+ CHECK_NUMBER (tem1);
f->output_data.x->left_pos = XINT (tem1);
if (f->output_data.x->left_pos < 0)
window_prompting |= XNegative;
window_prompting |= PPosition;
}
+ if (f->output_data.x->want_fullscreen != FULLSCREEN_NONE)
+ {
+ int left, top;
+ int width, height;
+
+ /* It takes both for some WM:s to place it where we want */
+ window_prompting = USPosition | PPosition;
+ x_fullscreen_adjust (f, &width, &height, &top, &left);
+ f->width = width;
+ f->height = height;
+ f->output_data.x->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
+ f->output_data.x->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
+ f->output_data.x->left_pos = left;
+ f->output_data.x->top_pos = top;
+ }
+
return window_prompting;
}
icon_y = x_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
{
- CHECK_NUMBER (icon_x, 0);
- CHECK_NUMBER (icon_y, 0);
+ CHECK_NUMBER (icon_x);
+ CHECK_NUMBER (icon_y);
}
else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
error ("Both left and top icon corners of icon must be specified");
if (EQ (parent, Qunbound))
parent = Qnil;
if (! NILP (parent))
- CHECK_NUMBER (parent, 0);
+ CHECK_NUMBER (parent);
/* make_frame_without_minibuffer can run Lisp code and garbage collect. */
/* No need to protect DISPLAY because that's not used after passing
BLOCK_INPUT;
/* First, try whatever font the caller has specified. */
if (STRINGP (font))
- {
- tem = Fquery_fontset (font, Qnil);
- if (STRINGP (tem))
- font = x_new_fontset (f, XSTRING (tem)->data);
- else
- font = x_new_font (f, XSTRING (font)->data);
- }
+ font = x_new_fontset (f, XSTRING (font)->data);
/* Try out a font which we hope has bold and italic variations. */
if (!STRINGP (font))
- font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
+ font = x_new_fontset (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
if (!STRINGP (font))
- font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
+ font = x_new_fontset (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
if (! STRINGP (font))
- font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
+ font = x_new_fontset (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
if (! STRINGP (font))
/* This was formerly the first thing tried, but it finds too many fonts
and takes too long. */
- font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
+ font = x_new_fontset (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
/* If those didn't work, look for something which will at least work. */
if (! STRINGP (font))
- font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
+ font = x_new_fontset (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
UNBLOCK_INPUT;
if (! STRINGP (font))
font = build_string ("fixed");
x_default_parameter (f, parms, Qborder_width, make_number (2),
"borderWidth", "BorderWidth", RES_TYPE_NUMBER);
- /* This defaults to 2 in order to match xterm. We recognize either
+ /* This defaults to 1 in order to match xterm. We recognize either
internalBorderWidth or internalBorder (which is what xterm calls
it). */
if (NILP (Fassq (Qinternal_border_width, parms)))
"screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
x_default_parameter (f, parms, Qline_spacing, Qnil,
"lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
+ x_default_parameter (f, parms, Qleft_fringe, Qnil,
+ "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
+ x_default_parameter (f, parms, Qright_fringe, Qnil,
+ "rightFringe", "RightFringe", RES_TYPE_NUMBER);
x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
"scrollBarForeground",
"title", "Title", RES_TYPE_STRING);
x_default_parameter (f, parms, Qwait_for_wm, Qt,
"waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
+ x_default_parameter (f, parms, Qfullscreen, Qnil,
+ "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
{
int margin, relief, bar_height;
- relief = (tool_bar_button_relief > 0
+ relief = (tool_bar_button_relief >= 0
? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF);
XColor foo;
FRAME_PTR f = check_x_frame (frame);
- CHECK_STRING (color, 1);
+ CHECK_STRING (color);
if (x_defined_color (f, XSTRING (color)->data, &foo, 0))
return Qt;
XColor foo;
FRAME_PTR f = check_x_frame (frame);
- CHECK_STRING (color, 1);
+ CHECK_STRING (color);
if (x_defined_color (f, XSTRING (color)->data, &foo, 0))
{
{"PseudoColor", PseudoColor},
{"TrueColor", TrueColor},
{"DirectColor", DirectColor},
- NULL
+ {NULL, 0}
};
int i;
for (i = 0; i < dpy->nscreens; ++i)
- if (scr == dpy->screens[i])
+ if (scr == dpy->screens + i)
break;
return i;
Lisp_Object names;
struct x_display_info *dpyinfo;
- CHECK_STRING (name, 0);
+ CHECK_STRING (name);
if (! EQ (Vwindow_system, intern ("x")))
error ("Not using X Windows");
unsigned char *xrm_option;
struct x_display_info *dpyinfo;
- CHECK_STRING (display, 0);
+ CHECK_STRING (display);
if (! NILP (xrm_string))
- CHECK_STRING (xrm_string, 1);
+ CHECK_STRING (xrm_string);
if (! EQ (Vwindow_system, intern ("x")))
error ("Not using X Windows");
return ascent;
}
+\f
+/* Image background colors. */
+
+static unsigned long
+four_corners_best (ximg, width, height)
+ XImage *ximg;
+ unsigned long width, height;
+{
+ unsigned long corners[4], best;
+ int i, best_count;
+
+ /* Get the colors at the corners of ximg. */
+ corners[0] = XGetPixel (ximg, 0, 0);
+ corners[1] = XGetPixel (ximg, width - 1, 0);
+ corners[2] = XGetPixel (ximg, width - 1, height - 1);
+ corners[3] = XGetPixel (ximg, 0, height - 1);
+
+ /* Choose the most frequently found color as background. */
+ for (i = best_count = 0; i < 4; ++i)
+ {
+ int j, n;
+
+ for (j = n = 0; j < 4; ++j)
+ if (corners[i] == corners[j])
+ ++n;
+
+ if (n > best_count)
+ best = corners[i], best_count = n;
+ }
+
+ return best;
+}
+
+/* Return the `background' field of IMG. If IMG doesn't have one yet,
+ it is guessed heuristically. If non-zero, XIMG is an existing XImage
+ object to use for the heuristic. */
+
+unsigned long
+image_background (img, f, ximg)
+ struct image *img;
+ struct frame *f;
+ XImage *ximg;
+{
+ if (! img->background_valid)
+ /* IMG doesn't have a background yet, try to guess a reasonable value. */
+ {
+ int free_ximg = !ximg;
+
+ if (! ximg)
+ ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
+ 0, 0, img->width, img->height, ~0, ZPixmap);
+
+ img->background = four_corners_best (ximg, img->width, img->height);
+
+ if (free_ximg)
+ XDestroyImage (ximg);
+
+ img->background_valid = 1;
+ }
+
+ return img->background;
+}
+
+/* Return the `background_transparent' field of IMG. If IMG doesn't
+ have one yet, it is guessed heuristically. If non-zero, MASK is an
+ existing XImage object to use for the heuristic. */
+
+int
+image_background_transparent (img, f, mask)
+ struct image *img;
+ struct frame *f;
+ XImage *mask;
+{
+ if (! img->background_transparent_valid)
+ /* IMG doesn't have a background yet, try to guess a reasonable value. */
+ {
+ if (img->mask)
+ {
+ int free_mask = !mask;
+
+ if (! mask)
+ mask = XGetImage (FRAME_X_DISPLAY (f), img->mask,
+ 0, 0, img->width, img->height, ~0, ZPixmap);
+
+ img->background_transparent
+ = !four_corners_best (mask, img->width, img->height);
+
+ if (free_mask)
+ XDestroyImage (mask);
+ }
+ else
+ img->background_transparent = 0;
+
+ img->background_transparent_valid = 1;
+ }
+
+ return img->background_transparent;
+}
\f
/***********************************************************************
{
XFreePixmap (FRAME_X_DISPLAY (f), img->pixmap);
img->pixmap = None;
+ img->background_valid = 0;
}
if (mask_p && img->mask)
{
XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
img->mask = None;
+ img->background_transparent_valid = 0;
}
if (colors_p && img->ncolors)
else
{
/* Handle image type independent image attributes
- `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF'. */
- Lisp_Object ascent, margin, relief;
+ `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
+ `:background COLOR'. */
+ Lisp_Object ascent, margin, relief, bg;
ascent = image_spec_value (spec, QCascent, NULL);
if (INTEGERP (ascent))
img->vmargin += abs (img->relief);
}
+ if (! img->background_valid)
+ {
+ bg = image_spec_value (img->spec, QCbackground, NULL);
+ if (!NILP (bg))
+ {
+ img->background
+ = x_alloc_image_color (f, img, bg,
+ FRAME_BACKGROUND_PIXEL (f));
+ img->background_valid = 1;
+ }
+ }
+
/* Do image transformations and compute masks, unless we
don't have the image yet. */
if (!EQ (*img->type->type, Qpostscript))
struct frame *f;
XImage *ximg;
Pixmap pixmap;
+ int width, height;
{
GC gc;
value = image_spec_value (img->spec, QCforeground, NULL);
if (!NILP (value))
foreground = x_alloc_image_color (f, img, value, foreground);
-
value = image_spec_value (img->spec, QCbackground, NULL);
if (!NILP (value))
- background = x_alloc_image_color (f, img, value, background);
+ {
+ background = x_alloc_image_color (f, img, value, background);
+ img->background = background;
+ img->background_valid = 1;
+ }
img->pixmap
= XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
XPM_HEURISTIC_MASK,
XPM_MASK,
XPM_COLOR_SYMBOLS,
+ XPM_BACKGROUND,
XPM_LAST
};
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
/* Structure describing the image type XBM. */
{
Display *dpy = FRAME_X_DISPLAY (f);
XImage *ximg, *mask_img;
- int x, y, rc, look_at_corners_p;
+ int x, y, rc, use_img_background;
unsigned long bg = 0;
if (img->mask)
{
XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
img->mask = None;
+ img->background_transparent_valid = 0;
}
/* Create an image and pixmap serving as mask. */
~0, ZPixmap);
/* Determine the background color of ximg. If HOW is `(R G B)'
- take that as color. Otherwise, try to determine the color
- heuristically. */
- look_at_corners_p = 1;
+ take that as color. Otherwise, use the image's background color. */
+ use_img_background = 1;
if (CONSP (how))
{
- int rgb[3], i = 0;
+ int rgb[3], i;
- while (i < 3
- && CONSP (how)
- && NATNUMP (XCAR (how)))
+ for (i = 0; i < 3 && CONSP (how) && NATNUMP (XCAR (how)); ++i)
{
rgb[i] = XFASTINT (XCAR (how)) & 0xffff;
how = XCDR (how);
if (i == 3 && NILP (how))
{
char color_name[30];
- XColor exact, color;
- Colormap cmap;
-
sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]);
-
- cmap = FRAME_X_COLORMAP (f);
- if (XLookupColor (dpy, cmap, color_name, &exact, &color))
- {
- bg = color.pixel;
- look_at_corners_p = 0;
- }
+ bg = x_alloc_image_color (f, img, build_string (color_name), 0);
+ use_img_background = 0;
}
}
- if (look_at_corners_p)
- {
- unsigned long corners[4];
- int i, best_count;
-
- /* Get the colors at the corners of ximg. */
- corners[0] = XGetPixel (ximg, 0, 0);
- corners[1] = XGetPixel (ximg, img->width - 1, 0);
- corners[2] = XGetPixel (ximg, img->width - 1, img->height - 1);
- corners[3] = XGetPixel (ximg, 0, img->height - 1);
-
- /* Choose the most frequently found color as background. */
- for (i = best_count = 0; i < 4; ++i)
- {
- int j, n;
-
- for (j = n = 0; j < 4; ++j)
- if (corners[i] == corners[j])
- ++n;
-
- if (n > best_count)
- bg = corners[i], best_count = n;
- }
- }
+ if (use_img_background)
+ bg = four_corners_best (ximg, img->width, img->height);
/* Set all bits in mask_img to 1 whose color in ximg is different
from the background color bg. */
for (x = 0; x < img->width; ++x)
XPutPixel (mask_img, x, y, XGetPixel (ximg, x, y) != bg);
+ /* Fill in the background_transparent field while we have the mask handy. */
+ image_background_transparent (img, f, mask_img);
+
/* Put mask_img into img->mask. */
x_put_x_image (f, mask_img, img->mask, img->width, img->height);
x_destroy_x_image (mask_img);
fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
if (fmt[PBM_BACKGROUND].count
&& STRINGP (fmt[PBM_BACKGROUND].value))
- bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
+ {
+ bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
+ img->background = bg;
+ img->background_valid = 1;
+ }
for (y = 0; y < height; ++y)
for (x = 0; x < width; ++x)
free the color table. */
img->colors = colors_in_color_table (&img->ncolors);
free_color_table ();
+
+ /* Maybe fill in the background field while we have ximg handy. */
+ if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+ IMAGE_BACKGROUND (img, f, ximg);
/* Put the image into a pixmap. */
x_put_x_image (f, ximg, img->pixmap, width, height);
PNG_ALGORITHM,
PNG_HEURISTIC_MASK,
PNG_MASK,
+ PNG_BACKGROUND,
PNG_LAST
};
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
/* Structure describing the image type `png'. */
simple transparency, we prefer a clipping mask. */
if (!transparent_p)
{
- png_color_16 *image_background;
+ png_color_16 *image_bg;
+ Lisp_Object specified_bg
+ = image_spec_value (img->spec, QCbackground, NULL);
+
+ if (STRINGP (specified_bg))
+ /* The user specified `:background', use that. */
+ {
+ XColor color;
+ if (x_defined_color (f, XSTRING (specified_bg)->data, &color, 0))
+ {
+ png_color_16 user_bg;
- if (png_get_bKGD (png_ptr, info_ptr, &image_background))
+ bzero (&user_bg, sizeof user_bg);
+ user_bg.red = color.red;
+ user_bg.green = color.green;
+ user_bg.blue = color.blue;
+
+ png_set_background (png_ptr, &user_bg,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+ }
+ }
+ else if (png_get_bKGD (png_ptr, info_ptr, &image_bg))
/* Image contains a background color with which to
combine the image. */
- png_set_background (png_ptr, image_background,
+ png_set_background (png_ptr, image_bg,
PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
else
{
}
}
+ if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+ /* Set IMG's background color from the PNG image, unless the user
+ overrode it. */
+ {
+ png_color_16 *bg;
+ if (png_get_bKGD (png_ptr, info_ptr, &bg))
+ {
+ img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
+ img->background_valid = 1;
+ }
+ }
+
/* Remember colors allocated for this image. */
img->colors = colors_in_color_table (&img->ncolors);
free_color_table ();
img->width = width;
img->height = height;
+ /* Maybe fill in the background field while we have ximg handy. */
+ IMAGE_BACKGROUND (img, f, ximg);
+
/* Put the image into the pixmap, then free the X image and its buffer. */
x_put_x_image (f, ximg, img->pixmap, width, height);
x_destroy_x_image (ximg);
/* Same for the mask. */
if (mask_img)
{
+ /* Fill in the background_transparent field while we have the mask
+ handy. */
+ image_background_transparent (img, f, mask_img);
+
x_put_x_image (f, mask_img, img->mask, img->width, img->height);
x_destroy_x_image (mask_img);
}
/* Work around a warning about HAVE_STDLIB_H being redefined in
jconfig.h. */
#ifdef HAVE_STDLIB_H
-#define HAVE_STDLIB_H_1
-#undef HAVE_STDLIB_H
-#endif /* HAVE_STLIB_H */
-
-#include <jpeglib.h>
+# undef HAVE_STDLIB_H
+# include <jpeglib.h>
+# undef HAVE_STDLIB_H
+# define HAVE_STDLIB_H 1
+#else
+# include <jpeglib.h>
+#endif /* HAVE_STDLIB_H */
#include <jerror.h>
-#include <setjmp.h>
-#ifdef HAVE_STLIB_H_1
-#define HAVE_STDLIB_H 1
-#endif
+#include <setjmp.h>
static int jpeg_image_p P_ ((Lisp_Object object));
static int jpeg_load P_ ((struct frame *f, struct image *img));
JPEG_ALGORITHM,
JPEG_HEURISTIC_MASK,
JPEG_MASK,
+ JPEG_BACKGROUND,
JPEG_LAST
};
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
/* Structure describing the image type `jpeg'. */
jpeg_destroy_decompress (&cinfo);
if (fp)
fclose ((FILE *) fp);
+
+ /* Maybe fill in the background field while we have ximg handy. */
+ if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+ IMAGE_BACKGROUND (img, f, ximg);
/* Put the image into the pixmap. */
x_put_x_image (f, ximg, img->pixmap, width, height);
TIFF_ALGORITHM,
TIFF_HEURISTIC_MASK,
TIFF_MASK,
+ TIFF_BACKGROUND,
TIFF_LAST
};
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
/* Structure describing the image type `tiff'. */
/* Remember the colors allocated for the image. Free the color table. */
img->colors = colors_in_color_table (&img->ncolors);
free_color_table ();
+
+ img->width = width;
+ img->height = height;
+
+ /* Maybe fill in the background field while we have ximg handy. */
+ if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+ IMAGE_BACKGROUND (img, f, ximg);
/* Put the image into the pixmap, then free the X image and its buffer. */
x_put_x_image (f, ximg, img->pixmap, width, height);
x_destroy_x_image (ximg);
xfree (buf);
-
- img->width = width;
- img->height = height;
UNGCPRO;
return 1;
GIF_HEURISTIC_MASK,
GIF_MASK,
GIF_IMAGE,
+ GIF_BACKGROUND,
GIF_LAST
};
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
+ {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
/* Structure describing the image type `gif'. */
return 0;
}
- width = img->width = gif->SWidth;
- height = img->height = gif->SHeight;
+ width = img->width = max (gif->SWidth, gif->Image.Left + gif->Image.Width);
+ height = img->height = max (gif->SHeight, gif->Image.Top + gif->Image.Height);
/* Create the X image and pixmap. */
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
}
DGifCloseFile (gif);
+
+ /* Maybe fill in the background field while we have ximg handy. */
+ if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+ IMAGE_BACKGROUND (img, f, ximg);
/* Put the image into the pixmap, then free the X image and its buffer. */
x_put_x_image (f, ximg, img->pixmap, width, height);
GS_ALGORITHM,
GS_HEURISTIC_MASK,
GS_MASK,
+ GS_BACKGROUND,
GS_LAST
};
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
/* Structure describing the image type `ghostscript'. */
struct frame *f = check_x_frame (frame);
Atom prop_atom;
- CHECK_STRING (prop, 1);
- CHECK_STRING (value, 2);
+ CHECK_STRING (prop);
+ CHECK_STRING (value);
BLOCK_INPUT;
prop_atom = XInternAtom (FRAME_X_DISPLAY (f), XSTRING (prop)->data, False);
struct frame *f = check_x_frame (frame);
Atom prop_atom;
- CHECK_STRING (prop, 1);
+ CHECK_STRING (prop);
BLOCK_INPUT;
prop_atom = XInternAtom (FRAME_X_DISPLAY (f), XSTRING (prop)->data, False);
XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
int actual_format;
unsigned long actual_size, bytes_remaining;
- CHECK_STRING (prop, 1);
+ CHECK_STRING (prop);
BLOCK_INPUT;
prop_atom = XInternAtom (FRAME_X_DISPLAY (f), XSTRING (prop)->data, False);
rc = XGetWindowProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
/* Move the tooltip window where the mouse pointer is. Resize and
show it. */
- if (!INTEGERP (left) && !INTEGERP (top))
+ if (!INTEGERP (left) || !INTEGERP (top))
{
BLOCK_INPUT;
XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
if (INTEGERP (left))
*root_x = XINT (left);
- else if (*root_x + XINT (dx) + width > FRAME_X_DISPLAY_INFO (f)->width)
+ else if (*root_x + XINT (dx) + width <= FRAME_X_DISPLAY_INFO (f)->width)
+ /* It fits to the right of the pointer. */
+ *root_x += XINT (dx);
+ else if (width + XINT (dx) <= *root_x)
+ /* It fits to the left of the pointer. */
*root_x -= width + XINT (dx);
else
- *root_x += XINT (dx);
+ /* Put it left-justified on the screen--it ought to fit that way. */
+ *root_x = 0;
}
GCPRO4 (string, parms, frame, timeout);
- CHECK_STRING (string, 0);
+ CHECK_STRING (string);
f = check_x_frame (frame);
if (NILP (timeout))
timeout = make_number (5);
else
- CHECK_NATNUM (timeout, 2);
+ CHECK_NATNUM (timeout);
if (NILP (dx))
dx = make_number (5);
else
- CHECK_NUMBER (dx, 5);
+ CHECK_NUMBER (dx);
if (NILP (dy))
dy = make_number (-10);
else
- CHECK_NUMBER (dy, 6);
+ CHECK_NUMBER (dy);
if (NILP (last_show_tip_args))
last_show_tip_args = Fmake_vector (make_number (3), Qnil);
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
GCPRO5 (prompt, dir, default_filename, mustmatch, file);
- CHECK_STRING (prompt, 0);
- CHECK_STRING (dir, 1);
+ CHECK_STRING (prompt);
+ CHECK_STRING (dir);
/* Prevent redisplay. */
specbind (Qinhibit_redisplay, Qt);
staticpro (&Qcancel_timer);
Qwait_for_wm = intern ("wait-for-wm");
staticpro (&Qwait_for_wm);
+ Qfullscreen = intern ("fullscreen");
+ staticpro (&Qfullscreen);
+ Qfullwidth = intern ("fullwidth");
+ staticpro (&Qfullwidth);
+ Qfullheight = intern ("fullheight");
+ staticpro (&Qfullheight);
+ Qfullboth = intern ("fullboth");
+ staticpro (&Qfullboth);
/* This is the end of symbol initialization. */
/* Text property `display' should be nonsticky by default. */
find_ccl_program_func = x_find_ccl_program;
query_font_func = x_query_font;
set_frame_fontset_func = x_set_font;
+ get_font_repertory_func = x_get_font_repertory;
check_window_system_func = check_x;
/* Images. */