/* X Communication module for terminals which understand the X protocol.
- Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 1999, 2000,01,02,03,04
- Free Software Foundation, Inc.
+ Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#ifdef HAVE_XAW3D
#include <X11/Xaw3d/Simple.h>
#include <X11/Xaw3d/Scrollbar.h>
-#define ARROW_SCROLLBAR
-#define XAW_ARROW_SCROLLBARS
-#include <X11/Xaw3d/ScrollbarP.h>
+#include <X11/Xaw3d/ThreeD.h>
#else /* !HAVE_XAW3D */
#include <X11/Xaw/Simple.h>
#include <X11/Xaw/Scrollbar.h>
static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
enum text_cursor_kinds));
-static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC));
+static void x_clip_to_row P_ ((struct window *, struct glyph_row *, int, GC));
static void x_flush P_ ((struct frame *f));
static void x_update_begin P_ ((struct frame *));
static void x_update_window_begin P_ ((struct window *));
output_cursor.vpos,
output_cursor.x, output_cursor.y);
- x_draw_vertical_border (w);
-
- draw_window_fringes (w);
+ if (draw_window_fringes (w, 1))
+ x_draw_vertical_border (w);
UNBLOCK_INPUT;
}
int oldVH = row->visible_height;
row->visible_height = p->h;
row->y -= rowY - p->y;
- x_clip_to_row (w, row, gc);
+ x_clip_to_row (w, row, -1, gc);
row->y = oldY;
row->visible_height = oldVH;
}
else
- x_clip_to_row (w, row, gc);
+ x_clip_to_row (w, row, -1, gc);
if (p->bx >= 0 && !p->overlay_p)
{
struct glyph *last_glyph;
XRectangle clip_rect;
- last_x = window_box_right (s->w, s->area);
- if (s->row->full_width_p
- && !s->w->pseudo_window_p)
- {
- last_x += WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s->w);
- if (s->area != RIGHT_MARGIN_AREA
- || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w))
- last_x += WINDOW_RIGHT_FRINGE_WIDTH (s->w);
- }
+ last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
+ ? WINDOW_RIGHT_EDGE_X (s->w)
+ : window_box_right (s->w, s->area));
/* The glyph that may have a right box line. */
last_glyph = (s->cmp || s->img
XFlush (FRAME_X_DISPLAY (f));
-#ifdef USE_GTK
- xg_frame_cleared (f);
-#endif
-
UNBLOCK_INPUT;
}
Alt keysyms are on. */
{
int row, col; /* The row and column in the modifier table. */
+ int found_alt_or_meta;
for (row = 3; row < 8; row++)
+ {
+ found_alt_or_meta = 0;
for (col = 0; col < mods->max_keypermod; col++)
{
- KeyCode code
- = mods->modifiermap[(row * mods->max_keypermod) + col];
+ KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
/* Zeroes are used for filler. Skip them. */
if (code == 0)
{
case XK_Meta_L:
case XK_Meta_R:
+ found_alt_or_meta = 1;
dpyinfo->meta_mod_mask |= (1 << row);
break;
case XK_Alt_L:
case XK_Alt_R:
+ found_alt_or_meta = 1;
dpyinfo->alt_mod_mask |= (1 << row);
break;
case XK_Hyper_L:
case XK_Hyper_R:
- dpyinfo->hyper_mod_mask |= (1 << row);
+ if (!found_alt_or_meta)
+ dpyinfo->hyper_mod_mask |= (1 << row);
+ code_col = syms_per_code;
+ col = mods->max_keypermod;
break;
case XK_Super_L:
case XK_Super_R:
- dpyinfo->super_mod_mask |= (1 << row);
+ if (!found_alt_or_meta)
+ dpyinfo->super_mod_mask |= (1 << row);
+ code_col = syms_per_code;
+ col = mods->max_keypermod;
break;
case XK_Shift_Lock:
/* Ignore this if it's not on the lock modifier. */
- if ((1 << row) == LockMask)
+ if (!found_alt_or_meta && ((1 << row) == LockMask))
dpyinfo->shift_lock_mask = LockMask;
+ code_col = syms_per_code;
+ col = mods->max_keypermod;
break;
}
}
}
}
+ }
}
/* If we couldn't find any meta keys, accept any alt keys as meta keys. */
{
Lisp_Object tail;
-#ifdef USE_GTK
+#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
-#endif /* USE_GTK */
+#endif /* USE_GTK && USE_TOOLKIT_SCROLL_BARS */
for (tail = Vframe_list;
XGCTYPE (tail) == Lisp_Cons;
int part = -1, whole = 0, portion = 0;
GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (widget));
- if (xg_ignore_gtk_scrollbar) return;
-
position = gtk_adjustment_get_value (adj);
p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA);
previous = *p;
*p = position;
+ if (xg_ignore_gtk_scrollbar) return;
+
diff = (int) (position - previous);
if (diff == (int) adj->step_increment)
f->output_data.x->scroll_bar_bottom_shadow_pixel = pixel;
}
+#ifdef XtNbeNiceToColormap
/* Tell the toolkit about them. */
if (f->output_data.x->scroll_bar_top_shadow_pixel == -1
|| f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
pixel = f->output_data.x->scroll_bar_top_shadow_pixel;
if (pixel != -1)
{
- XtSetArg (av[ac], "topShadowPixel", pixel);
+ XtSetArg (av[ac], XtNtopShadowPixel, pixel);
++ac;
}
pixel = f->output_data.x->scroll_bar_bottom_shadow_pixel;
if (pixel != -1)
{
- XtSetArg (av[ac], "bottomShadowPixel", pixel);
+ XtSetArg (av[ac], XtNbottomShadowPixel, pixel);
++ac;
}
}
+#endif
widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
f->output_data.x->edit_widget, av, ac);
XawScrollbarSetThumb (widget, top, shown);
else
{
-#ifdef HAVE_XAW3D
- ScrollbarWidget sb = (ScrollbarWidget) widget;
- int scroll_mode = 0;
-
- /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */
- if (xaw3d_arrow_scroll)
- {
- /* Xaw3d stupidly ignores resize requests while dragging
- so we have to make it believe it's not in dragging mode. */
- scroll_mode = sb->scrollbar.scroll_mode;
- if (scroll_mode == 2)
- sb->scrollbar.scroll_mode = 0;
- }
-#endif
/* Try to make the scrolling a tad smoother. */
if (!xaw3d_pick_top)
shown = min (shown, old_shown);
XawScrollbarSetThumb (widget, top, shown);
-
-#ifdef HAVE_XAW3D
- if (xaw3d_arrow_scroll && scroll_mode == 2)
- sb->scrollbar.scroll_mode = scroll_mode;
-#endif
}
}
}
top,
left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
- max (height, 1),
- left,
- width);
+ max (height, 1));
xg_show_scroll_bar (SCROLL_BAR_X_WINDOW (bar));
#else /* not USE_GTK */
Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
/* Compute the left edge of the scroll bar. */
#ifdef USE_TOOLKIT_SCROLL_BARS
if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
- sb_left = left + width - sb_width - (width - sb_width) / 2;
+ sb_left = (left +
+ (WINDOW_RIGHTMOST_P (w)
+ ? width - sb_width - (width - sb_width) / 2
+ : 0));
else
- sb_left = left + (width - sb_width) / 2;
+ sb_left = (left +
+ (WINDOW_LEFTMOST_P (w)
+ ? (width - sb_width) / 2
+ : width - sb_width));
#else
if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
sb_left = left + width - sb_width;
#ifdef USE_TOOLKIT_SCROLL_BARS
-#ifdef USE_GTK
- if (mask)
- xg_update_scrollbar_pos (f,
- SCROLL_BAR_X_WINDOW (bar),
- top,
- sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
- sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
- max (height, 1),
- left,
- width);
-#else /* not USE_GTK */
-
- /* Since toolkit scroll bars are smaller than the space reserved
- for them on the frame, we have to clear "under" them. */
- if (width > 0 && height > 0)
- x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- left, top, width, height, False);
/* Move/size the scroll bar widget. */
if (mask)
+ {
+ /* Since toolkit scroll bars are smaller than the space reserved
+ for them on the frame, we have to clear "under" them. */
+ if (width > 0 && height > 0)
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ left, top, width, height, False);
+#ifdef USE_GTK
+ xg_update_scrollbar_pos (f,
+ SCROLL_BAR_X_WINDOW (bar),
+ top,
+ sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
+ sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM *2,
+ max (height, 1));
+#else /* not USE_GTK */
XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
top,
sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
max (height, 1), 0);
-
#endif /* not USE_GTK */
+ }
#else /* not USE_TOOLKIT_SCROLL_BARS */
/* Clear areas not covered by the scroll bar because of
}
\f
-/* Define a queue to save up SelectionRequest events for later handling. */
-
-struct selection_event_queue
- {
- XEvent event;
- struct selection_event_queue *next;
- };
-
-static struct selection_event_queue *queue;
-
-/* Nonzero means queue up certain events--don't process them yet. */
-
-static int x_queue_selection_requests;
-
-/* Queue up an X event *EVENT, to be processed later. */
-
-static void
-x_queue_event (f, event)
- FRAME_PTR f;
- XEvent *event;
-{
- struct selection_event_queue *queue_tmp
- = (struct selection_event_queue *) xmalloc (sizeof (struct selection_event_queue));
-
- if (queue_tmp != NULL)
- {
- queue_tmp->event = *event;
- queue_tmp->next = queue;
- queue = queue_tmp;
- }
-}
-
-/* Take all the queued events and put them back
- so that they get processed afresh. */
-
-static void
-x_unqueue_events (display)
- Display *display;
-{
- while (queue != NULL)
- {
- struct selection_event_queue *queue_tmp = queue;
- XPutBackEvent (display, &queue_tmp->event);
- queue = queue_tmp->next;
- xfree ((char *)queue_tmp);
- }
-}
-
-/* Start queuing SelectionRequest events. */
-
-void
-x_start_queuing_selection_requests (display)
- Display *display;
-{
- x_queue_selection_requests++;
-}
-
-/* Stop queuing SelectionRequest events. */
-
-void
-x_stop_queuing_selection_requests (display)
- Display *display;
-{
- x_queue_selection_requests--;
- x_unqueue_events (display);
-}
-\f
/* The main X event-reading loop - XTread_socket. */
#if 0
f->output_data.x->saved_menu_event \
= (XEvent *) xmalloc (sizeof (XEvent)); \
bcopy (&event, f->output_data.x->saved_menu_event, size); \
- inev.kind = MENU_BAR_ACTIVATE_EVENT; \
- XSETFRAME (inev.frame_or_window, f); \
+ inev.ie.kind = MENU_BAR_ACTIVATE_EVENT; \
+ XSETFRAME (inev.ie.frame_or_window, f); \
} \
while (0)
int *finish;
struct input_event *hold_quit;
{
- struct input_event inev;
+ union {
+ struct input_event ie;
+ struct selection_input_event sie;
+ } inev;
int count = 0;
int do_help = 0;
int nbytes = 0;
*finish = X_EVENT_NORMAL;
- EVENT_INIT (inev);
- inev.kind = NO_EVENT;
- inev.arg = Qnil;
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
switch (event.type)
{
if (!f)
goto OTHER; /* May be a dialog that is to be removed */
- inev.kind = DELETE_WINDOW_EVENT;
- XSETFRAME (inev.frame_or_window, f);
+ inev.ie.kind = DELETE_WINDOW_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
goto done;
}
if (event.xclient.message_type
== dpyinfo->Xatom_Scrollbar)
{
- x_scroll_bar_to_input_event (&event, &inev);
+ x_scroll_bar_to_input_event (&event, &inev.ie);
*finish = X_EVENT_GOTO_OUT;
goto done;
}
if (!f)
goto OTHER;
- if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev))
+ if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev.ie))
*finish = X_EVENT_DROP;
}
break;
{
XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
- inev.kind = SELECTION_CLEAR_EVENT;
- SELECTION_EVENT_DISPLAY (&inev) = eventp->display;
- SELECTION_EVENT_SELECTION (&inev) = eventp->selection;
- SELECTION_EVENT_TIME (&inev) = eventp->time;
- inev.frame_or_window = Qnil;
+ inev.ie.kind = SELECTION_CLEAR_EVENT;
+ SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
+ SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
+ SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
+ inev.ie.frame_or_window = Qnil;
}
break;
if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner))
goto OTHER;
#endif /* USE_X_TOOLKIT */
- if (x_queue_selection_requests)
- x_queue_event (x_window_to_frame (dpyinfo, event.xselectionrequest.owner),
- &event);
- else
- {
+ {
XSelectionRequestEvent *eventp
= (XSelectionRequestEvent *) &event;
- inev.kind = SELECTION_REQUEST_EVENT;
- SELECTION_EVENT_DISPLAY (&inev) = eventp->display;
- SELECTION_EVENT_REQUESTOR (&inev) = eventp->requestor;
- SELECTION_EVENT_SELECTION (&inev) = eventp->selection;
- SELECTION_EVENT_TARGET (&inev) = eventp->target;
- SELECTION_EVENT_PROPERTY (&inev) = eventp->property;
- SELECTION_EVENT_TIME (&inev) = eventp->time;
- inev.frame_or_window = Qnil;
- }
+ inev.ie.kind = SELECTION_REQUEST_EVENT;
+ SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
+ SELECTION_EVENT_REQUESTOR (&inev.sie) = eventp->requestor;
+ SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
+ SELECTION_EVENT_TARGET (&inev.sie) = eventp->target;
+ SELECTION_EVENT_PROPERTY (&inev.sie) = eventp->property;
+ SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
+ inev.ie.frame_or_window = Qnil;
+ }
break;
case PropertyNotify:
{
x_check_fullscreen (f);
+#ifdef USE_GTK
+ /* This seems to be needed for GTK 2.6. */
+ x_clear_area (event.xexpose.display,
+ event.xexpose.window,
+ event.xexpose.x, event.xexpose.y,
+ event.xexpose.width, event.xexpose.height,
+ FALSE);
+#endif
if (f->async_visible == 0)
{
f->async_visible = 1;
{
f->async_iconified = 1;
- inev.kind = ICONIFY_EVENT;
- XSETFRAME (inev.frame_or_window, f);
+ inev.ie.kind = ICONIFY_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
}
}
goto OTHER;
if (f->iconified)
{
- inev.kind = DEICONIFY_EVENT;
- XSETFRAME (inev.frame_or_window, f);
+ inev.ie.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
}
else if (! NILP (Vframe_list)
&& ! NILP (XCDR (Vframe_list)))
orig_keysym = keysym;
/* Common for all keysym input events. */
- XSETFRAME (inev.frame_or_window, f);
- inev.modifiers
+ XSETFRAME (inev.ie.frame_or_window, f);
+ inev.ie.modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
- inev.timestamp = event.xkey.time;
+ inev.ie.timestamp = event.xkey.time;
/* First deal with keysyms which have defined
translations to characters. */
if (keysym >= 32 && keysym < 128)
/* Avoid explicitly decoding each ASCII character. */
{
- inev.kind = ASCII_KEYSTROKE_EVENT;
- inev.code = keysym;
+ inev.ie.kind = ASCII_KEYSTROKE_EVENT;
+ inev.ie.code = keysym;
goto done_keysym;
}
Vx_keysym_table,
Qnil))))
{
- inev.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
- ? ASCII_KEYSTROKE_EVENT
- : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
- inev.code = XFASTINT (c);
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ inev.ie.code = XFASTINT (c);
goto done_keysym;
}
STORE_KEYSYM_FOR_DEBUG (keysym);
/* make_lispy_event will convert this to a symbolic
key. */
- inev.kind = NON_ASCII_KEYSTROKE_EVENT;
- inev.code = keysym;
+ inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
+ inev.ie.code = keysym;
goto done_keysym;
}
else
c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
nbytes - i, len);
- inev.kind = (SINGLE_BYTE_CHAR_P (c)
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (c)
? ASCII_KEYSTROKE_EVENT
: MULTIBYTE_CHAR_KEYSTROKE_EVENT);
- inev.code = c;
- kbd_buffer_store_event_hold (&inev, hold_quit);
+ inev.ie.code = c;
+ kbd_buffer_store_event_hold (&inev.ie, hold_quit);
}
/* Previous code updated count by nchars rather than nbytes,
but that seems bogus to me. ++kfs */
count += nbytes;
- inev.kind = NO_EVENT; /* Already stored above. */
+ inev.ie.kind = NO_EVENT; /* Already stored above. */
if (keysym == NoSymbol)
break;
#endif
case EnterNotify:
- x_detect_focus_change (dpyinfo, &event, &inev);
+ x_detect_focus_change (dpyinfo, &event, &inev.ie);
f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
goto OTHER;
case FocusIn:
- x_detect_focus_change (dpyinfo, &event, &inev);
+ x_detect_focus_change (dpyinfo, &event, &inev.ie);
goto OTHER;
case LeaveNotify:
- x_detect_focus_change (dpyinfo, &event, &inev);
+ x_detect_focus_change (dpyinfo, &event, &inev.ie);
f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
if (f)
goto OTHER;
case FocusOut:
- x_detect_focus_change (dpyinfo, &event, &inev);
+ x_detect_focus_change (dpyinfo, &event, &inev.ie);
goto OTHER;
case MotionNotify:
&& !EQ (window, last_window)
&& !EQ (window, selected_window))
{
- inev.kind = SELECT_WINDOW_EVENT;
- inev.frame_or_window = window;
+ inev.ie.kind = SELECT_WINDOW_EVENT;
+ inev.ie.frame_or_window = window;
}
last_window=window;
&& (int)(event.xbutton.time - ignore_next_mouse_click_timeout) > 0)
{
ignore_next_mouse_click_timeout = 0;
- construct_mouse_click (&inev, &event, f);
+ construct_mouse_click (&inev.ie, &event, f);
}
if (event.type == ButtonRelease)
ignore_next_mouse_click_timeout = 0;
}
else
- construct_mouse_click (&inev, &event, f);
+ construct_mouse_click (&inev.ie, &event, f);
}
}
}
scroll bars. */
if (bar && event.xbutton.state & ControlMask)
{
- x_scroll_bar_handle_click (bar, &event, &inev);
+ x_scroll_bar_handle_click (bar, &event, &inev.ie);
*finish = X_EVENT_DROP;
}
#else /* not USE_TOOLKIT_SCROLL_BARS */
if (bar)
- x_scroll_bar_handle_click (bar, &event, &inev);
+ x_scroll_bar_handle_click (bar, &event, &inev.ie);
#endif /* not USE_TOOLKIT_SCROLL_BARS */
}
}
done:
- if (inev.kind != NO_EVENT)
+ if (inev.ie.kind != NO_EVENT)
{
- kbd_buffer_store_event_hold (&inev, hold_quit);
+ kbd_buffer_store_event_hold (&inev.ie, hold_quit);
count++;
}
mode lines must be clipped to the whole window. */
static void
-x_clip_to_row (w, row, gc)
+x_clip_to_row (w, row, area, gc)
struct window *w;
struct glyph_row *row;
+ int area;
GC gc;
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
XRectangle clip_rect;
- int window_y, window_width;
+ int window_x, window_y, window_width;
- window_box (w, -1, 0, &window_y, &window_width, 0);
+ window_box (w, area, &window_x, &window_y, &window_width, 0);
- clip_rect.x = WINDOW_TO_FRAME_PIXEL_X (w, 0);
- clip_rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
+ clip_rect.x = window_x;
+ clip_rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
clip_rect.y = max (clip_rect.y, window_y);
clip_rect.width = window_width;
clip_rect.height = row->visible_height;
if (cursor_glyph == NULL)
return;
- /* Compute the width of the rectangle to draw. If on a stretch
- glyph, and `x-stretch-block-cursor' is nil, don't draw a
- rectangle as wide as the glyph, but use a canonical character
- width instead. */
- wd = cursor_glyph->pixel_width - 1;
- if (cursor_glyph->type == STRETCH_GLYPH
- && !x_stretch_cursor_p)
- wd = min (FRAME_COLUMN_WIDTH (f), wd);
- w->phys_cursor_width = wd;
-
- /* Compute frame-relative coordinates from window-relative
- coordinates. */
+ /* Compute frame-relative coordinates for phys cursor. */
x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
- y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
-
- /* Compute the proper height and ascent of the rectangle, based
- on the actual glyph. Using the full height of the row looks
- bad when there are tall images on that row. */
- h = max (min (FRAME_LINE_HEIGHT (f), row->height),
- cursor_glyph->ascent + cursor_glyph->descent);
- if (h < row->height)
- y += row->ascent /* - w->phys_cursor_ascent */ + cursor_glyph->descent - h;
- h--;
+ y = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
+ wd = w->phys_cursor_width;
/* The foreground of cursor_gc is typically the same as the normal
background color, which can cause the cursor box to be invisible. */
gc = dpyinfo->scratch_cursor_gc;
/* Set clipping, draw the rectangle, and reset clipping again. */
- x_clip_to_row (w, row, gc);
+ x_clip_to_row (w, row, TEXT_AREA, gc);
XDrawRectangle (dpy, FRAME_X_WINDOW (f), gc, x, y, wd, h);
XSetClipMask (dpy, gc, None);
}
width = min (cursor_glyph->pixel_width, width);
w->phys_cursor_width = width;
- x_clip_to_row (w, row, gc);
+ x_clip_to_row (w, row, TEXT_AREA, gc);
if (kind == BAR_CURSOR)
XFillRectangle (dpy, window, gc,
/* The display may have been closed before this function is called.
Check if it is still open before calling XSync. */
if (x_display_info_for_display (dpy) != 0)
- XSync (dpy, False);
+ {
+ BLOCK_INPUT;
+ XSync (dpy, False);
+ UNBLOCK_INPUT;
+ }
x_error_message_string = XCDR (old_val);
return Qnil;
error ("%s", error_msg);
}
+/* We specifically use it before defining it, so that gcc doesn't inline it,
+ otherwise gdb doesn't know how to properly put a breakpoint on it. */
+static void x_error_quitter (Display *display, XErrorEvent *error);
+
+/* This is the first-level handler for X protocol errors.
+ It calls x_error_quitter or x_error_catcher. */
+
+static int
+x_error_handler (display, error)
+ Display *display;
+ XErrorEvent *error;
+{
+ if (! NILP (x_error_message_string))
+ x_error_catcher (display, error);
+ else
+ x_error_quitter (display, error);
+ return 0;
+}
/* This is the usual handler for X protocol errors.
It kills all frames on the display that we got the error for.
If that was the only one, it prints an error message and kills Emacs. */
-static void
+/* .gdbinit puts a breakpoint here, so make sure it is not inlined. */
+
+#if __GNUC__ >= 3 /* On GCC 3.0 we might get a warning. */
+#define NO_INLINE __attribute__((noinline))
+#else
+#define NO_INLINE
+#endif
+
+/* On older GCC versions, just putting x_error_quitter
+ after x_error_handler prevents inlining into the former. */
+
+static void NO_INLINE
x_error_quitter (display, error)
Display *display;
XErrorEvent *error;
}
-/* This is the first-level handler for X protocol errors.
- It calls x_error_quitter or x_error_catcher. */
-
-static int
-x_error_handler (display, error)
- Display *display;
- XErrorEvent *error;
-{
- if (! NILP (x_error_message_string))
- x_error_catcher (display, error);
- else
- x_error_quitter (display, error);
- return 0;
-}
-
/* This is the handler for X IO errors, always.
It kills all frames on the display that we lost touch with.
If that was the only one, it prints an error message and kills Emacs. */
FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
FRAME_FONTSET (f) = -1;
- FRAME_COLUMN_WIDTH (f) = FONT_WIDTH (FRAME_FONT (f));
+ FRAME_COLUMN_WIDTH (f) = fontp->average_width;
+ FRAME_SPACE_WIDTH (f) = fontp->space_width;
FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (FRAME_FONT (f));
compute_fringe_widths (f, 1);
if (FRAME_X_DISPLAY_INFO (f) == dpyinfo)
{
FRAME_XIC (f) = NULL;
- if (FRAME_XIC_FONTSET (f))
- {
- XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
- FRAME_XIC_FONTSET (f) = NULL;
- }
+ xic_free_xfontset (f);
}
}
if (! ((flags & XNegative) || (flags & YNegative)))
return;
- /* Find the offsets of the outside upper-left corner of
- the inner window, with respect to the outer window.
- But do this only if we will need the results. */
- if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
- /* This is to get *_pixels_outer_diff. */
- x_real_positions (f, &win_x, &win_y);
-
/* Treat negative positions as relative to the leftmost bottommost
position that fits on the screen. */
if (flags & XNegative)
f->left_pos = (FRAME_X_DISPLAY_INFO (f)->width
- - 2 * FRAME_X_OUTPUT (f)->x_pixels_outer_diff
- - FRAME_PIXEL_WIDTH (f)
- + f->left_pos);
+ - FRAME_PIXEL_WIDTH (f) + f->left_pos);
{
int height = FRAME_PIXEL_HEIGHT (f);
#endif
if (flags & YNegative)
- f->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
- - FRAME_X_OUTPUT (f)->y_pixels_outer_diff
-
- /* Assume the window manager decorations are the same size on
- three sides, i.e. left, right and bottom. This is to
- compensate for the bottom part. */
- - FRAME_X_OUTPUT (f)->x_pixels_outer_diff
- - height
- + f->top_pos);
+ f->top_pos = (FRAME_X_DISPLAY_INFO (f)->height - height + f->top_pos);
}
/* The left_pos and top_pos
FRAME_X_OUTPUT (f)->move_offset_left = expect_left - f->left_pos;
FRAME_X_OUTPUT (f)->move_offset_top = expect_top - f->top_pos;
- x_set_offset (f, expect_left, expect_top, 1);
+ f->left_pos = expect_left;
+ f->top_pos = expect_top;
+ x_set_offset (f, expect_left, expect_top, 0);
}
else if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN)
FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;
fontp->name = (char *) xmalloc (strlen (fontname) + 1);
bcopy (fontname, fontp->name, strlen (fontname) + 1);
+ if (font->min_bounds.width == font->max_bounds.width)
+ {
+ /* Fixed width font. */
+ fontp->average_width = fontp->space_width = font->min_bounds.width;
+ }
+ else
+ {
+ XChar2b char2b;
+ XCharStruct *pcm;
+
+ char2b.byte1 = 0x00, char2b.byte2 = 0x20;
+ pcm = x_per_char_metric (font, &char2b, 0);
+ if (pcm)
+ fontp->space_width = pcm->width;
+ else
+ fontp->space_width = FONT_WIDTH (font);
+
+ fontp->average_width
+ = (XGetFontProperty (font, dpyinfo->Xatom_AVERAGE_WIDTH, &value)
+ ? (long) value / 10 : 0);
+ if (fontp->average_width < 0)
+ fontp->average_width = - fontp->average_width;
+ if (fontp->average_width == 0)
+ {
+ if (pcm)
+ {
+ int width = pcm->width;
+ for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
+ if ((pcm = x_per_char_metric (font, &char2b, 0)) != NULL)
+ width += pcm->width;
+ fontp->average_width = width / 95;
+ }
+ else
+ fontp->average_width = FONT_WIDTH (font);
+ }
+ }
+
/* Try to get the full name of FONT. Put it in FULL_NAME. */
full_name = 0;
if (XGetFontProperty (font, XA_FONT, &value))
/* For properties of font. */
dpyinfo->Xatom_PIXEL_SIZE
= XInternAtom (dpyinfo->display, "PIXEL_SIZE", False);
+ dpyinfo->Xatom_AVERAGE_WIDTH
+ = XInternAtom (dpyinfo->display, "AVERAGE_WIDTH", False);
dpyinfo->Xatom_MULE_BASELINE_OFFSET
= XInternAtom (dpyinfo->display, "_MULE_BASELINE_OFFSET", False);
dpyinfo->Xatom_MULE_RELATIVE_COMPOSE
x_update_window_end,
x_cursor_to,
x_flush,
-#ifndef XFlush
+#ifdef XFlush
x_flush,
#else
0, /* flush_display_optional */