#endif
#endif
-#ifdef USE_LUCID
+#if defined (USE_LUCID) || defined (USE_MOTIF)
#include "../lwlib/xlwmenu.h"
#endif
#ifdef USE_TOOLKIT_SCROLL_BARS
#if defined USE_MOTIF
-#include <Xm/Xm.h> /* for LESSTIF_VERSION */
+#include <Xm/Xm.h> /* For LESSTIF_VERSION */
#include <Xm/ScrollBar.h>
#else /* !USE_MOTIF i.e. use Xaw */
struct x_display_info *x_display_list;
-/* This is a list of cons cells, each of the form (NAME
- . FONT-LIST-CACHE), one for each element of x_display_list and in
- the same order. NAME is the name of the frame. FONT-LIST-CACHE
- records previous values returned by x-list-fonts. */
-
-Lisp_Object x_display_name_list;
-
-/* This is a frame waiting to be auto-raised, within XTread_socket. */
-
-static struct frame *pending_autoraise_frame;
-
#ifdef USE_X_TOOLKIT
/* The application context for Xt use. */
static Time ignore_next_mouse_click_timeout;
-/* Mouse movement.
-
- Formerly, we used PointerMotionHintMask (in standard_event_mask)
- so that we would have to call XQueryPointer after each MotionNotify
- event to ask for another such event. However, this made mouse tracking
- slow, and there was a bug that made it eventually stop.
-
- Simply asking for MotionNotify all the time seems to work better.
-
- In order to avoid asking for motion events and then throwing most
- of them away or busy-polling the server for mouse positions, we ask
- the server for pointer motion hints. This means that we get only
- one event per group of mouse movements. "Groups" are delimited by
- other kinds of events (focus changes and button clicks, for
- example), or by XQueryPointer calls; when one of these happens, we
- get another MotionNotify event the next time the mouse moves. This
- is at least as efficient as getting motion events when mouse
- tracking is on, and I suspect only negligibly worse when tracking
- is off. */
-
-/* Where the mouse was last time we reported a mouse event. */
-
-static XRectangle last_mouse_glyph;
-static struct frame *last_mouse_glyph_frame;
-
-/* The scroll bar in which the last X motion event occurred.
-
- If the last X motion event occurred in a scroll bar, we set this so
- XTmouse_position can know whether to report a scroll bar motion or
- an ordinary motion.
-
- If the last X motion event didn't occur in a scroll bar, we set
- this to Qnil, to tell XTmouse_position to return an ordinary motion
- event. */
-
-static Lisp_Object last_mouse_scroll_bar;
-
-/* This is a hack. We would really prefer that XTmouse_position would
- return the time associated with the position it returns, but there
- doesn't seem to be any way to wrest the time-stamp from the server
- along with the position query. So, we just keep track of the time
- of the last movement we received, and return that in hopes that
- it's somewhat accurate. */
-
-static Time last_mouse_movement_time;
-
/* Incremented by XTread_socket whenever it really tries to read
events. */
};
static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
-static void x_set_window_size_1 (struct frame *, int, int, int);
+static void x_set_window_size_1 (struct frame *, int, int, int, bool);
static void x_raise_frame (struct frame *);
static void x_lower_frame (struct frame *);
static const XColor *x_color_cells (Display *, int *);
f->output_data.x->normal_gc, x, y0, x, y1);
}
+/* Draw a window divider from (x0,y0) to (x1,y1) */
+
+static void
+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);
+
+ XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ f->output_data.x->normal_gc, x0, y0, x1 - x0, y1 - y0);
+}
+
/* End update of window W.
Draw vertical borders between horizontally adjacent windows, and
w->output_cursor.x, w->output_cursor.y);
if (draw_window_fringes (w, 1))
- x_draw_vertical_border (w);
+ {
+ if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+ x_draw_right_divider (w);
+ else
+ x_draw_vertical_border (w);
+ }
unblock_input ();
}
if (sb_width > 0)
{
int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
- int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
- * FRAME_COLUMN_WIDTH (f));
+ int bar_area_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
if (bx < 0)
{
get color reference counts right. */
unsigned long
-x_copy_color (struct frame *f, long unsigned int pixel)
+x_copy_color (struct frame *f, unsigned long pixel)
{
XColor color;
Value is non-zero if successful. */
static bool
-x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap, long unsigned int *pixel, double factor, int delta)
+x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
+ unsigned long *pixel, double factor, int delta)
{
XColor color, new;
long bright;
be allocated, use DEFAULT_PIXEL, instead. */
static void
-x_setup_relief_color (struct frame *f, struct relief *relief, double factor, int delta, long unsigned int default_pixel)
+x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
+ int delta, unsigned long default_pixel)
{
XGCValues xgcv;
struct x_output *di = f->output_data.x;
/* Free previously allocated color. The color cell will be reused
when it has been freed as many times as it was allocated, so this
doesn't affect faces using the same colors. */
- if (relief->gc
- && relief->allocated_p)
+ if (relief->gc && relief->pixel != -1)
{
x_free_colors (f, &relief->pixel, 1);
- relief->allocated_p = 0;
+ relief->pixel = -1;
}
/* Allocate new color. */
pixel = background;
if (dpyinfo->n_planes != 1
&& x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
- {
- relief->allocated_p = 1;
- xgcv.foreground = relief->pixel = pixel;
- }
+ xgcv.foreground = relief->pixel = pixel;
if (relief->gc == 0)
{
if (sb_width > 0)
{
int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
- int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
- * FRAME_COLUMN_WIDTH (f));
+ int bar_area_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
if (bar_area_x + bar_area_width == x)
{
x_lower_frame (old_focus);
if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
- pending_autoraise_frame = dpyinfo->x_focus_frame;
+ dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
else
- pending_autoraise_frame = 0;
+ dpyinfo->x_pending_autoraise_frame = NULL;
}
x_frame_rehighlight (dpyinfo);
}
-#if defined HAVE_MENUS && !defined USE_X_TOOLKIT && !defined USE_GTK
+#if !defined USE_X_TOOLKIT && !defined USE_GTK
/* Handle an event saying the mouse has moved out of an Emacs frame. */
void
return value;
}
+/* Mouse clicks and mouse movement. Rah.
-\f
-/* Mouse clicks and mouse movement. Rah. */
+ Formerly, we used PointerMotionHintMask (in standard_event_mask)
+ so that we would have to call XQueryPointer after each MotionNotify
+ event to ask for another such event. However, this made mouse tracking
+ slow, and there was a bug that made it eventually stop.
+
+ Simply asking for MotionNotify all the time seems to work better.
+
+ In order to avoid asking for motion events and then throwing most
+ of them away or busy-polling the server for mouse positions, we ask
+ the server for pointer motion hints. This means that we get only
+ one event per group of mouse movements. "Groups" are delimited by
+ other kinds of events (focus changes and button clicks, for
+ example), or by XQueryPointer calls; when one of these happens, we
+ get another MotionNotify event the next time the mouse moves. This
+ is at least as efficient as getting motion events when mouse
+ tracking is on, and I suspect only negligibly worse when tracking
+ is off. */
/* Prepare a mouse-event in *RESULT for placement in the input queue.
the mainstream emacs code by setting mouse_moved. If not, ask for
another motion event, so we can check again the next time it moves. */
-static XMotionEvent last_mouse_motion_event;
-static Lisp_Object last_mouse_motion_frame;
-
static int
note_mouse_movement (struct frame *frame, const XMotionEvent *event)
{
- last_mouse_movement_time = event->time;
- last_mouse_motion_event = *event;
- XSETFRAME (last_mouse_motion_frame, frame);
+ XRectangle *r;
+ struct x_display_info *dpyinfo;
if (!FRAME_X_OUTPUT (frame))
return 0;
+ dpyinfo = FRAME_DISPLAY_INFO (frame);
+ dpyinfo->last_mouse_movement_time = event->time;
+ dpyinfo->last_mouse_motion_frame = frame;
+ dpyinfo->last_mouse_motion_x = event->x;
+ dpyinfo->last_mouse_motion_y = event->y;
+
if (event->window != FRAME_X_WINDOW (frame))
{
frame->mouse_moved = 1;
- last_mouse_scroll_bar = Qnil;
+ dpyinfo->last_mouse_scroll_bar = NULL;
note_mouse_highlight (frame, -1, -1);
- last_mouse_glyph_frame = 0;
+ dpyinfo->last_mouse_glyph_frame = NULL;
return 1;
}
/* Has the mouse moved off the glyph it was on at the last sighting? */
- if (frame != last_mouse_glyph_frame
- || event->x < last_mouse_glyph.x
- || event->x >= last_mouse_glyph.x + last_mouse_glyph.width
- || event->y < last_mouse_glyph.y
- || event->y >= last_mouse_glyph.y + last_mouse_glyph.height)
+ r = &dpyinfo->last_mouse_glyph;
+ if (frame != dpyinfo->last_mouse_glyph_frame
+ || event->x < r->x || event->x >= r->x + r->width
+ || event->y < r->y || event->y >= r->y + r->height)
{
frame->mouse_moved = 1;
- last_mouse_scroll_bar = Qnil;
+ dpyinfo->last_mouse_scroll_bar = NULL;
note_mouse_highlight (frame, event->x, event->y);
/* Remember which glyph we're now on. */
- remember_mouse_glyph (frame, event->x, event->y, &last_mouse_glyph);
- last_mouse_glyph_frame = frame;
+ remember_mouse_glyph (frame, event->x, event->y, r);
+ dpyinfo->last_mouse_glyph_frame = frame;
return 1;
}
return 0;
}
-\f
-/************************************************************************
- Mouse Face
- ************************************************************************/
-
-static void
-redo_mouse_highlight (void)
-{
- if (!NILP (last_mouse_motion_frame)
- && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
- note_mouse_highlight (XFRAME (last_mouse_motion_frame),
- last_mouse_motion_event.x,
- last_mouse_motion_event.y);
-}
-
-
-
/* Return the current position of the mouse.
*FP should be a frame which indicates which display to ask about.
Time *timestamp)
{
struct frame *f1;
+ struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
block_input ();
- if (! NILP (last_mouse_scroll_bar) && insist == 0)
+ if (dpyinfo->last_mouse_scroll_bar && insist == 0)
x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
else
{
&& FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
XFRAME (frame)->mouse_moved = 0;
- last_mouse_scroll_bar = Qnil;
+ dpyinfo->last_mouse_scroll_bar = NULL;
/* Figure out which root window we're on. */
XQueryPointer (FRAME_X_DISPLAY (*fp),
x_catch_errors (FRAME_X_DISPLAY (*fp));
- if (FRAME_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
- && FRAME_LIVE_P (last_mouse_frame))
+ if (x_mouse_grabbed (dpyinfo))
{
/* If mouse was grabbed on a frame, give coords for that frame
even if the mouse is now outside it. */
XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
- /* From-window, to-window. */
- root, FRAME_X_WINDOW (last_mouse_frame),
+ /* From-window. */
+ root,
+
+ /* To-window. */
+ FRAME_X_WINDOW (dpyinfo->last_mouse_frame),
/* From-position, to-position. */
root_x, root_y, &win_x, &win_y,
/* Child of win. */
&child);
- f1 = last_mouse_frame;
+ f1 = dpyinfo->last_mouse_frame;
}
else
{
want the edit window. For non-Gtk+ the innermost
window is the edit window. For Gtk+ it might not
be. It might be the tool bar for example. */
- if (x_window_to_frame (FRAME_DISPLAY_INFO (*fp), win))
+ if (x_window_to_frame (dpyinfo, win))
break;
#endif
win = child;
#ifdef USE_GTK
/* We don't wan't to know the innermost window. We
want the edit window. */
- f1 = x_window_to_frame (FRAME_DISPLAY_INFO (*fp), win);
+ f1 = x_window_to_frame (dpyinfo, win);
#else
/* Is win one of our frames? */
- f1 = x_any_window_to_frame (FRAME_DISPLAY_INFO (*fp), win);
+ f1 = x_any_window_to_frame (dpyinfo, win);
#endif
#ifdef USE_X_TOOLKIT
on it, i.e. into the same rectangles that matrices on
the frame are divided into. */
- remember_mouse_glyph (f1, win_x, win_y, &last_mouse_glyph);
- last_mouse_glyph_frame = f1;
+ /* FIXME: what if F1 is not an X frame? */
+ dpyinfo = FRAME_DISPLAY_INFO (f1);
+ remember_mouse_glyph (f1, win_x, win_y, &dpyinfo->last_mouse_glyph);
+ dpyinfo->last_mouse_glyph_frame = f1;
*bar_window = Qnil;
*part = 0;
*fp = f1;
XSETINT (*x, win_x);
XSETINT (*y, win_y);
- *timestamp = last_mouse_movement_time;
+ *timestamp = dpyinfo->last_mouse_movement_time;
}
}
}
}
#endif /* not USE_GTK */
-/* A vector of windows used for communication between
- x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
-
-static struct window **scroll_bar_windows;
-static ptrdiff_t scroll_bar_windows_size;
-
-
/* Send a client message with message type Xatom_Scrollbar for a
scroll action to the frame of WINDOW. PART is a value identifying
the part of the scroll bar that was clicked on. PORTION is the
x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
{
XEvent event;
- XClientMessageEvent *ev = (XClientMessageEvent *) &event;
+ XClientMessageEvent *ev = &event.xclient;
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
- ptrdiff_t i;
+ intptr_t iw = (intptr_t) w;
+ enum { BITS_PER_INTPTR = CHAR_BIT * sizeof iw };
+ verify (BITS_PER_INTPTR <= 64);
+ int sign_shift = BITS_PER_INTPTR - 32;
block_input ();
ev->window = FRAME_X_WINDOW (f);
ev->format = 32;
- /* We can only transfer 32 bits in the XClientMessageEvent, which is
- not enough to store a pointer or Lisp_Object on a 64 bit system.
- So, store the window in scroll_bar_windows and pass the index
- into that array in the event. */
- for (i = 0; i < scroll_bar_windows_size; ++i)
- if (scroll_bar_windows[i] == NULL)
- break;
-
- if (i == scroll_bar_windows_size)
- {
- ptrdiff_t old_nbytes =
- scroll_bar_windows_size * sizeof *scroll_bar_windows;
- ptrdiff_t nbytes;
- enum { XClientMessageEvent_MAX = 0x7fffffff };
- scroll_bar_windows =
- xpalloc (scroll_bar_windows, &scroll_bar_windows_size, 1,
- XClientMessageEvent_MAX, sizeof *scroll_bar_windows);
- nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows;
- memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes);
- }
-
- scroll_bar_windows[i] = w;
- ev->data.l[0] = (long) i;
- ev->data.l[1] = (long) part;
- ev->data.l[2] = (long) 0;
- ev->data.l[3] = (long) portion;
- ev->data.l[4] = (long) whole;
+ /* A 32-bit X client on a 64-bit X server can pass a window pointer
+ as-is. A 64-bit client on a 32-bit X server is in trouble
+ because a pointer does not fit and would be truncated while
+ passing through the server. So use two slots and hope that X12
+ will resolve such issues someday. */
+ ev->data.l[0] = iw >> 31 >> 1;
+ ev->data.l[1] = sign_shift <= 0 ? iw : iw << sign_shift >> sign_shift;
+ ev->data.l[2] = part;
+ ev->data.l[3] = portion;
+ ev->data.l[4] = whole;
/* Make Xt timeouts work while the scroll bar is active. */
#ifdef USE_X_TOOLKIT
x_scroll_bar_to_input_event (const XEvent *event,
struct input_event *ievent)
{
- XClientMessageEvent *ev = (XClientMessageEvent *) event;
+ const XClientMessageEvent *ev = &event->xclient;
Lisp_Object window;
struct window *w;
- w = scroll_bar_windows[ev->data.l[0]];
- scroll_bar_windows[ev->data.l[0]] = NULL;
+ /* See the comment in the function above. */
+ intptr_t iw0 = ev->data.l[0];
+ intptr_t iw1 = ev->data.l[1];
+ intptr_t iw = (iw0 << 31 << 1) + (iw1 & 0xffffffffu);
+ w = (struct window *) iw;
XSETWINDOW (window, w);
ievent->timestamp =
XtLastTimestampProcessed (FRAME_X_DISPLAY (XFRAME (w->frame)));
#endif
- ievent->part = ev->data.l[1];
- ievent->code = ev->data.l[2];
- ievent->x = make_number ((int) ev->data.l[3]);
- ievent->y = make_number ((int) ev->data.l[4]);
+ ievent->code = 0;
+ ievent->part = ev->data.l[2];
+ ievent->x = make_number (ev->data.l[3]);
+ ievent->y = make_number (ev->data.l[4]);
ievent->modifiers = 0;
}
/* Clear the area of W that will serve as a scroll bar. This is
for the case that a window has been split horizontally. In
this case, no clear_frame is generated to reduce flickering. */
- if (width > 0 && height > 0)
+ if (width > 0 && window_box_height (w) > 0)
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
left, top, width, window_box_height (w));
/* Get window dimensions. */
window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
top = window_y;
- width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
+ width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
height = window_height;
/* Compute the left edge of the scroll bar area. */
unblock_input ();
}
- bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
+ bar = x_scroll_bar_create (w, top, sb_left, sb_width, max (height, 1));
}
else
{
previous mode line display is cleared after C-x 2 C-x 1, for
example. */
{
- int area_width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
+ int area_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
int rest = area_width - sb_width;
if (rest > 0 && height > 0)
{
const XMotionEvent *event)
{
struct frame *f = XFRAME (XWINDOW (bar->window)->frame);
+ struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
- last_mouse_movement_time = event->time;
-
+ dpyinfo->last_mouse_movement_time = event->time;
+ dpyinfo->last_mouse_scroll_bar = bar;
f->mouse_moved = 1;
- XSETVECTOR (last_mouse_scroll_bar, bar);
/* If we're dragging the bar, display it. */
if (bar->dragging != -1)
enum scroll_bar_part *part, Lisp_Object *x,
Lisp_Object *y, Time *timestamp)
{
- struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
+ struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
+ struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
Window w = bar->x_window;
struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
int win_x, win_y;
/* Get the mouse's position relative to the scroll bar window, and
report that. */
- if (! XQueryPointer (FRAME_X_DISPLAY (f), w,
+ if (XQueryPointer (FRAME_X_DISPLAY (f), w,
- /* Root, child, root x and root y. */
- &dummy_window, &dummy_window,
- &dummy_coord, &dummy_coord,
+ /* Root, child, root x and root y. */
+ &dummy_window, &dummy_window,
+ &dummy_coord, &dummy_coord,
- /* Position relative to scroll bar. */
- &win_x, &win_y,
+ /* Position relative to scroll bar. */
+ &win_x, &win_y,
- /* Mouse buttons and modifier keys. */
- &dummy_mask))
- ;
- else
+ /* Mouse buttons and modifier keys. */
+ &dummy_mask))
{
- int top_range
- = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
+ int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
XSETINT (*y, top_range);
f->mouse_moved = 0;
- last_mouse_scroll_bar = Qnil;
+ dpyinfo->last_mouse_scroll_bar = NULL;
+ *timestamp = dpyinfo->last_mouse_movement_time;
}
- *timestamp = last_mouse_movement_time;
-
unblock_input ();
}
*FINISH is X_EVENT_DROP if event should not be passed to the toolkit.
*EVENT is unchanged unless we're processing KeyPress event.
- We return the number of characters stored into the buffer. */
+ We return the number of characters stored into the buffer. */
static int
handle_one_xevent (struct x_display_info *dpyinfo,
f = x_top_window_to_frame (dpyinfo, event->xreparent.window);
if (f)
{
- int x, y;
f->output_data.x->parent_desc = event->xreparent.parent;
- x_real_positions (f, &x, &y);
- f->left_pos = x;
- f->top_pos = y;
+ x_real_positions (f, &f->left_pos, &f->top_pos);
/* Perhaps reparented due to a WM restart. Reset this. */
FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN;
f = x_window_to_frame (dpyinfo, event->xexpose.window);
if (f)
{
-#if ! GTK_CHECK_VERSION (2, 7, 0)
- /* 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);
-#endif
if (!FRAME_VISIBLE_P (f))
{
SET_FRAME_VISIBLE (f, 1);
SET_FRAME_GARBAGED (f);
}
else
- expose_frame (f, event->xexpose.x, event->xexpose.y,
- event->xexpose.width, event->xexpose.height);
+ {
+#ifdef USE_GTK
+ /* This seems to be needed for GTK 2.6 and later, see
+ http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15398. */
+ x_clear_area (event->xexpose.display,
+ event->xexpose.window,
+ event->xexpose.x, event->xexpose.y,
+ event->xexpose.width, event->xexpose.height);
+#endif
+ expose_frame (f, event->xexpose.x, event->xexpose.y,
+ event->xexpose.width, event->xexpose.height);
+ }
}
else
{
if (event->xunmap.window == tip_window)
{
tip_window = 0;
- redo_mouse_highlight ();
+ x_redo_mouse_highlight (dpyinfo);
}
f = x_top_window_to_frame (dpyinfo, event->xunmap.window);
SET_FRAME_GARBAGED (f);
/* Check if fullscreen was specified before we where mapped the
- first time, i.e. from the command line. */
+ first time, i.e. from the command line. */
if (!f->output_data.x->has_been_visible)
x_check_fullscreen (f);
#ifdef USE_GTK
/* We may get an EnterNotify on the buttons in the toolbar. In that
case we moved out of any highlighted area and need to note this. */
- if (!f && last_mouse_glyph_frame)
- note_mouse_movement (last_mouse_glyph_frame, &event->xmotion);
+ if (!f && dpyinfo->last_mouse_glyph_frame)
+ note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &event->xmotion);
#endif
goto OTHER;
}
#ifdef USE_GTK
/* See comment in EnterNotify above */
- else if (last_mouse_glyph_frame)
- note_mouse_movement (last_mouse_glyph_frame, &event->xmotion);
+ else if (dpyinfo->last_mouse_glyph_frame)
+ note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &event->xmotion);
#endif
goto OTHER;
previous_help_echo_string = help_echo_string;
help_echo_string = Qnil;
- if (dpyinfo->grabbed && last_mouse_frame
- && FRAME_LIVE_P (last_mouse_frame))
- f = last_mouse_frame;
- else
- f = x_window_to_frame (dpyinfo, event->xmotion.window);
+ f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame
+ : x_window_to_frame (dpyinfo, event->xmotion.window));
if (hlinfo->mouse_face_hidden)
{
{
#ifndef USE_X_TOOLKIT
#ifndef USE_GTK
- int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, event->xconfigure.height);
- int columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, event->xconfigure.width);
+ int width = FRAME_PIXEL_TO_TEXT_WIDTH (f, event->xconfigure.width);
+ int height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, event->xconfigure.height);
/* In the toolkit version, change_frame_size
is called by the code that handles resizing
/* Even if the number of character rows and columns has
not changed, the font size may have changed, so we need
to check the pixel dimensions as well. */
- if (columns != FRAME_COLS (f)
- || rows != FRAME_LINES (f)
+ if (width != FRAME_TEXT_WIDTH (f)
+ || height != FRAME_TEXT_HEIGHT (f)
|| event->xconfigure.width != FRAME_PIXEL_WIDTH (f)
|| event->xconfigure.height != FRAME_PIXEL_HEIGHT (f))
{
- change_frame_size (f, rows, columns, 0, 1, 0);
+ change_frame_size (f, width, height, 0, 1, 0, 1);
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
}
if (FRAME_GTK_OUTER_WIDGET (f)
&& gtk_widget_get_mapped (FRAME_GTK_OUTER_WIDGET (f)))
#endif
- {
- x_real_positions (f, &f->left_pos, &f->top_pos);
- }
+ x_real_positions (f, &f->left_pos, &f->top_pos);
#ifdef HAVE_X_I18N
if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
bool tool_bar_p = 0;
memset (&compose_status, 0, sizeof (compose_status));
- last_mouse_glyph_frame = 0;
+ dpyinfo->last_mouse_glyph_frame = NULL;
dpyinfo->last_user_time = event->xbutton.time;
- if (dpyinfo->grabbed
- && last_mouse_frame
- && FRAME_LIVE_P (last_mouse_frame))
- f = last_mouse_frame;
- else
- f = x_window_to_frame (dpyinfo, event->xbutton.window);
+ f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame
+ : x_window_to_frame (dpyinfo, event->xbutton.window));
#ifdef USE_GTK
if (f && xg_event_is_for_scrollbar (f, event))
if (event->type == ButtonPress)
{
dpyinfo->grabbed |= (1 << event->xbutton.button);
- last_mouse_frame = f;
+ dpyinfo->last_mouse_frame = f;
if (!tool_bar_p)
last_tool_bar_item = -1;
{
int count = 0;
int event_found = 0;
+ struct x_display_info *dpyinfo = terminal->display_info.x;
block_input ();
input_signal_count++;
/* For debugging, this gives a way to fake an I/O error. */
- if (terminal->display_info.x == XTread_socket_fake_io_error)
+ if (dpyinfo == XTread_socket_fake_io_error)
{
XTread_socket_fake_io_error = 0;
- x_io_error_quitter (terminal->display_info.x->display);
+ x_io_error_quitter (dpyinfo->display);
}
#ifndef USE_GTK
- while (XPending (terminal->display_info.x->display))
+ while (XPending (dpyinfo->display))
{
int finish;
XEvent event;
- XNextEvent (terminal->display_info.x->display, &event);
+ XNextEvent (dpyinfo->display, &event);
#ifdef HAVE_X_I18N
/* Filter events for the current X input method. */
- if (x_filter_event (terminal->display_info.x, &event))
+ if (x_filter_event (dpyinfo, &event))
continue;
#endif
event_found = 1;
- count += handle_one_xevent (terminal->display_info.x,
- &event, &finish, hold_quit);
+ count += handle_one_xevent (dpyinfo, &event, &finish, hold_quit);
if (finish == X_EVENT_GOTO_OUT)
- goto out;
+ break;
}
- out:;
-
#else /* USE_GTK */
/* For GTK we must use the GTK event loop. But XEvents gets passed
}
/* If the focus was just given to an auto-raising frame,
- raise it now. */
- /* ??? This ought to be able to handle more than one such frame. */
- if (pending_autoraise_frame)
+ raise it now. FIXME: handle more than one such frame. */
+ if (dpyinfo->x_pending_autoraise_frame)
{
- x_raise_frame (pending_autoraise_frame);
- pending_autoraise_frame = 0;
+ x_raise_frame (dpyinfo->x_pending_autoraise_frame);
+ dpyinfo->x_pending_autoraise_frame = NULL;
}
unblock_input ();
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;
}
doing it because it's done in Fx_show_tip, and it leads to
problems because the tip frame has no widget. */
if (NILP (tip_frame) || XFRAME (tip_frame) != f)
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
}
#ifdef HAVE_X_I18N
size changes. Otherwise we leave the window gravity unchanged. */
static void
-x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows)
+x_set_window_size_1 (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
{
int pixelwidth, pixelheight;
- check_frame_size (f, &rows, &cols);
+ check_frame_size (f, &width, &height, pixelwise);
f->scroll_bar_actual_width
= (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
? 0
compute_fringe_widths (f, 0);
- pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols)
+ pixelwidth =
+ (pixelwise ? width : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width))
+ FRAME_TOOLBAR_WIDTH (f);
- pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows)
+ pixelheight =
+ (pixelwise ? height : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height))
+ FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
if (change_gravity) f->win_gravity = NorthWestGravity;
x_wait_for_event (f, ConfigureNotify);
else
{
- change_frame_size (f, rows, cols, 0, 1, 0);
+ change_frame_size (f, width, height, 0, 1, 0, 1);
FRAME_PIXEL_WIDTH (f) = pixelwidth;
FRAME_PIXEL_HEIGHT (f) = pixelheight;
x_sync (f);
Otherwise we leave the window gravity unchanged. */
void
-x_set_window_size (struct frame *f, int change_gravity, int cols, int rows)
+x_set_window_size (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
{
block_input ();
if (NILP (tip_frame) || XFRAME (tip_frame) != f)
{
- int r, c;
+ int r, c, text_width, text_height;
/* When the frame is maximized/fullscreen or running under for
example Xmonad, x_set_window_size_1 will be a no-op.
- In that case, the right thing to do is extend rows/cols to
+ In that case, the right thing to do is extend rows/width to
the current frame size. We do that first if x_set_window_size_1
turns out to not be a no-op (there is no way to know).
The size will be adjusted again if the frame gets a
is however. */
pixelh -= FRAME_MENUBAR_HEIGHT (f);
#endif
+ text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, FRAME_PIXEL_WIDTH (f));
+ text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelh);
r = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (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);
c = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, FRAME_PIXEL_WIDTH (f));
- change_frame_size (f, r, c, 0, 1, 0);
+ change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
}
#ifdef USE_GTK
if (FRAME_GTK_WIDGET (f))
- xg_frame_set_char_size (f, cols, rows);
+ xg_frame_set_char_size (f, width, height);
else
- x_set_window_size_1 (f, change_gravity, cols, rows);
+ x_set_window_size_1 (f, change_gravity, width, height, pixelwise);
#else /* not USE_GTK */
- x_set_window_size_1 (f, change_gravity, cols, rows);
+ x_set_window_size_1 (f, change_gravity, width, height, pixelwise);
#endif /* not USE_GTK */
void
x_make_frame_visible (struct frame *f)
{
- Lisp_Object type;
int original_top, original_left;
int retry_count = 2;
block_input ();
- type = x_icon_type (f);
- if (!NILP (type))
- x_bitmap_icon (f, type);
+ x_set_bitmap_icon (f);
if (! FRAME_VISIBLE_P (f))
{
#ifdef USE_X_TOOLKIT
int result;
#endif
- Lisp_Object type;
/* Don't keep the highlight on an invisible frame. */
if (FRAME_DISPLAY_INFO (f)->x_highlight_frame == f)
block_input ();
- type = x_icon_type (f);
- if (!NILP (type))
- x_bitmap_icon (f, type);
+ x_set_bitmap_icon (f);
#if defined (USE_GTK)
if (FRAME_GTK_OUTER_WIDGET (f))
if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
#endif /* USE_TOOLKIT_SCROLL_BARS */
- if (f->output_data.x->white_relief.allocated_p)
+ if (f->output_data.x->white_relief.pixel != -1)
unload_color (f, f->output_data.x->white_relief.pixel);
- if (f->output_data.x->black_relief.allocated_p)
+ if (f->output_data.x->black_relief.pixel != -1)
unload_color (f, f->output_data.x->black_relief.pixel);
x_free_gcs (f);
base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
- check_frame_size (f, &min_rows, &min_cols);
+ check_frame_size (f, &min_cols, &min_rows, 0);
/* The window manager uses the base width hints to calculate the
current number of rows and columns in the frame while
get to the first bit. With MASK 0x7e0, *BITS is set to 6, and *OFFSET
to 5. */
static void
-get_bits_and_offset (long unsigned int mask, int *bits, int *offset)
+get_bits_and_offset (unsigned long mask, int *bits, int *offset)
{
int nr = 0;
int off = 0;
{
struct x_display_info *share;
- Lisp_Object tail;
- for (share = x_display_list, tail = x_display_name_list; share;
- share = share->next, tail = XCDR (tail))
- if (same_x_server (SSDATA (XCAR (XCAR (tail))),
+ for (share = x_display_list; share; share = share->next)
+ if (same_x_server (SSDATA (XCAR (share->name_list_element)),
SSDATA (display_name)))
break;
if (share)
terminal->kboard = share->terminal->kboard;
else
{
- terminal->kboard = xmalloc (sizeof *terminal->kboard);
- init_kboard (terminal->kboard);
- kset_window_system (terminal->kboard, Qx);
-
- /* Add the keyboard to the list before running Lisp code (via
- Qvendor_specific_keysyms below), since these are not traced
- via terminals but only through all_kboards. */
- terminal->kboard->next_kboard = all_kboards;
- all_kboards = terminal->kboard;
+ terminal->kboard = allocate_kboard (Qx);
if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound))
{
dpyinfo->next = x_display_list;
x_display_list = dpyinfo;
- /* Put it on x_display_name_list as well, to keep them parallel. */
- x_display_name_list = Fcons (Fcons (display_name, Qnil),
- x_display_name_list);
- dpyinfo->name_list_element = XCAR (x_display_name_list);
-
+ dpyinfo->name_list_element = Fcons (display_name, Qnil);
dpyinfo->display = dpy;
/* Set the name of the terminal. */
break;
}
- /* Discard this display from x_display_name_list and x_display_list.
- We can't use Fdelq because that can quit. */
- if (! NILP (x_display_name_list)
- && EQ (XCAR (x_display_name_list), dpyinfo->name_list_element))
- x_display_name_list = XCDR (x_display_name_list);
- else
- {
- Lisp_Object tail;
-
- tail = x_display_name_list;
- while (CONSP (tail) && CONSP (XCDR (tail)))
- {
- if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
- {
- XSETCDR (tail, XCDR (XCDR (tail)));
- break;
- }
- tail = XCDR (tail);
- }
- }
-
if (next_noop_dpyinfo == dpyinfo)
next_noop_dpyinfo = dpyinfo->next;
x_clear_frame_area,
x_draw_window_cursor,
x_draw_vertical_window_border,
+ x_draw_window_divider,
x_shift_glyphs_for_insert
};
terminal->delete_terminal_hook = x_delete_terminal;
terminal->rif = &x_redisplay_interface;
- terminal->scroll_region_ok = 1; /* We'll scroll partial frames. */
- terminal->char_ins_del_ok = 1;
- terminal->line_ins_del_ok = 1; /* We'll just blt 'em. */
- terminal->fast_clear_end_of_line = 1; /* X does this well. */
- terminal->memory_below_frame = 0; /* We don't remember what scrolls
- off the bottom. */
return terminal;
}
#endif
#endif
- pending_autoraise_frame = 0;
-
/* Note that there is no real way portable across R3/R4 to get the
original error handler. */
XSetErrorHandler (x_error_handler);
{
x_error_message = NULL;
- staticpro (&x_display_name_list);
- x_display_name_list = Qnil;
-
- staticpro (&last_mouse_scroll_bar);
- last_mouse_scroll_bar = Qnil;
-
DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
DEFSYM (Qlatin_1, "latin-1");
Vx_toolkit_scroll_bars = Qnil;
#endif
- staticpro (&last_mouse_motion_frame);
- last_mouse_motion_frame = Qnil;
-
- Qmodifier_value = intern_c_string ("modifier-value");
- Qalt = intern_c_string ("alt");
+ DEFSYM (Qmodifier_value, "modifier-value");
+ DEFSYM (Qalt, "alt");
Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
- Qhyper = intern_c_string ("hyper");
+ DEFSYM (Qhyper, "hyper");
Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier));
- Qmeta = intern_c_string ("meta");
+ DEFSYM (Qmeta, "meta");
Fput (Qmeta, Qmodifier_value, make_number (meta_modifier));
- Qsuper = intern_c_string ("super");
+ DEFSYM (Qsuper, "super");
Fput (Qsuper, Qmodifier_value, make_number (super_modifier));
DEFVAR_LISP ("x-alt-keysym", Vx_alt_keysym,