#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
extern void free_frame_menubar ();
extern double atof ();
-#endif /* USE_X_TOOLKIT */
+#ifdef USE_MOTIF
+
+/* LessTif/Motif version info. */
+
+static Lisp_Object Vmotif_version_string;
+
+#endif /* USE_MOTIF */
-#define min(a,b) ((a) < (b) ? (a) : (b))
-#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif /* USE_X_TOOLKIT */
#ifdef HAVE_X11R4
#define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
Lisp_Object Vx_resource_class;
-/* Non-zero means we're allowed to display a busy cursor. */
+/* Non-zero means we're allowed to display an hourglass cursor. */
-int display_busy_cursor_p;
+int display_hourglass_p;
/* The background and shape of the mouse pointer, and shape when not
over text or in the modeline. */
Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
-Lisp_Object Vx_busy_pointer_shape;
+Lisp_Object Vx_hourglass_pointer_shape;
/* The shape when over mouse-sensitive text. */
Lisp_Object Qauto_raise;
Lisp_Object Qauto_lower;
-Lisp_Object Qbar;
+Lisp_Object Qbar, Qhbar;
Lisp_Object Qborder_color;
Lisp_Object Qborder_width;
Lisp_Object Qbox;
Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
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");
dpyinfo = x_display_info_for_name (frame);
else
{
- FRAME_PTR f;
-
- CHECK_LIVE_FRAME (frame, 0);
- f = XFRAME (frame);
- if (! FRAME_X_P (f))
- error ("Non-X frame used");
+ FRAME_PTR f = check_x_frame (frame);
dpyinfo = FRAME_X_DISPLAY_INFO (f);
}
f = XFRAME (frame);
if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
continue;
- if (f->output_data.x->busy_window == wdesc)
+ if (f->output_data.x->hourglass_window == wdesc)
return f;
#ifdef USE_X_TOOLKIT
if ((f->output_data.x->edit_widget
{
/* This frame matches if the window is any of its widgets. */
x = f->output_data.x;
- if (x->busy_window == wdesc)
+ if (x->hourglass_window == wdesc)
found = f;
else if (x->widget)
{
continue;
x = f->output_data.x;
/* This frame matches if the window is any of its widgets. */
- if (x->busy_window == wdesc)
+ if (x->hourglass_window == wdesc)
return f;
else if (x->widget)
{
{
if (dpyinfo->bitmaps[id].refcount
&& dpyinfo->bitmaps[id].file
- && !strcmp (dpyinfo->bitmaps[id].file, (char *) XSTRING (file)->data))
+ && !strcmp (dpyinfo->bitmaps[id].file, (char *) SDATA (file)))
{
++dpyinfo->bitmaps[id].refcount;
return id + 1;
}
/* Search bitmap-file-path for the file, if appropriate. */
- fd = openp (Vx_bitmap_file_path, file, "", &found, 0);
+ fd = openp (Vx_bitmap_file_path, file, Qnil, &found, Qnil);
if (fd < 0)
return -1;
emacs_close (fd);
- filename = (char *) XSTRING (found)->data;
+ filename = (char *) SDATA (found);
result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
filename, &width, &height, &bitmap, &xhot, &yhot);
dpyinfo->bitmaps[id - 1].pixmap = bitmap;
dpyinfo->bitmaps[id - 1].refcount = 1;
dpyinfo->bitmaps[id - 1].file
- = (char *) xmalloc (STRING_BYTES (XSTRING (file)) + 1);
+ = (char *) xmalloc (SBYTES (file) + 1);
dpyinfo->bitmaps[id - 1].depth = 1;
dpyinfo->bitmaps[id - 1].height = height;
dpyinfo->bitmaps[id - 1].width = width;
- strcpy (dpyinfo->bitmaps[id - 1].file, XSTRING (file)->data);
+ strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file));
return id;
}
static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
static void x_change_window_heights P_ ((Lisp_Object, int));
static void x_disable_image P_ ((struct frame *, struct image *));
-static void x_create_im P_ ((struct frame *));
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
+ {"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;
- while (1)
+ count = x_catch_errors (FRAME_X_DISPLAY (f));
+
+ 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;
+ int success;
- XQueryTree (FRAME_X_DISPLAY (f), outer, &tmp_root_window,
- &f->output_data.x->parent_desc,
- &tmp_children, &tmp_nchildren);
- XFree ((char *) tmp_children);
+ success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
+ &wm_window, &tmp_children, &tmp_nchildren);
- 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;
+ /* Don't free tmp_children if XQueryTree failed. */
+ if (! success)
+ break;
+
+ XFree ((char *) tmp_children);
+
+ 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
an important optimization. */
- if (strcmp (XSTRING (color_name)->data, "black") == 0)
+ if (strcmp (SDATA (color_name), "black") == 0)
return BLACK_PIX_DEFAULT (f);
- else if (strcmp (XSTRING (color_name)->data, "white") == 0)
+ else if (strcmp (SDATA (color_name), "white") == 0)
return WHITE_PIX_DEFAULT (f);
#endif
/* x_defined_color is responsible for coping with failures
by looking for a near-miss. */
- if (x_defined_color (f, XSTRING (color_name)->data, &cdef, 1))
+ if (x_defined_color (f, SDATA (color_name), &cdef, 1))
return cdef.pixel;
Fsignal (Qerror, Fcons (build_string ("Undefined color"),
}
+/* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
+ the previous value of that parameter, NEW_VALUE is the new value.
+ See also the comment of wait_for_wm in struct x_output. */
+
+static void
+x_set_wait_for_wm (f, new_value, old_value)
+ struct frame *f;
+ Lisp_Object new_value, old_value;
+{
+ f->output_data.x->wait_for_wm = !NILP (new_value);
+}
+
+
+/* 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. */
+ the previous value of that parameter, NEW_VALUE is the new
+ value. */
static void
x_set_screen_gamma (f, new_value, old_value)
struct frame *f;
Lisp_Object arg, oldval;
{
- unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+ struct x_output *x = f->output_data.x;
+ unsigned long fg, old_fg;
- unload_color (f, f->output_data.x->foreground_pixel);
- f->output_data.x->foreground_pixel = pixel;
+ fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+ old_fg = x->foreground_pixel;
+ x->foreground_pixel = fg;
if (FRAME_X_WINDOW (f) != 0)
{
+ Display *dpy = FRAME_X_DISPLAY (f);
+
BLOCK_INPUT;
- XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
- f->output_data.x->foreground_pixel);
- XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc,
- f->output_data.x->foreground_pixel);
+ XSetForeground (dpy, x->normal_gc, fg);
+ XSetBackground (dpy, x->reverse_gc, fg);
+
+ if (x->cursor_pixel == old_fg)
+ {
+ unload_color (f, x->cursor_pixel);
+ x->cursor_pixel = x_copy_color (f, fg);
+ XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
+ }
+
UNBLOCK_INPUT;
+
update_face_from_frame_parameter (f, Qforeground_color, arg);
+
if (FRAME_VISIBLE_P (f))
redraw_frame (f);
}
+
+ unload_color (f, old_fg);
}
void
struct frame *f;
Lisp_Object arg, oldval;
{
- unsigned long pixel = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
+ struct x_output *x = f->output_data.x;
+ unsigned long bg;
- unload_color (f, f->output_data.x->background_pixel);
- f->output_data.x->background_pixel = pixel;
+ bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
+ unload_color (f, x->background_pixel);
+ x->background_pixel = bg;
if (FRAME_X_WINDOW (f) != 0)
{
+ Display *dpy = FRAME_X_DISPLAY (f);
+
BLOCK_INPUT;
- /* The main frame area. */
- XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
- f->output_data.x->background_pixel);
- XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc,
- f->output_data.x->background_pixel);
- XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc,
- f->output_data.x->background_pixel);
- XSetWindowBackground (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- f->output_data.x->background_pixel);
+ XSetBackground (dpy, x->normal_gc, bg);
+ XSetForeground (dpy, x->reverse_gc, bg);
+ XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
+ XSetForeground (dpy, x->cursor_gc, bg);
+
+#ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
+ toolkit scroll bars. */
{
Lisp_Object bar;
- for (bar = FRAME_SCROLL_BARS (f); !NILP (bar);
+ for (bar = FRAME_SCROLL_BARS (f);
+ !NILP (bar);
bar = XSCROLL_BAR (bar)->next)
- XSetWindowBackground (FRAME_X_DISPLAY (f),
- SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)),
- f->output_data.x->background_pixel);
+ {
+ Window window = SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar));
+ XSetWindowBackground (dpy, window, bg);
+ }
}
- UNBLOCK_INPUT;
+#endif /* USE_TOOLKIT_SCROLL_BARS */
+ UNBLOCK_INPUT;
update_face_from_frame_parameter (f, Qbackground_color, arg);
if (FRAME_VISIBLE_P (f))
struct frame *f;
Lisp_Object arg, oldval;
{
+ struct x_output *x = f->output_data.x;
+ Display *dpy = FRAME_X_DISPLAY (f);
Cursor cursor, nontext_cursor, mode_cursor, cross_cursor;
- Cursor busy_cursor, horizontal_drag_cursor;
+ Cursor hourglass_cursor, horizontal_drag_cursor;
int count;
unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
- unsigned long mask_color = f->output_data.x->background_pixel;
+ unsigned long mask_color = x->background_pixel;
/* Don't let pointers be invisible. */
- if (mask_color == pixel
- && mask_color == f->output_data.x->background_pixel)
+ if (mask_color == pixel)
{
x_free_colors (f, &pixel, 1);
- pixel = x_copy_color (f, f->output_data.x->foreground_pixel);
+ pixel = x_copy_color (f, x->foreground_pixel);
}
- unload_color (f, f->output_data.x->mouse_pixel);
- f->output_data.x->mouse_pixel = pixel;
+ unload_color (f, x->mouse_pixel);
+ x->mouse_pixel = pixel;
BLOCK_INPUT;
/* It's not okay to crash if the user selects a screwy cursor. */
- count = x_catch_errors (FRAME_X_DISPLAY (f));
+ count = x_catch_errors (dpy);
- if (!EQ (Qnil, Vx_pointer_shape))
+ if (!NILP (Vx_pointer_shape))
{
- CHECK_NUMBER (Vx_pointer_shape, 0);
- cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XINT (Vx_pointer_shape));
+ CHECK_NUMBER (Vx_pointer_shape);
+ cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
}
else
- cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_xterm);
- x_check_errors (FRAME_X_DISPLAY (f), "bad text pointer cursor: %s");
+ cursor = XCreateFontCursor (dpy, XC_xterm);
+ x_check_errors (dpy, "bad text pointer cursor: %s");
- if (!EQ (Qnil, Vx_nontext_pointer_shape))
+ if (!NILP (Vx_nontext_pointer_shape))
{
- CHECK_NUMBER (Vx_nontext_pointer_shape, 0);
- nontext_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f),
- XINT (Vx_nontext_pointer_shape));
+ CHECK_NUMBER (Vx_nontext_pointer_shape);
+ nontext_cursor
+ = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
}
else
- nontext_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_left_ptr);
- x_check_errors (FRAME_X_DISPLAY (f), "bad nontext pointer cursor: %s");
+ nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
+ x_check_errors (dpy, "bad nontext pointer cursor: %s");
- if (!EQ (Qnil, Vx_busy_pointer_shape))
+ if (!NILP (Vx_hourglass_pointer_shape))
{
- CHECK_NUMBER (Vx_busy_pointer_shape, 0);
- busy_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f),
- XINT (Vx_busy_pointer_shape));
+ CHECK_NUMBER (Vx_hourglass_pointer_shape);
+ hourglass_cursor
+ = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
}
else
- busy_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_watch);
- x_check_errors (FRAME_X_DISPLAY (f), "bad busy pointer cursor: %s");
+ hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
+ x_check_errors (dpy, "bad hourglass pointer cursor: %s");
- x_check_errors (FRAME_X_DISPLAY (f), "bad nontext pointer cursor: %s");
- if (!EQ (Qnil, Vx_mode_pointer_shape))
+ x_check_errors (dpy, "bad nontext pointer cursor: %s");
+ if (!NILP (Vx_mode_pointer_shape))
{
- CHECK_NUMBER (Vx_mode_pointer_shape, 0);
- mode_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f),
- XINT (Vx_mode_pointer_shape));
+ CHECK_NUMBER (Vx_mode_pointer_shape);
+ mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
}
else
- mode_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_xterm);
- x_check_errors (FRAME_X_DISPLAY (f), "bad modeline pointer cursor: %s");
+ mode_cursor = XCreateFontCursor (dpy, XC_xterm);
+ x_check_errors (dpy, "bad modeline pointer cursor: %s");
- if (!EQ (Qnil, Vx_sensitive_text_pointer_shape))
+ 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 (FRAME_X_DISPLAY (f),
- XINT (Vx_sensitive_text_pointer_shape));
+ = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
}
else
- cross_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_crosshair);
+ cross_cursor = XCreateFontCursor (dpy, XC_hand2);
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 (FRAME_X_DISPLAY (f),
- XINT (Vx_window_horizontal_drag_shape));
+ = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
}
else
horizontal_drag_cursor
- = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_h_double_arrow);
+ = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
/* Check and report errors with the above calls. */
- x_check_errors (FRAME_X_DISPLAY (f), "can't set cursor shape: %s");
- x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+ x_check_errors (dpy, "can't set cursor shape: %s");
+ x_uncatch_errors (dpy, count);
{
XColor fore_color, back_color;
- fore_color.pixel = f->output_data.x->mouse_pixel;
+ fore_color.pixel = x->mouse_pixel;
x_query_color (f, &fore_color);
back_color.pixel = mask_color;
x_query_color (f, &back_color);
- XRecolorCursor (FRAME_X_DISPLAY (f), cursor,
- &fore_color, &back_color);
- XRecolorCursor (FRAME_X_DISPLAY (f), nontext_cursor,
- &fore_color, &back_color);
- XRecolorCursor (FRAME_X_DISPLAY (f), mode_cursor,
- &fore_color, &back_color);
- XRecolorCursor (FRAME_X_DISPLAY (f), cross_cursor,
- &fore_color, &back_color);
- XRecolorCursor (FRAME_X_DISPLAY (f), busy_cursor,
- &fore_color, &back_color);
- XRecolorCursor (FRAME_X_DISPLAY (f), horizontal_drag_cursor,
- &fore_color, &back_color);
+ XRecolorCursor (dpy, cursor, &fore_color, &back_color);
+ XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
+ XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
+ XRecolorCursor (dpy, cross_cursor, &fore_color, &back_color);
+ XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
+ XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
}
if (FRAME_X_WINDOW (f) != 0)
- XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
-
- if (cursor != f->output_data.x->text_cursor
- && f->output_data.x->text_cursor != 0)
- XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->text_cursor);
- f->output_data.x->text_cursor = cursor;
-
- if (nontext_cursor != f->output_data.x->nontext_cursor
- && f->output_data.x->nontext_cursor != 0)
- XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->nontext_cursor);
- f->output_data.x->nontext_cursor = nontext_cursor;
-
- if (busy_cursor != f->output_data.x->busy_cursor
- && f->output_data.x->busy_cursor != 0)
- XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->busy_cursor);
- f->output_data.x->busy_cursor = busy_cursor;
-
- if (mode_cursor != f->output_data.x->modeline_cursor
- && f->output_data.x->modeline_cursor != 0)
- XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->modeline_cursor);
- f->output_data.x->modeline_cursor = mode_cursor;
-
- if (cross_cursor != f->output_data.x->cross_cursor
- && f->output_data.x->cross_cursor != 0)
- XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->cross_cursor);
- f->output_data.x->cross_cursor = cross_cursor;
-
- if (horizontal_drag_cursor != f->output_data.x->horizontal_drag_cursor
- && f->output_data.x->horizontal_drag_cursor != 0)
- XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->horizontal_drag_cursor);
- f->output_data.x->horizontal_drag_cursor = horizontal_drag_cursor;
+ XDefineCursor (dpy, FRAME_X_WINDOW (f), cursor);
+
+ if (cursor != x->text_cursor
+ && x->text_cursor != 0)
+ XFreeCursor (dpy, x->text_cursor);
+ x->text_cursor = cursor;
+
+ if (nontext_cursor != x->nontext_cursor
+ && x->nontext_cursor != 0)
+ XFreeCursor (dpy, x->nontext_cursor);
+ x->nontext_cursor = nontext_cursor;
+
+ if (hourglass_cursor != x->hourglass_cursor
+ && x->hourglass_cursor != 0)
+ XFreeCursor (dpy, x->hourglass_cursor);
+ x->hourglass_cursor = hourglass_cursor;
+
+ if (mode_cursor != x->modeline_cursor
+ && x->modeline_cursor != 0)
+ XFreeCursor (dpy, f->output_data.x->modeline_cursor);
+ x->modeline_cursor = mode_cursor;
+
+ if (cross_cursor != x->cross_cursor
+ && x->cross_cursor != 0)
+ XFreeCursor (dpy, x->cross_cursor);
+ x->cross_cursor = cross_cursor;
- XFlush (FRAME_X_DISPLAY (f));
+ if (horizontal_drag_cursor != x->horizontal_drag_cursor
+ && x->horizontal_drag_cursor != 0)
+ XFreeCursor (dpy, x->horizontal_drag_cursor);
+ x->horizontal_drag_cursor = horizontal_drag_cursor;
+
+ XFlush (dpy);
UNBLOCK_INPUT;
update_face_from_frame_parameter (f, Qmouse_color, arg);
{
unsigned long fore_pixel, pixel;
int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
+ struct x_output *x = f->output_data.x;
if (!NILP (Vx_cursor_fore_pixel))
{
fore_pixel_allocated_p = 1;
}
else
- fore_pixel = f->output_data.x->background_pixel;
+ fore_pixel = x->background_pixel;
pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
pixel_allocated_p = 1;
/* Make sure that the cursor color differs from the background color. */
- if (pixel == f->output_data.x->background_pixel)
+ if (pixel == x->background_pixel)
{
if (pixel_allocated_p)
{
pixel_allocated_p = 0;
}
- pixel = f->output_data.x->mouse_pixel;
+ pixel = x->mouse_pixel;
if (pixel == fore_pixel)
{
if (fore_pixel_allocated_p)
x_free_colors (f, &fore_pixel, 1);
fore_pixel_allocated_p = 0;
}
- fore_pixel = f->output_data.x->background_pixel;
+ fore_pixel = x->background_pixel;
}
}
- unload_color (f, f->output_data.x->cursor_foreground_pixel);
+ unload_color (f, x->cursor_foreground_pixel);
if (!fore_pixel_allocated_p)
fore_pixel = x_copy_color (f, fore_pixel);
- f->output_data.x->cursor_foreground_pixel = fore_pixel;
+ x->cursor_foreground_pixel = fore_pixel;
- unload_color (f, f->output_data.x->cursor_pixel);
+ unload_color (f, x->cursor_pixel);
if (!pixel_allocated_p)
pixel = x_copy_color (f, pixel);
- f->output_data.x->cursor_pixel = pixel;
+ x->cursor_pixel = pixel;
if (FRAME_X_WINDOW (f) != 0)
{
BLOCK_INPUT;
- XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc,
- f->output_data.x->cursor_pixel);
- XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc,
- fore_pixel);
+ XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
+ XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
UNBLOCK_INPUT;
if (FRAME_VISIBLE_P (f))
{
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);
type = BAR_CURSOR;
*width = XINT (XCDR (arg));
}
+ else if (EQ (arg, Qhbar))
+ {
+ type = HBAR_CURSOR;
+ *width = 2;
+ }
+ else if (CONSP (arg)
+ && EQ (XCAR (arg), Qhbar)
+ && INTEGERP (XCDR (arg))
+ && XINT (XCDR (arg)) >= 0)
+ {
+ type = HBAR_CURSOR;
+ *width = XINT (XCDR (arg));
+ }
else if (NILP (arg))
type = NO_CURSOR;
else
FRAME_DESIRED_CURSOR (f) = x_specified_cursor_type (arg, &width);
f->output_data.x->cursor_width = width;
- /* Make sure the cursor gets redrawn. This is overkill, but how
- often do people change cursor types? */
- update_mode_lines++;
+ /* Make sure the cursor gets redrawn. */
+ cursor_type_changed = 1;
}
\f
void
BLOCK_INPUT;
if (NILP (arg))
result = x_text_icon (f,
- (char *) XSTRING ((!NILP (f->icon_name)
+ (char *) SDATA ((!NILP (f->icon_name)
? f->icon_name
- : f->name))->data);
+ : f->name)));
else
result = x_bitmap_icon (f, arg);
BLOCK_INPUT;
result = x_text_icon (f,
- (char *) XSTRING ((!NILP (f->icon_name)
- ? f->icon_name
- : !NILP (f->title)
- ? f->title
- : f->name))->data);
+ (char *) SDATA ((!NILP (f->icon_name)
+ ? f->icon_name
+ : !NILP (f->title)
+ ? f->title
+ : f->name)));
if (result)
{
Lisp_Object result;
Lisp_Object fontset_name;
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, SDATA (fontset_name))
+ : x_new_font (f, SDATA (arg)));
UNBLOCK_INPUT;
if (EQ (result, Qnil))
- error ("Font `%s' is not defined", XSTRING (arg)->data);
+ error ("Font `%s' is not defined", SDATA (arg));
else if (EQ (result, Qt))
error ("The characters of the given font have varying widths");
else if (STRINGP (result))
{
+ 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 == f->output_data.x->fontset)
+ return;
+ }
+ else if (!NILP (Fequal (result, oldval)))
+ return;
+
store_frame_param (f, Qfont, result);
recompute_basic_faces (f);
}
}
}
+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
int delta, nlines, root_height;
Lisp_Object root_window;
+ /* Treat tool bars like menu bars. */
+ if (FRAME_MINIBUF_ONLY_P (f))
+ return;
+
/* Use VALUE only if an integer >= 0. */
if (INTEGERP (value) && XINT (value) >= 0)
nlines = XFASTINT (value);
int y = nlines * CANON_Y_UNIT (f);
BLOCK_INPUT;
- XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- 0, y, width, height, False);
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ 0, y, width, height, False);
UNBLOCK_INPUT;
+
+ if (WINDOWP (f->tool_bar_window))
+ clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
}
}
if (f->output_data.x->scroll_bar_background_pixel != -1)
unload_color (f, f->output_data.x->scroll_bar_background_pixel);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ /* Scrollbar shadow colors. */
+ if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
+ {
+ unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
+ f->output_data.x->scroll_bar_top_shadow_pixel = -1;
+ }
+ if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
+ {
+ unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
+ f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
+ }
+#endif /* USE_TOOLKIT_SCROLL_BARS */
+
f->output_data.x->scroll_bar_background_pixel = pixel;
if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
{
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));
+ unsigned char *str = SDATA (string);
+ int chars = SCHARS (string);
+ int bytes = SBYTES (string);
int charset_info;
int bufsize;
unsigned char *buf;
struct coding_system coding;
+ extern Lisp_Object Qcompound_text_with_extensions;
charset_info = find_charset_in_text (str, chars, bytes, NULL, Qnil);
if (charset_info == 0)
}
setup_coding_system (coding_system, &coding);
+ if (selectionp
+ && SYMBOLP (coding.pre_write_conversion)
+ && !NILP (Ffboundp (coding.pre_write_conversion)))
+ {
+ string = run_pre_post_conversion_on_str (string, &coding, 1);
+ str = SDATA (string);
+ chars = SCHARS (string);
+ bytes = SBYTES (string);
+ }
coding.src_multibyte = 1;
coding.dst_multibyte = 0;
coding.mode |= CODING_MODE_LAST_BLOCK;
buf = (unsigned char *) xmalloc (bufsize);
encode_coding (&coding, str, buf, bytes, bufsize);
*text_bytes = coding.produced;
- *stringp = (charset_info == 1 || !EQ (coding_system, Qcompound_text));
+ *stringp = (charset_info == 1
+ || (!EQ (coding_system, Qcompound_text)
+ && !EQ (coding_system, Qcompound_text_with_extensions)));
return buf;
}
/* Check for no change needed in this very common case
before we do any consing. */
if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
- XSTRING (f->name)->data))
+ SDATA (f->name)))
return;
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);
XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon);
#endif /* not USE_X_TOOLKIT */
if (!NILP (f->icon_name)
- && icon.value != XSTRING (f->icon_name)->data)
+ && icon.value != SDATA (f->icon_name))
xfree (icon.value);
- if (text.value != XSTRING (name)->data)
+ if (text.value != SDATA (name))
xfree (text.value);
}
#else /* not HAVE_X11R4 */
XSetIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- XSTRING (name)->data);
+ SDATA (name));
XStoreName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- XSTRING (name)->data);
+ SDATA (name));
#endif /* not HAVE_X11R4 */
UNBLOCK_INPUT;
}
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);
XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon);
#endif /* not USE_X_TOOLKIT */
if (!NILP (f->icon_name)
- && icon.value != XSTRING (f->icon_name)->data)
+ && icon.value != SDATA (f->icon_name))
xfree (icon.value);
- if (text.value != XSTRING (name)->data)
+ if (text.value != SDATA (name))
xfree (text.value);
}
#else /* not HAVE_X11R4 */
XSetIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- XSTRING (name)->data);
+ SDATA (name));
XStoreName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- XSTRING (name)->data);
+ SDATA (name));
#endif /* not HAVE_X11R4 */
UNBLOCK_INPUT;
}
if (STRINGP (Vx_resource_name))
{
- unsigned char *p = XSTRING (Vx_resource_name)->data;
+ unsigned char *p = SDATA (Vx_resource_name);
int i;
- len = STRING_BYTES (XSTRING (Vx_resource_name));
+ len = SBYTES (Vx_resource_name);
/* Only letters, digits, - and _ are valid in resource names.
Count the valid characters and count the invalid ones. */
for (i = 0; i < len; i++)
{
- int c = XSTRING (new)->data[i];
+ int c = SREF (new, i);
if (! ((c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z')
|| (c >= '0' && c <= '9')
|| c == '-' || c == '_'))
- XSTRING (new)->data[i] = '_';
+ SSET (new, i, '_');
}
}
extern char *x_get_string_resource ();
DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
- "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
-This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
-class, where INSTANCE is the name under which Emacs was invoked, or\n\
-the name specified by the `-name' or `-rn' command-line arguments.\n\
-\n\
-The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
-class, respectively. You must specify both of them or neither.\n\
-If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
-and the class is `Emacs.CLASS.SUBCLASS'.")
- (attribute, class, component, subclass)
+ 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.
+
+The optional arguments COMPONENT and SUBCLASS add to the key and the
+class, respectively. You must specify both of them or neither.
+If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
+and the class is `Emacs.CLASS.SUBCLASS'. */)
+ (attribute, class, component, subclass)
Lisp_Object attribute, class, component, subclass;
{
register char *value;
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");
/* Allocate space for the components, the dots which separate them,
and the final '\0'. Make them big enough for the worst case. */
- name_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_name))
+ name_key = (char *) alloca (SBYTES (Vx_resource_name)
+ (STRINGP (component)
- ? STRING_BYTES (XSTRING (component)) : 0)
- + STRING_BYTES (XSTRING (attribute))
+ ? SBYTES (component) : 0)
+ + SBYTES (attribute)
+ 3);
- class_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_class))
- + STRING_BYTES (XSTRING (class))
+ class_key = (char *) alloca (SBYTES (Vx_resource_class)
+ + SBYTES (class)
+ (STRINGP (subclass)
- ? STRING_BYTES (XSTRING (subclass)) : 0)
+ ? SBYTES (subclass) : 0)
+ 3);
/* Start with emacs.FRAMENAME for the name (the specific one)
and with `Emacs' for the class key (the general one). */
- strcpy (name_key, XSTRING (Vx_resource_name)->data);
- strcpy (class_key, XSTRING (Vx_resource_class)->data);
+ strcpy (name_key, SDATA (Vx_resource_name));
+ strcpy (class_key, SDATA (Vx_resource_class));
strcat (class_key, ".");
- strcat (class_key, XSTRING (class)->data);
+ strcat (class_key, SDATA (class));
if (!NILP (component))
{
strcat (class_key, ".");
- strcat (class_key, XSTRING (subclass)->data);
+ strcat (class_key, SDATA (subclass));
strcat (name_key, ".");
- strcat (name_key, XSTRING (component)->data);
+ strcat (name_key, SDATA (component));
}
strcat (name_key, ".");
- strcat (name_key, XSTRING (attribute)->data);
+ strcat (name_key, SDATA (attribute));
value = x_get_string_resource (check_x_display_info (Qnil)->xrdb,
name_key, class_key);
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");
/* Allocate space for the components, the dots which separate them,
and the final '\0'. Make them big enough for the worst case. */
- name_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_name))
+ name_key = (char *) alloca (SBYTES (Vx_resource_name)
+ (STRINGP (component)
- ? STRING_BYTES (XSTRING (component)) : 0)
- + STRING_BYTES (XSTRING (attribute))
+ ? SBYTES (component) : 0)
+ + SBYTES (attribute)
+ 3);
- class_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_class))
- + STRING_BYTES (XSTRING (class))
+ class_key = (char *) alloca (SBYTES (Vx_resource_class)
+ + SBYTES (class)
+ (STRINGP (subclass)
- ? STRING_BYTES (XSTRING (subclass)) : 0)
+ ? SBYTES (subclass) : 0)
+ 3);
/* Start with emacs.FRAMENAME for the name (the specific one)
and with `Emacs' for the class key (the general one). */
- strcpy (name_key, XSTRING (Vx_resource_name)->data);
- strcpy (class_key, XSTRING (Vx_resource_class)->data);
+ strcpy (name_key, SDATA (Vx_resource_name));
+ strcpy (class_key, SDATA (Vx_resource_class));
strcat (class_key, ".");
- strcat (class_key, XSTRING (class)->data);
+ strcat (class_key, SDATA (class));
if (!NILP (component))
{
strcat (class_key, ".");
- strcat (class_key, XSTRING (subclass)->data);
+ strcat (class_key, SDATA (subclass));
strcat (name_key, ".");
- strcat (name_key, XSTRING (component)->data);
+ strcat (name_key, SDATA (component));
}
strcat (name_key, ".");
- strcat (name_key, XSTRING (attribute)->data);
+ strcat (name_key, SDATA (attribute));
value = x_get_string_resource (dpyinfo->xrdb, name_key, class_key);
/* Allocate space for the components, the dots which separate them,
and the final '\0'. */
- name_key = (char *) alloca (STRING_BYTES (XSTRING (Vinvocation_name))
+ name_key = (char *) alloca (SBYTES (Vinvocation_name)
+ strlen (attribute) + 2);
class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
+ strlen (class) + 2);
sprintf (name_key, "%s.%s",
- XSTRING (Vinvocation_name)->data,
+ SDATA (Vinvocation_name),
attribute);
sprintf (class_key, "%s.%s", EMACS_CLASS, class);
switch (type)
{
case RES_TYPE_NUMBER:
- return make_number (atoi (XSTRING (tem)->data));
+ return make_number (atoi (SDATA (tem)));
case RES_TYPE_FLOAT:
- return make_float (atof (XSTRING (tem)->data));
+ return make_float (atof (SDATA (tem)));
case RES_TYPE_BOOLEAN:
tem = Fdowncase (tem);
- if (!strcmp (XSTRING (tem)->data, "on")
- || !strcmp (XSTRING (tem)->data, "true"))
+ if (!strcmp (SDATA (tem), "on")
+ || !strcmp (SDATA (tem), "true"))
return Qt;
else
return Qnil;
{
Lisp_Object lower;
lower = Fdowncase (tem);
- if (!strcmp (XSTRING (lower)->data, "on")
- || !strcmp (XSTRING (lower)->data, "true"))
+ if (!strcmp (SDATA (lower), "on")
+ || !strcmp (SDATA (lower), "true"))
return Qt;
- else if (!strcmp (XSTRING (lower)->data, "off")
- || !strcmp (XSTRING (lower)->data, "false"))
+ else if (!strcmp (SDATA (lower), "off")
+ || !strcmp (SDATA (lower), "false"))
return Qnil;
else
return Fintern (tem, Qnil);
build_string (foreground_p
? "foreground"
: "background"),
- build_string (""),
+ empty_string,
build_string ("verticalScrollBar"),
- build_string (""));
+ empty_string);
if (!STRINGP (tem))
{
/* If nothing has been specified, scroll bars will use a
\f
DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
- "Parse an X-style geometry string STRING.\n\
-Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
-The properties returned may include `top', `left', `height', and `width'.\n\
-The value of `left' or `top' may be an integer,\n\
-or a list (+ N) meaning N pixels relative to top/left corner,\n\
-or a list (- N) meaning -N pixels relative to bottom/right corner.")
+ doc: /* Parse an X-style geometry string STRING.
+Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
+The properties returned may include `top', `left', `height', and `width'.
+The value of `left' or `top' may be an integer,
+or a list (+ N) meaning N pixels relative to top/left corner,
+or a list (- N) meaning -N pixels relative to bottom/right corner. */)
(string)
Lisp_Object string;
{
unsigned int width, height;
Lisp_Object result;
- CHECK_STRING (string, 0);
+ CHECK_STRING (string);
- geometry = XParseGeometry ((char *) XSTRING (string)->data,
+ geometry = XParseGeometry ((char *) SDATA (string),
&x, &y, &width, &height);
#if 0
{
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;
}
/* Create XIC for frame F. */
+static XIMStyle xic_style;
+
void
create_frame_xic (f)
struct frame *f;
XIM xim;
XIC xic = NULL;
XFontSet xfs = NULL;
- static XIMStyle xic_style;
if (FRAME_XIC (f))
return;
{
/* Determine the base fontname from the ASCII font name of
FONTSET. */
- char *ascii_font = (char *) XSTRING (fontset_ascii (fontset))->data;
+ char *ascii_font = (char *) SDATA (fontset_ascii (fontset));
char *p = ascii_font;
int i;
Elsewhere we specify the window name for the window manager. */
{
- char *str = (char *) XSTRING (Vx_resource_name)->data;
+ char *str = (char *) SDATA (Vx_resource_name);
f->namebuf = (char *) xmalloc (strlen (str) + 1);
strcpy (f->namebuf, str);
}
validate_x_resource_name ();
- class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;
- class_hints.res_class = (char *) XSTRING (Vx_resource_class)->data;
+ class_hints.res_name = (char *) SDATA (Vx_resource_name);
+ class_hints.res_class = (char *) SDATA (Vx_resource_class);
XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
#ifdef HAVE_X_I18N
validate_x_resource_name ();
- class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;
- class_hints.res_class = (char *) XSTRING (Vx_resource_class)->data;
+ class_hints.res_name = (char *) SDATA (Vx_resource_name);
+ class_hints.res_class = (char *) SDATA (Vx_resource_class);
XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
/* The menubar is part of the ordinary display;
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");
? IconicState
: NormalState));
- x_text_icon (f, (char *) XSTRING ((!NILP (f->icon_name)
+ x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
? f->icon_name
- : f->name))->data);
+ : f->name)));
UNBLOCK_INPUT;
}
gray_bits, gray_width, gray_height,
f->output_data.x->foreground_pixel,
f->output_data.x->background_pixel,
- DefaultDepth (FRAME_X_DISPLAY (f),
- XScreenNumberOfScreen (FRAME_X_SCREEN (f)))));
+ DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
UNBLOCK_INPUT;
}
DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
1, 1, 0,
- "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
-Returns an Emacs frame object.\n\
-ALIST is an alist of frame parameters.\n\
-If the parameters specify that the frame should not have a minibuffer,\n\
-and do not specify a specific minibuffer window to use,\n\
-then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
-be shared by the new frame.\n\
-\n\
-This function is an internal primitive--use `make-frame' instead.")
- (parms)
+ doc: /* Make a new X window, which is called a "frame" in Emacs terms.
+Returns an Emacs frame object.
+ALIST is an alist of frame parameters.
+If the parameters specify that the frame should not have a minibuffer,
+and do not specify a specific minibuffer window to use,
+then `default-minibuffer-frame' must be a frame whose minibuffer can
+be shared by the new frame.
+
+This function is an internal primitive--use `make-frame' instead. */)
+ (parms)
Lisp_Object parms;
{
struct frame *f;
int minibuffer_only = 0;
long window_prompting = 0;
int width, height;
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
Lisp_Object display;
struct x_display_info *dpyinfo = NULL;
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
f->output_data.x->fontset = -1;
f->output_data.x->scroll_bar_foreground_pixel = -1;
f->output_data.x->scroll_bar_background_pixel = -1;
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ f->output_data.x->scroll_bar_top_shadow_pixel = -1;
+ f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
+#endif /* USE_TOOLKIT_SCROLL_BARS */
record_unwind_protect (unwind_create_frame, frame);
f->icon_name
{
Lisp_Object black;
struct gcpro gcpro1;
+
+ /* Function x_decode_color can signal an error. Make
+ sure to initialize color slots so that we won't try
+ to free colors we haven't allocated. */
+ f->output_data.x->foreground_pixel = -1;
+ f->output_data.x->background_pixel = -1;
+ f->output_data.x->cursor_pixel = -1;
+ f->output_data.x->cursor_foreground_pixel = -1;
+ f->output_data.x->border_pixel = -1;
+ f->output_data.x->mouse_pixel = -1;
black = build_string ("black");
GCPRO1 (black);
{
tem = Fquery_fontset (font, Qnil);
if (STRINGP (tem))
- font = x_new_fontset (f, XSTRING (tem)->data);
+ font = x_new_fontset (f, SDATA (tem));
else
- font = x_new_font (f, XSTRING (font)->data);
+ font = x_new_font (f, SDATA (font));
}
/* Try out a font which we hope has bold and italic variations. */
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",
RES_TYPE_SYMBOL);
x_default_parameter (f, parms, Qtitle, Qnil,
"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;
+
+ /* 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);
+ }
+
+ /* Compute the size of the X window. */
window_prompting = x_figure_window_size (f, parms);
if (window_prompting & XNegative)
tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
f->no_split = minibuffer_only || EQ (tem, Qt);
- /* Create the X widget or 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. */
- f->height += FRAME_TOOL_BAR_LINES (f);
-
+ /* Create the X widget or window. */
#ifdef USE_X_TOOLKIT
x_window (f, window_prompting, minibuffer_only);
#else
f->height. */
width = f->width;
height = f->height;
+
f->height = 0;
SET_FRAME_WIDTH (f, 0);
change_frame_size (f, height, width, 1, 0, 0);
}
UNGCPRO;
+
+ /* Make sure windows on this frame appear in calls to next-window
+ and similar functions. */
+ Vwindow_list = Qnil;
+
return unbind_to (count, frame);
}
following a user-command. */
DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
- "Set the input focus to FRAME.\n\
-FRAME nil means use the selected frame.")
- (frame)
+ doc: /* Set the input focus to FRAME.
+FRAME nil means use the selected frame. */)
+ (frame)
Lisp_Object frame;
{
struct frame *f = check_x_frame (frame);
\f
DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
- "Internal function called by `color-defined-p', which see.")
- (color, frame)
+ doc: /* Internal function called by `color-defined-p', which see. */)
+ (color, frame)
Lisp_Object color, frame;
{
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))
+ if (x_defined_color (f, SDATA (color), &foo, 0))
return Qt;
else
return Qnil;
}
DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
- "Internal function called by `color-values', which see.")
- (color, frame)
+ doc: /* Internal function called by `color-values', which see. */)
+ (color, frame)
Lisp_Object color, frame;
{
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))
+ if (x_defined_color (f, SDATA (color), &foo, 0))
{
Lisp_Object rgb[3];
}
DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
- "Internal function called by `display-color-p', which see.")
- (display)
+ doc: /* Internal function called by `display-color-p', which see. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
- 0, 1, 0,
- "Return t if the X display supports shades of gray.\n\
-Note that color displays do support shades of gray.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ 0, 1, 0,
+ doc: /* Return t if the X display supports shades of gray.
+Note that color displays do support shades of gray.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
- 0, 1, 0,
- "Returns the width in pixels of the X display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ 0, 1, 0,
+ doc: /* Returns the width in pixels of the X display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
- Sx_display_pixel_height, 0, 1, 0,
- "Returns the height in pixels of the X display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ Sx_display_pixel_height, 0, 1, 0,
+ doc: /* Returns the height in pixels of the X display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
- 0, 1, 0,
- "Returns the number of bitplanes of the X display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ 0, 1, 0,
+ doc: /* Returns the number of bitplanes of the X display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
- 0, 1, 0,
- "Returns the number of color cells of the X display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ 0, 1, 0,
+ doc: /* Returns the number of color cells of the X display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
Sx_server_max_request_size,
- 0, 1, 0,
- "Returns the maximum request size of the X server of display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ 0, 1, 0,
+ doc: /* Returns the maximum request size of the X server of display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
- "Returns the vendor ID string of the X server of display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ doc: /* Returns the vendor ID string of the X server of display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
- "Returns the version numbers of the X server of display DISPLAY.\n\
-The value is a list of three integers: the major and minor\n\
-version numbers of the X Protocol in use, and the vendor-specific release\n\
-number. See also the function `x-server-vendor'.\n\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ doc: /* Returns the version numbers of the X server of display DISPLAY.
+The value is a list of three integers: the major and minor
+version numbers of the X Protocol in use, and the vendor-specific release
+number. See also the function `x-server-vendor'.
+
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
- "Returns the number of screens on the X server of display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ doc: /* Return the number of screens on the X server of display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
- "Returns the height in millimeters of the X display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ doc: /* Return the height in millimeters of the X display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
- "Returns the width in millimeters of the X display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ doc: /* Return the width in millimeters of the X display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-display-backing-store", Fx_display_backing_store,
- Sx_display_backing_store, 0, 1, 0,
- "Returns an indication of whether X display DISPLAY does backing store.\n\
-The value may be `always', `when-mapped', or `not-useful'.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ Sx_display_backing_store, 0, 1, 0,
+ doc: /* Returns an indication of whether X display DISPLAY does backing store.
+The value may be `always', `when-mapped', or `not-useful'.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-display-visual-class", Fx_display_visual_class,
- Sx_display_visual_class, 0, 1, 0,
- "Returns the visual class of the X display DISPLAY.\n\
-The value is one of the symbols `static-gray', `gray-scale',\n\
-`static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ Sx_display_visual_class, 0, 1, 0,
+ doc: /* Return the visual class of the X display DISPLAY.
+The value is one of the symbols `static-gray', `gray-scale',
+`static-color', `pseudo-color', `true-color', or `direct-color'.
+
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
}
DEFUN ("x-display-save-under", Fx_display_save_under,
- Sx_display_save_under, 0, 1, 0,
- "Returns t if the X display DISPLAY supports the save-under feature.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
- (display)
+ Sx_display_save_under, 0, 1, 0,
+ doc: /* Returns t if the X display DISPLAY supports the save-under feature.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (display)
Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
{"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;
/* VALUE should be of the form CLASS-DEPTH, where CLASS is one
of `PseudoColor', `TrueColor' etc. and DEPTH is the color
depth, a decimal number. NAME is compared with case ignored. */
- char *s = (char *) alloca (STRING_BYTES (XSTRING (value)) + 1);
+ char *s = (char *) alloca (SBYTES (value) + 1);
char *dash;
int i, class = -1;
XVisualInfo vinfo;
- strcpy (s, XSTRING (value)->data);
+ strcpy (s, SDATA (value));
dash = index (s, '-');
if (dash)
{
if (class == -1
|| !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
dpyinfo->n_planes, class, &vinfo))
- fatal ("Invalid visual specification `%s'", XSTRING (value)->data);
+ fatal ("Invalid visual specification `%s'", SDATA (value));
dpyinfo->visual = vinfo.visual;
}
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");
validate_x_resource_name ();
dpyinfo = x_term_init (name, (char *)0,
- (char *) XSTRING (Vx_resource_name)->data);
+ (char *) SDATA (Vx_resource_name));
if (dpyinfo == 0)
- error ("Cannot connect to X server %s", XSTRING (name)->data);
+ error ("Cannot connect to X server %s", SDATA (name));
x_in_use = 1;
XSETFASTINT (Vwindow_system_version, 11);
DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
- 1, 3, 0, "Open a connection to an X server.\n\
-DISPLAY is the name of the display to connect to.\n\
-Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
-If the optional third arg MUST-SUCCEED is non-nil,\n\
-terminate Emacs if we can't open the connection.")
- (display, xrm_string, must_succeed)
+ 1, 3, 0,
+ doc: /* Open a connection to an X server.
+DISPLAY is the name of the display to connect to.
+Optional second arg XRM-STRING is a string of resources in xrdb format.
+If the optional third arg MUST-SUCCEED is non-nil,
+terminate Emacs if we can't open the connection. */)
+ (display, xrm_string, must_succeed)
Lisp_Object display, xrm_string, must_succeed;
{
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");
if (! NILP (xrm_string))
- xrm_option = (unsigned char *) XSTRING (xrm_string)->data;
+ xrm_option = (unsigned char *) SDATA (xrm_string);
else
xrm_option = (unsigned char *) 0;
/* This is what opens the connection and sets x_current_display.
This also initializes many symbols, such as those used for input. */
dpyinfo = x_term_init (display, xrm_option,
- (char *) XSTRING (Vx_resource_name)->data);
+ (char *) SDATA (Vx_resource_name));
if (dpyinfo == 0)
{
Check the DISPLAY environment variable or use `-d'.\n\
Also use the `xhost' program to verify that it is set to permit\n\
connections from your machine.\n",
- XSTRING (display)->data);
+ SDATA (display));
else
- error ("Cannot connect to X server %s", XSTRING (display)->data);
+ error ("Cannot connect to X server %s", SDATA (display));
}
x_in_use = 1;
DEFUN ("x-close-connection", Fx_close_connection,
Sx_close_connection, 1, 1, 0,
- "Close the connection to DISPLAY's X server.\n\
-For DISPLAY, specify either a frame or a display name (a string).\n\
-If DISPLAY is nil, that stands for the selected frame's display.")
- (display)
- Lisp_Object display;
+ doc: /* Close the connection to DISPLAY's X server.
+For DISPLAY, specify either a frame or a display name (a string).
+If DISPLAY is nil, that stands for the selected frame's display. */)
+ (display)
+ Lisp_Object display;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
int i;
}
DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
- "Return the list of display names that Emacs has connections to.")
- ()
+ doc: /* Return the list of display names that Emacs has connections to. */)
+ ()
{
Lisp_Object tail, result;
}
DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
- "If ON is non-nil, report X errors as soon as the erring request is made.\n\
-If ON is nil, allow buffering of requests.\n\
-Turning on synchronization prohibits the Xlib routines from buffering\n\
-requests and seriously degrades performance, but makes debugging much\n\
-easier.\n\
-The optional second argument DISPLAY specifies which display to act on.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If DISPLAY is omitted or nil, that stands for the selected frame's display.")
- (on, display)
+ doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
+If ON is nil, allow buffering of requests.
+Turning on synchronization prohibits the Xlib routines from buffering
+requests and seriously degrades performance, but makes debugging much
+easier.
+The optional second argument DISPLAY specifies which display to act on.
+DISPLAY should be either a frame or a display name (a string).
+If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
+ (on, display)
Lisp_Object display, on;
{
struct x_display_info *dpyinfo = check_x_display_info (display);
/* Keywords. */
extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
-extern Lisp_Object QCdata;
-Lisp_Object QCtype, QCascent, QCmargin, QCrelief;
+extern Lisp_Object QCdata, QCtype;
+Lisp_Object QCascent, QCmargin, QCrelief;
Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
if (CONSP (object) && EQ (XCAR (object), Qimage))
{
- Lisp_Object symbol = Fplist_get (XCDR (object), QCtype);
- struct image_type *type = lookup_image_type (symbol);
-
- if (type)
- valid_p = type->valid_p (object);
+ 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;
{
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,
/* Find key in KEYWORDS. Error if not found. */
for (i = 0; i < nkeywords; ++i)
- if (strcmp (keywords[i].name, XSYMBOL (key)->name->data) == 0)
+ if (strcmp (keywords[i].name, SDATA (SYMBOL_NAME (key))) == 0)
break;
if (i == nkeywords)
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;
DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,
- "Return the size of image SPEC as pair (WIDTH . HEIGHT).\n\
-PIXELS non-nil means return the size in pixels, otherwise return the\n\
-size in canonical character units.\n\
-FRAME is the frame on which the image will be displayed. FRAME nil\n\
-or omitted means use the selected frame.")
- (spec, pixels, frame)
+ doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
+PIXELS non-nil means return the size in pixels, otherwise return the
+size in canonical character units.
+FRAME is the frame on which the image will be displayed. FRAME nil
+or omitted means use the selected frame. */)
+ (spec, pixels, frame)
Lisp_Object spec, pixels, frame;
{
Lisp_Object size;
DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0,
- "Return t if image SPEC has a mask bitmap.\n\
-FRAME is the frame on which the image will be displayed. FRAME nil\n\
-or omitted means use the selected frame.")
- (spec, frame)
+ doc: /* Return t if image SPEC has a mask bitmap.
+FRAME is the frame on which the image will be displayed. FRAME nil
+or omitted means use the selected frame. */)
+ (spec, frame)
Lisp_Object spec, frame;
{
Lisp_Object mask;
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)
xassert (STRINGP (color_name));
- if (x_defined_color (f, XSTRING (color_name)->data, &color, 1))
+ if (x_defined_color (f, SDATA (color_name), &color, 1))
{
/* This isn't called frequently so we get away with simply
reallocating the color vector to the needed size, here. */
***********************************************************************/
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
DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
0, 1, 0,
- "Clear the image cache of FRAME.\n\
-FRAME nil or omitted means use the selected frame.\n\
-FRAME t means clear the image caches of all frames.")
- (frame)
+ doc: /* Clear the image cache of FRAME.
+FRAME nil or omitted means use the selected frame.
+FRAME t means clear the image caches of all frames. */)
+ (frame)
Lisp_Object frame;
{
if (EQ (frame, Qt))
}
+/* 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;
+{
+ /* 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 = None;
+ }
+ }
+
+
+ /* 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));
+ }
+ }
+}
+
+
/* Return the id of image with Lisp specification SPEC on frame F.
SPEC must be a valid Lisp image specification (see valid_image_p). */
/* 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);
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);
}
- /* 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;
- }
- }
- }
-
- /* Should we apply an image transformation algorithm? */
- if (img->pixmap)
+ if (! img->background_valid)
{
- Lisp_Object conversion;
-
- 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))
+ bg = image_spec_value (img->spec, QCbackground, NULL);
+ if (!NILP (bg))
{
- Lisp_Object tem;
- tem = XCDR (conversion);
- if (CONSP (tem))
- x_edge_detection (f, img,
- Fplist_get (tem, QCmatrix),
- Fplist_get (tem, QCcolor_adjustment));
+ 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))
+ postprocess_image (f, img);
}
UNBLOCK_INPUT;
GCPRO2 (file_found, search_path);
/* Try to find FILE in data-directory, then x-bitmap-file-path. */
- fd = openp (search_path, file, "", &file_found, 0);
+ fd = openp (search_path, file, Qnil, &file_found, Qnil);
if (fd == -1)
file_found = Qnil;
{":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_ASCENT_VALUE, 0},
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
if (STRINGP (elt))
{
- if (XSTRING (elt)->size
+ if (SCHARS (elt)
< (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR)
return 0;
}
}
else if (STRINGP (data))
{
- if (XSTRING (data)->size
+ if (SCHARS (data)
< (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR * height)
return 0;
}
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),
{
int w, h;
return (STRINGP (data)
- && xbm_read_bitmap_data (XSTRING (data)->data,
- (XSTRING (data)->data
- + STRING_BYTES (XSTRING (data))),
+ && xbm_read_bitmap_data (SDATA (data),
+ (SDATA (data)
+ + SBYTES (data)),
&w, &h, NULL));
}
return 0;
}
- contents = slurp_file (XSTRING (file)->data, &size);
+ contents = slurp_file (SDATA (file), &size);
if (contents == NULL)
{
image_error ("Error loading XBM image `%s'", img->spec, Qnil);
}
/* Get foreground and background colors, maybe allocate colors. */
- if (fmt[XBM_FOREGROUND].count)
+ if (fmt[XBM_FOREGROUND].count
+ && STRINGP (fmt[XBM_FOREGROUND].value))
foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value,
foreground);
- if (fmt[XBM_BACKGROUND].count)
+ if (fmt[XBM_BACKGROUND].count
+ && STRINGP (fmt[XBM_BACKGROUND].value))
background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value,
background);
if (in_memory_file_p)
- success_p = xbm_load_image (f, img, XSTRING (data)->data,
- (XSTRING (data)->data
- + STRING_BYTES (XSTRING (data))));
+ success_p = xbm_load_image (f, img, SDATA (data),
+ (SDATA (data)
+ + SBYTES (data)));
else
{
if (VECTORP (data))
{
Lisp_Object line = XVECTOR (data)->contents[i];
if (STRINGP (line))
- bcopy (XSTRING (line)->data, p, nbytes);
+ bcopy (SDATA (line), p, nbytes);
else
bcopy (XBOOL_VECTOR (line)->data, p, nbytes);
}
}
else if (STRINGP (data))
- bits = XSTRING (data)->data;
+ bits = SDATA (data);
else
bits = XBOOL_VECTOR (data)->data;
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. */
{
Lisp_Object name = XCAR (XCAR (tail));
Lisp_Object color = XCDR (XCAR (tail));
- xpm_syms[i].name = (char *) alloca (XSTRING (name)->size + 1);
- strcpy (xpm_syms[i].name, XSTRING (name)->data);
- xpm_syms[i].value = (char *) alloca (XSTRING (color)->size + 1);
- strcpy (xpm_syms[i].value, XSTRING (color)->data);
+ xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
+ strcpy (xpm_syms[i].name, SDATA (name));
+ xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
+ strcpy (xpm_syms[i].value, SDATA (color));
}
}
}
rc = XpmReadFileToPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- XSTRING (file)->data, &img->pixmap, &img->mask,
+ SDATA (file), &img->pixmap, &img->mask,
&attrs);
}
else
{
Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
rc = XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- XSTRING (buffer)->data,
+ SDATA (buffer),
&img->pixmap, &img->mask,
&attrs);
}
Algorithms
***********************************************************************/
-static void x_laplace_write_row P_ ((struct frame *, long *,
- int, XImage *, int));
-static void x_laplace_read_row P_ ((struct frame *, Colormap,
- XColor *, int, XImage *, int));
static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int));
static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *));
static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int));
{
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);
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":mask", 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}
};
/* Structure describing the image type `pbm'. */
return 0;
}
- contents = slurp_file (XSTRING (file)->data, &size);
+ contents = slurp_file (SDATA (file), &size);
if (contents == NULL)
{
image_error ("Error reading `%s'", file, Qnil);
{
Lisp_Object data;
data = image_spec_value (img->spec, QCdata, NULL);
- p = XSTRING (data)->data;
- end = p + STRING_BYTES (XSTRING (data));
+ p = SDATA (data);
+ end = p + SBYTES (data);
}
/* Check magic number. */
parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
/* Get foreground and background colors, maybe allocate colors. */
- if (fmt[PBM_FOREGROUND].count)
+ if (fmt[PBM_FOREGROUND].count
+ && STRINGP (fmt[PBM_FOREGROUND].value))
fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
- if (fmt[PBM_BACKGROUND].count)
- bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
+ if (fmt[PBM_BACKGROUND].count
+ && STRINGP (fmt[PBM_BACKGROUND].value))
+ {
+ 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'. */
png_byte channels;
png_uint_32 row_bytes;
int transparent_p;
- char *gamma_str;
double screen_gamma, image_gamma;
int intent;
struct png_memory_storage tbr; /* Data to be read */
}
/* Open the image file. */
- fp = fopen (XSTRING (file)->data, "rb");
+ fp = fopen (SDATA (file), "rb");
if (!fp)
{
image_error ("Cannot open image file `%s'", file, Qnil);
else
{
/* Read from memory. */
- tbr.bytes = XSTRING (specified_data)->data;
- tbr.len = STRING_BYTES (XSTRING (specified_data));
+ tbr.bytes = SDATA (specified_data);
+ tbr.len = SBYTES (specified_data);
tbr.index = 0;
/* Check PNG signature. */
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb (png_ptr);
- /* The value 2.2 is a guess for PC monitors from PNG example.c. */
- gamma_str = getenv ("SCREEN_GAMMA");
- screen_gamma = gamma_str ? atof (gamma_str) : 2.2;
+ screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2);
/* Tell the PNG lib to handle gamma correction for us. */
#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
if (png_get_sRGB (png_ptr, info_ptr, &intent))
- /* There is a special chunk in the image specifying the gamma. */
- png_set_sRGB (png_ptr, info_ptr, intent);
+ /* The libpng documentation says this is right in this case. */
+ png_set_gamma (png_ptr, screen_gamma, 0.45455);
else
#endif
if (png_get_gAMA (png_ptr, info_ptr, &image_gamma))
/* Image contains gamma information. */
png_set_gamma (png_ptr, screen_gamma, image_gamma);
else
- /* Use a default of 0.5 for the image gamma. */
- png_set_gamma (png_ptr, screen_gamma, 0.5);
+ /* Use the standard default for the image gamma. */
+ png_set_gamma (png_ptr, screen_gamma, 0.45455);
/* Handle alpha channel by combining the image with a background
color. Do this only if a real alpha channel is supplied. For
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, SDATA (specified_bg), &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);
}
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'. */
return 0;
}
- fp = fopen (XSTRING (file)->data, "r");
+ fp = fopen (SDATA (file), "r");
if (fp == NULL)
{
image_error ("Cannot open `%s'", file, Qnil);
if (NILP (specified_data))
jpeg_stdio_src (&cinfo, (FILE *) fp);
else
- jpeg_memory_src (&cinfo, XSTRING (specified_data)->data,
- STRING_BYTES (XSTRING (specified_data)));
+ jpeg_memory_src (&cinfo, SDATA (specified_data),
+ SBYTES (specified_data));
jpeg_read_header (&cinfo, TRUE);
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'. */
}
+static void
+tiff_error_handler (title, format, ap)
+ const char *title, *format;
+ va_list ap;
+{
+ char buf[512];
+ int len;
+
+ len = sprintf (buf, "TIFF error: %s ", title);
+ vsprintf (buf + len, format, ap);
+ add_to_log (buf, Qnil, Qnil);
+}
+
+
+static void
+tiff_warning_handler (title, format, ap)
+ const char *title, *format;
+ va_list ap;
+{
+ char buf[512];
+ int len;
+
+ len = sprintf (buf, "TIFF warning: %s ", title);
+ vsprintf (buf + len, format, ap);
+ add_to_log (buf, Qnil, Qnil);
+}
+
+
/* Load TIFF image IMG for use on frame F. Value is non-zero if
successful. */
file = Qnil;
GCPRO1 (file);
+ TIFFSetErrorHandler (tiff_error_handler);
+ TIFFSetWarningHandler (tiff_warning_handler);
+
if (NILP (specified_data))
{
/* Read from a file */
}
/* Try to open the image file. */
- tiff = TIFFOpen (XSTRING (file)->data, "r");
+ tiff = TIFFOpen (SDATA (file), "r");
if (tiff == NULL)
{
image_error ("Cannot open `%s'", file, Qnil);
else
{
/* Memory source! */
- memsrc.bytes = XSTRING (specified_data)->data;
- memsrc.len = STRING_BYTES (XSTRING (specified_data));
+ memsrc.bytes = SDATA (specified_data);
+ memsrc.len = SBYTES (specified_data);
memsrc.index = 0;
tiff = TIFFClientOpen ("memory_source", "r", &memsrc,
/* 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'. */
}
/* Open the GIF file. */
- gif = DGifOpenFileName (XSTRING (file)->data);
+ gif = DGifOpenFileName (SDATA (file));
if (gif == NULL)
{
image_error ("Cannot open `%s'", file, Qnil);
{
/* Read from memory! */
current_gif_memory_src = &memsrc;
- memsrc.bytes = XSTRING (specified_data)->data;
- memsrc.len = STRING_BYTES (XSTRING (specified_data));
+ memsrc.bytes = SDATA (specified_data);
+ memsrc.len = SBYTES (specified_data);
memsrc.index = 0;
gif = DGifOpen(&memsrc, gif_read_from_memory);
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'. */
if (c->images[i]->pixmap == pixmap)
break;
+ /* Should someone in between have cleared the image cache, for
+ instance, give up. */
+ if (i == c->used)
+ return;
+
/* Kill the GS process. We should have found PIXMAP in the image
cache and its image should contain a process object. */
- xassert (i < c->used);
img = c->images[i];
xassert (PROCESSP (img->data.lisp_val));
Fkill_process (img->data.lisp_val, Qnil);
UNBLOCK_INPUT;
}
+
+ /* Now that we have the pixmap, compute mask and transform the
+ image if requested. */
+ BLOCK_INPUT;
+ postprocess_image (f, img);
+ UNBLOCK_INPUT;
}
DEFUN ("x-change-window-property", Fx_change_window_property,
Sx_change_window_property, 2, 3, 0,
- "Change window property PROP to VALUE on the X window of FRAME.\n\
-PROP and VALUE must be strings. FRAME nil or omitted means use the\n\
-selected frame. Value is VALUE.")
- (prop, value, frame)
+ doc: /* Change window property PROP to VALUE on the X window of FRAME.
+PROP and VALUE must be strings. FRAME nil or omitted means use the
+selected frame. Value is VALUE. */)
+ (prop, value, frame)
Lisp_Object frame, prop, value;
{
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);
+ prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
prop_atom, XA_STRING, 8, PropModeReplace,
- XSTRING (value)->data, XSTRING (value)->size);
+ SDATA (value), SCHARS (value));
/* Make sure the property is set when we return. */
XFlush (FRAME_X_DISPLAY (f));
DEFUN ("x-delete-window-property", Fx_delete_window_property,
Sx_delete_window_property, 1, 2, 0,
- "Remove window property PROP from X window of FRAME.\n\
-FRAME nil or omitted means use the selected frame. Value is PROP.")
- (prop, frame)
+ doc: /* Remove window property PROP from X window of FRAME.
+FRAME nil or omitted means use the selected frame. Value is PROP. */)
+ (prop, frame)
Lisp_Object prop, frame;
{
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);
+ prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
/* Make sure the property is removed when we return. */
DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
1, 2, 0,
- "Value is the value of window property PROP on FRAME.\n\
-If FRAME is nil or omitted, use the selected frame. Value is nil\n\
-if FRAME hasn't a property with name PROP or if PROP has no string\n\
-value.")
- (prop, frame)
+ doc: /* Value is the value of window property PROP on FRAME.
+If FRAME is nil or omitted, use the selected frame. Value is nil
+if FRAME hasn't a property with name PROP or if PROP has no string
+value. */)
+ (prop, frame)
Lisp_Object prop, frame;
{
struct frame *f = check_x_frame (frame);
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);
+ prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
rc = XGetWindowProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
prop_atom, 0, 0, False, XA_STRING,
&actual_type, &actual_format, &actual_size,
&actual_type, &actual_format,
&actual_size, &bytes_remaining,
(unsigned char **) &tmp_data);
- if (rc == Success)
+ if (rc == Success && tmp_data)
prop_value = make_string (tmp_data, size);
XFree (tmp_data);
***********************************************************************/
/* If non-null, an asynchronous timer that, when it expires, displays
- a busy cursor on all frames. */
+ an hourglass cursor on all frames. */
-static struct atimer *busy_cursor_atimer;
+static struct atimer *hourglass_atimer;
-/* Non-zero means a busy cursor is currently shown. */
+/* Non-zero means an hourglass cursor is currently shown. */
-static int busy_cursor_shown_p;
+static int hourglass_shown_p;
-/* Number of seconds to wait before displaying a busy cursor. */
+/* Number of seconds to wait before displaying an hourglass cursor. */
-static Lisp_Object Vbusy_cursor_delay;
+static Lisp_Object Vhourglass_delay;
-/* Default number of seconds to wait before displaying a busy
+/* Default number of seconds to wait before displaying an hourglass
cursor. */
-#define DEFAULT_BUSY_CURSOR_DELAY 1
+#define DEFAULT_HOURGLASS_DELAY 1
/* Function prototypes. */
-static void show_busy_cursor P_ ((struct atimer *));
-static void hide_busy_cursor P_ ((void));
+static void show_hourglass P_ ((struct atimer *));
+static void hide_hourglass P_ ((void));
-/* Cancel a currently active busy-cursor timer, and start a new one. */
+/* Cancel a currently active hourglass timer, and start a new one. */
void
-start_busy_cursor ()
+start_hourglass ()
{
EMACS_TIME delay;
int secs, usecs = 0;
- cancel_busy_cursor ();
+ cancel_hourglass ();
- if (INTEGERP (Vbusy_cursor_delay)
- && XINT (Vbusy_cursor_delay) > 0)
- secs = XFASTINT (Vbusy_cursor_delay);
- else if (FLOATP (Vbusy_cursor_delay)
- && XFLOAT_DATA (Vbusy_cursor_delay) > 0)
+ if (INTEGERP (Vhourglass_delay)
+ && XINT (Vhourglass_delay) > 0)
+ secs = XFASTINT (Vhourglass_delay);
+ else if (FLOATP (Vhourglass_delay)
+ && XFLOAT_DATA (Vhourglass_delay) > 0)
{
Lisp_Object tem;
- tem = Ftruncate (Vbusy_cursor_delay, Qnil);
+ tem = Ftruncate (Vhourglass_delay, Qnil);
secs = XFASTINT (tem);
- usecs = (XFLOAT_DATA (Vbusy_cursor_delay) - secs) * 1000000;
+ usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
}
else
- secs = DEFAULT_BUSY_CURSOR_DELAY;
+ secs = DEFAULT_HOURGLASS_DELAY;
EMACS_SET_SECS_USECS (delay, secs, usecs);
- busy_cursor_atimer = start_atimer (ATIMER_RELATIVE, delay,
- show_busy_cursor, NULL);
+ hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
+ show_hourglass, NULL);
}
-/* Cancel the busy cursor timer if active, hide a busy cursor if
+/* Cancel the hourglass cursor timer if active, hide a busy cursor if
shown. */
void
-cancel_busy_cursor ()
+cancel_hourglass ()
{
- if (busy_cursor_atimer)
+ if (hourglass_atimer)
{
- cancel_atimer (busy_cursor_atimer);
- busy_cursor_atimer = NULL;
+ cancel_atimer (hourglass_atimer);
+ hourglass_atimer = NULL;
}
- if (busy_cursor_shown_p)
- hide_busy_cursor ();
+ if (hourglass_shown_p)
+ hide_hourglass ();
}
-/* Timer function of busy_cursor_atimer. TIMER is equal to
- busy_cursor_atimer.
+/* Timer function of hourglass_atimer. TIMER is equal to
+ hourglass_atimer.
- Display a busy cursor on all frames by mapping the frames'
- busy_window. Set the busy_p flag in the frames' output_data.x
- structure to indicate that a busy cursor is shown on the
- frames. */
+ Display an hourglass pointer on all frames by mapping the frames'
+ hourglass_window. Set the hourglass_p flag in the frames'
+ output_data.x structure to indicate that an hourglass cursor is
+ shown on the frames. */
static void
-show_busy_cursor (timer)
+show_hourglass (timer)
struct atimer *timer;
{
/* The timer implementation will cancel this timer automatically
- after this function has run. Set busy_cursor_atimer to null
+ after this function has run. Set hourglass_atimer to null
so that we know the timer doesn't have to be canceled. */
- busy_cursor_atimer = NULL;
+ hourglass_atimer = NULL;
- if (!busy_cursor_shown_p)
+ if (!hourglass_shown_p)
{
Lisp_Object rest, frame;
if (FRAME_OUTER_WINDOW (f))
#endif
{
- f->output_data.x->busy_p = 1;
+ f->output_data.x->hourglass_p = 1;
- if (!f->output_data.x->busy_window)
+ if (!f->output_data.x->hourglass_window)
{
unsigned long mask = CWCursor;
XSetWindowAttributes attrs;
- attrs.cursor = f->output_data.x->busy_cursor;
+ attrs.cursor = f->output_data.x->hourglass_cursor;
- f->output_data.x->busy_window
+ f->output_data.x->hourglass_window
= XCreateWindow (dpy, FRAME_OUTER_WINDOW (f),
0, 0, 32000, 32000, 0, 0,
InputOnly,
mask, &attrs);
}
- XMapRaised (dpy, f->output_data.x->busy_window);
+ XMapRaised (dpy, f->output_data.x->hourglass_window);
XFlush (dpy);
}
}
}
- busy_cursor_shown_p = 1;
+ hourglass_shown_p = 1;
UNBLOCK_INPUT;
}
}
-/* Hide the busy cursor on all frames, if it is currently shown. */
+/* Hide the hourglass pointer on all frames, if it is currently
+ shown. */
static void
-hide_busy_cursor ()
+hide_hourglass ()
{
- if (busy_cursor_shown_p)
+ if (hourglass_shown_p)
{
Lisp_Object rest, frame;
if (FRAME_X_P (f)
/* Watch out for newly created frames. */
- && f->output_data.x->busy_window)
+ && f->output_data.x->hourglass_window)
{
- XUnmapWindow (FRAME_X_DISPLAY (f), f->output_data.x->busy_window);
- /* Sync here because XTread_socket looks at the busy_p flag
- that is reset to zero below. */
+ XUnmapWindow (FRAME_X_DISPLAY (f),
+ f->output_data.x->hourglass_window);
+ /* Sync here because XTread_socket looks at the
+ hourglass_p flag that is reset to zero below. */
XSync (FRAME_X_DISPLAY (f), False);
- f->output_data.x->busy_p = 0;
+ f->output_data.x->hourglass_p = 0;
}
}
- busy_cursor_shown_p = 0;
+ hourglass_shown_p = 0;
UNBLOCK_INPUT;
}
}
***********************************************************************/
static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
- Lisp_Object));
+ Lisp_Object, Lisp_Object));
static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
- Lisp_Object, int *, int *));
+ Lisp_Object, int, int, int *, int *));
/* The frame of a currently visible tooltip. */
Lisp_Object last_show_tip_args;
+/* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
+
+Lisp_Object Vx_max_tooltip_size;
+
static Lisp_Object
unwind_create_tip_frame (frame)
/* Create a frame for a tooltip on the display described by DPYINFO.
- PARMS is a list of frame parameters. Value is the frame.
+ PARMS is a list of frame parameters. TEXT is the string to
+ display in the tip frame. Value is the frame.
Note that functions called here, esp. x_default_parameter can
signal errors, for instance when a specified color name is
when this happens. */
static Lisp_Object
-x_create_tip_frame (dpyinfo, parms)
+x_create_tip_frame (dpyinfo, parms, text)
struct x_display_info *dpyinfo;
- Lisp_Object parms;
+ Lisp_Object parms, text;
{
struct frame *f;
Lisp_Object frame, tem;
Lisp_Object name;
long window_prompting = 0;
int width, height;
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3;
struct kboard *kb;
int face_change_count_before = face_change_count;
+ Lisp_Object buffer;
+ struct buffer *old_buffer;
check_x ();
GCPRO3 (parms, name, frame);
f = make_frame (1);
XSETFRAME (frame, f);
+
+ buffer = Fget_buffer_create (build_string (" *tip*"));
+ Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer);
+ old_buffer = current_buffer;
+ set_buffer_internal_1 (XBUFFER (buffer));
+ current_buffer->truncate_lines = Qnil;
+ Ferase_buffer ();
+ Finsert (1, &text);
+ set_buffer_internal_1 (old_buffer);
+
FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
record_unwind_protect (unwind_create_tip_frame, frame);
f->output_data.x->fontset = -1;
f->output_data.x->scroll_bar_foreground_pixel = -1;
f->output_data.x->scroll_bar_background_pixel = -1;
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ f->output_data.x->scroll_bar_top_shadow_pixel = -1;
+ f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
+#endif /* USE_TOOLKIT_SCROLL_BARS */
f->icon_name = Qnil;
FRAME_X_DISPLAY_INFO (f) = dpyinfo;
#if GLYPH_DEBUG
{
tem = Fquery_fontset (font, Qnil);
if (STRINGP (tem))
- font = x_new_fontset (f, XSTRING (tem)->data);
+ font = x_new_fontset (f, SDATA (tem));
else
- font = x_new_font (f, XSTRING (font)->data);
+ font = x_new_font (f, SDATA (font));
}
/* Try out a font which we hope has bold and italic variations. */
change_frame_size (f, height, width, 1, 0, 0);
/* Set up faces after all frame parameters are known. This call
- also merges in face attributes specified for new frames. If we
- don't do this, the `menu' face for instance won't have the right
- colors, and the menu bar won't appear in the specified colors for
- new frames. */
- call1 (Qface_set_after_frame_default, frame);
+ also merges in face attributes specified for new frames.
+
+ Frame parameters may be changed if .Xdefaults contains
+ specifications for the default font. For example, if there is an
+ `Emacs.default.attributeBackground: pink', the `background-color'
+ attribute of the frame get's set, which let's the internal border
+ of the tooltip frame appear in pink. Prevent this. */
+ {
+ Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
+
+ /* Set tip_frame here, so that */
+ tip_frame = frame;
+ call1 (Qface_set_after_frame_default, frame);
+
+ if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
+ Qnil));
+ }
f->no_split = 1;
below. And the frame needs to be on Vframe_list or making it
visible won't work. */
Vframe_list = Fcons (frame, Vframe_list);
- tip_frame = frame;
/* Now that the frame is official, it counts as a reference to
its display. */
/* Compute where to display tip frame F. PARMS is the list of frame
parameters for F. DX and DY are specified offsets from the current
- location of the mouse. Return coordinates relative to the root
- window of the display in *ROOT_X, and *ROOT_Y. */
+ location of the mouse. WIDTH and HEIGHT are the width and height
+ of the tooltip. Return coordinates relative to the root window of
+ the display in *ROOT_X, and *ROOT_Y. */
static void
-compute_tip_xy (f, parms, dx, dy, root_x, root_y)
+compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
struct frame *f;
Lisp_Object parms, dx, dy;
+ int width, height;
int *root_x, *root_y;
{
Lisp_Object left, top;
/* Move the tooltip window where the mouse pointer is. Resize and
show it. */
- BLOCK_INPUT;
- XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
- &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
- UNBLOCK_INPUT;
+ if (!INTEGERP (left) || !INTEGERP (top))
+ {
+ BLOCK_INPUT;
+ XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
+ &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
+ UNBLOCK_INPUT;
+ }
- *root_x += XINT (dx);
- *root_y += XINT (dy);
-
- if (INTEGERP (left))
- *root_x = XINT (left);
if (INTEGERP (top))
*root_y = XINT (top);
+ else if (*root_y + XINT (dy) - height < 0)
+ *root_y -= XINT (dy);
+ else
+ {
+ *root_y -= height;
+ *root_y += XINT (dy);
+ }
+
+ if (INTEGERP (left))
+ *root_x = XINT (left);
+ 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
+ /* Put it left-justified on the screen--it ought to fit that way. */
+ *root_x = 0;
}
DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
- "Show STRING in a \"tooltip\" window on frame FRAME.\n\
-A tooltip window is a small X window displaying a string.\n\
-\n\
-FRAME nil or omitted means use the selected frame.\n\
-\n\
-PARMS is an optional list of frame parameters which can be\n\
-used to change the tooltip's appearance.\n\
-\n\
-Automatically hide the tooltip after TIMEOUT seconds.\n\
-TIMEOUT nil means use the default timeout of 5 seconds.\n\
-\n\
-If the list of frame parameters PARAMS contains a `left' parameters,\n\
-the tooltip is displayed at that x-position. Otherwise it is\n\
-displayed at the mouse position, with offset DX added (default is 5 if\n\
-DX isn't specified). Likewise for the y-position; if a `top' frame\n\
-parameter is specified, it determines the y-position of the tooltip\n\
-window, otherwise it is displayed at the mouse position, with offset\n\
-DY added (default is -10).")
- (string, frame, parms, timeout, dx, dy)
+ doc: /* Show STRING in a "tooltip" window on frame FRAME.
+A tooltip window is a small X window displaying a string.
+
+FRAME nil or omitted means use the selected frame.
+
+PARMS is an optional list of frame parameters which can be used to
+change the tooltip's appearance.
+
+Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
+means use the default timeout of 5 seconds.
+
+If the list of frame parameters PARAMS contains a `left' parameters,
+the tooltip is displayed at that x-position. Otherwise it is
+displayed at the mouse position, with offset DX added (default is 5 if
+DX isn't specified). Likewise for the y-position; if a `top' frame
+parameter is specified, it determines the y-position of the tooltip
+window, otherwise it is displayed at the mouse position, with offset
+DY added (default is -10).
+
+A tooltip's maximum size is specified by `x-max-tooltip-size'.
+Text larger than the specified size is clipped. */)
+ (string, frame, parms, timeout, dx, dy)
Lisp_Object string, frame, parms, timeout, dx, dy;
{
struct frame *f;
struct window *w;
- Lisp_Object buffer, top, left;
int root_x, root_y;
struct buffer *old_buffer;
struct text_pos pos;
int i, width, height;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
int old_windows_or_buffers_changed = windows_or_buffers_changed;
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
specbind (Qinhibit_redisplay, Qt);
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);
}
BLOCK_INPUT;
- compute_tip_xy (f, parms, dx, dy, &root_x, &root_y);
+ compute_tip_xy (f, parms, dx, dy, PIXEL_WIDTH (f),
+ PIXEL_HEIGHT (f), &root_x, &root_y);
XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- root_x, root_y - PIXEL_HEIGHT (f));
+ root_x, root_y);
UNBLOCK_INPUT;
goto start_timer;
}
/* Create a frame for the tooltip, and record it in the global
variable tip_frame. */
- frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms);
+ frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
f = XFRAME (frame);
- /* Set up the frame's root window. Currently we use a size of 80
- columns x 40 lines. If someone wants to show a larger tip, he
- will loose. I don't think this is a realistic case. */
+ /* Set up the frame's root window. */
w = XWINDOW (FRAME_ROOT_WINDOW (f));
w->left = w->top = make_number (0);
- w->width = make_number (80);
- w->height = make_number (40);
+
+ if (CONSP (Vx_max_tooltip_size)
+ && INTEGERP (XCAR (Vx_max_tooltip_size))
+ && XINT (XCAR (Vx_max_tooltip_size)) > 0
+ && INTEGERP (XCDR (Vx_max_tooltip_size))
+ && XINT (XCDR (Vx_max_tooltip_size)) > 0)
+ {
+ w->width = XCAR (Vx_max_tooltip_size);
+ w->height = XCDR (Vx_max_tooltip_size);
+ }
+ else
+ {
+ w->width = make_number (80);
+ w->height = make_number (40);
+ }
+
+ f->window_width = XINT (w->width);
adjust_glyphs (f);
w->pseudo_window_p = 1;
/* Display the tooltip text in a temporary buffer. */
- buffer = Fget_buffer_create (build_string (" *tip*"));
- Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer);
old_buffer = current_buffer;
- set_buffer_internal_1 (XBUFFER (buffer));
- Ferase_buffer ();
- Finsert (1, &string);
+ set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
+ current_buffer->truncate_lines = Qnil;
clear_glyph_matrix (w->desired_matrix);
clear_glyph_matrix (w->current_matrix);
SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
/* Move the tooltip window where the mouse pointer is. Resize and
show it. */
- compute_tip_xy (f, parms, dx, dy, &root_x, &root_y);
+ compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
BLOCK_INPUT;
XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- root_x, root_y - height, width, height);
+ root_x, root_y, width, height);
XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
UNBLOCK_INPUT;
DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
- "Hide the current tooltip window, if there is any.\n\
-Value is t is tooltip was open, nil otherwise.")
- ()
+ doc: /* Hide the current tooltip window, if there is any.
+Value is t if tooltip was open, nil otherwise. */)
+ ()
{
int count;
Lisp_Object deleted, frame, timer;
GCPRO2 (frame, timer);
tip_frame = tip_timer = deleted = Qnil;
- count = BINDING_STACK_SIZE ();
+ count = SPECPDL_INDEX ();
specbind (Qinhibit_redisplay, Qt);
specbind (Qinhibit_quit, Qt);
struct frame *f = SELECTED_FRAME ();
Widget w = f->output_data.x->menubar_widget;
extern void xlwmenu_redisplay P_ ((Widget));
-
+
if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
- && w != None)
+ && w != NULL)
{
BLOCK_INPUT;
xlwmenu_redisplay (w);
}
+/* Callback for unmapping a file selection dialog. This is used to
+ capture the case where a dialog is closed via a window manager's
+ closer button, for example. Using a XmNdestroyCallback didn't work
+ in this case. */
+
+static void
+file_dialog_unmap_cb (widget, client_data, call_data)
+ Widget widget;
+ XtPointer call_data, client_data;
+{
+ int *result = (int *) client_data;
+ *result = XmCR_CANCEL;
+}
+
+
DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
- "Read file name, prompting with PROMPT in directory DIR.\n\
-Use a file selection dialog.\n\
-Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
-specified. Don't let the user enter a file name in the file\n\
-selection dialog's entry field, if MUSTMATCH is non-nil.")
- (prompt, dir, default_filename, mustmatch)
+ doc: /* Read file name, prompting with PROMPT in directory DIR.
+Use a file selection dialog.
+Select DEFAULT-FILENAME in the dialog's file selection box, if
+specified. Don't let the user enter a file name in the file
+selection dialog's entry field, if MUSTMATCH is non-nil. */)
+ (prompt, dir, default_filename, mustmatch)
Lisp_Object prompt, dir, default_filename, mustmatch;
{
int result;
Arg al[10];
int ac = 0;
extern XtAppContext Xt_app_con;
- char *title;
XmString dir_xmstring, pattern_xmstring;
- int popup_activated_flag;
- int count = specpdl_ptr - specpdl;
+ int count = SPECPDL_INDEX ();
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);
/* Create the dialog with PROMPT as title, using DIR as initial
directory and using "*" as pattern. */
dir = Fexpand_file_name (dir, Qnil);
- dir_xmstring = XmStringCreateLocalized (XSTRING (dir)->data);
+ dir_xmstring = XmStringCreateLocalized (SDATA (dir));
pattern_xmstring = XmStringCreateLocalized ("*");
- XtSetArg (al[ac], XmNtitle, XSTRING (prompt)->data); ++ac;
+ XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
(XtPointer) &result);
XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
(XtPointer) &result);
+ XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
+ (XtPointer) &result);
/* Disable the help button since we can't display help. */
help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
int item_pos;
default_xmstring
- = XmStringCreateLocalized (XSTRING (default_filename)->data);
+ = XmStringCreateLocalized (SDATA (default_filename));
if (!XmListItemExists (list, default_xmstring))
{
XmListSetPos (list, item_pos);
}
-#ifdef HAVE_MOTIF_2_1
-
- /* Process events until the user presses Cancel or OK. */
+ /* Process events until the user presses Cancel or OK. Block
+ and unblock input here so that we get a chance of processing
+ expose events. */
+ UNBLOCK_INPUT;
result = 0;
- while (result == 0 || XtAppPending (Xt_app_con))
- XtAppProcessEvent (Xt_app_con, XtIMAll);
-
-#else /* not HAVE_MOTIF_2_1 */
-
- /* Process all events until the user presses Cancel or OK. */
- for (result = 0; result == 0;)
+ while (result == 0)
{
- XEvent event;
- Widget widget, parent;
-
- XtAppNextEvent (Xt_app_con, &event);
-
- /* See if the receiver of the event is one of the widgets of
- the file selection dialog. If so, dispatch it. If not,
- discard it. */
- widget = XtWindowToWidget (event.xany.display, event.xany.window);
- parent = widget;
- while (parent && parent != dialog)
- parent = XtParent (parent);
-
- if (parent == dialog
- || (event.type == Expose
- && !process_expose_from_menu (event)))
- XtDispatchEvent (&event);
+ BLOCK_INPUT;
+ XtAppProcessEvent (Xt_app_con, XtIMAll);
+ UNBLOCK_INPUT;
}
-
-#endif /* not HAVE_MOTIF_2_1 */
+ BLOCK_INPUT;
/* Get the result. */
if (result == XmCR_OK)
DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
Sx_backspace_delete_keys_p, 0, 1, 0,
- "Check if both Backspace and Delete keys are on the keyboard of FRAME.\n\
-FRAME nil means use the selected frame.\n\
-Value is t if we know that both keys are present, and are mapped to the\n\
-usual X keysyms.")
- (frame)
+ doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
+FRAME nil means use the selected frame.
+Value is t if we know that both keys are present, and are mapped to the
+usual X keysyms. */)
+ (frame)
Lisp_Object frame;
{
#ifdef HAVE_XKBGETKEYBOARD
&& (delete_keycode == 0 || backspace_keycode == 0));
++i)
{
- /* The XKB symbolic key names can be seen most easily
- in the PS file generated by `xkbprint -label name $DISPLAY'. */
+ /* The XKB symbolic key names can be seen most easily in
+ the PS file generated by `xkbprint -label name
+ $DISPLAY'. */
if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
delete_keycode = i;
else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
staticpro (&Qauto_lower);
Qbar = intern ("bar");
staticpro (&Qbar);
+ Qhbar = intern ("hbar");
+ staticpro (&Qhbar);
Qborder_color = intern ("border-color");
staticpro (&Qborder_color);
Qborder_width = intern ("border-width");
staticpro (&Qcompound_text);
Qcancel_timer = intern ("cancel-timer");
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. */
init_x_parm_symbols ();
DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images,
- "Non-nil means always draw a cross over disabled images.\n\
-Disabled images are those having an `:conversion disabled' property.\n\
-A cross is always drawn on black & white displays.");
+ doc: /* Non-nil means always draw a cross over disabled images.
+Disabled images are those having an `:conversion disabled' property.
+A cross is always drawn on black & white displays. */);
cross_disabled_images = 0;
DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
- "List of directories to search for bitmap files for X.");
+ doc: /* List of directories to search for bitmap files for X. */);
Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS);
DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
- "The shape of the pointer when over text.\n\
-Changing the value does not affect existing frames\n\
-unless you set the mouse color.");
+ doc: /* The shape of the pointer when over text.
+Changing the value does not affect existing frames
+unless you set the mouse color. */);
Vx_pointer_shape = Qnil;
DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
- "The name Emacs uses to look up X resources.\n\
-`x-get-resource' uses this as the first component of the instance name\n\
-when requesting resource values.\n\
-Emacs initially sets `x-resource-name' to the name under which Emacs\n\
-was invoked, or to the value specified with the `-name' or `-rn'\n\
-switches, if present.\n\
-\n\
-It may be useful to bind this variable locally around a call\n\
-to `x-get-resource'. See also the variable `x-resource-class'.");
+ doc: /* The name Emacs uses to look up X resources.
+`x-get-resource' uses this as the first component of the instance name
+when requesting resource values.
+Emacs initially sets `x-resource-name' to the name under which Emacs
+was invoked, or to the value specified with the `-name' or `-rn'
+switches, if present.
+
+It may be useful to bind this variable locally around a call
+to `x-get-resource'. See also the variable `x-resource-class'. */);
Vx_resource_name = Qnil;
DEFVAR_LISP ("x-resource-class", &Vx_resource_class,
- "The class Emacs uses to look up X resources.\n\
-`x-get-resource' uses this as the first component of the instance class\n\
-when requesting resource values.\n\
-Emacs initially sets `x-resource-class' to \"Emacs\".\n\
-\n\
-Setting this variable permanently is not a reasonable thing to do,\n\
-but binding this variable locally around a call to `x-get-resource'\n\
-is a reasonable practice. See also the variable `x-resource-name'.");
+ doc: /* The class Emacs uses to look up X resources.
+`x-get-resource' uses this as the first component of the instance class
+when requesting resource values.
+
+Emacs initially sets `x-resource-class' to "Emacs".
+
+Setting this variable permanently is not a reasonable thing to do,
+but binding this variable locally around a call to `x-get-resource'
+is a reasonable practice. See also the variable `x-resource-name'. */);
Vx_resource_class = build_string (EMACS_CLASS);
#if 0 /* This doesn't really do anything. */
DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
- "The shape of the pointer when not over text.\n\
-This variable takes effect when you create a new frame\n\
-or when you set the mouse color.");
+ doc: /* The shape of the pointer when not over text.
+This variable takes effect when you create a new frame
+or when you set the mouse color. */);
#endif
Vx_nontext_pointer_shape = Qnil;
- DEFVAR_LISP ("x-busy-pointer-shape", &Vx_busy_pointer_shape,
- "The shape of the pointer when Emacs is busy.\n\
-This variable takes effect when you create a new frame\n\
-or when you set the mouse color.");
- Vx_busy_pointer_shape = Qnil;
+ DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
+ doc: /* The shape of the pointer when Emacs is busy.
+This variable takes effect when you create a new frame
+or when you set the mouse color. */);
+ Vx_hourglass_pointer_shape = Qnil;
- DEFVAR_BOOL ("display-busy-cursor", &display_busy_cursor_p,
- "Non-zero means Emacs displays a busy cursor on window systems.");
- display_busy_cursor_p = 1;
+ DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
+ doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
+ display_hourglass_p = 1;
- DEFVAR_LISP ("busy-cursor-delay", &Vbusy_cursor_delay,
- "*Seconds to wait before displaying a busy-cursor.\n\
-Value must be an integer or float.");
- Vbusy_cursor_delay = make_number (DEFAULT_BUSY_CURSOR_DELAY);
+ DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
+ doc: /* *Seconds to wait before displaying an hourglass pointer.
+Value must be an integer or float. */);
+ Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
#if 0 /* This doesn't really do anything. */
DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
- "The shape of the pointer when over the mode line.\n\
-This variable takes effect when you create a new frame\n\
-or when you set the mouse color.");
+ doc: /* The shape of the pointer when over the mode line.
+This variable takes effect when you create a new frame
+or when you set the mouse color. */);
#endif
Vx_mode_pointer_shape = Qnil;
DEFVAR_LISP ("x-sensitive-text-pointer-shape",
&Vx_sensitive_text_pointer_shape,
- "The shape of the pointer when over mouse-sensitive text.\n\
-This variable takes effect when you create a new frame\n\
-or when you set the mouse color.");
+ doc: /* The shape of the pointer when over mouse-sensitive text.
+This variable takes effect when you create a new frame
+or when you set the mouse color. */);
Vx_sensitive_text_pointer_shape = Qnil;
DEFVAR_LISP ("x-window-horizontal-drag-cursor",
&Vx_window_horizontal_drag_shape,
- "Pointer shape to use for indicating a window can be dragged horizontally.\n\
-This variable takes effect when you create a new frame\n\
-or when you set the mouse color.");
+ doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
+This variable takes effect when you create a new frame
+or when you set the mouse color. */);
Vx_window_horizontal_drag_shape = Qnil;
DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
- "A string indicating the foreground color of the cursor box.");
+ doc: /* A string indicating the foreground color of the cursor box. */);
Vx_cursor_fore_pixel = Qnil;
+ DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
+ doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
+Text larger than this is clipped. */);
+ Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
+
DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
- "Non-nil if no X window manager is in use.\n\
-Emacs doesn't try to figure this out; this is always nil\n\
-unless you set it to something else.");
+ doc: /* Non-nil if no X window manager is in use.
+Emacs doesn't try to figure this out; this is always nil
+unless you set it to something else. */);
/* We don't have any way to find this out, so set it to nil
and maybe the user would like to set it to t. */
Vx_no_window_manager = Qnil;
DEFVAR_LISP ("x-pixel-size-width-font-regexp",
&Vx_pixel_size_width_font_regexp,
- "Regexp matching a font name whose width is the same as `PIXEL_SIZE'.\n\
-\n\
-Since Emacs gets width of a font matching with this regexp from\n\
-PIXEL_SIZE field of the name, font finding mechanism gets faster for\n\
-such a font. This is especially effective for such large fonts as\n\
-Chinese, Japanese, and Korean.");
+ doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
+
+Since Emacs gets width of a font matching with this regexp from
+PIXEL_SIZE field of the name, font finding mechanism gets faster for
+such a font. This is especially effective for such large fonts as
+Chinese, Japanese, and Korean. */);
Vx_pixel_size_width_font_regexp = Qnil;
DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay,
- "Time after which cached images are removed from the cache.\n\
-When an image has not been displayed this many seconds, remove it\n\
-from the image cache. Value must be an integer or nil with nil\n\
-meaning don't clear the cache.");
+ doc: /* Time after which cached images are removed from the cache.
+When an image has not been displayed this many seconds, remove it
+from the image cache. Value must be an integer or nil with nil
+meaning don't clear the cache. */);
Vimage_cache_eviction_delay = make_number (30 * 60);
#ifdef USE_X_TOOLKIT
- Fprovide (intern ("x-toolkit"));
-#endif
+ Fprovide (intern ("x-toolkit"), Qnil);
#ifdef USE_MOTIF
- Fprovide (intern ("motif"));
-#endif
+ Fprovide (intern ("motif"), Qnil);
+
+ DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
+ doc: /* Version info for LessTif/Motif. */);
+ Vmotif_version_string = build_string (XmVERSION_STRING);
+#endif /* USE_MOTIF */
+#endif /* USE_X_TOOLKIT */
defsubr (&Sx_get_resource);
/* Images. */
Qxbm = intern ("xbm");
staticpro (&Qxbm);
- QCtype = intern (":type");
- staticpro (&QCtype);
QCconversion = intern (":conversion");
staticpro (&QCconversion);
QCheuristic_mask = intern (":heuristic-mask");
defsubr (&Simage_size);
defsubr (&Simage_mask_p);
- busy_cursor_atimer = NULL;
- busy_cursor_shown_p = 0;
+ hourglass_atimer = NULL;
+ hourglass_shown_p = 0;
defsubr (&Sx_show_tip);
defsubr (&Sx_hide_tip);