/* On 4.3 these lose if they come after xterm.h. */
/* On HP-UX 8.0 signal.h loses if it comes after config.h. */
/* Putting these at the beginning seems to be standard for other .c files. */
-#include <stdio.h>
#include <signal.h>
#include <config.h>
+#include <stdio.h>
+
/* Need syssignal.h for various externs and definitions that may be required
by some configurations for calls to signal later in this source file. */
#include "syssignal.h"
#ifdef BSD
#include <sys/ioctl.h>
-#include <strings.h>
-#else /* ! defined (BSD) */
-#ifndef VMS
-#include <string.h>
-#endif
#endif /* ! defined (BSD) */
#include "systty.h"
#include "disptab.h"
#include "buffer.h"
#include "window.h"
+#include "keyboard.h"
+#include "intervals.h"
#ifdef USE_X_TOOLKIT
extern XtAppContext Xt_app_con;
#define x_top_window_to_frame x_window_to_frame
#endif
-#ifdef HAVE_X11
+#ifdef USE_X_TOOLKIT
+#ifndef XtNinitialState
+#define XtNinitialState "initialState"
+#endif
+#endif
+
#define XMapWindow XMapRaised /* Raise them when mapping. */
-#else /* ! defined (HAVE_X11) */
-#include <X/Xkeyboard.h>
-/*#include <X/Xproto.h> */
-#endif /* ! defined (HAVE_X11) */
#ifdef FD_SET
/* We could get this from param.h, but better not to depend on finding that.
static int expose_all_icons;
-#ifndef HAVE_X11
-/* ExposeRegion events, when received, are copied into this queue
- for later processing. */
-
-static struct event_queue x_expose_queue;
-
-/* ButtonPress and ButtonReleased events, when received,
- are copied into this queue for later processing. */
-
-struct event_queue x_mouse_queue;
-#endif /* HAVE_X11 */
-
#if defined (SIGIO) && defined (FIONREAD)
int BLOCK_INPUT_mask;
#endif /* ! defined (SIGIO) && defined (FIONREAD) */
/* Stuff for dealing with the main icon title. */
-extern Lisp_Object Vcommand_line_args;
-char *hostname, *x_id_name;
+extern Lisp_Object Vcommand_line_args, Vsystem_name;
+char *x_id_name;
+
+/* Initial values of argv and argc. */
+extern char **initial_argv;
+extern int initial_argc;
/* This is the X connection that we are using. */
static int curs_x;
static int curs_y;
+/* Reusable Graphics Context for drawing a cursor in a non-default face. */
+static GC scratch_cursor_gc;
+
/* Mouse movement.
In order to avoid asking for motion events and then throwing most
to Qnil, to tell XTmouse_position to return an ordinary motion event. */
static Lisp_Object last_mouse_scroll_bar;
-/* Record which buttons are currently pressed. */
+/* Record which buttons are currently pressed. */
unsigned int x_mouse_grabbed;
/* This is a hack. We would really prefer that XTmouse_position would
in its mouse-face, together with the window they apply to.
As long as the mouse stays within this range, we need not
redraw anything on its account. */
-static int mouse_face_beg, mouse_face_end;
+static int mouse_face_beg_row, mouse_face_beg_col;
+static int mouse_face_end_row, mouse_face_end_col;
+static int mouse_face_past_end;
static Lisp_Object mouse_face_window;
static int mouse_face_face_id;
gc was in progress. */
static int mouse_face_deferred_gc;
-/* FRAME and X, Y position of mouse when last checked for highlighting. */
+/* FRAME and X, Y position of mouse when last checked for
+ highlighting. X and Y can be negative or out of range for the frame. */
static FRAME_PTR mouse_face_mouse_frame;
static int mouse_face_mouse_x, mouse_face_mouse_y;
/* Nonzero means defer mouse-motion highlighting. */
static int mouse_face_defer;
-#ifdef HAVE_X11
+/* Incremented by XTread_socket whenever it really tries to read events. */
+#ifdef __STDC__
+static int volatile input_signal_count;
+#else
+static int input_signal_count;
+#endif
+
/* `t' if a mouse button is depressed. */
extern Lisp_Object Vmouse_depressed;
extern Lisp_Object Qface, Qmouse_face;
-#else /* ! defined (HAVE_X11) */
-
-/* Bit patterns for the mouse cursor. */
-
-short MouseCursor[] = {
- 0x0000, 0x0008, 0x0018, 0x0038,
- 0x0078, 0x00f8, 0x01f8, 0x03f8,
- 0x07f8, 0x00f8, 0x00d8, 0x0188,
- 0x0180, 0x0300, 0x0300, 0x0000};
-
-short MouseMask[] = {
- 0x000c, 0x001c, 0x003c, 0x007c,
- 0x00fc, 0x01fc, 0x03fc, 0x07fc,
- 0x0ffc, 0x0ffc, 0x01fc, 0x03dc,
- 0x03cc, 0x0780, 0x0780, 0x0300};
+static int x_noop_count;
-static short grey_bits[] = {
- 0x0005, 0x000a, 0x0005, 0x000a};
-
-static Pixmap GreyPixmap = 0;
-#endif /* ! defined (HAVE_X11) */
/* From time to time we get info on an Emacs window, here. */
static void redraw_following_char ();
static unsigned int x_x_to_emacs_modifiers ();
+static int fast_find_position ();
static void note_mouse_highlight ();
static void clear_mouse_face ();
static void show_mouse_face ();
-#ifndef HAVE_X11
-static void dumpqueue ();
-#endif /* HAVE_X11 */
-
void dumpborder ();
static int XTcursor_to ();
static int XTclear_end_of_line ();
clear_mouse_face ();
}
}
-#ifndef HAVE_X11
- dumpqueue ();
-#endif /* HAVE_X11 */
+
UNBLOCK_INPUT;
}
-#ifndef HAVE_X11
-static void x_do_pending_expose ();
-#endif
-
static
XTupdate_end (f)
struct frame *f;
int mask;
BLOCK_INPUT;
-#ifndef HAVE_X11
- dumpqueue ();
- x_do_pending_expose ();
-#endif /* HAVE_X11 */
x_display_cursor (f, 1);
struct face *face = FRAME_DEFAULT_FACE (f);
FONT_TYPE *font = FACE_FONT (face);
GC gc = FACE_GC (face);
- int gc_temporary = 0;
/* HL = 3 means use a mouse face previously chosen. */
if (hl == 3)
/* Now override that if the cursor's on this character. */
if (hl == 2)
{
- if (!face->font
- || (int) face->font == FACE_DEFAULT)
+ if ((!face->font
+ || (int) face->font == FACE_DEFAULT
+ || face->font == f->display.x->font)
+ && face->background == f->display.x->background_pixel
+ && face->foreground == f->display.x->foreground_pixel)
{
gc = f->display.x->cursor_gc;
}
unsigned long mask;
xgcv.background = f->display.x->cursor_pixel;
- if (face == FRAME_DEFAULT_FACE (f))
- xgcv.foreground = f->display.x->cursor_foreground_pixel;
- else
- xgcv.foreground = face->foreground;
+ xgcv.foreground = face->background;
/* If the glyph would be invisible,
try a different foreground. */
if (xgcv.foreground == xgcv.background)
- xgcv.foreground = face->background;
+ xgcv.foreground = face->foreground;
if (xgcv.foreground == xgcv.background)
xgcv.foreground = f->display.x->cursor_foreground_pixel;
if (xgcv.foreground == xgcv.background)
xgcv.font = face->font->fid;
xgcv.graphics_exposures = 0;
mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
- gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
- mask, &xgcv);
+ if (scratch_cursor_gc)
+ XChangeGC (x_current_display, scratch_cursor_gc, mask, &xgcv);
+ else
+ scratch_cursor_gc =
+ XCreateGC (x_current_display, window, mask, &xgcv);
+ gc = scratch_cursor_gc;
#if 0
+/* If this code is restored, it must also reset to the default stipple
+ if necessary. */
if (face->stipple && face->stipple != FACE_DEFAULT)
XSetStipple (x_current_display, gc, face->stipple);
#endif
- gc_temporary = 1;
}
}
}
#endif
- if (gc_temporary)
- XFreeGC (x_current_display, gc);
-
/* We should probably check for XA_UNDERLINE_POSITION and
XA_UNDERLINE_THICKNESS properties on the font, but let's
just get the thing working, and come back to that. */
&& f->phys_cursor_x < first_unused)
f->phys_cursor_x = -1;
-#ifdef HAVE_X11
XClearArea (x_current_display, FRAME_X_WINDOW (f),
CHAR_TO_PIXEL_COL (f, curs_x),
CHAR_TO_PIXEL_ROW (f, curs_y),
#if 0
redraw_previous_char (f, curs_x, curs_y, highlight);
#endif
-#else /* ! defined (HAVE_X11) */
- XPixSet (FRAME_X_WINDOW (f),
- CHAR_TO_PIXEL_COL (f, curs_x),
- CHAR_TO_PIXEL_ROW (f, curs_y),
- FONT_WIDTH (f->display.x->font) * (first_unused - curs_x),
- f->display.x->line_height,
- f->display.x->background_pixel);
-#endif /* ! defined (HAVE_X11) */
UNBLOCK_INPUT;
}
colors or something like that, then they should be notified. */
x_scroll_bar_clear (f);
-#ifndef HAVE_X11
- dumpborder (f, 0);
-#endif /* HAVE_X11 */
-
XFlushQueue ();
UNBLOCK_INPUT;
}
/* Make audible bell. */
-#ifdef HAVE_X11
#define XRINGBELL XBell (x_current_display, 0)
-#else /* ! defined (HAVE_X11) */
-#define XRINGBELL XFeep (0);
-#endif /* ! defined (HAVE_X11) */
XTring_bell ()
{
newtop = topregion + n;
length = (bottomregion - topregion) + 1;
-#ifndef HAVE_X11
- dumpqueue ();
-#endif /* HAVE_X11 */
-
if ((length > 0) && (newtop <= flexlines))
- {
-#ifdef HAVE_X11
- XCopyArea (x_current_display, FRAME_X_WINDOW (f),
- FRAME_X_WINDOW (f), f->display.x->normal_gc,
- intborder, CHAR_TO_PIXEL_ROW (f, topregion),
- f->width * FONT_WIDTH (f->display.x->font),
- length * f->display.x->line_height, intborder,
- CHAR_TO_PIXEL_ROW (f, newtop));
-#else /* ! defined (HAVE_X11) */
- XMoveArea (FRAME_X_WINDOW (f),
- intborder, CHAR_TO_PIXEL_ROW (f, topregion),
- intborder, CHAR_TO_PIXEL_ROW (f, newtop),
- f->width * FONT_WIDTH (f->display.x->font),
- length * f->display.x->line_height);
- /* Now we must process any ExposeRegion events that occur
- if the area being copied from is obscured.
- We can't let it wait because further i/d operations
- may want to copy this area to another area. */
- x_read_exposes ();
-#endif /* ! defined (HAVE_X11) */
- }
+ XCopyArea (x_current_display, FRAME_X_WINDOW (f),
+ FRAME_X_WINDOW (f), f->display.x->normal_gc,
+ intborder, CHAR_TO_PIXEL_ROW (f, topregion),
+ f->width * FONT_WIDTH (f->display.x->font),
+ length * f->display.x->line_height, intborder,
+ CHAR_TO_PIXEL_ROW (f, newtop));
newtop = min (newtop, (flexlines - 1));
length = newtop - topregion;
if (length > 0)
- {
-#ifdef HAVE_X11
- XClearArea (x_current_display, FRAME_X_WINDOW (f), intborder,
- CHAR_TO_PIXEL_ROW (f, topregion),
- f->width * FONT_WIDTH (f->display.x->font),
- n * f->display.x->line_height, False);
-#else /* ! defined (HAVE_X11) */
- XPixSet (FRAME_X_WINDOW (f),
- intborder,
- CHAR_TO_PIXEL_ROW (f, topregion),
- f->width * FONT_WIDTH (f->display.x->font),
- n * f->display.x->line_height,
- f->display.x->background_pixel);
-#endif /* ! defined (HAVE_X11) */
- }
+ XClearArea (x_current_display, FRAME_X_WINDOW (f), intborder,
+ CHAR_TO_PIXEL_ROW (f, topregion),
+ f->width * FONT_WIDTH (f->display.x->font),
+ n * f->display.x->line_height, False);
}
/* Perform a delete-lines operation, deleting N lines
if (curs_y >= flexlines)
return;
-#ifndef HAVE_X11
- dumpqueue ();
-#endif /* HAVE_X11 */
-
if ((curs_y + n) >= flexlines)
{
if (flexlines >= (curs_y + 1))
- {
-#ifdef HAVE_X11
- XClearArea (x_current_display, FRAME_X_WINDOW (f), intborder,
- CHAR_TO_PIXEL_ROW (f, curs_y),
- f->width * FONT_WIDTH (f->display.x->font),
- (flexlines - curs_y) * f->display.x->line_height, False);
-#else /* ! defined (HAVE_X11) */
- XPixSet (FRAME_X_WINDOW (f),
- intborder, CHAR_TO_PIXEL_ROW (f, curs_y),
- f->width * FONT_WIDTH (f->display.x->font),
- (flexlines - curs_y) * f->display.x->line_height,
- f->display.x->background_pixel);
-#endif /* ! defined (HAVE_X11) */
- }
+ XClearArea (x_current_display, FRAME_X_WINDOW (f), intborder,
+ CHAR_TO_PIXEL_ROW (f, curs_y),
+ f->width * FONT_WIDTH (f->display.x->font),
+ (flexlines - curs_y) * f->display.x->line_height, False);
}
else
{
-#ifdef HAVE_X11
XCopyArea (x_current_display, FRAME_X_WINDOW (f),
FRAME_X_WINDOW (f), f->display.x->normal_gc,
intborder,
CHAR_TO_PIXEL_ROW (f, flexlines - n),
f->width * FONT_WIDTH (f->display.x->font),
n * f->display.x->line_height, False);
-#else /* ! defined (HAVE_X11) */
- XMoveArea (FRAME_X_WINDOW (f),
- intborder,
- CHAR_TO_PIXEL_ROW (f, curs_y + n),
- intborder, CHAR_TO_PIXEL_ROW (f, curs_y),
- f->width * FONT_WIDTH (f->display.x->font),
- (flexlines - (curs_y + n)) * f->display.x->line_height);
- /* Now we must process any ExposeRegion events that occur
- if the area being copied from is obscured.
- We can't let it wait because further i/d operations
- may want to copy this area to another area. */
- x_read_exposes ();
- XPixSet (FRAME_X_WINDOW (f), intborder,
- CHAR_TO_PIXEL_ROW (f, flexlines - n),
- f->width * FONT_WIDTH (f->display.x->font),
- n * f->display.x->line_height, f->display.x->background_pixel);
-#endif /* ! defined (HAVE_X11) */
}
}
/* Express rectangle as four edges, instead of position-and-size. */
bottom = top + rows;
right = left + cols;
-
-#ifndef HAVE_X11 /* Window manger does this for X11. */
- {
- int intborder = f->display.x->internal_border_width;
-
- /* If the rectangle includes any of the internal border area,
- redisplay the border emphasis. */
- if (top < intborder || left < intborder
- || bottom > intborder + f->height * f->display.x->line_height
- || right > intborder + f->width * f->display.x->line_height)
- dumpborder (f, 0);
- }
-#endif /* not HAVE_X11 Window manger does this for X11. */
/* Convert rectangle edges in pixels to edges in chars.
Round down for left and top, up for right and bottom. */
if (cursor_cleared)
x_display_cursor (f, 1);
}
-
-#ifndef HAVE_X11
-/* Process all queued ExposeRegion events. */
-
-static void
-dumpqueue ()
-{
- register int i;
- XExposeRegionEvent r;
-
- while (dequeue_event (&r, &x_expose_queue))
- {
- struct frame *f = x_window_to_frame (r.window);
- if (f->display.x->icon_desc == r.window)
- refreshicon (f);
- else
- dumprectangle (f, r.x, r.y, r.width, r.height);
- }
- XFlushQueue ();
-}
-#endif /* HAVE_X11 */
\f
-/* Process all expose events that are pending, for X10.
- Redraws the cursor if necessary on any frame that
- is not in the process of being updated with update_frame. */
-
-#ifndef HAVE_X11
-static void
-x_do_pending_expose ()
-{
- int mask;
- struct frame *f;
- Lisp_Object tail, frame;
-
- if (expose_all_windows)
- {
- expose_all_windows = 0;
- for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
- {
- register int temp_width, temp_height;
- int intborder;
-
- frame = XCONS (tail)->car;
- if (XGCTYPE (frame) != Lisp_Frame)
- continue;
- f = XFRAME (frame);
- if (! FRAME_X_P (f))
- continue;
- if (!f->async_visible)
- continue;
- if (!f->display.x->needs_exposure)
- continue;
-
- intborder = f->display.x->internal_border_width;
-
- clear_cursor (f);
- XGetWindowInfo (FRAME_X_WINDOW (f), &windowinfo);
- temp_width = ((windowinfo.width - 2 * intborder
- - f->display.x->v_scroll_bar_width)
- / FONT_WIDTH (f->display.x->font));
- temp_height = ((windowinfo.height- 2 * intborder
- - f->display.x->h_scroll_bar_height)
- / f->display.x->line_height);
- if (temp_width != f->width || temp_height != f->height)
- {
- change_frame_size (f, max (1, temp_height),
- max (1, temp_width), 0, 1);
- x_resize_scroll_bars (f);
- }
- f->display.x->left_pos = windowinfo.x;
- f->display.x->top_pos = windowinfo.y;
- dumprectangle (f, 0, 0, PIXEL_WIDTH (f), PIXEL_HEIGHT (f));
-#if 0
- dumpborder (f, 0);
-#endif /* ! 0 */
- f->display.x->needs_exposure = 0;
- if (updating_frame != f)
- x_display_cursor (f, 1);
- XFlushQueue ();
- }
- }
- else
- /* Handle any individual-rectangle expose events queued
- for various windows. */
-#ifdef HAVE_X11
- ;
-#else /* ! defined (HAVE_X11) */
- dumpqueue ();
-#endif /* ! defined (HAVE_X11) */
-}
-#endif
-
-#ifdef HAVE_X11
static void
frame_highlight (frame)
struct frame *frame;
UNBLOCK_INPUT;
x_display_cursor (frame, 1);
}
-#else /* ! defined (HAVE_X11) */
-/* Dump the border-emphasis of frame F.
- If F is selected, this is a lining of the same color as the border,
- just within the border, occupying a portion of the internal border.
- If F is not selected, it is background in the same place.
- If ALWAYS is 0, don't bother explicitly drawing if it's background.
-
- ALWAYS = 1 is used when a frame becomes selected or deselected.
- In that case, we also turn the cursor off and on again
- so it will appear in the proper shape (solid if selected; else hollow.) */
-
-static void
-dumpborder (f, always)
- struct frame *f;
- int always;
-{
- int thickness = f->display.x->internal_border_width / 2;
- int width = PIXEL_WIDTH (f);
- int height = PIXEL_HEIGHT (f);
- int pixel;
-
- if (f != selected_frame)
- {
- if (!always)
- return;
-
- pixel = f->display.x->background_pixel;
- }
- else
- {
- pixel = f->display.x->border_pixel;
- }
-
- XPixSet (FRAME_X_WINDOW (f), 0, 0, width, thickness, pixel);
- XPixSet (FRAME_X_WINDOW (f), 0, 0, thickness, height, pixel);
- XPixSet (FRAME_X_WINDOW (f), 0, height - thickness, width,
- thickness, pixel);
- XPixSet (FRAME_X_WINDOW (f), width - thickness, 0, thickness,
- height, pixel);
-
- if (always)
- x_display_cursor (f, 1);
-}
-#endif /* ! defined (HAVE_X11) */
static void XTframe_rehighlight ();
| ((state & ctrl_modifier) ? ControlMask : 0)
| ((state & meta_modifier) ? x_meta_mod_mask : 0));
}
-
-/* Return true iff KEYSYM is a vendor-specific keysym that we should
- return as a function key. If you add a keysym to this, you should
- make sure that the tables make_lispy_event uses contain a suitable
- name for it. */
-static int
-x_is_vendor_fkey (sym)
- KeySym sym;
-{
- return 0
-#ifdef DXK_Remove
- || (sym == DXK_Remove)
-#endif
- ;
-}
-
\f
/* Mouse clicks and mouse movement. Rah. */
-#ifdef HAVE_X11
/* Given a pixel position (PIX_X, PIX_Y) on the frame F, return
glyph co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle
? up_modifier
: down_modifier));
- /* Notice if the mouse is still grabbed. */
- if (event->type == ButtonPress)
- {
- if (! x_mouse_grabbed)
- Vmouse_depressed = Qt;
- x_mouse_grabbed |= (1 << event->button);
- last_mouse_frame = f;
- }
- else if (event->type == ButtonRelease)
- {
- x_mouse_grabbed &= ~(1 << event->button);
- if (!x_mouse_grabbed)
- Vmouse_depressed = Qnil;
- }
-
{
int row, column;
{
last_mouse_movement_time = event->time;
+ if (event->window != FRAME_X_WINDOW (frame))
+ {
+ mouse_moved = 1;
+ last_mouse_scroll_bar = Qnil;
+
+ note_mouse_highlight (frame, -1, -1);
+
+ /* Ask for another mouse motion event. */
+ {
+ int dummy;
+ Window dummy_window;
+
+ XQueryPointer (event->display, FRAME_X_WINDOW (frame),
+ &dummy_window, &dummy_window,
+ &dummy, &dummy, &dummy, &dummy,
+ (unsigned int *) &dummy);
+ }
+ }
+
/* Has the mouse moved off the glyph it was on at the last sighting? */
- if (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)
+ else if (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)
{
mouse_moved = 1;
last_mouse_scroll_bar = Qnil;
/* Ask for another mouse motion event. */
{
int dummy;
+ Window dummy_window;
- XQueryPointer (event->display, event->window,
- (Window *) &dummy, (Window *) &dummy,
+ XQueryPointer (event->display, FRAME_X_WINDOW (frame),
+ &dummy_window, &dummy_window,
&dummy, &dummy, &dummy, &dummy,
(unsigned int *) &dummy);
}
event the next time the mouse moves and we can see if it's
*still* on the same glyph. */
int dummy;
+ Window dummy_window;
- XQueryPointer (event->display, event->window,
- (Window *) &dummy, (Window *) &dummy,
+ XQueryPointer (event->display, FRAME_X_WINDOW (frame),
+ &dummy_window, &dummy_window,
&dummy, &dummy, &dummy, &dummy,
(unsigned int *) &dummy);
}
/* Take proper action when the mouse has moved to position X, Y on frame F
as regards highlighting characters that have mouse-face properties.
- Also dehighlighting chars where the mouse was before. */
+ Also dehighlighting chars where the mouse was before.
+ X and Y can be negative or out of range. */
static void
note_mouse_highlight (f, x, y)
/* Are we in a window whose display is up to date?
And verify the buffer's text has not changed. */
- if (WINDOWP (window) && portion == 0
+ if (WINDOWP (window) && portion == 0 && row >= 0 && column >= 0
+ && row < FRAME_HEIGHT (f) && column < FRAME_WIDTH (f)
&& EQ (w->window_end_valid, w->buffer)
&& w->last_modified == BUF_MODIFF (XBUFFER (w->buffer)))
{
break;
pos = ptr[i];
/* Is it outside the displayed active region (if any)? */
- if (pos > 0
- && ! (EQ (window, mouse_face_window)
- && pos >= mouse_face_beg && pos < mouse_face_end))
+ if (pos <= 0)
+ clear_mouse_face ();
+ else if (! (EQ (window, mouse_face_window)
+ && row >= mouse_face_beg_row
+ && row <= mouse_face_end_row
+ && (row > mouse_face_beg_row || column >= mouse_face_beg_col)
+ && (row < mouse_face_end_row || column < mouse_face_end_col
+ || mouse_face_past_end)))
{
Lisp_Object mouse_face, overlay, position;
Lisp_Object *overlay_vec;
/* Put all the overlays we want in a vector in overlay_vec.
Store the length in len. */
- noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, &ignor1);
+ noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
+ NULL, NULL);
noverlays = sort_overlays (overlay_vec, noverlays, w);
/* Find the highest priority overlay that has a mouse-face prop. */
before = Foverlay_start (overlay);
after = Foverlay_end (overlay);
/* Record this as the current active region. */
- mouse_face_beg = XFASTINT (before);
- mouse_face_end = XFASTINT (after);
+ fast_find_position (window, before, &mouse_face_beg_col,
+ &mouse_face_beg_row);
+ mouse_face_past_end
+ = !fast_find_position (window, after, &mouse_face_end_col,
+ &mouse_face_end_row);
mouse_face_window = window;
mouse_face_face_id = compute_char_face (f, w, pos, 0, 0,
&ignore, pos + 1, 1);
= Fnext_single_property_change (position, Qmouse_face,
w->buffer, end);
/* Record this as the current active region. */
- mouse_face_beg = XFASTINT (before);
- mouse_face_end = XFASTINT (after);
+ fast_find_position (window, before, &mouse_face_beg_col,
+ &mouse_face_beg_row);
+ mouse_face_past_end
+ = !fast_find_position (window, after, &mouse_face_end_col,
+ &mouse_face_end_row);
mouse_face_window = window;
mouse_face_face_id
= compute_char_face (f, w, pos, 0, 0,
ZV = ozv;
current_buffer = obuf;
}
- else if (pos <= 0)
- clear_mouse_face ();
}
}
\f
This assumes display in WINDOW is up to date.
If POS is above start of WINDOW, return coords
of start of first screen line.
- If POS is after end of WINDOW, return coords of end of last screen line. */
+ If POS is after end of WINDOW, return coords of end of last screen line.
+
+ Value is 1 if POS is in range, 0 if it was off screen. */
static int
fast_find_position (window, pos, columnp, rowp)
struct window *w = XWINDOW (window);
FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
int i;
- int row;
+ int row = 0;
int left = w->left;
int top = w->top;
int height = XFASTINT (w->height) - ! MINI_WINDOW_P (w);
int *charstarts;
int lastcol;
+ /* Find the right row. */
for (i = 0;
i < height;
i++)
row = i;
}
+ /* Find the right column with in it. */
charstarts = FRAME_CURRENT_GLYPHS (f)->charstarts[top + row];
lastcol = left;
for (i = 0; i < width; i++)
return 1;
}
else if (charstarts[left + i] > pos)
+ break;
+ else if (charstarts[left + i] > 0)
lastcol = left + i;
}
show_mouse_face (hl)
int hl;
{
- int begcol, begrow, endcol, endrow;
struct window *w = XWINDOW (mouse_face_window);
int width = window_internal_width (w);
FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
int i;
- int curs_x = f->phys_cursor_x;
- int curs_y = f->phys_cursor_y;
int cursor_off = 0;
+ int old_curs_x = curs_x;
+ int old_curs_y = curs_y;
- fast_find_position (mouse_face_window, mouse_face_beg,
- &begcol, &begrow);
- fast_find_position (mouse_face_window, mouse_face_end,
- &endcol, &endrow);
+ /* Set these variables temporarily
+ so that if we have to turn the cursor off and on again
+ we will put it back at the same place. */
+ curs_x = f->phys_cursor_x;
+ curs_y = f->phys_cursor_y;
- for (i = begrow; i <= endrow; i++)
+ for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++)
{
- int column = (i == begrow ? begcol : w->left);
- int endcolumn = (i == endrow ? endcol : w->left + width);
- endcolumn = min (endcolumn, FRAME_CURRENT_GLYPHS (f)->used[i] - w->left);
+ int column = (i == mouse_face_beg_row ? mouse_face_beg_col : w->left);
+ int endcolumn = (i == mouse_face_end_row ? mouse_face_end_col : w->left + width);
+ endcolumn = min (endcolumn, FRAME_CURRENT_GLYPHS (f)->used[i]);
/* If the cursor's in the text we are about to rewrite,
turn the cursor off. */
if (i == curs_y
- && (curs_x >= begrow - 1 || curs_x <= endrow))
+ && curs_x >= mouse_face_beg_col - 1 && curs_x <= mouse_face_end_col)
{
x_display_cursor (f, 0);
cursor_off = 1;
if (cursor_off)
x_display_cursor (f, 1);
+ curs_x = old_curs_x;
+ curs_y = old_curs_y;
+
/* Change the mouse cursor according to the value of HL. */
if (hl > 0)
XDefineCursor (XDISPLAY FRAME_X_WINDOW (f), f->display.x->cross_cursor);
if (! NILP (mouse_face_window))
show_mouse_face (0);
- mouse_face_beg = -1;
- mouse_face_end = -1;
+ mouse_face_beg_row = mouse_face_beg_col = -1;
+ mouse_face_end_row = mouse_face_end_col = -1;
mouse_face_window = Qnil;
}
\f
win = root;
- if (x_mouse_grabbed)
+ if (x_mouse_grabbed && last_mouse_frame
+ && FRAME_LIVE_P (last_mouse_frame))
{
/* If mouse was grabbed on a frame, give coords for that frame
even if the mouse is now outside it. */
UNBLOCK_INPUT;
}
-
-#else /* ! defined (HAVE_X11) */
-#define XEvent XKeyPressedEvent
-#endif /* ! defined (HAVE_X11) */
\f
/* Scroll bar support. */
/* Where should this scroll bar be, pixelwise? */
int pixel_top = CHAR_TO_PIXEL_ROW (f, top);
int pixel_left = CHAR_TO_PIXEL_COL (f, left);
- int pixel_width = VERTICAL_SCROLL_BAR_PIXEL_WIDTH (f);
+ int pixel_width
+ = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
+ ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
+ : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->display.x->font)));
int pixel_height = VERTICAL_SCROLL_BAR_PIXEL_HEIGHT (f, height);
struct scroll_bar *bar;
moves and we can see *still* on the same position. */
{
int dummy;
+ Window dummy_window;
XQueryPointer (event->xmotion.display, event->xmotion.window,
- (Window *) &dummy, (Window *) &dummy,
+ &dummy_window, &dummy_window,
&dummy, &dummy, &dummy, &dummy,
(unsigned int *) &dummy);
}
{
Lisp_Object bar;
- for (bar = FRAME_SCROLL_BARS (f);
- XTYPE (bar) == Lisp_Vector;
+ for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
bar = XSCROLL_BAR (bar)->next)
XClearArea (x_current_display, SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)),
0, 0, 0, 0, True);
UNBLOCK_INPUT;
}
+\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 (event)
+ XEvent *event;
+{
+ struct selection_event_queue *queue_tmp
+ = (struct selection_event_queue *) malloc (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 ()
+{
+ while (queue != NULL)
+ {
+ struct selection_event_queue *queue_tmp = queue;
+ XPutBackEvent (XDISPLAY &queue_tmp->event);
+ queue = queue_tmp->next;
+ free ((char *)queue_tmp);
+ }
+}
+
+/* Start queuing SelectionRequest events. */
+
+void
+x_start_queuing_selection_requests ()
+{
+ x_queue_selection_requests++;
+}
+
+/* Stop queuing SelectionRequest events. */
+void
+x_stop_queuing_selection_requests ()
+{
+ x_queue_selection_requests--;
+ x_unqueue_events ();
+}
\f
/* The main X event-reading loop - XTread_socket. */
interrupt_input_pending = 0;
BLOCK_INPUT;
-
+
+ /* So people can tell when we have read the available input. */
+ input_signal_count++;
+
if (numchars <= 0)
abort (); /* Don't think this happens. */
switch (event.type)
{
-#ifdef HAVE_X11
case ClientMessage:
{
if (event.xclient.message_type == Xatom_wm_protocols
if (event.xclient.data.l[0] == Xatom_wm_take_focus)
{
f = x_window_to_frame (event.xclient.window);
-#if 0 /* x_focus_on_frame is a no-op anyway. */
+ /* Since we set WM_TAKE_FOCUS, we must call
+ XSetInputFocus explicitly. But not if f is null,
+ since that might be an event for a deleted frame. */
if (f)
- x_focus_on_frame (f);
- else
-#endif
- /* Since we set WM_TAKE_FOCUS, we must call
- XSetInputFocus explicitly. */
XSetInputFocus (event.xclient.display,
event.xclient.window,
RevertToPointerRoot,
a keyboard or mouse event arrives. */
if (numchars > 0)
{
+ /* This is just so we only give real data once
+ for a single Emacs process. */
+ if (x_top_window_to_frame (event.xclient.window)
+ == selected_frame)
+ XSetCommand (x_current_display,
+ event.xclient.window,
+ initial_argv, initial_argc);
+ else
+ XSetCommand (x_current_display,
+ event.xclient.window,
+ 0, 0);
}
}
else if (event.xclient.data.l[0] == Xatom_wm_delete_window)
if (!x_window_to_frame (event.xselectionrequest.owner))
goto OTHER;
#endif /* USE_X_TOOLKIT */
- {
- XSelectionRequestEvent *eventp = (XSelectionRequestEvent *) &event;
+ if (x_queue_selection_requests)
+ x_queue_event (&event);
+ else
+ {
+ XSelectionRequestEvent *eventp = (XSelectionRequestEvent *) &event;
- if (numchars == 0)
- abort ();
+ if (numchars == 0)
+ abort ();
- bufp->kind = selection_request_event;
- SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
- SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor;
- SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
- SELECTION_EVENT_TARGET (bufp) = eventp->target;
- SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
- SELECTION_EVENT_TIME (bufp) = eventp->time;
- bufp++;
+ bufp->kind = selection_request_event;
+ SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
+ SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor;
+ SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
+ SELECTION_EVENT_TARGET (bufp) = eventp->target;
+ SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
+ SELECTION_EVENT_TIME (bufp) = eventp->time;
+ bufp++;
- count += 1;
- numchars -= 1;
- }
+ count += 1;
+ numchars -= 1;
+ }
break;
case PropertyNotify:
break;
case ReparentNotify:
- f = x_window_to_frame (event.xreparent.window);
+ f = x_top_window_to_frame (event.xreparent.window);
if (f)
- f->display.x->parent_desc = event.xreparent.parent;
+ {
+ int x, y;
+ f->display.x->parent_desc = event.xreparent.parent;
+ x_real_positions (f, &x, &y);
+ f->display.x->left_pos = x;
+ f->display.x->top_pos = y;
+ }
break;
case Expose:
source area was completely
available */
break;
-#else /* ! defined (HAVE_X11) */
- case ExposeWindow:
- if (event.subwindow != 0)
- break; /* duplicate event */
- f = x_window_to_frame (event.window);
- if (event.window == f->display.x->icon_desc)
- {
- refreshicon (f);
- f->async_iconified = 1;
- }
- if (event.window == FRAME_X_WINDOW (f))
- {
- /* Say must check all windows' needs_exposure flags. */
- expose_all_windows = 1;
- f->display.x->needs_exposure = 1;
- f->async_visible = 1;
- }
- break;
-
- case ExposeRegion:
- if (event.subwindow != 0)
- break; /* duplicate event */
- f = x_window_to_frame (event.window);
- if (event.window == f->display.x->icon_desc)
- {
- refreshicon (f);
- break;
- }
- /* If window already needs full redraw, ignore this rectangle. */
- if (expose_all_windows && f->display.x->needs_exposure)
- break;
- /* Put the event on the queue of rectangles to redraw. */
- if (enqueue_event (&event, &x_expose_queue))
- /* If it is full, we can't record the rectangle,
- so redraw this entire window. */
- {
- /* Say must check all windows' needs_exposure flags. */
- expose_all_windows = 1;
- f->display.x->needs_exposure = 1;
- }
- break;
-
- case ExposeCopy:
- /* This should happen only when we are expecting it,
- in x_read_exposes. */
- abort ();
-#endif /* ! defined (HAVE_X11) */
-#ifdef HAVE_X11
case UnmapNotify:
f = x_any_window_to_frame (event.xunmap.window);
if (f) /* F may no longer exist if
case VisibilityNotify:
break;
-#else /* ! defined (HAVE_X11) */
- case UnmapWindow:
- f = x_window_to_frame (event.window);
- if (event.window == f->display.x->icon_desc)
- f->async_iconified = 0;
- if (event.window == FRAME_X_WINDOW (f))
- f->async_visible = 0;
- break;
-#endif /* ! defined (HAVE_X11) */
-
-#ifdef HAVE_X11
case KeyPress:
f = x_any_window_to_frame (event.xkey.window);
XLookupString (&event.xkey, copy_buffer, 80, &keysym,
&compose_status);
- /* Strip off the vendor-specific keysym bit, and take a shot
- at recognizing the codes. HP servers have extra keysyms
- that fit into the MiscFunctionKey category. */
orig_keysym = keysym;
- keysym &= ~(1<<28);
if (numchars > 1)
{
#endif
|| IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
|| IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
- || x_is_vendor_fkey (orig_keysym))
+ /* Any "vendor-specific" key is ok. */
+ || (orig_keysym & (1 << 28)))
&& ! (IsModifierKey (orig_keysym)
#ifndef HAVE_X11R5
#ifdef XK_Mode_switch
abort ();
}
break;
-#else /* ! defined (HAVE_X11) */
- case KeyPressed:
- {
- register char *where_mapping;
-
- f = x_window_to_frame (event.window);
- /* Ignore keys typed on icon windows. */
- if (f != 0 && event.window == f->display.x->icon_desc)
- break;
- where_mapping = XLookupMapping (&event, &nbytes);
- /* Nasty fix for arrow keys */
- if (!nbytes && IsCursorKey (event.detail & 0xff))
- {
- switch (event.detail & 0xff)
- {
- case KC_CURSOR_LEFT:
- where_mapping = "\002";
- break;
- case KC_CURSOR_RIGHT:
- where_mapping = "\006";
- break;
- case KC_CURSOR_UP:
- where_mapping = "\020";
- break;
- case KC_CURSOR_DOWN:
- where_mapping = "\016";
- break;
- }
- nbytes = 1;
- }
- if (numchars - nbytes > 0)
- {
- register int i;
-
- for (i = 0; i < nbytes; i++)
- {
- bufp->kind = ascii_keystroke;
- bufp->code = where_mapping[i];
- XSET (bufp->time, Lisp_Int, event.xkey.time);
- XSET (bufp->frame_or_window, Lisp_Frame, f);
- bufp++;
- }
- count += nbytes;
- numchars -= nbytes;
- }
- }
- break;
-#endif /* ! defined (HAVE_X11) */
-
-#ifdef HAVE_X11
/* Here's a possible interpretation of the whole
FocusIn-EnterNotify FocusOut-LeaveNotify mess. If you get a
}
else if (f == x_focus_frame)
x_new_focus_frame (0);
+ /* EnterNotify counts as mouse movement,
+ so update things that depend on mouse position. */
+ if (f)
+ note_mouse_movement (f, &event.xmotion);
#ifdef USE_X_TOOLKIT
goto OTHER;
#endif /* USE_X_TOOLKIT */
case LeaveNotify:
- f = x_any_window_to_frame (event.xcrossing.window);
-
- if (f == mouse_face_mouse_frame)
- /* If we move outside the frame,
- then we're certainly no longer on any text in the frame. */
- clear_mouse_face ();
-
- if (event.xcrossing.focus)
- {
- if (! x_focus_event_frame)
- x_new_focus_frame (0);
- else
- x_new_focus_frame (f);
- }
- else
+ f = x_top_window_to_frame (event.xcrossing.window);
+ if (f)
{
- if (f == x_focus_event_frame)
- x_focus_event_frame = 0;
- if (f == x_focus_frame)
- x_new_focus_frame (0);
+ if (f == mouse_face_mouse_frame)
+ /* If we move outside the frame,
+ then we're certainly no longer on any text in the frame. */
+ clear_mouse_face ();
+
+ if (event.xcrossing.focus)
+ {
+ if (! x_focus_event_frame)
+ x_new_focus_frame (0);
+ else
+ x_new_focus_frame (f);
+ }
+ else
+ {
+ if (f == x_focus_event_frame)
+ x_focus_event_frame = 0;
+ if (f == x_focus_frame)
+ x_new_focus_frame (0);
+ }
}
#ifdef USE_X_TOOLKIT
goto OTHER;
#endif /* USE_X_TOOLKIT */
break;
-#else /* ! defined (HAVE_X11) */
-
- case EnterWindow:
- if ((event.detail & 0xFF) == 1)
- break; /* Coming from our own subwindow */
- if (event.subwindow != 0)
- break; /* Entering our own subwindow. */
-
+ case MotionNotify:
{
- f = x_window_to_frame (event.window);
- x_mouse_frame = f;
-
- x_new_focus_frame (f);
- }
- break;
-
- case LeaveWindow:
- if ((event.detail & 0xFF) == 1)
- break; /* Entering our own subwindow */
- if (event.subwindow != 0)
- break; /* Leaving our own subwindow. */
-
- x_mouse_frame = 0;
- if (x_focus_frame == 0
- && x_input_frame != 0
- && x_input_frame == x_window_to_frame (event.window)
- && event.window == FRAME_X_WINDOW (x_input_frame))
- {
- f = x_input_frame;
- x_input_frame = 0;
- if (f)
- frame_unhighlight (f);
- }
- break;
-#endif /* ! defined (HAVE_X11) */
-
-#ifdef HAVE_X11
- case MotionNotify:
- {
- if (x_mouse_grabbed)
+ if (x_mouse_grabbed && last_mouse_frame
+ && FRAME_LIVE_P (last_mouse_frame))
f = last_mouse_frame;
else
f = x_window_to_frame (event.xmotion.window);
clear_mouse_face ();
}
}
+#if 0 /* This should be unnecessary, since the toolkit has no use
+ for motion events that happen outside of the menu event loop,
+ and it seems to cause the bug that mouse events stop coming
+ after a while. */
#ifdef USE_X_TOOLKIT
goto OTHER;
#endif /* USE_X_TOOLKIT */
+#endif
break;
case ConfigureNotify:
f = x_any_window_to_frame (event.xconfigure.window);
#ifdef USE_X_TOOLKIT
if (f
+#if 0
&& ! event.xconfigure.send_event
+#endif
&& (event.xconfigure.window == XtWindow (f->display.x->widget)))
{
Window win, child;
f->display.x->pixel_height = event.xconfigure.height;
f->display.x->left_pos = event.xconfigure.x;
f->display.x->top_pos = event.xconfigure.y;
+
+ /* What we have now is the position of Emacs's own window.
+ Convert that to the position of the window manager window. */
+ {
+ int x, y;
+ x_real_positions (f, &x, &y);
+ f->display.x->left_pos = x;
+ f->display.x->top_pos = y;
+ }
}
goto OTHER;
#else /* not USE_X_TOOLKIT */
f->display.x->pixel_height = event.xconfigure.height;
f->display.x->left_pos = event.xconfigure.x;
f->display.x->top_pos = event.xconfigure.y;
+
+ /* What we have now is the position of Emacs's own window.
+ Convert that to the position of the window manager window. */
+ {
+ int x, y;
+ x_real_positions (f, &x, &y);
+ f->display.x->left_pos = x;
+ f->display.x->top_pos = y;
+ if (y != event.xconfigure.y)
+ {
+ /* Since the WM decorations come below top_pos now,
+ we must put them below top_pos in the future. */
+ f->display.x->win_gravity = NorthWestGravity;
+ x_wm_set_size_hint (f, 0, 0);
+ }
+ }
}
#endif /* not USE_X_TOOLKIT */
break;
struct input_event emacs_event;
emacs_event.kind = no_event;
+ bzero (&compose_status, sizeof (compose_status));
+
f = x_window_to_frame (event.xbutton.window);
if (f)
{
}
else
{
- struct scroll_bar *bar =
- x_window_to_scroll_bar (event.xbutton.window);
+ struct scroll_bar *bar
+ = x_window_to_scroll_bar (event.xbutton.window);
if (bar)
x_scroll_bar_handle_click (bar, &event, &emacs_event);
#ifdef USE_X_TOOLKIT
else
{
- f = x_any_window_to_frame (event.xbutton.window);
- if (f && event.type == ButtonPress)
- construct_menu_click (&emacs_event,
- &event, f);
+ /* Assume we have a menubar button press. A bad
+ assumption should behave benignly. */
+ popup_get_selection (&event);
+ break;
}
#endif /* USE_X_TOOLKIT */
}
+ if (event.type == ButtonPress)
+ {
+ x_mouse_grabbed |= (1 << event.xbutton.button);
+ Vmouse_depressed = Qt;
+ last_mouse_frame = f;
+ }
+ else
+ {
+ x_mouse_grabbed &= ~(1 << event.xbutton.button);
+ if (!x_mouse_grabbed)
+ Vmouse_depressed = Qnil;
+ }
+
if (numchars >= 1 && emacs_event.kind != no_event)
{
bcopy (&emacs_event, bufp, sizeof (struct input_event));
}
break;
-#else /* ! defined (HAVE_X11) */
- case ButtonPressed:
- case ButtonReleased:
- f = x_window_to_frame (event.window);
- if (f)
- {
- if (event.window == f->display.x->icon_desc)
- {
- x_make_frame_visible (f);
-
- if (warp_mouse_on_deiconify)
- XWarpMouse (FRAME_X_WINDOW (f), 10, 10);
- break;
- }
- if (event.window == FRAME_X_WINDOW (f))
- {
- if (f->auto_raise)
- x_raise_frame (f);
- }
- }
- enqueue_event (&event, &x_mouse_queue);
- if (numchars >= 2)
- {
- bufp->kind = ascii_keystroke;
- bufp->code = 'X' & 037; /* C-x */
- XSET (bufp->frame_or_window, Lisp_Frame, f);
- XSET (bufp->time, Lisp_Int, event.xkey.time);
- bufp++;
-
- bufp->kind = ascii_keystroke;
- bufp->code = 0; /* C-@ */
- XSET (bufp->frame_or_window, Lisp_Frame, f);
- XSET (bufp->time, Lisp_Int, event.xkey.time);
- bufp++;
-
- count += 2;
- numchars -= 2;
- }
- break;
-#endif /* ! defined (HAVE_X11) */
-
-#ifdef HAVE_X11
-
case CirculateNotify:
break;
case CirculateRequest:
break;
-#endif /* ! defined (HAVE_X11) */
-
case MappingNotify:
/* Someone has changed the keyboard mapping - update the
local cache. */
}
}
-#ifdef X_IO_BUG
- if (! event_found)
- /* On some systems, an X bug causes Emacs to get no more events
- when the window is destroyed. Detect that. (1994.) */
- XNoOp (x_current_display);
-#endif /* X_IO_BUG */
+ /* On some systems, an X bug causes Emacs to get no more events
+ when the window is destroyed. Detect that. (1994.) */
+ if (! event_found)
+ {
+ /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
+ One XNOOP in 100 loops will make Emacs terminate.
+ B. Bretthauer, 1994 */
+ x_noop_count++;
+ if (x_noop_count >= 100)
+ {
+ x_noop_count=0;
+ XNoOp (x_current_display);
+ }
+ }
#if 0 /* This fails for serial-line connections to the X server,
because the characters arrive one by one, and a partial
#endif /* HAVE_SELECT */
#endif /* 0 */
-#ifndef HAVE_X11
- if (updating_frame == 0)
- x_do_pending_expose ();
-#endif
-
/* If the focus was just given to an autoraising frame,
raise it now. */
-#ifdef HAVE_X11
if (pending_autoraise_frame)
{
x_raise_frame (pending_autoraise_frame);
pending_autoraise_frame = 0;
}
-#endif
UNBLOCK_INPUT;
return count;
}
-
-#ifndef HAVE_X11
-/* Read and process only Expose events
- until we get an ExposeCopy event; then return.
- This is used in insert/delete line.
- We assume input is already blocked. */
-
-static void
-x_read_exposes ()
-{
- struct frame *f;
- XKeyPressedEvent event;
-
- while (1)
- {
- /* while there are more events*/
- XMaskEvent (ExposeWindow | ExposeRegion | ExposeCopy, &event);
- switch (event.type)
- {
- case ExposeWindow:
- if (event.subwindow != 0)
- break; /* duplicate event */
- f = x_window_to_frame (event.window);
- if (event.window == f->display.x->icon_desc)
- {
- refreshicon (f);
- break;
- }
- if (event.window == FRAME_X_WINDOW (f))
- {
- expose_all_windows = 1;
- f->display.x->needs_exposure = 1;
- break;
- }
- break;
-
- case ExposeRegion:
- if (event.subwindow != 0)
- break; /* duplicate event */
- f = x_window_to_frame (event.window);
- if (event.window == f->display.x->icon_desc)
- {
- refreshicon (f);
- break;
- }
- /* If window already needs full redraw, ignore this rectangle. */
- if (expose_all_windows && f->display.x->needs_exposure)
- break;
- /* Put the event on the queue of rectangles to redraw. */
- if (enqueue_event (&event, &x_expose_queue))
- /* If it is full, we can't record the rectangle,
- so redraw this entire window. */
- {
- /* Say must check all windows' needs_exposure flags. */
- expose_all_windows = 1;
- f->display.x->needs_exposure = 1;
- }
- break;
-
- case ExposeCopy:
- return;
- }
- }
-}
-#endif /* HAVE_X11 */
-
\f
/* Drawing the cursor. */
x_draw_box (f)
struct frame *f;
{
- int left = CHAR_TO_PIXEL_COL (f, f->cursor_x);
- int top = CHAR_TO_PIXEL_ROW (f, f->cursor_y);
+ int left = CHAR_TO_PIXEL_COL (f, curs_x);
+ int top = CHAR_TO_PIXEL_ROW (f, curs_y);
int width = FONT_WIDTH (f->display.x->font);
int height = f->display.x->line_height;
-#ifdef HAVE_X11
XDrawRectangle (x_current_display, FRAME_X_WINDOW (f),
f->display.x->cursor_gc,
left, top, width - 1, height - 1);
-#else /* ! defined (HAVE_X11) */
- XPixSet (FRAME_X_WINDOW (f),
- left, top, width, 1,
- f->display.x->cursor_pixel);
-
- XPixSet (FRAME_X_WINDOW (f),
- left, top, 1, height,
- f->display.x->cursor_pixel);
-
- XPixSet (FRAME_X_WINDOW (f),
- left+width-1, top, 1, height,
- f->display.x->cursor_pixel);
-
- XPixSet (FRAME_X_WINDOW (f),
- left, top+height-1, width, 1,
- f->display.x->cursor_pixel);
-#endif /* ! defined (HAVE_X11) */
}
/* Clear the cursor of frame F to background color,
|| f->phys_cursor_x < 0)
return;
-#ifdef HAVE_X11
x_display_cursor (f, 0);
-#else /* ! defined (HAVE_X11) */
- XPixSet (FRAME_X_WINDOW (f),
- CHAR_TO_PIXEL_COL (f, f->phys_cursor_x),
- CHAR_TO_PIXEL_ROW (f, f->phys_cursor_y),
- FONT_WIDTH (f->display.x->font), f->display.x->line_height,
- f->display.x->background_pixel);
-#endif /* ! defined (HAVE_X11) */
f->phys_cursor_x = -1;
}
|| (f->display.x->current_cursor != hollow_box_cursor
&& (f != x_highlight_frame))))
{
+ int mouse_face_here = 0;
+
+ /* If the cursor is in the mouse face area, redisplay that when
+ we clear the cursor. */
+ if (f == mouse_face_mouse_frame
+ &&
+ (f->phys_cursor_y > mouse_face_beg_row
+ || (f->phys_cursor_y == mouse_face_beg_row
+ && f->phys_cursor_x >= mouse_face_beg_col))
+ &&
+ (f->phys_cursor_y < mouse_face_end_row
+ || (f->phys_cursor_y == mouse_face_end_row
+ && f->phys_cursor_x < mouse_face_end_col)))
+ mouse_face_here = 1;
+
/* If the font is not as tall as a whole line,
we must explicitly clear the line's whole height. */
if (FONT_HEIGHT (f->display.x->font) != f->display.x->line_height)
/* Erase the cursor by redrawing the character underneath it. */
x_draw_single_glyph (f, f->phys_cursor_y, f->phys_cursor_x,
f->phys_cursor_glyph,
- current_glyphs->highlight[f->phys_cursor_y]);
+ (mouse_face_here
+ ? 3
+ : current_glyphs->highlight[f->phys_cursor_y]));
f->phys_cursor_x = -1;
}
refreshicon (f)
struct frame *f;
{
-#ifdef HAVE_X11
/* Normally, the window manager handles this function. */
-#else /* ! defined (HAVE_X11) */
- int mask;
-
- if (f->display.x->icon_bitmap_flag)
- XBitmapBitsPut (f->display.x->icon_desc, 0, 0, sink_width, sink_height,
- sink_bits, BlackPixel, WHITE_PIX_DEFAULT,
- icon_bitmap, GXcopy, AllPlanes);
- else
- {
- extern struct frame *selected_frame;
- struct Lisp_String *str;
- unsigned char *string;
-
- string
- = XSTRING (XBUFFER (XWINDOW (f->selected_window)->buffer)->name)->data;
-
- if (f->display.x->icon_label != string)
- {
- f->display.x->icon_label = string;
- XChangeWindow (f->display.x->icon_desc,
- XQueryWidth (string, icon_font_info->id) + 10,
- icon_font_info->height + 10);
- }
-
- XText (f->display.x->icon_desc, 5, 5, string,
- str->size, icon_font_info->id,
- BLACK_PIX_DEFAULT, WHITE_PIX_DEFAULT);
- }
- XFlushQueue ();
-#endif /* ! defined (HAVE_X11) */
}
/* Make the x-window of frame F use the gnu icon bitmap. */
if (FRAME_X_WINDOW (f) == 0)
return 1;
-#ifdef HAVE_X11
if (! icon_bitmap)
icon_bitmap =
XCreateBitmapFromData (x_current_display, FRAME_X_WINDOW (f),
gnu_bits, gnu_width, gnu_height);
x_wm_set_icon_pixmap (f, icon_bitmap);
f->display.x->icon_bitmap_flag = 1;
-#else /* ! defined (HAVE_X11) */
- if (f->display.x->icon_desc)
- {
- XClearIconWindow (FRAME_X_WINDOW (f));
- XDestroyWindow (f->display.x->icon_desc);
- }
-
- icon_window = XCreateWindow (f->display.x->parent_desc,
- 0, 0, sink_width, sink_height,
- 2, WhitePixmap, (Pixmap) NULL);
-
- if (icon_window == 0)
- return 1;
-
- XSetIconWindow (FRAME_X_WINDOW (f), icon_window);
- XSelectInput (icon_window, ExposeWindow | UnmapWindow);
-
- f->display.x->icon_desc = icon_window;
- f->display.x->icon_bitmap_flag = 1;
-
- if (icon_bitmap == 0)
- icon_bitmap
- = XStoreBitmap (sink_mask_width, sink_mask_height, sink_mask_bits);
-#endif /* ! defined (HAVE_X11) */
return 0;
}
struct frame *f;
char *icon_name;
{
-#ifndef HAVE_X11
- int mask;
- int width;
- Window icon_window;
- char *X_DefaultValue;
- Bitmap b1;
-
-#ifndef WhitePixel
-#define WhitePixel 1
-#endif /* WhitePixel */
-
-#ifndef BlackPixel
-#define BlackPixel 0
-#endif /* BlackPixel */
-#endif /* HAVE_X11 */
-
if (FRAME_X_WINDOW (f) == 0)
return 1;
-#ifdef HAVE_X11
if (icon_name)
f->display.x->icon_label = icon_name;
else
f->display.x->icon_bitmap_flag = 0;
x_wm_set_icon_pixmap (f, 0);
-#else /* ! defined (HAVE_X11) */
- if (icon_font_info == 0)
- icon_font_info
- = XGetFont (XGetDefault (XDISPLAY
- (char *) XSTRING (Vinvocation_name)->data,
- "BodyFont"));
-
- if (f->display.x->icon_desc)
- {
- XClearIconWindow (XDISPLAY FRAME_X_WINDOW (f));
- XDestroyWindow (XDISPLAY f->display.x->icon_desc);
- }
-
- if (icon_name)
- f->display.x->icon_label = (unsigned char *) icon_name;
- else
- if (! f->display.x->icon_label)
- f->display.x->icon_label = XSTRING (f->name)->data;
-
- width = XStringWidth (f->display.x->icon_label, icon_font_info, 0, 0);
- icon_window = XCreateWindow (f->display.x->parent_desc,
- f->display.x->left_pos,
- f->display.x->top_pos,
- width + 10, icon_font_info->height + 10,
- 2, BlackPixmap, WhitePixmap);
-
- if (icon_window == 0)
- return 1;
-
- XSetIconWindow (FRAME_X_WINDOW (f), icon_window);
- XSelectInput (icon_window, ExposeWindow | ExposeRegion | UnmapWindow | ButtonPressed);
-
- f->display.x->icon_desc = icon_window;
- f->display.x->icon_bitmap_flag = 0;
- f->display.x->icon_label = 0;
-#endif /* ! defined (HAVE_X11) */
return 0;
}
to the font named NEWNAME. This is safe to use
even before F has an actual x-window. */
-#ifdef HAVE_X11
-
struct font_info
{
XFontStruct *font;
char *name;
+ char *full_name;
};
/* A table of all the fonts we have already loaded. */
0 <= n_fonts <= x_font_table_size. */
static int n_fonts;
+/* Give frame F the font named FONTNAME as its default font, and
+ return the full name of that font. FONTNAME may be a wildcard
+ pattern; in that case, we choose some font that fits the pattern.
+ The return value shows which font we chose. */
+
Lisp_Object
x_new_font (f, fontname)
struct frame *f;
for (i = 0; i < n_fonts; i++)
for (j = 0; j < n_matching_fonts; j++)
- if (!strcmp (x_font_table[i].name, font_names[j]))
+ if (!strcmp (x_font_table[i].name, font_names[j])
+ || !strcmp (x_font_table[i].full_name, font_names[j]))
{
already_loaded = i;
- fontname = font_names[j];
+ fontname = x_font_table[i].full_name;
goto found_font;
}
}
/* If we have, just return it from the table. */
if (already_loaded >= 0)
f->display.x->font = x_font_table[already_loaded].font;
-
/* Otherwise, load the font and add it to the table. */
else
{
int i;
+ char *full_name;
XFontStruct *font;
/* Try to find a character-cell font in the list. */
* sizeof (x_font_table[0])));
}
+ /* Try to get the full name of FONT. Put it in full_name. */
+ full_name = 0;
+ for (i = 0; i < font->n_properties; i++)
+ {
+ char *atom
+ = XGetAtomName (x_current_display, font->properties[i].name);
+ if (!strcmp (atom, "FONT"))
+ {
+ char *name = XGetAtomName (x_current_display,
+ (Atom) (font->properties[i].card32));
+ char *p = name;
+ int dashes = 0;
+
+ /* Count the number of dashes in the "full name".
+ If it is too few, this isn't really the font's full name,
+ so don't use it.
+ In X11R4, the fonts did not come with their canonical names
+ stored in them. */
+ while (*p)
+ {
+ if (*p == '-')
+ dashes++;
+ p++;
+ }
+
+ if (dashes >= 13)
+ full_name = name;
+ }
+
+ XFree (atom);
+ }
+
x_font_table[n_fonts].name = (char *) xmalloc (strlen (fontname) + 1);
bcopy (fontname, x_font_table[n_fonts].name, strlen (fontname) + 1);
+ if (full_name != 0)
+ x_font_table[n_fonts].full_name = full_name;
+ else
+ x_font_table[n_fonts].full_name = x_font_table[n_fonts].name;
f->display.x->font = x_font_table[n_fonts++].font = font;
+
+ if (full_name)
+ fontname = full_name;
}
+ /* Compute the scroll bar width in character columns. */
+ if (f->scroll_bar_pixel_width > 0)
+ {
+ int wid = FONT_WIDTH (f->display.x->font);
+ f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
+ }
+ else
+ f->scroll_bar_cols = 2;
+
/* Now make the frame display the given font. */
if (FRAME_X_WINDOW (f) != 0)
{
return lispy_name;
}
}
-#else /* ! defined (HAVE_X11) */
-x_new_font (f, newname)
- struct frame *f;
- register char *newname;
-{
- FONT_TYPE *temp;
- int mask;
-
- temp = XGetFont (newname);
- if (temp == (FONT_TYPE *) 0)
- return 1;
-
- if (f->display.x->font)
- XLoseFont (f->display.x->font);
-
- f->display.x->font = temp;
-
- if (FRAME_X_WINDOW (f) != 0)
- x_set_window_size (f, 0, f->width, f->height);
-
- return 0;
-}
-#endif /* ! defined (HAVE_X11) */
\f
x_calc_absolute_position (f)
struct frame *f;
{
-#ifdef HAVE_X11
Window win, child;
int win_x = 0, win_y = 0;
+ int flags = f->display.x->size_hint_flags;
/* Find the position of the outside upper-left corner of
the inner window, with respect to the outer window. */
/* Treat negative positions as relative to the leftmost bottommost
position that fits on the screen. */
- if (f->display.x->left_pos < 0)
+ if (flags & XNegative)
f->display.x->left_pos = (x_screen_width
- 2 * f->display.x->border_width - win_x
- PIXEL_WIDTH (f)
+ f->display.x->left_pos);
- if (f->display.x->top_pos < 0)
+ if (flags & YNegative)
f->display.x->top_pos = (x_screen_height
- 2 * f->display.x->border_width - win_y
- PIXEL_HEIGHT (f)
+ f->display.x->top_pos);
-
-#else /* ! defined (HAVE_X11) */
- WINDOWINFO_TYPE parentinfo;
-
- XGetWindowInfo (FRAME_X_WINDOW (f), &parentinfo);
-
- if (f->display.x->left_pos < 0)
- f->display.x->left_pos = parentinfo.width + (f->display.x->left_pos + 1)
- - PIXEL_WIDTH (f) - 2 * f->display.x->internal_border_width;
-
- if (f->display.x->top_pos < 0)
- f->display.x->top_pos = parentinfo.height + (f->display.x->top_pos + 1)
- - PIXEL_HEIGHT (f) - 2 * f->display.x->internal_border_width;
-#endif /* ! defined (HAVE_X11) */
+ /* The left_pos and top_pos
+ are now relative to the top and left screen edges,
+ so the flags should correspond. */
+ f->display.x->size_hint_flags &= ~ (XNegative | YNegative);
}
+/* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
+ to really change the position, and 0 when calling from
+ x_make_frame_visible (in that case, XOFF and YOFF are the current
+ position values). */
+
x_set_offset (f, xoff, yoff, change_gravity)
struct frame *f;
register int xoff, yoff;
int change_gravity;
{
- f->display.x->top_pos = yoff;
- f->display.x->left_pos = xoff;
+ if (change_gravity)
+ {
+ f->display.x->top_pos = yoff;
+ f->display.x->left_pos = xoff;
+ f->display.x->size_hint_flags &= ~ (XNegative | YNegative);
+ if (xoff < 0)
+ f->display.x->size_hint_flags |= XNegative;
+ if (yoff < 0)
+ f->display.x->size_hint_flags |= YNegative;
+ f->display.x->win_gravity = NorthWestGravity;
+ }
x_calc_absolute_position (f);
BLOCK_INPUT;
+ x_wm_set_size_hint (f, 0, 0);
+
#ifdef USE_X_TOOLKIT
XMoveWindow (XDISPLAY XtWindow (f->display.x->widget),
f->display.x->left_pos, f->display.x->top_pos);
XMoveWindow (XDISPLAY FRAME_X_WINDOW (f),
f->display.x->left_pos, f->display.x->top_pos);
#endif /* not USE_X_TOOLKIT */
-#ifdef HAVE_X11
- if (change_gravity)
- f->display.x->win_gravity = NorthWestGravity;
-
- x_wm_set_size_hint (f, 0, 1);
-#endif /* ! defined (HAVE_X11) */
UNBLOCK_INPUT;
}
#ifdef USE_X_TOOLKIT
BLOCK_INPUT;
- EmacsFrameSetCharSize (f->display.x->edit_widget, cols, rows);
+ {
+ /* The x and y position of the widget is clobbered by the
+ call to XtSetValues within EmacsFrameSetCharSize.
+ This is a real kludge, but I don't understand Xt so I can't
+ figure out a correct fix. Can anyone else tell me? -- rms. */
+ int xpos = f->display.x->widget->core.x;
+ int ypos = f->display.x->widget->core.y;
+ EmacsFrameSetCharSize (f->display.x->edit_widget, cols, rows);
+ f->display.x->widget->core.x = xpos;
+ f->display.x->widget->core.y = ypos;
+ }
UNBLOCK_INPUT;
#else /* not USE_X_TOOLKIT */
check_frame_size (f, &rows, &cols);
f->display.x->vertical_scroll_bar_extra
- = (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
- ? VERTICAL_SCROLL_BAR_PIXEL_WIDTH (f)
- : 0);
+ = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
+ ? 0
+ : FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
+ ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
+ : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->display.x->font)));
pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
-#ifdef HAVE_X11
- x_wm_set_size_hint (f, 0, change_gravity);
-#endif /* ! defined (HAVE_X11) */
+ f->display.x->win_gravity = NorthWestGravity;
+ x_wm_set_size_hint (f, 0, 0);
+
XSync (x_current_display, False);
XChangeWindowSize (FRAME_X_WINDOW (f), pixelwidth, pixelheight);
PIXEL_WIDTH (f) = pixelwidth;
PIXEL_HEIGHT (f) = pixelheight;
+ /* If cursor was outside the new size, mark it as off. */
+ if (f->phys_cursor_y >= rows
+ || f->phys_cursor_x >= cols)
+ {
+ f->phys_cursor_x = -1;
+ f->phys_cursor_y = -1;
+ }
+
/* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
receive in the ConfigureNotify event; if we get what we asked
for, then the event won't cause the screen to become garbaged, so
UNBLOCK_INPUT;
#endif /* not USE_X_TOOLKIT */
}
-
-#ifndef HAVE_X11
-x_set_resize_hint (f)
- struct frame *f;
-{
- XSetResizeHint (FRAME_X_WINDOW (f),
- 2 * f->display.x->internal_border_width,
- 2 * f->display.x->internal_border_width,
- FONT_WIDTH (f->display.x->font),
- f->display.x->line_height);
-}
-#endif /* HAVE_X11 */
\f
/* Mouse warping, focus shifting, raising and lowering. */
+void
x_set_mouse_position (f, x, y)
struct frame *f;
int x, y;
{
int pix_x, pix_y;
-#if 0 /* Let the user ask for this if he wants it. */
- x_raise_frame (f);
-#endif
-
pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH (f->display.x->font) / 2;
pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->display.x->line_height / 2;
UNBLOCK_INPUT;
}
-#ifdef HAVE_X11
+/* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
+
+void
+x_set_mouse_pixel_position (f, pix_x, pix_y)
+ struct frame *f;
+ int pix_x, pix_y;
+{
+ BLOCK_INPUT;
+
+ XWarpMousePointer (FRAME_X_WINDOW (f), pix_x, pix_y);
+ UNBLOCK_INPUT;
+}
+
x_focus_on_frame (f)
struct frame *f;
{
#endif /* ! 0 */
}
-#endif /* ! defined (HAVE_X11) */
-
/* Raise frame F. */
x_raise_frame (f)
x_lower_frame (f);
}
-
-/* Change from withdrawn state to mapped state. */
+/* Change from withdrawn state to mapped state,
+ or deiconify. */
x_make_frame_visible (f)
struct frame *f;
if (! FRAME_VISIBLE_P (f))
{
-#ifdef HAVE_X11
- x_set_offset (f, f->display.x->left_pos, f->display.x->top_pos, 0);
+#ifndef USE_X_TOOLKIT
+ if (! FRAME_ICONIFIED_P (f))
+ x_set_offset (f, f->display.x->left_pos, f->display.x->top_pos, 0);
+#endif
if (! EQ (Vx_no_window_manager, Qt))
x_wm_set_window_state (f, NormalState);
#ifdef USE_X_TOOLKIT
- XtPopup (f->display.x->widget, XtGrabNone);
+ /* This was XtPopup, but that did nothing for an iconified frame. */
+ XtMapWidget (f->display.x->widget);
#else /* not USE_X_TOOLKIT */
XMapWindow (XDISPLAY FRAME_X_WINDOW (f));
#endif /* not USE_X_TOOLKIT */
if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
XMapSubwindows (x_current_display, FRAME_X_WINDOW (f));
#endif
-#else /* ! defined (HAVE_X11) */
- XMapWindow (XDISPLAY FRAME_X_WINDOW (f));
- if (f->display.x->icon_desc != 0)
- XUnmapWindow (f->display.x->icon_desc);
-
- /* Handled by the MapNotify event for X11 */
- f->async_visible = 1;
- f->async_iconified = 0;
-
- /* NOTE: this may cause problems for the first frame. */
- XTcursor_to (0, 0);
-#endif /* ! defined (HAVE_X11) */
}
XFlushQueue ();
- UNBLOCK_INPUT;
+ /* Synchronize to ensure Emacs knows the frame is visible
+ before we do anything else. We do this loop with input not blocked
+ so that incoming events are handled. */
+ {
+ Lisp_Object frame;
+ int count = input_signal_count;
+
+ /* This must come after we set COUNT. */
+ UNBLOCK_INPUT;
+
+ XSET (frame, Lisp_Frame, f);
+
+ while (1)
+ {
+ x_sync (frame);
+ /* Once we have handled input events,
+ we should have received the MapNotify if one is coming.
+ So if we have not got it yet, stop looping.
+ Some window managers make their own decisions
+ about visibility. */
+ if (input_signal_count != count)
+ break;
+ /* Machines that do polling rather than SIGIO have been observed
+ to go into a busy-wait here. So we'll fake an alarm signal
+ to let the handler know that there's something to be read.
+ We used to raise a real alarm, but it seems that the handler
+ isn't always enabled here. This is probably a bug. */
+ if (input_polling_used ())
+ {
+ /* It could be confusing if a real alarm arrives while processing
+ the fake one. Turn it off and let the handler reset it. */
+ alarm (0);
+ input_poll_signal ();
+ }
+ /* Once we have handled input events,
+ we should have received the MapNotify if one is coming.
+ So if we have not got it yet, stop looping.
+ Some window managers make their own decisions
+ about visibility. */
+ if (input_signal_count != count)
+ break;
+ }
+ FRAME_SAMPLE_VISIBILITY (f);
+ }
}
/* Change from mapped state to withdrawn state. */
struct frame *f;
{
int mask;
+ Window window;
+
+#ifdef USE_X_TOOLKIT
+ /* Use the frame's outermost window, not the one we normally draw on. */
+ window = XtWindow (f->display.x->widget);
+#else /* not USE_X_TOOLKIT */
+ window = FRAME_X_WINDOW (f);
+#endif /* not USE_X_TOOLKIT */
/* Don't keep the highlight on an invisible frame. */
if (x_highlight_frame == f)
BLOCK_INPUT;
+ /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
+ that the current position of the window is user-specified, rather than
+ program-specified, so that when the window is mapped again, it will be
+ placed at the same location, without forcing the user to position it
+ by hand again (they have already done that once for this window.) */
+ x_wm_set_size_hint (f, 0, 1);
+
#ifdef HAVE_X11R4
-#ifdef USE_X_TOOLKIT
- XtPopdown (f->display.x->widget);
-#else /* not USE_X_TOOLKIT */
- if (! XWithdrawWindow (x_current_display, FRAME_X_WINDOW (f),
+ if (! XWithdrawWindow (x_current_display, window,
DefaultScreen (x_current_display)))
{
UNBLOCK_INPUT_RESIGNAL;
- error ("can't notify window manager of window withdrawal");
+ error ("Can't notify window manager of window withdrawal");
}
-#endif /* not USE_X_TOOLKIT */
-
#else /* ! defined (HAVE_X11R4) */
-#ifdef HAVE_X11
/* Tell the window manager what we're going to do. */
if (! EQ (Vx_no_window_manager, Qt))
XEvent unmap;
unmap.xunmap.type = UnmapNotify;
-#ifdef USE_X_TOOLKIT
- unmap.xunmap.window = XtWindow (f->display.x->widget);
-#else /* not USE_X_TOOLKIT */
- unmap.xunmap.window = FRAME_X_WINDOW (f);
-#endif /* not USE_X_TOOLKIT */
+ unmap.xunmap.window = window;
unmap.xunmap.event = DefaultRootWindow (x_current_display);
unmap.xunmap.from_configure = False;
if (! XSendEvent (x_current_display,
&unmap))
{
UNBLOCK_INPUT_RESIGNAL;
- error ("can't notify window manager of withdrawal");
+ error ("Can't notify window manager of withdrawal");
}
}
/* Unmap the window ourselves. Cheeky! */
-#ifdef USE_X_TOOLKIT
- XUnmapWindow (x_current_display, XtWindow (f->display.x->widget));
-#else /* not USE_X_TOOLKIT */
- XUnmapWindow (x_current_display, FRAME_X_WINDOW (f));
-#endif /* not USE_X_TOOLKIT */
-#else /* ! defined (HAVE_X11) */
-
- XUnmapWindow (FRAME_X_WINDOW (f));
- if (f->display.x->icon_desc != 0)
- XUnmapWindow (f->display.x->icon_desc);
-
-#endif /* ! defined (HAVE_X11) */
+ XUnmapWindow (x_current_display, window);
#endif /* ! defined (HAVE_X11R4) */
/* We can't distinguish this from iconification
#ifdef USE_X_TOOLKIT
BLOCK_INPUT;
+
+ if (! FRAME_VISIBLE_P (f))
+ {
+ if (! EQ (Vx_no_window_manager, Qt))
+ x_wm_set_window_state (f, IconicState);
+ /* This was XtPopup, but that did nothing for an iconified frame. */
+ XtMapWidget (f->display.x->widget);
+ UNBLOCK_INPUT;
+ return;
+ }
+
result = XIconifyWindow (x_current_display,
XtWindow (f->display.x->widget),
DefaultScreen (x_current_display));
UNBLOCK_INPUT;
if (!result)
- error ("Can't notify window manager of iconification.");
+ error ("Can't notify window manager of iconification");
f->async_iconified = 1;
BLOCK_INPUT;
-#ifdef HAVE_X11
+ /* Make sure the X server knows where the window should be positioned,
+ in case the user deiconifies with the window manager. */
+ if (! FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f))
+ x_set_offset (f, f->display.x->left_pos, f->display.x->top_pos, 0);
+
/* Since we don't know which revision of X we're running, we'll use both
the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
&message))
{
UNBLOCK_INPUT_RESIGNAL;
- error ("Can't notify window manager of iconification.");
+ error ("Can't notify window manager of iconification");
}
}
}
f->async_iconified = 1;
-#else /* ! defined (HAVE_X11) */
- XUnmapWindow (XDISPLAY FRAME_X_WINDOW (f));
-
- f->async_visible = 0; /* Handled in the UnMap event for X11. */
- if (f->display.x->icon_desc != 0)
- {
- XMapWindow (XDISPLAY f->display.x->icon_desc);
- refreshicon (f);
- }
-#endif /* ! defined (HAVE_X11) */
XFlushQueue ();
UNBLOCK_INPUT;
free_frame_faces (f);
XFlushQueue ();
+ FRAME_X_SCREEN (f)->reference_count--;
+#if 0
+ if (FRAME_X_SCREEN (f)->reference_count == 0)
+ free (FRAME_X_SCREEN (f));
+#endif
+
xfree (f->display.x);
f->display.x = 0;
if (f == x_focus_frame)
if (f == mouse_face_mouse_frame)
{
- mouse_face_beg = -1;
- mouse_face_end = -1;
+ mouse_face_beg_row = mouse_face_beg_col = -1;
+ mouse_face_end_row = mouse_face_end_col = -1;
mouse_face_window = Qnil;
}
UNBLOCK_INPUT;
}
\f
-/* Manage event queues for X10. */
-
-#ifndef HAVE_X11
-
-/* Manage event queues.
-
- This code is only used by the X10 support.
-
- We cannot leave events in the X queue and get them when we are ready
- because X does not provide a subroutine to get only a certain kind
- of event but not block if there are no queued events of that kind.
-
- Therefore, we must examine events as they come in and copy events
- of certain kinds into our private queues.
-
- All ExposeRegion events are put in x_expose_queue.
- All ButtonPress and ButtonRelease events are put in x_mouse_queue. */
-
-
-/* Write the event *P_XREP into the event queue *QUEUE.
- If the queue is full, do nothing, but return nonzero. */
-
-int
-enqueue_event (p_xrep, queue)
- register XEvent *p_xrep;
- register struct event_queue *queue;
-{
- int newindex = queue->windex + 1;
- if (newindex == EVENT_BUFFER_SIZE)
- newindex = 0;
- if (newindex == queue->rindex)
- return -1;
- queue->xrep[queue->windex] = *p_xrep;
- queue->windex = newindex;
- return 0;
-}
-
-/* Fetch the next event from queue *QUEUE and store it in *P_XREP.
- If *QUEUE is empty, do nothing and return 0. */
-
-int
-dequeue_event (p_xrep, queue)
- register XEvent *p_xrep;
- register struct event_queue *queue;
-{
- if (queue->windex == queue->rindex)
- return 0;
- *p_xrep = queue->xrep[queue->rindex++];
- if (queue->rindex == EVENT_BUFFER_SIZE)
- queue->rindex = 0;
- return 1;
-}
-
-/* Return the number of events buffered in *QUEUE. */
-
-int
-queue_event_count (queue)
- register struct event_queue *queue;
-{
- int tem = queue->windex - queue->rindex;
- if (tem >= 0)
- return tem;
- return EVENT_BUFFER_SIZE + tem;
-}
-
-/* Return nonzero if mouse input is pending. */
-
-int
-mouse_event_pending_p ()
-{
- return queue_event_count (&x_mouse_queue);
-}
-#endif /* HAVE_X11 */
-\f
/* Setting window manager hints. */
-#ifdef HAVE_X11
-
-/* SPEC_X and SPEC_Y are the specified positions.
- We look only at their sign, to decide the gravity.
- If CHANGE_GRAVITY is 0, we may set PWinGravity. */
+/* Set the normal size hints for the window manager, for frame F.
+ FLAGS is the flags word to use--or 0 meaning preserve the flags
+ that the window now has.
+ If USER_POSITION is nonzero, we set the USPosition
+ flag (this is useful when FLAGS is 0). */
-x_wm_set_size_hint (f, prompting, change_gravity)
+x_wm_set_size_hint (f, flags, user_position)
struct frame *f;
- long prompting;
- int change_gravity;
+ long flags;
+ int user_position;
{
XSizeHints size_hints;
Window window = FRAME_X_WINDOW (f);
#endif /* not USE_X_TOOLKIT */
+ /* Setting PMaxSize caused various problems. */
size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
flexlines = f->height;
size_hints.x = f->display.x->left_pos;
size_hints.y = f->display.x->top_pos;
+
#ifdef USE_X_TOOLKIT
XtSetArg (al[ac], XtNwidth, &widget_width); ac++;
XtSetArg (al[ac], XtNheight, &widget_height); ac++;
size_hints.height = PIXEL_HEIGHT (f);
size_hints.width = PIXEL_WIDTH (f);
#endif /* not USE_X_TOOLKIT */
+
size_hints.width_inc = FONT_WIDTH (f->display.x->font);
size_hints.height_inc = f->display.x->line_height;
+ size_hints.max_width = x_screen_width - CHAR_TO_PIXEL_WIDTH (f, 0);
+ size_hints.max_height = x_screen_height - CHAR_TO_PIXEL_HEIGHT (f, 0);
{
int base_width, base_height;
#endif
}
- if (prompting)
- size_hints.flags |= prompting;
+ if (flags)
+ size_hints.flags |= flags;
else
{
XSizeHints hints; /* Sometimes I hate X Windows... */
+ long supplied_return;
+ int value;
+
+#ifdef HAVE_X11R4
+ value = XGetWMNormalHints (x_current_display, window, &hints,
+ &supplied_return);
+#else
+ value = XGetNormalHints (x_current_display, window, &hints);
+#endif
- if (XGetNormalHints (x_current_display, window, &hints) == 0)
+ if (value == 0)
hints.flags = 0;
if (hints.flags & PSize)
size_hints.flags |= PSize;
size_hints.flags |= USSize;
}
+#ifdef PWinGravity
size_hints.win_gravity = f->display.x->win_gravity;
+ size_hints.flags |= PWinGravity;
-#if defined (PWinGravity)
- if (change_gravity)
+ if (user_position)
{
- if (! (size_hints.flags & USPosition))
- size_hints.flags |= PWinGravity;
+ size_hints.flags &= ~ PPosition;
+ size_hints.flags |= USPosition;
}
#endif /* PWinGravity */
int state;
{
#ifdef USE_X_TOOLKIT
- Window window = XtWindow (f->display.x->widget);
+ Arg al[1];
+
+ XtSetArg (al[0], XtNinitialState, state);
+ XtSetValues (f->display.x->widget, al, 1);
#else /* not USE_X_TOOLKIT */
Window window = FRAME_X_WINDOW (f);
-#endif /* not USE_X_TOOLKIT */
f->display.x->wm_hints.flags |= StateHint;
f->display.x->wm_hints.initial_state = state;
XSetWMHints (x_current_display, window, &f->display.x->wm_hints);
+#endif /* not USE_X_TOOLKIT */
}
x_wm_set_icon_pixmap (f, icon_pixmap)
struct frame *f;
Pixmap icon_pixmap;
{
+#ifdef USE_X_TOOLKIT
+ Window window = XtWindow (f->display.x->widget);
+#else
Window window = FRAME_X_WINDOW (f);
+#endif
if (icon_pixmap)
{
struct frame *f;
int icon_x, icon_y;
{
+#ifdef USE_X_TOOLKIT
+ Window window = XtWindow (f->display.x->widget);
+#else
Window window = FRAME_X_WINDOW (f);
+#endif
f->display.x->wm_hints.flags |= IconPositionHint;
f->display.x->wm_hints.icon_x = icon_x;
#endif /* USE_X_TOOLKIT */
void
-x_term_init (display_name)
+x_term_init (display_name, xrm_option, resource_name)
char *display_name;
+ char *xrm_option;
+ char *resource_name;
{
Lisp_Object frame;
char *defaultvalue;
#endif /* ! defined (F_SETOWN) */
#endif /* F_SETOWN_BUG */
+ x_noop_count = 0;
+
x_focus_frame = x_highlight_frame = 0;
#ifdef USE_X_TOOLKIT
- argv = (char **) XtMalloc (5 * sizeof (char *));
- argv [0] = "";
- argv [1] = "-display";
- argv [2] = display_name;
- argv [3] = "-name";
- argv [4] = "emacs";
+ argv = (char **) XtMalloc (7 * sizeof (char *));
+ argv[0] = "";
+ argv[1] = "-display";
+ argv[2] = display_name;
+ argv[3] = "-name";
+ /* Usually `emacs', but not always. */
+ argv[4] = resource_name;
argc = 5;
+ if (xrm_option)
+ {
+ argv[argc++] = "-xrm";
+ argv[argc++] = xrm_option;
+ }
Xt_app_shell = XtAppInitialize (&Xt_app_con, "Emacs",
emacs_options, XtNumber (emacs_options),
&argc, argv,
NULL, NULL, 0);
- XtFree (argv);
+ XtFree ((char *)argv);
x_current_display = XtDisplay (Xt_app_shell);
#else /* not USE_X_TOOLKIT */
Check the DISPLAY environment variable or use \"-d\"\n",
display_name);
-#ifdef HAVE_X11
{
#if 0
XSetAfterFunction (x_current_display, x_trace_wire);
#endif /* ! 0 */
- hostname = get_system_name ();
x_id_name = (char *) xmalloc (XSTRING (Vinvocation_name)->size
- + strlen (hostname)
+ + XSTRING (Vsystem_name)->size
+ 2);
- sprintf (x_id_name, "%s@%s", XSTRING (Vinvocation_name)->data, hostname);
+ sprintf (x_id_name, "%s@%s",
+ XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
}
/* Figure out which modifier bits mean what. */
change_keyboard_wait_descriptor (ConnectionNumber (x_current_display));
change_input_fd (ConnectionNumber (x_current_display));
-#endif /* ! defined (HAVE_X11) */
-
#ifndef F_SETOWN_BUG
#ifdef F_SETOWN
old_fcntl_owner = fcntl (ConnectionNumber (x_current_display), F_GETOWN, 0);
staticpro (&mouse_face_window);
mouse_face_window = Qnil;
}
-#endif /* ! defined (HAVE_X11) */
#endif /* ! defined (HAVE_X_WINDOWS) */