/* X Communication module for terminals which understand the X protocol.
-Copyright (C) 1989, 1993-2013 Free Software Foundation, Inc.
+Copyright (C) 1989, 1993-2014 Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* Default to using XIM if available. */
#ifdef USE_XIM
-int use_xim = 1;
+bool use_xim = true;
#else
-int use_xim = 0; /* configure --without-xim */
+bool use_xim = false; /* configure --without-xim */
#endif
/* Non-zero means that a HELP_EVENT has been generated since Emacs
x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
- struct face *face;
-
- face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
- if (face)
- XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
- face->foreground);
+ struct face *face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
+ struct face *face_first = FACE_FROM_ID (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
+ struct face *face_last = FACE_FROM_ID (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
+ unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
+ unsigned long color_first = (face_first
+ ? face_first->foreground
+ : FRAME_FOREGROUND_PIXEL (f));
+ unsigned long color_last = (face_last
+ ? face_last->foreground
+ : FRAME_FOREGROUND_PIXEL (f));
+ Display *display = FRAME_X_DISPLAY (f);
+ Window window = FRAME_X_WINDOW (f);
- XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- f->output_data.x->normal_gc, x0, y0, x1 - x0, y1 - y0);
+ if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
+ /* Vertical. */
+ {
+ XSetForeground (display, f->output_data.x->normal_gc, color_first);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x0, y0, 1, y1 - y0);
+ XSetForeground (display, f->output_data.x->normal_gc, color);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x0 + 1, y0, x1 - x0 - 2, y1 - y0);
+ XSetForeground (display, f->output_data.x->normal_gc, color_last);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x1 - 1, y0, 1, y1 - y0);
+ }
+ else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
+ /* Horizontal. */
+ {
+ XSetForeground (display, f->output_data.x->normal_gc, color_first);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x0, y0, x1 - x0, 1);
+ XSetForeground (display, f->output_data.x->normal_gc, color);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x0, y0 + 1, x1 - x0, y1 - y0 - 2);
+ XSetForeground (display, f->output_data.x->normal_gc, color_last);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x0, y1 - 1, x1 - x0, 1);
+ }
+ else
+ {
+ XSetForeground (display, f->output_data.x->normal_gc, color);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x0, y0, x1 - x0, y1 - y0);
+ }
}
/* End update of window W.
}
+/* Clear under internal border if any for non-toolkit builds. */
+
+
+#if !defined USE_X_TOOLKIT && !defined USE_GTK
+void
+x_clear_under_internal_border (struct frame *f)
+{
+ if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
+ {
+ Display *display = FRAME_X_DISPLAY (f);
+ Window window = FRAME_X_WINDOW (f);
+ int border = FRAME_INTERNAL_BORDER_WIDTH (f);
+ int width = FRAME_PIXEL_WIDTH (f);
+ int height = FRAME_PIXEL_HEIGHT (f);
+ int margin = FRAME_TOP_MARGIN_HEIGHT (f);
+
+ block_input ();
+ x_clear_area (display, window, 0, 0, border, height);
+ x_clear_area (display, window, 0, margin, width, border);
+ x_clear_area (display, window, width - border, 0, border, height);
+ x_clear_area (display, window, 0, height - border, width, border);
+ unblock_input ();
+ }
+}
+#endif
+
/* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
arrow bitmaps, or clear the fringes if no bitmaps are required
before DESIRED_ROW is made current. This function is called from
static void
x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
{
- struct frame *f;
- int width, height;
-
eassert (w);
if (!desired_row->mode_line_p && !w->pseudo_window_p)
desired_row->redraw_fringe_bitmaps_p = 1;
+#ifdef USE_X_TOOLKIT
/* When a window has disappeared, make sure that no rest of
full-width rows stays visible in the internal border. Could
check here if updated window is the leftmost/rightmost window,
but I guess it's not worth doing since vertically split windows
are almost never used, internal border is rarely set, and the
overhead is very small. */
- if (windows_or_buffers_changed
- && desired_row->full_width_p
- && (f = XFRAME (w->frame),
- width = FRAME_INTERNAL_BORDER_WIDTH (f),
- width != 0)
- && (height = desired_row->visible_height,
- height > 0))
- {
- int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
+ {
+ struct frame *f;
+ int width, height;
+
+ if (windows_or_buffers_changed
+ && desired_row->full_width_p
+ && (f = XFRAME (w->frame),
+ width = FRAME_INTERNAL_BORDER_WIDTH (f),
+ width != 0)
+ && (height = desired_row->visible_height,
+ height > 0))
+ {
+ int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
- block_input ();
- x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- 0, y, width, height);
- x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- FRAME_PIXEL_WIDTH (f) - width,
- y, width, height);
- unblock_input ();
- }
+ block_input ();
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ 0, y, width, height);
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ FRAME_PIXEL_WIDTH (f) - width,
+ y, width, height);
+ unblock_input ();
+ }
+ }
+#endif
}
static void
/* Don't stop displaying the initial startup message
for a switch-frame event we don't need. */
/* When run as a daemon, Vterminal_frame is always NIL. */
- bufp->arg = (((NILP (Vterminal_frame) || EQ (Fdaemonp (), Qt))
+ bufp->arg = (((NILP (Vterminal_frame)
+ || ! FRAME_X_P (XFRAME (Vterminal_frame))
+ || EQ (Fdaemonp (), Qt))
&& CONSP (Vframe_list)
&& !NILP (XCDR (Vframe_list)))
? Qt : Qnil);
/* Compute the left edge and the width of the scroll bar area. */
left = WINDOW_SCROLL_BAR_AREA_X (w);
- width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
+ width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
/* Does the scroll bar exist yet? */
if (NILP (w->vertical_scroll_bar))
#ifdef USE_GTK
/* Don't pass keys to GTK. A Tab will shift focus to the
tool bar in GTK 2.4. Keys will still go to menus and
- dialogs because in that case popup_activated is TRUE
+ dialogs because in that case popup_activated is nonzero
(see above). */
*finish = X_EVENT_DROP;
#endif
|| event->xconfigure.height != FRAME_PIXEL_HEIGHT (f))
{
change_frame_size (f, width, height, 0, 1, 0, 1);
- SET_FRAME_GARBAGED (f);
+ x_clear_under_internal_border (f);
+ SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
}
x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
{
struct font *font = XFONT_OBJECT (font_object);
+ int unit;
if (fontset < 0)
fontset = fontset_from_font (font_object);
compute_fringe_widths (f, 1);
- /* Compute the scroll bar width in character columns. */
- if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
- {
- int wid = FRAME_COLUMN_WIDTH (f);
-
- FRAME_CONFIG_SCROLL_BAR_COLS (f)
- = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid;
- }
- else
- {
- int wid = FRAME_COLUMN_WIDTH (f);
-
- FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 14;
- FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
- }
+ unit = FRAME_COLUMN_WIDTH (f);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ /* The width of a toolkit scrollbar does not change with the new
+ font but we have to calculate the number of columns it occupies
+ anew. */
+ FRAME_CONFIG_SCROLL_BAR_COLS (f)
+ = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
+#else
+ /* The width of a non-toolkit scrollbar is at least 14 pixels and a
+ multiple of the frame's character width. */
+ FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
+ FRAME_CONFIG_SCROLL_BAR_WIDTH (f)
+ = FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit;
+#endif
if (FRAME_X_WINDOW (f) != 0)
{
int pixelwidth, pixelheight;
check_frame_size (f, &width, &height, pixelwise);
- f->scroll_bar_actual_width
- = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
- ? 0
- : FRAME_CONFIG_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f));
compute_fringe_widths (f, 0);
#endif
text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, FRAME_PIXEL_WIDTH (f));
text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelh);
- /* Update f->scroll_bar_actual_width because it is used in
- FRAME_PIXEL_WIDTH_TO_TEXT_COLS. */
- f->scroll_bar_actual_width
- = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
+
change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
}
#else /* not USE_GTK */
x_set_window_size_1 (f, change_gravity, width, height, pixelwise);
+#if !defined USE_X_TOOLKIT
+ x_clear_under_internal_border (f);
+#endif
#endif /* not USE_GTK */
size_hints.height = FRAME_PIXEL_HEIGHT (f);
size_hints.width = FRAME_PIXEL_WIDTH (f);
- size_hints.width_inc = FRAME_COLUMN_WIDTH (f);
- size_hints.height_inc = FRAME_LINE_HEIGHT (f);
+ size_hints.width_inc = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f);
+ size_hints.height_inc = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f);
+
size_hints.max_width = x_display_pixel_width (FRAME_DISPLAY_INFO (f))
- FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
size_hints.max_height = x_display_pixel_height (FRAME_DISPLAY_INFO (f))
check_frame_size (f, &min_cols, &min_rows, 0);
+ if (frame_resize_pixelwise)
+ /* Needed to prevent a bad protocol error crash when making the
+ frame size very small. */
+ {
+ min_cols = 2 * min_cols;
+ min_rows = 2 * min_rows;
+ }
+
/* The window manager uses the base width hints to calculate the
current number of rows and columns in the frame while
resizing; min_width and min_height aren't useful for this
size_hints.flags |= PBaseSize;
size_hints.base_width = base_width;
size_hints.base_height = base_height + FRAME_MENUBAR_HEIGHT (f);
- size_hints.min_width = base_width + min_cols * size_hints.width_inc;
- size_hints.min_height = base_height + min_rows * size_hints.height_inc;
+ size_hints.min_width = base_width + min_cols * FRAME_COLUMN_WIDTH (f);
+ size_hints.min_height = base_height + min_rows * FRAME_LINE_HEIGHT (f);
}
/* If we don't need the old flags, we don't need the old hint at all. */
if (STRINGP (value)
&& (!strcmp (SSDATA (value), "false")
|| !strcmp (SSDATA (value), "off")))
- use_xim = 0;
+ use_xim = false;
#else
if (STRINGP (value)
&& (!strcmp (SSDATA (value), "true")
|| !strcmp (SSDATA (value), "on")))
- use_xim = 1;
+ use_xim = true;
#endif
}