/* X Communication module for terminals which understand the X protocol.
- Copyright (C) 1989, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1989, 93, 94, 95, 1996 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* Xt features made by Fred Pierresteguy. */
#endif /* makedev */
#endif /* USG */
-#ifdef BSD
+#ifdef BSD_SYSTEM
#include <sys/ioctl.h>
-#endif /* ! defined (BSD) */
+#endif /* ! defined (BSD_SYSTEM) */
#include "systty.h"
#include "systime.h"
#include "keyboard.h"
#include "intervals.h"
+#ifdef USE_X_TOOLKIT
+#include <X11/Shell.h>
+#endif
+
#ifdef USE_X_TOOLKIT
extern void free_frame_menubar ();
+extern FRAME_PTR x_menubar_window_to_frame ();
+#if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
+#define HACK_EDITRES
extern void _XEditResCheckMessages ();
+#endif /* not NO_EDITRES */
#endif /* USE_X_TOOLKIT */
#ifndef USE_X_TOOLKIT
#endif
#ifdef USE_X_TOOLKIT
+#include "widget.h"
#ifndef XtNinitialState
#define XtNinitialState "initialState"
#endif
#endif
+#ifdef HAVE_SETLOCALE
+/* So we can do setlocale. */
+#include <locale.h>
+#endif
+
+#ifdef SOLARIS2
+/* memmove will be defined as a macro in Xfuncs.h unless
+ <string.h> is included beforehand. The declaration for memmove in
+ <string.h> will cause a syntax error when Xfuncs.h later includes it. */
+#include <string.h>
+#endif
+
+#ifndef min
#define min(a,b) ((a)<(b) ? (a) : (b))
+#endif
+#ifndef max
#define max(a,b) ((a)>(b) ? (a) : (b))
+#endif
\f
/* This is a chain of structures for all the X displays currently in use. */
struct x_display_info *x_display_list;
is the frame to apply to. */
extern struct frame *updating_frame;
+extern waiting_for_input;
+
/* This is a frame waiting to be autoraised, within XTread_socket. */
struct frame *pending_autoraise_frame;
#ifdef USE_X_TOOLKIT
/* The application context for Xt use. */
XtAppContext Xt_app_con;
+
+static String Xt_default_resources[] =
+{
+ 0
+};
#endif
/* During an update, maximum vpos for ins/del line operations to affect. */
/* 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
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.
-
- The silly O'Reilly & Associates Nutshell guides barely document
- pointer motion hints at all (I think you have to infer how they
- work from an example), and the description of XQueryPointer doesn't
- mention that calling it causes you to get another motion hint from
- the server, which is very important. */
+ is off. */
/* Where the mouse was last time we reported a mouse event. */
static FRAME_PTR last_mouse_frame;
static XRectangle last_mouse_glyph;
+static Lisp_Object last_mouse_press_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
extern Lisp_Object Vx_no_window_manager;
-/* Nonzero enables some debugging for the X interface code. */
-extern int _Xdebug;
-
extern Lisp_Object Qface, Qmouse_face;
extern int errno;
void x_catch_errors ();
void x_uncatch_errors ();
\f
+#if 0
+/* This is a function useful for recording debugging information
+ about the sequence of occurrences in this file. */
+
+struct record
+{
+ char *locus;
+ int type;
+};
+
+struct record event_record[100];
+
+int event_record_index;
+
+record_event (locus, type)
+ char *locus;
+ int type;
+{
+ if (event_record_index == sizeof (event_record) / sizeof (struct record))
+ event_record_index = 0;
+
+ event_record[event_record_index].locus = locus;
+ event_record[event_record_index].type = type;
+ event_record_index++;
+}
+
+#endif /* 0 */
+\f
/* Return the struct x_display_info corresponding to DPY. */
struct x_display_info *
BLOCK_INPUT;
+ curs_x = FRAME_CURSOR_X (f);
+ curs_y = FRAME_CURSOR_Y (f);
+
if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
{
/* Don't do highlighting for mouse motion during the update. */
BLOCK_INPUT;
do_line_dance ();
- x_display_cursor (f, 1);
+ x_display_cursor (f, 1, curs_x, curs_y);
- if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
- FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
#if 0
/* This fails in the case of having updated only the echo area
if we have switched buffers. In that case, FRAME_CURRENT_GLYPHS
XTframe_up_to_date (f)
FRAME_PTR f;
{
+ BLOCK_INPUT;
if (FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc
|| f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
{
FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc = 0;
}
+ UNBLOCK_INPUT;
}
\f
/* External interface to control of standout mode.
{
highlight = new_highlight;
XTcursor_to (vpos, 0);
- XTclear_end_of_line (updating_frame->width);
+ XTclear_end_of_line (FRAME_WINDOW_WIDTH (updating_frame));
}
/* This is used when starting Emacs and when restarting after suspend.
if (updating_frame == 0)
{
BLOCK_INPUT;
- x_display_cursor (selected_frame, 1);
+ x_display_cursor (selected_frame, 1, curs_x, curs_y);
XFlush (FRAME_X_DISPLAY (selected_frame));
UNBLOCK_INPUT;
}
int just_foreground;
{
/* Holds characters to be displayed. */
- char *buf = (char *) alloca (f->width * sizeof (*buf));
+ char *buf = (char *) alloca (FRAME_WINDOW_WIDTH (f) * sizeof (*buf));
register char *cp; /* Steps through buf[]. */
register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
if ((!face->font
|| face->font == (XFontStruct *) FACE_DEFAULT
- || face->font == f->display.x->font)
- && face->background == f->display.x->background_pixel
- && face->foreground == f->display.x->foreground_pixel)
+ || face->font == f->output_data.x->font)
+ && face->background == f->output_data.x->background_pixel
+ && face->foreground == f->output_data.x->foreground_pixel)
{
- gc = f->display.x->cursor_gc;
+ gc = f->output_data.x->cursor_gc;
}
/* Cursor on non-default face: must merge. */
else
XGCValues xgcv;
unsigned long mask;
- xgcv.background = f->display.x->cursor_pixel;
+ xgcv.background = f->output_data.x->cursor_pixel;
xgcv.foreground = face->background;
/* If the glyph would be invisible,
try a different foreground. */
if (xgcv.foreground == xgcv.background)
xgcv.foreground = face->foreground;
if (xgcv.foreground == xgcv.background)
- xgcv.foreground = f->display.x->cursor_foreground_pixel;
+ xgcv.foreground = f->output_data.x->cursor_foreground_pixel;
if (xgcv.foreground == xgcv.background)
xgcv.foreground = face->foreground;
/* Make sure the cursor is distinct from text in this face. */
}
if (font == (XFontStruct *) FACE_DEFAULT)
- font = f->display.x->font;
+ font = f->output_data.x->font;
if (just_foreground)
XDrawString (FRAME_X_DISPLAY (f), window, gc,
left, top + FONT_BASE (font), buf, len);
/* Clear the rest of the line's height. */
- if (f->display.x->line_height != FONT_HEIGHT (font))
+ if (f->output_data.x->line_height != FONT_HEIGHT (font))
XClearArea (FRAME_X_DISPLAY (f), window, left,
top + FONT_HEIGHT (font),
FONT_WIDTH (font) * len,
/* This is how many pixels of height
we have to clear. */
- f->display.x->line_height - FONT_HEIGHT (font),
+ f->output_data.x->line_height - FONT_HEIGHT (font),
False);
}
{
register int len;
Window window = FRAME_X_WINDOW (f);
- GC drawing_gc = (hl == 2 ? f->display.x->cursor_gc
- : (hl ? f->display.x->reverse_gc
- : f->display.x->normal_gc));
+ GC drawing_gc = (hl == 2 ? f->output_data.x->cursor_gc
+ : (hl ? f->output_data.x->reverse_gc
+ : f->output_data.x->normal_gc));
if (sizeof (GLYPH) == sizeof (XChar2b))
XDrawImageString16 (FRAME_X_DISPLAY (f), window, drawing_gc,
f->phys_cursor_x = -1;
if (updating_frame == 0)
- {
- f->cursor_x += len;
- x_display_cursor (f, 1);
- f->cursor_x -= len;
- }
+ x_display_cursor (f, 1, FRAME_CURSOR_X (f) + len, FRAME_CURSOR_Y (f));
else
curs_x += len;
if (first_unused <= 0)
return;
- if (first_unused >= f->width)
- first_unused = f->width;
+ if (first_unused >= FRAME_WINDOW_WIDTH (f))
+ first_unused = FRAME_WINDOW_WIDTH (f);
+
+ first_unused += FRAME_LEFT_SCROLL_BAR_WIDTH (f);
BLOCK_INPUT;
XClearArea (FRAME_X_DISPLAY (f), 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, False);
+ FONT_WIDTH (f->output_data.x->font) * (first_unused - curs_x),
+ f->output_data.x->line_height, False);
#if 0
redraw_previous_char (f, curs_x, curs_y, highlight);
#endif
XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
CHAR_TO_PIXEL_COL (f, x - 1),
CHAR_TO_PIXEL_ROW (f, y),
- FONT_WIDTH (f->display.x->font),
- f->display.x->line_height, False);
+ FONT_WIDTH (f->output_data.x->font),
+ f->output_data.x->line_height, False);
dumpglyphs (f, CHAR_TO_PIXEL_COL (f, start_x),
CHAR_TO_PIXEL_ROW (f, y),
XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
CHAR_TO_PIXEL_COL (f, x),
CHAR_TO_PIXEL_ROW (f, y),
- FONT_WIDTH (f->display.x->font),
- f->display.x->line_height, False);
+ FONT_WIDTH (f->output_data.x->font),
+ f->output_data.x->line_height, False);
dumpglyphs (f, CHAR_TO_PIXEL_COL (f, x),
CHAR_TO_PIXEL_ROW (f, y),
{
/* If char is out of range, try the font's default char instead. */
c = font->default_char;
- row = c >> (INTBITS - 8);
+ row = c >> (BITS_PER_INT - 8);
within = c & 0177;
}
if (!(within >= font->min_char_or_byte2
{
/* If char is out of range, try the font's default char instead. */
c = font->default_char;
- row = c >> (INTBITS - 8);
+ row = c >> (BITS_PER_INT - 8);
within = c & 0177;
}
if (!(within >= font->min_char_or_byte2
XGCValues values;
values.function = GXxor;
- values.foreground = (f->display.x->foreground_pixel
- ^ f->display.x->background_pixel);
+ values.foreground = (f->output_data.x->foreground_pixel
+ ^ f->output_data.x->background_pixel);
gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
GCFunction | GCForeground, &values);
}
{
- int width = PIXEL_WIDTH (f);
- int height = PIXEL_HEIGHT (f);
+ /* Get the height not including a menu bar widget. */
+ int height = CHAR_TO_PIXEL_HEIGHT (f, FRAME_HEIGHT (f));
+ /* Height of each line to flash. */
+ int flash_height = FRAME_LINE_HEIGHT (f);
+ /* These will be the left and right margins of the rectangles. */
+ int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
+ int flash_right = PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
+
+ int width;
+
+ /* Don't flash the area between a scroll bar and the frame
+ edge it is next to. */
+ switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f))
+ {
+ case vertical_scroll_bar_left:
+ flash_left += VERTICAL_SCROLL_BAR_WIDTH_TRIM;
+ break;
+
+ case vertical_scroll_bar_right:
+ flash_right -= VERTICAL_SCROLL_BAR_WIDTH_TRIM;
+ break;
+ }
+
+ width = flash_right - flash_left;
+
+ /* If window is tall, flash top and bottom line. */
+ if (height > 3 * FRAME_LINE_HEIGHT (f))
+ {
+ XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+ flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
+ width, flash_height);
+ XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+ flash_left,
+ (height - flash_height
+ - FRAME_INTERNAL_BORDER_WIDTH (f)),
+ width, flash_height);
+ }
+ else
+ /* If it is short, flash it all. */
+ XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+ flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
+ width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
- XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
- width/4, height/4, width/2, height/2);
XFlush (FRAME_X_DISPLAY (f));
{
}
}
- XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
- width/4, height/4, width/2, height/2);
+ /* If window is tall, flash top and bottom line. */
+ if (height > 3 * FRAME_LINE_HEIGHT (f))
+ {
+ XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+ flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
+ width, flash_height);
+ XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+ flash_left,
+ (height - flash_height
+ - FRAME_INTERNAL_BORDER_WIDTH (f)),
+ width, flash_height);
+ }
+ else
+ /* If it is short, flash it all. */
+ XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+ flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
+ width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
+
XFreeGC (FRAME_X_DISPLAY (f), gc);
XFlush (FRAME_X_DISPLAY (f));
}
abort ();
ht = f->height;
- intborder = f->display.x->internal_border_width;
+ intborder = CHAR_TO_PIXEL_COL (f, FRAME_LEFT_SCROLL_BAR_WIDTH (f));
- x_display_cursor (updating_frame, 0);
+ x_update_cursor (updating_frame, 0);
for (i = 0; i < ht; ++i)
if (line_dance[i] != -1 && (distance = line_dance[i]-i) > 0)
&& line_dance[j]-j == distance); ++j);
/* Copy [i,j) upward from [i+distance,j+distance) */
XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- FRAME_X_WINDOW (f), f->display.x->normal_gc,
+ FRAME_X_WINDOW (f), f->output_data.x->normal_gc,
intborder, CHAR_TO_PIXEL_ROW (f, i+distance),
- f->width * FONT_WIDTH (f->display.x->font),
- (j-i) * f->display.x->line_height,
+ FRAME_WINDOW_WIDTH (f) * FONT_WIDTH (f->output_data.x->font),
+ (j-i) * f->output_data.x->line_height,
intborder, CHAR_TO_PIXEL_ROW (f, i));
i = j-1;
}
&& line_dance[j]-j == distance););
/* Copy (j,i] downward from (j+distance, i+distance] */
XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- FRAME_X_WINDOW (f), f->display.x->normal_gc,
+ FRAME_X_WINDOW (f), f->output_data.x->normal_gc,
intborder, CHAR_TO_PIXEL_ROW (f, j+1+distance),
- f->width * FONT_WIDTH (f->display.x->font),
- (i-j) * f->display.x->line_height,
+ FRAME_WINDOW_WIDTH (f) * FONT_WIDTH (f->output_data.x->font),
+ (i-j) * f->output_data.x->line_height,
intborder, CHAR_TO_PIXEL_ROW (f, j+1));
i = j+1;
}
/* Clear [i,j) */
XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
intborder, CHAR_TO_PIXEL_ROW (f, i),
- f->width * FONT_WIDTH (f->display.x->font),
- (j-i) * f->display.x->line_height, False);
+ FRAME_WINDOW_WIDTH (f) * FONT_WIDTH (f->output_data.x->font),
+ (j-i) * f->output_data.x->line_height, False);
i = j-1;
}
line_dance_in_progress = 0;
Round down for left and top, up for right and bottom. */
top = PIXEL_TO_CHAR_ROW (f, top);
left = PIXEL_TO_CHAR_COL (f, left);
- bottom += (f->display.x->line_height - 1);
- right += (FONT_WIDTH (f->display.x->font) - 1);
+ bottom += (f->output_data.x->line_height - 1);
+ right += (FONT_WIDTH (f->output_data.x->font) - 1);
bottom = PIXEL_TO_CHAR_ROW (f, bottom);
right = PIXEL_TO_CHAR_COL (f, right);
left = 0;
if (top < 0)
top = 0;
- if (right > f->width)
- right = f->width;
+ if (right > FRAME_WINDOW_WIDTH (f))
+ right = FRAME_WINDOW_WIDTH (f);
if (bottom > f->height)
bottom = f->height;
/* Turn the cursor on if we turned it off. */
if (cursor_cleared)
- x_display_cursor (f, 1);
+ x_update_cursor (f, 1);
}
\f
static void
client", so we can always change it to whatever we want. */
BLOCK_INPUT;
XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- f->display.x->border_pixel);
+ f->output_data.x->border_pixel);
UNBLOCK_INPUT;
- x_display_cursor (f, 1);
+ x_update_cursor (f, 1);
}
static void
client", so we can always change it to whatever we want. */
BLOCK_INPUT;
XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- f->display.x->border_tile);
+ f->output_data.x->border_tile);
UNBLOCK_INPUT;
- x_display_cursor (f, 1);
+ x_update_cursor (f, 1);
}
static void XTframe_rehighlight ();
#ifdef HAVE_X11R4
XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
#else
- min_code = display->min_keycode;
- max_code = display->max_keycode;
+ min_code = dpyinfo->display->min_keycode;
+ max_code = dpyinfo->display->max_keycode;
#endif
syms = XGetKeyboardMapping (dpyinfo->display,
/* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
even for negative values. */
if (pix_x < 0)
- pix_x -= FONT_WIDTH ((f)->display.x->font) - 1;
+ pix_x -= FONT_WIDTH ((f)->output_data.x->font) - 1;
if (pix_y < 0)
- pix_y -= (f)->display.x->line_height - 1;
+ pix_y -= (f)->output_data.x->line_height - 1;
pix_x = PIXEL_TO_CHAR_COL (f, pix_x);
pix_y = PIXEL_TO_CHAR_ROW (f, pix_y);
if (bounds)
{
- bounds->width = FONT_WIDTH (f->display.x->font);
- bounds->height = f->display.x->line_height;
+ bounds->width = FONT_WIDTH (f->output_data.x->font);
+ bounds->height = f->output_data.x->line_height;
bounds->x = CHAR_TO_PIXEL_COL (f, pix_x);
bounds->y = CHAR_TO_PIXEL_ROW (f, pix_y);
}
{
if (pix_x < 0)
pix_x = 0;
- else if (pix_x > f->width)
- pix_x = f->width;
+ else if (pix_x > FRAME_WINDOW_WIDTH (f))
+ pix_x = FRAME_WINDOW_WIDTH (f);
if (pix_y < 0)
pix_y = 0;
if (event->window != FRAME_X_WINDOW (frame))
{
- mouse_moved = 1;
+ 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? */
|| event->y < last_mouse_glyph.y
|| event->y >= last_mouse_glyph.y + last_mouse_glyph.height)
{
- mouse_moved = 1;
+ frame->mouse_moved = 1;
last_mouse_scroll_bar = Qnil;
note_mouse_highlight (frame, event->x, event->y);
-
- /* 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);
- }
- }
- else
- {
- /* It's on the same glyph. Call XQueryPointer so we'll get an
- 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, FRAME_X_WINDOW (frame),
- &dummy_window, &dummy_window,
- &dummy, &dummy, &dummy, &dummy,
- (unsigned int *) &dummy);
}
}
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)))
+ && w->last_modified == BUF_MODIFF (XBUFFER (w->buffer))
+ && w->last_overlay_modified == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer)))
{
int *ptr = FRAME_CURRENT_GLYPHS (f)->charstarts[row];
int i, pos;
before = Foverlay_start (overlay);
after = Foverlay_end (overlay);
/* Record this as the current active region. */
- fast_find_position (window, before,
+ fast_find_position (window, XFASTINT (before),
&FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col,
&FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row);
FRAME_X_DISPLAY_INFO (f)->mouse_face_past_end
- = !fast_find_position (window, after,
+ = !fast_find_position (window, XFASTINT (after),
&FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col,
&FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row);
FRAME_X_DISPLAY_INFO (f)->mouse_face_window = window;
= Fnext_single_property_change (position, Qmouse_face,
w->buffer, end);
/* Record this as the current active region. */
- fast_find_position (window, before,
+ fast_find_position (window, XFASTINT (before),
&FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col,
&FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row);
FRAME_X_DISPLAY_INFO (f)->mouse_face_past_end
- = !fast_find_position (window, after,
+ = !fast_find_position (window, XFASTINT (after),
&FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col,
&FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row);
FRAME_X_DISPLAY_INFO (f)->mouse_face_window = window;
FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
int i;
int row = 0;
- int left = w->left;
+ int left = WINDOW_LEFT_MARGIN (w);
int top = w->top;
int height = XFASTINT (w->height) - ! MINI_WINDOW_P (w);
int width = window_internal_width (w);
if (maybe_next_line)
{
row++;
- i = 0;
+ lastcol = left;
}
*rowp = row + top;
FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
int i;
int cursor_off = 0;
- int old_curs_x = curs_x;
- int old_curs_y = curs_y;
-
- /* 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 = FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row;
i <= FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row; i++)
{
int column = (i == FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
? FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col
- : w->left);
+ : WINDOW_LEFT_MARGIN (w));
int endcolumn = (i == FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
? FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col
- : w->left + width);
+ : WINDOW_LEFT_MARGIN (w) + 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 >= FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col - 1
- && curs_x <= FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col)
+ && curs_x >= column - 1
+ && curs_x <= endcolumn)
{
- x_display_cursor (f, 0);
+ x_update_cursor (f, 0);
cursor_off = 1;
}
/* If we turned the cursor off, turn it back on. */
if (cursor_off)
- x_display_cursor (f, 1);
-
- curs_x = old_curs_x;
- curs_y = old_curs_y;
+ x_update_cursor (f, 1);
/* Change the mouse cursor according to the value of HL. */
if (hl > 0)
XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- f->display.x->cross_cursor);
+ f->output_data.x->cross_cursor);
else
XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- f->display.x->text_cursor);
+ f->output_data.x->text_cursor);
}
/* Clear out the mouse-highlighted active region.
Don't store anything if we don't have a valid set of values to report.
This clears the mouse_moved flag, so we can wait for the next mouse
- movement. This also calls XQueryPointer, which will cause the
- server to give us another MotionNotify when the mouse moves
- again. */
+ movement. */
static void
XTmouse_position (fp, insist, bar_window, part, x, y, time)
Window dummy_window;
int dummy;
- mouse_moved = 0;
+ Lisp_Object frame, tail;
+
+ /* Clear the mouse-moved flag for every frame on this display. */
+ FOR_EACH_FRAME (tail, frame)
+ if (FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
+ XFRAME (frame)->mouse_moved = 0;
+
last_mouse_scroll_bar = Qnil;
/* Figure out which root window we're on. */
/* Child of win. */
&child);
- if (child == None)
+ if (child == None || child == win)
break;
win = child;
{
XSetWindowAttributes a;
unsigned long mask;
- a.background_pixel = f->display.x->background_pixel;
+ a.background_pixel = f->output_data.x->background_pixel;
a.event_mask = (ButtonPressMask | ButtonReleaseMask
| ButtonMotionMask | PointerMotionHintMask
| ExposureMask);
XtSetArg (al[ac], XtNborderWidth, 0); ac++;
sb_widget = XtCreateManagedWidget ("box",
boxWidgetClass,
- f->display.x->edit_widget, al, ac);
+ f->output_data.x->edit_widget, al, ac);
SET_SCROLL_BAR_X_WINDOW
(bar, sb_widget->core.window);
#endif
XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
/* Position and size of scroll bar. */
- left, top, width, height,
+ left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, top,
+ width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, height,
/* Border width, depth, class, and visual. */
0, CopyFromParent, CopyFromParent, CopyFromParent,
int dragging = ! NILP (bar->dragging);
Window w = SCROLL_BAR_X_WINDOW (bar);
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
- GC gc = f->display.x->normal_gc;
+ GC gc = f->output_data.x->normal_gc;
/* If the display is already accurate, do nothing. */
if (! rebuild
BLOCK_INPUT;
{
- int inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (XINT (bar->width));
- int inside_height = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (XINT (bar->height));
- int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height));
+ int inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f, XINT (bar->width));
+ int inside_height = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, XINT (bar->height));
+ int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
/* Make sure the values are reasonable, and try to preserve
the distance between start and end. */
XWindowChanges wc;
unsigned int mask = 0;
- wc.x = left;
+ wc.x = left + VERTICAL_SCROLL_BAR_WIDTH_TRIM;
wc.y = top;
- wc.width = width;
+
+ wc.width = width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2;
wc.height = height;
if (left != XINT (bar->left)) mask |= CWX;
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)));
+ : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.x->font)));
int pixel_height = VERTICAL_SCROLL_BAR_PIXEL_HEIGHT (f, height);
struct scroll_bar *bar;
dragged. */
if (NILP (bar->dragging))
{
- int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (pixel_height);
+ int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, pixel_height);
if (whole == 0)
x_scroll_bar_set_handle (bar, 0, top_range, 0);
XTcondemn_scroll_bars (frame)
FRAME_PTR frame;
{
- /* The condemned list should be empty at this point; if it's not,
- then the rest of Emacs isn't using the condemn/redeem/judge
- protocol correctly. */
- if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
- abort ();
-
- /* Move them all to the "condemned" list. */
- FRAME_CONDEMNED_SCROLL_BARS (frame) = FRAME_SCROLL_BARS (frame);
- FRAME_SCROLL_BARS (frame) = Qnil;
+ /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
+ while (! NILP (FRAME_SCROLL_BARS (frame)))
+ {
+ Lisp_Object bar;
+ bar = FRAME_SCROLL_BARS (frame);
+ FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
+ XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
+ XSCROLL_BAR (bar)->prev = Qnil;
+ if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
+ XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
+ FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
+ }
}
/* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
{
Window w = SCROLL_BAR_X_WINDOW (bar);
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
- GC gc = f->display.x->normal_gc;
+ GC gc = f->output_data.x->normal_gc;
+ int width_trim = VERTICAL_SCROLL_BAR_WIDTH_TRIM;
BLOCK_INPUT;
XDrawRectangle (FRAME_X_DISPLAY (f), w, gc,
/* x, y, width, height */
- 0, 0, XINT (bar->width) - 1, XINT (bar->height) - 1);
-
+ 0, 0,
+ XINT (bar->width) - 1 - width_trim - width_trim,
+ XINT (bar->height) - 1);
+
UNBLOCK_INPUT;
}
emacs_event->frame_or_window = bar->window;
emacs_event->timestamp = event->xbutton.time;
{
+ FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
int internal_height
- = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (XINT (bar->height));
+ = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, XINT (bar->height));
int top_range
- = VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height));
+ = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
int y = event->xbutton.y - VERTICAL_SCROLL_BAR_TOP_BORDER;
if (y < 0) y = 0;
struct scroll_bar *bar;
XEvent *event;
{
+ FRAME_PTR f = XFRAME (XWINDOW (bar->window)->frame);
+
last_mouse_movement_time = event->xmotion.time;
- mouse_moved = 1;
+ f->mouse_moved = 1;
XSETVECTOR (last_mouse_scroll_bar, bar);
/* If we're dragging the bar, display it. */
x_scroll_bar_set_handle (bar, new_start, new_end, 0);
}
}
-
- /* Call XQueryPointer so we'll get an event the next time the mouse
- moves and we can see *still* on the same position. */
- {
- int dummy;
- Window dummy_window;
-
- XQueryPointer (event->xmotion.display, event->xmotion.window,
- &dummy_window, &dummy_window,
- &dummy, &dummy, &dummy, &dummy,
- (unsigned int *) &dummy);
- }
}
/* Return information to the user about the current position of the mouse
else
{
int inside_height
- = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (XINT (bar->height));
+ = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, XINT (bar->height));
int top_range
- = VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height));
+ = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
XSETINT (*x, win_y);
XSETINT (*y, top_range);
- mouse_moved = 0;
+ f->mouse_moved = 0;
last_mouse_scroll_bar = Qnil;
}
{
Lisp_Object bar;
- for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
- bar = XSCROLL_BAR (bar)->next)
- XClearArea (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)),
- 0, 0, 0, 0, True);
+ /* We can have scroll bars even if this is 0,
+ if we just turned off scroll bar mode.
+ But in that case we should not clear them. */
+ if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+ for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
+ bar = XSCROLL_BAR (bar)->next)
+ XClearArea (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)),
+ 0, 0, 0, 0, True);
}
/* This processes Expose events from the menubar specific X event
/* Record the last 100 characters stored
to help debug the loss-of-chars-during-GC problem. */
-int temp_index;
-short temp_buffer[100];
+static int temp_index;
+static short temp_buffer[100];
/* Set this to nonzero to fake an "X I/O error"
on a particular display. */
struct x_display_info *XTread_socket_fake_io_error;
+/* When we find no input here, we occasionally do a no-op command
+ to verify that the X server is still running and we can still talk with it.
+ We try all the open displays, one by one.
+ This variable is used for cycling thru the displays. */
+static struct x_display_info *next_noop_dpyinfo;
+
+#define SET_SAVED_MENU_EVENT(size) { \
+ if (f->output_data.x->saved_menu_event == 0) \
+ f->output_data.x->saved_menu_event = (XEvent*)xmalloc (sizeof (XEvent)); \
+ bcopy (&event, f->output_data.x->saved_menu_event, size); \
+ if (numchars >= 1) \
+ { \
+ bufp->kind = menu_bar_activate_event; \
+ XSETFRAME (bufp->frame_or_window, f); \
+ bufp++; \
+ count++; \
+ numchars--; \
+ } \
+ }
+#define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent))
+#define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent))
+
/* Read events coming from the X server.
This routine is called by the SIGIO handler.
We return as soon as there are no more events to be read.
We return the number of characters stored into the buffer,
thus pretending to be `read'.
- WAITP is nonzero if we should block until input arrives.
EXPECTED is nonzero if the caller knows input is available. */
int
-XTread_socket (sd, bufp, numchars, waitp, expected)
+XTread_socket (sd, bufp, numchars, expected)
register int sd;
- register struct input_event *bufp;
- register int numchars;
- int waitp;
+ /* register */ struct input_event *bufp;
+ /* register */ int numchars;
int expected;
{
int count = 0;
int prefix;
Lisp_Object part;
struct x_display_info *dpyinfo;
+#ifdef HAVE_X_I18N
+ Status status_return;
+#endif
if (interrupt_input_blocked)
{
#ifdef FIOSNBIO
/* If available, Xlib uses FIOSNBIO to make the socket
non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
- FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK,
+ FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK,
a read returns 0, which Xlib interprets as equivalent to EPIPE. */
fcntl (dpyinfo->connection, F_SETFL, 0);
#endif /* ! defined (FIOSNBIO) */
while (XPending (dpyinfo->display) != 0)
{
+#ifdef USE_X_TOOLKIT
+ /* needed to raise Motif submenus */
+ XtAppNextEvent (Xt_app_con, &event);
+#else
XNextEvent (dpyinfo->display, &event);
+#endif
+#ifdef HAVE_X_I18N
+ {
+ struct frame *f1 = x_any_window_to_frame (dpyinfo,
+ &event.xclient.window);
+ /* The necessity of the following line took me
+ a full work-day to decipher from the docs!! */
+ if (f1 != 0 && FRAME_XIC (f1) && XFilterEvent (&event, None))
+ break;
+ }
+#endif
event_found = 1;
switch (event.type)
/* 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. */
+#ifdef HAVE_X_I18N
+ /* Not quite sure this is needed -pd */
+ if (f)
+ XSetICFocus (FRAME_XIC (f));
+#endif
if (f)
XSetInputFocus (event.xclient.display,
event.xclient.window,
XSetCommand (FRAME_X_DISPLAY (f),
event.xclient.window,
initial_argv, initial_argc);
- else
+ else if (f)
XSetCommand (FRAME_X_DISPLAY (f),
event.xclient.window,
0, 0);
if (f)
{
- f->display.x->left_pos = new_x;
- f->display.x->top_pos = new_y;
+ f->output_data.x->left_pos = new_x;
+ f->output_data.x->top_pos = new_y;
}
}
-#if defined (USE_X_TOOLKIT) && defined (HAVE_X11R5)
+#ifdef HACK_EDITRES
else if (event.xclient.message_type
== dpyinfo->Xatom_editres)
{
struct frame *f
= x_any_window_to_frame (dpyinfo, event.xclient.window);
- _XEditResCheckMessages (f->display.x->widget, NULL,
+ _XEditResCheckMessages (f->output_data.x->widget, NULL,
&event, NULL);
}
-#endif /* USE_X_TOOLKIT and HAVE_X11R5 */
+#endif /* HACK_EDITRES */
}
break;
SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
SELECTION_EVENT_TIME (bufp) = eventp->time;
+ bufp->frame_or_window = Qnil;
bufp++;
count += 1;
SELECTION_EVENT_TARGET (bufp) = eventp->target;
SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
SELECTION_EVENT_TIME (bufp) = eventp->time;
+ bufp->frame_or_window = Qnil;
bufp++;
count += 1;
if (f)
{
int x, y;
- f->display.x->parent_desc = event.xreparent.parent;
+ f->output_data.x->parent_desc = event.xreparent.parent;
x_real_positions (f, &x, &y);
- f->display.x->left_pos = x;
- f->display.x->top_pos = y;
+ f->output_data.x->left_pos = x;
+ f->output_data.x->top_pos = y;
}
break;
break;
case UnmapNotify:
- f = x_any_window_to_frame (dpyinfo, event.xunmap.window);
+ f = x_top_window_to_frame (dpyinfo, event.xunmap.window);
if (f) /* F may no longer exist if
the frame was deleted. */
{
/* We can't distinguish, from the event, whether the window
has become iconified or invisible. So assume, if it
was previously visible, than now it is iconified.
- We depend on x_make_frame_invisible to mark it iconified. */
+ We depend on x_make_frame_invisible to mark it invisible. */
if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
f->async_iconified = 1;
count++;
numchars--;
}
-#ifdef USE_X_TOOLKIT
goto OTHER;
-#endif /* USE_X_TOOLKIT */
- break;
case MapNotify:
/* We use x_top_window_to_frame because map events can come
count++;
numchars--;
}
- else
+ else if (! NILP(Vframe_list)
+ && ! NILP (XCONS (Vframe_list)->cdr))
/* Force a redisplay sooner or later
to update the frame titles
in case this is the second frame. */
record_asynch_buffer_change ();
}
-#ifdef USE_X_TOOLKIT
goto OTHER;
-#endif /* USE_X_TOOLKIT */
- break;
/* Turn off processing if we become fully obscured. */
case VisibilityNotify:
unsigned char copy_buffer[81];
int modifiers;
+#if 0 /* This was how we made f10 work in Motif.
+ The drawback is, you can't type at Emacs when the
+ the mouse is in the menu bar. So it is better to
+ turn off f10 in Motif and let Emacs handle it. */
+#ifdef USE_MOTIF
+ if (lw_window_is_in_menubar (event.xkey.window,
+ f->output_data.x->menubar_widget
+ ))
+ {
+ SET_SAVED_KEY_EVENT;
+ break;
+ }
+#endif /* USE_MOTIF */
+#endif /* 0 */
+
event.xkey.state
|= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f),
extra_keyboard_modifiers);
/* make_lispy_event turns chars into control chars.
Don't do it here because XLookupString is too eager. */
event.xkey.state &= ~ControlMask;
+ event.xkey.state &= ~(dpyinfo->meta_mod_mask
+ | dpyinfo->super_mod_mask
+ | dpyinfo->hyper_mod_mask
+ | dpyinfo->alt_mod_mask);
+
+#ifdef HAVE_X_I18N
+ if (FRAME_XIC (f))
+ {
+ nbytes = XmbLookupString (FRAME_XIC (f),
+ &event.xkey, copy_buffer,
+ 80, &keysym,
+ &status_return);
+ }
+ else
+ nbytes = XLookupString (&event.xkey, copy_buffer,
+ 80, &keysym, &compose_status);
+#else
nbytes = XLookupString (&event.xkey, copy_buffer,
80, &keysym, &compose_status);
+#endif
orig_keysym = keysym;
else
abort ();
}
- break;
+ goto OTHER;
/* Here's a possible interpretation of the whole
FocusIn-EnterNotify FocusOut-LeaveNotify mess. If you get a
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 */
- break;
case FocusIn:
f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
dpyinfo->x_focus_event_frame = f;
if (f)
x_new_focus_frame (dpyinfo, f);
-#ifdef USE_X_TOOLKIT
- goto OTHER;
-#endif /* USE_X_TOOLKIT */
- break;
+#ifdef HAVE_X_I18N
+ if (f && FRAME_XIC (f))
+ XSetICFocus (FRAME_XIC (f));
+#endif
+
+ goto OTHER;
case LeaveNotify:
f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
x_new_focus_frame (dpyinfo, 0);
}
}
-#ifdef USE_X_TOOLKIT
goto OTHER;
-#endif /* USE_X_TOOLKIT */
- break;
case FocusOut:
f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
dpyinfo->x_focus_event_frame = 0;
if (f && f == dpyinfo->x_focus_frame)
x_new_focus_frame (dpyinfo, 0);
-#ifdef USE_X_TOOLKIT
+
+#ifdef HAVE_X_I18N
+ if (f && FRAME_XIC (f))
+ XUnsetICFocus (FRAME_XIC (f));
+#endif
+
goto OTHER;
-#endif /* USE_X_TOOLKIT */
- break;
case MotionNotify:
{
clear_mouse_face (dpyinfo);
}
}
-#ifdef USE_X_TOOLKIT
goto OTHER;
-#endif /* USE_X_TOOLKIT */
- break;
case ConfigureNotify:
f = x_any_window_to_frame (dpyinfo, event.xconfigure.window);
if (f
#ifdef USE_X_TOOLKIT
- && (event.xconfigure.window == XtWindow (f->display.x->widget))
+ && (event.xconfigure.window == XtWindow (f->output_data.x->widget))
#endif
)
{
to check the pixel dimensions as well. */
if (columns != f->width
|| rows != f->height
- || event.xconfigure.width != f->display.x->pixel_width
- || event.xconfigure.height != f->display.x->pixel_height)
+ || event.xconfigure.width != f->output_data.x->pixel_width
+ || event.xconfigure.height != f->output_data.x->pixel_height)
{
change_frame_size (f, rows, columns, 0, 1);
SET_FRAME_GARBAGED (f);
event.xconfigure.y = win_y;
}
- f->display.x->pixel_width = event.xconfigure.width;
- f->display.x->pixel_height = event.xconfigure.height;
- f->display.x->left_pos = event.xconfigure.x;
- f->display.x->top_pos = event.xconfigure.y;
+ f->output_data.x->pixel_width = event.xconfigure.width;
+ f->output_data.x->pixel_height = event.xconfigure.height;
+ f->output_data.x->left_pos = event.xconfigure.x;
+ f->output_data.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;
+ f->output_data.x->left_pos = x;
+ f->output_data.x->top_pos = y;
/* Formerly we did not do this in the USE_X_TOOLKIT
version. Let's try making them the same. */
/* #ifndef USE_X_TOOLKIT */
{
/* 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;
+ f->output_data.x->win_gravity = NorthWestGravity;
x_wm_set_size_hint (f, (long) 0, 0);
}
/* #endif */
}
}
-#ifdef USE_X_TOOLKIT
goto OTHER;
-#else
- break;
-#endif
case ButtonPress:
case ButtonRelease:
&& FRAME_LIVE_P (last_mouse_frame))
f = last_mouse_frame;
else
- f = x_window_to_frame (dpyinfo, event.xmotion.window);
+ f = x_window_to_frame (dpyinfo, event.xbutton.window);
if (f)
{
if (bar)
x_scroll_bar_handle_click (bar, &event, &emacs_event);
-#if 0 /* It doesn't make sense to do this.
- Menu bar clicks are handled within the toolkit itself. */
-#ifdef USE_X_TOOLKIT
- else
- {
- /* Assume we have a menubar button press. A bad
- assumption should behave benignly. */
- popup_get_selection (&event, dpyinfo);
- break;
- }
-#endif /* USE_X_TOOLKIT */
-#endif
}
if (event.type == ButtonPress)
}
#ifdef USE_X_TOOLKIT
- goto OTHER;
+ f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window);
+ /* For a down-event in the menu bar,
+ don't pass it to Xt right now.
+ Instead, save it away
+ and we will pass it to Xt from kbd_buffer_get_event.
+ That way, we can run some Lisp code first. */
+ if (f && event.type == ButtonPress
+ /* Verify the event is really within the menu bar
+ and not just sent to it due to grabbing. */
+ && event.xbutton.x >= 0
+ && event.xbutton.x < f->output_data.x->pixel_width
+ && event.xbutton.y >= 0
+ && event.xbutton.y < f->output_data.x->menubar_height
+ && event.xbutton.same_screen)
+ {
+ SET_SAVED_BUTTON_EVENT;
+ XSETFRAME (last_mouse_press_frame, f);
+ }
+ else if (event.type == ButtonPress)
+ {
+ last_mouse_press_frame = Qnil;
+ goto OTHER;
+ }
+#ifdef USE_MOTIF /* This should do not harm for Lucid,
+ but I am trying to be cautious. */
+ else if (event.type == ButtonRelease)
+ {
+ if (!NILP (last_mouse_press_frame))
+ {
+ f = XFRAME (last_mouse_press_frame);
+ if (f->output_data.x)
+ {
+ SET_SAVED_BUTTON_EVENT;
+ }
+ }
+ else
+ goto OTHER;
+ }
+#endif /* USE_MOTIF */
+ else
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
}
break;
case MappingKeyboard:
XRefreshKeyboardMapping (&event.xmapping);
}
-#ifdef USE_X_TOOLKIT
goto OTHER;
-#endif /* USE_X_TOOLKIT */
- break;
default:
-#ifdef USE_X_TOOLKIT
OTHER:
+#ifdef USE_X_TOOLKIT
BLOCK_INPUT;
XtDispatchEvent (&event);
UNBLOCK_INPUT;
if (x_noop_count >= 100)
{
x_noop_count=0;
- /* Use the first display in the list. Why not? */
- XNoOp (x_display_list->display);
+
+ if (next_noop_dpyinfo == 0)
+ next_noop_dpyinfo = x_display_list;
+
+ XNoOp (next_noop_dpyinfo->display);
+
+ /* Each time we get here, cycle through the displays now open. */
+ next_noop_dpyinfo = next_noop_dpyinfo->next;
}
}
/* Drawing the cursor. */
-/* Draw a hollow box cursor. Don't change the inside of the box. */
+/* Draw a hollow box cursor on frame F at X, Y.
+ Don't change the inside of the box. */
static void
-x_draw_box (f)
+x_draw_box (f, x, y)
struct frame *f;
+ int x, 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;
+ int left = CHAR_TO_PIXEL_COL (f, x);
+ int top = CHAR_TO_PIXEL_ROW (f, y);
+ int width = FONT_WIDTH (f->output_data.x->font);
+ int height = f->output_data.x->line_height;
XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- f->display.x->cursor_gc,
+ f->output_data.x->cursor_gc,
left, top, width - 1, height - 1);
}
|| f->phys_cursor_x < 0)
return;
- x_display_cursor (f, 0);
+ x_update_cursor (f, 0);
f->phys_cursor_x = -1;
}
}
static void
-x_display_bar_cursor (f, on)
+x_display_bar_cursor (f, on, x, y)
struct frame *f;
int on;
+ int x, y;
{
struct frame_glyphs *current_glyphs = FRAME_CURRENT_GLYPHS (f);
/* This is pointless on invisible frames, and dangerous on garbaged
frames; in the latter case, the frame may be in the midst of
- changing its size, and curs_x and curs_y may be off the frame. */
+ changing its size, and x and y may be off the frame. */
if (! FRAME_VISIBLE_P (f) || FRAME_GARBAGED_P (f))
return;
if (! on && f->phys_cursor_x < 0)
return;
- /* If we're not updating, then we want to use the current frame's
- cursor position, not our local idea of where the cursor ought to be. */
- if (f != updating_frame)
- {
- curs_x = FRAME_CURSOR_X (f);
- curs_y = FRAME_CURSOR_Y (f);
- }
-
/* If there is anything wrong with the current cursor state, remove it. */
if (f->phys_cursor_x >= 0
&& (!on
- || f->phys_cursor_x != curs_x
- || f->phys_cursor_y != curs_y
- || f->display.x->current_cursor != bar_cursor))
+ || f->phys_cursor_x != x
+ || f->phys_cursor_y != y
+ || f->output_data.x->current_cursor != bar_cursor))
{
/* Erase the cursor by redrawing the character underneath it. */
x_draw_single_glyph (f, f->phys_cursor_y, f->phys_cursor_x,
/* If we now need a cursor in the new place or in the new form, do it so. */
if (on
&& (f->phys_cursor_x < 0
- || (f->display.x->current_cursor != bar_cursor)))
+ || (f->output_data.x->current_cursor != bar_cursor)))
{
f->phys_cursor_glyph
- = ((current_glyphs->enable[curs_y]
- && curs_x < current_glyphs->used[curs_y])
- ? current_glyphs->glyphs[curs_y][curs_x]
+ = ((current_glyphs->enable[y]
+ && x < current_glyphs->used[y])
+ ? current_glyphs->glyphs[y][x]
: SPACEGLYPH);
XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- f->display.x->cursor_gc,
- CHAR_TO_PIXEL_COL (f, curs_x),
- CHAR_TO_PIXEL_ROW (f, curs_y),
- max (f->display.x->cursor_width, 1),
- f->display.x->line_height);
+ f->output_data.x->cursor_gc,
+ CHAR_TO_PIXEL_COL (f, x),
+ CHAR_TO_PIXEL_ROW (f, y),
+ max (f->output_data.x->cursor_width, 1),
+ f->output_data.x->line_height);
- f->phys_cursor_x = curs_x;
- f->phys_cursor_y = curs_y;
+ f->phys_cursor_x = x;
+ f->phys_cursor_y = y;
- f->display.x->current_cursor = bar_cursor;
+ f->output_data.x->current_cursor = bar_cursor;
}
if (updating_frame != f)
/* Turn the displayed cursor of frame F on or off according to ON.
- If ON is nonzero, where to put the cursor is specified
- by F->cursor_x and F->cursor_y. */
+ If ON is nonzero, where to put the cursor is specified by X and Y. */
static void
-x_display_box_cursor (f, on)
+x_display_box_cursor (f, on, x, y)
struct frame *f;
int on;
+ int x, y;
{
struct frame_glyphs *current_glyphs = FRAME_CURRENT_GLYPHS (f);
/* This is pointless on invisible frames, and dangerous on garbaged
frames; in the latter case, the frame may be in the midst of
- changing its size, and curs_x and curs_y may be off the frame. */
+ changing its size, and x and y may be off the frame. */
if (! FRAME_VISIBLE_P (f) || FRAME_GARBAGED_P (f))
return;
if (!on && f->phys_cursor_x < 0)
return;
- /* If we're not updating, then we want to use the current frame's
- cursor position, not our local idea of where the cursor ought to be. */
- if (f != updating_frame)
- {
- curs_x = FRAME_CURSOR_X (f);
- curs_y = FRAME_CURSOR_Y (f);
- }
-
/* If cursor is currently being shown and we don't want it to be
or it is in the wrong place,
or we want a hollow box and it's not so, (pout!)
erase it. */
if (f->phys_cursor_x >= 0
&& (!on
- || f->phys_cursor_x != curs_x
- || f->phys_cursor_y != curs_y
- || (f->display.x->current_cursor != hollow_box_cursor
+ || f->phys_cursor_x != x
+ || f->phys_cursor_y != y
+ || (f->output_data.x->current_cursor != hollow_box_cursor
&& (f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame))))
{
int mouse_face_here = 0;
/* 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)
+ if (FONT_HEIGHT (f->output_data.x->font) != f->output_data.x->line_height)
XClearArea (FRAME_X_DISPLAY (f), 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, False);
+ FONT_WIDTH (f->output_data.x->font),
+ f->output_data.x->line_height, False);
/* 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,
write it in the right place. */
if (on
&& (f->phys_cursor_x < 0
- || (f->display.x->current_cursor != filled_box_cursor
+ || (f->output_data.x->current_cursor != filled_box_cursor
&& f == FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)))
{
f->phys_cursor_glyph
- = ((current_glyphs->enable[curs_y]
- && curs_x < current_glyphs->used[curs_y])
- ? current_glyphs->glyphs[curs_y][curs_x]
+ = ((current_glyphs->enable[y]
+ && x < current_glyphs->used[y])
+ ? current_glyphs->glyphs[y][x]
: SPACEGLYPH);
if (f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
{
- x_draw_box (f);
- f->display.x->current_cursor = hollow_box_cursor;
+ x_draw_box (f, x, y);
+ f->output_data.x->current_cursor = hollow_box_cursor;
}
else
{
- x_draw_single_glyph (f, curs_y, curs_x,
+ x_draw_single_glyph (f, y, x,
f->phys_cursor_glyph, 2);
- f->display.x->current_cursor = filled_box_cursor;
+ f->output_data.x->current_cursor = filled_box_cursor;
}
- f->phys_cursor_x = curs_x;
- f->phys_cursor_y = curs_y;
+ f->phys_cursor_x = x;
+ f->phys_cursor_y = y;
}
if (updating_frame != f)
XFlush (FRAME_X_DISPLAY (f));
}
-x_display_cursor (f, on)
+/* Display the cursor on frame F, or clear it, according to ON.
+ Also set the frame's cursor position to X and Y. */
+
+x_display_cursor (f, on, x, y)
+ struct frame *f;
+ int on;
+ int x, y;
+{
+ BLOCK_INPUT;
+
+ if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
+ x_display_box_cursor (f, on, x, y);
+ else if (FRAME_DESIRED_CURSOR (f) == bar_cursor)
+ x_display_bar_cursor (f, on, x, y);
+ else
+ /* Those are the only two we have implemented! */
+ abort ();
+
+ UNBLOCK_INPUT;
+}
+
+/* Display the cursor on frame F, or clear it, according to ON.
+ Don't change the cursor's position. */
+
+x_update_cursor (f, on)
struct frame *f;
int on;
{
+ /* If we don't have any previous cursor position to use,
+ leave the cursor off. */
+ if (f->phys_cursor_x < 0)
+ return;
+
BLOCK_INPUT;
if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
- x_display_box_cursor (f, on);
+ x_display_box_cursor (f, on, f->phys_cursor_x, f->phys_cursor_y);
else if (FRAME_DESIRED_CURSOR (f) == bar_cursor)
- x_display_bar_cursor (f, on);
+ x_display_bar_cursor (f, on, f->phys_cursor_x, f->phys_cursor_y);
else
/* Those are the only two we have implemented! */
abort ();
return 1;
/* Free up our existing icon bitmap if any. */
- if (f->display.x->icon_bitmap > 0)
- x_destroy_bitmap (f, f->display.x->icon_bitmap);
- f->display.x->icon_bitmap = 0;
+ if (f->output_data.x->icon_bitmap > 0)
+ x_destroy_bitmap (f, f->output_data.x->icon_bitmap);
+ f->output_data.x->icon_bitmap = 0;
if (STRINGP (file))
bitmap_id = x_create_bitmap_from_file (f, file);
}
x_wm_set_icon_pixmap (f, bitmap_id);
- f->display.x->icon_bitmap = bitmap_id;
+ f->output_data.x->icon_bitmap = bitmap_id;
return 0;
}
text.format = 8;
text.nitems = strlen (icon_name);
#ifdef USE_X_TOOLKIT
- XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->display.x->widget),
+ XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget),
&text);
#else /* not USE_X_TOOLKIT */
XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text);
XSetIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), icon_name);
#endif /* not HAVE_X11R4 */
- if (f->display.x->icon_bitmap > 0)
- x_destroy_bitmap (f, f->display.x->icon_bitmap);
- f->display.x->icon_bitmap = 0;
+ if (f->output_data.x->icon_bitmap > 0)
+ x_destroy_bitmap (f, f->output_data.x->icon_bitmap);
+ f->output_data.x->icon_bitmap = 0;
x_wm_set_icon_pixmap (f, 0);
return 0;
struct x_display_info *dpyinfo = x_display_info_for_display (display);
Lisp_Object frame, tail;
- /* Whatever we were in the middle of, we are going to throw out of it,
- so reassure various things that have error checks about being
- called with input blocked. */
- TOTALLY_UNBLOCK_INPUT;
+ /* Indicate that this display is dead. */
- if (_Xdebug)
- abort ();
+ #ifdef USE_X_TOOLKIT
+ XtCloseDisplay (display);
+ #endif
+
+ dpyinfo->display = 0;
/* First delete frames whose minibuffers are on frames
that are on the dead display. */
Fdelete_frame (frame, Qt);
}
- x_delete_display (dpyinfo);
+ if (dpyinfo)
+ x_delete_display (dpyinfo);
if (x_display_list == 0)
{
- fprintf (stderr, "%s", error_message);
+ fprintf (stderr, "%s\n", error_message);
shut_down_emacs (0, 0, Qnil);
exit (70);
}
sigunblock (sigmask (SIGALRM));
TOTALLY_UNBLOCK_INPUT;
+ clear_waiting_for_input ();
error ("%s", error_message);
}
-static SIGTYPE
-x_connection_signal (signalnum) /* If we don't have an argument, */
- int signalnum; /* some compilers complain in signal calls. */
-{
- /* We really ought to close the connection to the display
- that actually failed.
- But do we actually get this signal ever with X11? */
- fprintf (stderr, "X connection closed");
- shut_down_emacs (0, 0, Qnil);
- exit (70);
-}
-
/* This is the usual handler for X protocol errors.
It kills all frames on the display that we got the error for.
If that was the only one, it prints an error message and kills Emacs. */
x_connection_closed (display, buf);
}
\f
+/* Handle SIGPIPE, which can happen when the connection to a server
+ simply goes away. SIGPIPE is handled by x_connection_signal.
+ Don't need to do anything, because the write which caused the
+ SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
+ which will do the appropriate cleanup for us. */
+
+static SIGTYPE
+x_connection_signal (signalnum) /* If we don't have an argument, */
+ int signalnum; /* some compilers complain in signal calls. */
+{
+#ifdef USG
+ /* USG systems forget handlers when they are used;
+ must reestablish each time */
+ signal (signalnum, x_connection_signal);
+#endif /* USG */
+}
+\f
/* A buffer for storing X error messages. */
static char *x_caught_error_message;
#define X_CAUGHT_ERROR_MESSAGE_SIZE 200
/* If we have, just return it from the table. */
if (already_loaded >= 0)
- f->display.x->font = FRAME_X_DISPLAY_INFO (f)->font_table[already_loaded].font;
+ f->output_data.x->font = FRAME_X_DISPLAY_INFO (f)->font_table[already_loaded].font;
/* Otherwise, load the font and add it to the table. */
else
{
full_name = 0;
for (i = 0; i < font->n_properties; i++)
{
- char *atom
- = XGetAtomName (FRAME_X_DISPLAY (f), font->properties[i].name);
- if (!strcmp (atom, "FONT"))
+ if (FRAME_X_DISPLAY_INFO (f)->Xatom_FONT == font->properties[i].name)
{
char *name = XGetAtomName (FRAME_X_DISPLAY (f),
(Atom) (font->properties[i].card32));
break;
}
-
- XFree (atom);
}
n_fonts = FRAME_X_DISPLAY_INFO (f)->n_fonts;
FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].full_name = full_name;
else
FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].full_name = FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].name;
- f->display.x->font = FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].font = font;
+ f->output_data.x->font = FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].font = font;
FRAME_X_DISPLAY_INFO (f)->n_fonts++;
if (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);
+ int wid = FONT_WIDTH (f->output_data.x->font);
f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
}
else
/* Now make the frame display the given font. */
if (FRAME_X_WINDOW (f) != 0)
{
- XSetFont (FRAME_X_DISPLAY (f), f->display.x->normal_gc,
- f->display.x->font->fid);
- XSetFont (FRAME_X_DISPLAY (f), f->display.x->reverse_gc,
- f->display.x->font->fid);
- XSetFont (FRAME_X_DISPLAY (f), f->display.x->cursor_gc,
- f->display.x->font->fid);
+ XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
+ f->output_data.x->font->fid);
+ XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc,
+ f->output_data.x->font->fid);
+ XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc,
+ f->output_data.x->font->fid);
frame_update_line_height (f);
x_set_window_size (f, 0, f->width, f->height);
else
/* If we are setting a new frame's font for the first time,
there are no faces yet, so this font's height is the line height. */
- f->display.x->line_height = FONT_HEIGHT (f->display.x->font);
+ f->output_data.x->line_height = FONT_HEIGHT (f->output_data.x->font);
{
Lisp_Object lispy_name;
}
}
\f
+/* Calculate the absolute position in frame F
+ from its current recorded position values and gravity. */
+
x_calc_absolute_position (f)
struct frame *f;
{
Window win, child;
int win_x = 0, win_y = 0;
- int flags = f->display.x->size_hint_flags;
+ int flags = f->output_data.x->size_hint_flags;
int this_window;
#ifdef USE_X_TOOLKIT
- this_window = XtWindow (f->display.x->widget);
+ this_window = XtWindow (f->output_data.x->widget);
#else
this_window = FRAME_X_WINDOW (f);
#endif
/* Find the position of the outside upper-left corner of
the inner window, with respect to the outer window. */
- if (f->display.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
+ if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
{
BLOCK_INPUT;
XTranslateCoordinates (FRAME_X_DISPLAY (f),
/* From-window, to-window. */
this_window,
- f->display.x->parent_desc,
+ f->output_data.x->parent_desc,
/* From-position, to-position. */
0, 0, &win_x, &win_y,
/* Treat negative positions as relative to the leftmost bottommost
position that fits on the screen. */
if (flags & XNegative)
- f->display.x->left_pos = (FRAME_X_DISPLAY_INFO (f)->width
- - 2 * f->display.x->border_width - win_x
- - PIXEL_WIDTH (f)
- + f->display.x->left_pos);
+ f->output_data.x->left_pos = (FRAME_X_DISPLAY_INFO (f)->width
+ - 2 * f->output_data.x->border_width - win_x
+ - PIXEL_WIDTH (f)
+ + f->output_data.x->left_pos);
if (flags & YNegative)
- f->display.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
- - 2 * f->display.x->border_width - win_y
- - PIXEL_HEIGHT (f)
- - (FRAME_EXTERNAL_MENU_BAR (f)
- ? f->display.x->menubar_height : 0)
- + f->display.x->top_pos);
+ /* We used to subtract f->output_data.x->menubar_height here
+ in the toolkit case, but PIXEL_HEIGHT already includes that. */
+ f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
+ - 2 * f->output_data.x->border_width - win_y
+ - PIXEL_HEIGHT (f)
+ + f->output_data.x->top_pos);
+
/* 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);
+ f->output_data.x->size_hint_flags &= ~ (XNegative | YNegative);
}
/* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
if (change_gravity > 0)
{
- f->display.x->top_pos = yoff;
- f->display.x->left_pos = xoff;
- f->display.x->size_hint_flags &= ~ (XNegative | YNegative);
+ f->output_data.x->top_pos = yoff;
+ f->output_data.x->left_pos = xoff;
+ f->output_data.x->size_hint_flags &= ~ (XNegative | YNegative);
if (xoff < 0)
- f->display.x->size_hint_flags |= XNegative;
+ f->output_data.x->size_hint_flags |= XNegative;
if (yoff < 0)
- f->display.x->size_hint_flags |= YNegative;
- f->display.x->win_gravity = NorthWestGravity;
+ f->output_data.x->size_hint_flags |= YNegative;
+ f->output_data.x->win_gravity = NorthWestGravity;
}
x_calc_absolute_position (f);
/* It is a mystery why we need to add the border_width here
when the frame is already visible, but experiment says we do. */
- modified_left = f->display.x->left_pos;
- modified_top = f->display.x->top_pos;
+ modified_left = f->output_data.x->left_pos;
+ modified_top = f->output_data.x->top_pos;
if (change_gravity != 0)
{
- modified_left += f->display.x->border_width;
- modified_top += f->display.x->border_width;
+ modified_left += f->output_data.x->border_width;
+ modified_top += f->output_data.x->border_width;
}
#ifdef USE_X_TOOLKIT
- XMoveWindow (FRAME_X_DISPLAY (f), XtWindow (f->display.x->widget),
+ XMoveWindow (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget),
modified_left, modified_top);
#else /* not USE_X_TOOLKIT */
XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
{
int pixelwidth, pixelheight;
int mask;
+ Lisp_Object window;
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-#ifdef USE_X_TOOLKIT
BLOCK_INPUT;
+
+#ifdef USE_X_TOOLKIT
{
/* 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;
+ int xpos = f->output_data.x->widget->core.x;
+ int ypos = f->output_data.x->widget->core.y;
+ EmacsFrameSetCharSize (f->output_data.x->edit_widget, cols, rows);
+ f->output_data.x->widget->core.x = xpos;
+ f->output_data.x->widget->core.y = ypos;
}
- UNBLOCK_INPUT;
#else /* not USE_X_TOOLKIT */
- BLOCK_INPUT;
-
check_frame_size (f, &rows, &cols);
- f->display.x->vertical_scroll_bar_extra
+ f->output_data.x->vertical_scroll_bar_extra
= (!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)));
+ : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.x->font)));
pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
- f->display.x->win_gravity = NorthWestGravity;
+ f->output_data.x->win_gravity = NorthWestGravity;
x_wm_set_size_hint (f, (long) 0, 0);
XSync (FRAME_X_DISPLAY (f), False);
PIXEL_WIDTH (f) = pixelwidth;
PIXEL_HEIGHT (f) = pixelheight;
+ /* 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
+ we have to make sure to do it here. */
+ SET_FRAME_GARBAGED (f);
+
+ XFlush (FRAME_X_DISPLAY (f));
+
+#endif /* not USE_X_TOOLKIT */
+
/* 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_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
- we have to make sure to do it here. */
- SET_FRAME_GARBAGED (f);
+ /* Clear out any recollection of where the mouse highlighting was,
+ since it might be in a place that's outside the new frame size.
+ Actually checking whether it is outside is a pain in the neck,
+ so don't try--just let the highlighting be done afresh with new size. */
+ window = dpyinfo->mouse_face_window;
+ if (! NILP (window) && XFRAME (window) == f)
+ {
+ dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
+ dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
+ dpyinfo->mouse_face_window = Qnil;
+ }
- XFlush (FRAME_X_DISPLAY (f));
UNBLOCK_INPUT;
-#endif /* not USE_X_TOOLKIT */
}
\f
/* Mouse warping. */
{
int pix_x, pix_y;
- 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;
+ pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH (f->output_data.x->font) / 2;
+ pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->output_data.x->line_height / 2;
if (pix_x < 0) pix_x = 0;
if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f);
{
BLOCK_INPUT;
#ifdef USE_X_TOOLKIT
- XRaiseWindow (FRAME_X_DISPLAY (f), XtWindow (f->display.x->widget));
+ XRaiseWindow (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget));
#else /* not USE_X_TOOLKIT */
XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
#endif /* not USE_X_TOOLKIT */
{
BLOCK_INPUT;
#ifdef USE_X_TOOLKIT
- XLowerWindow (FRAME_X_DISPLAY (f), XtWindow (f->display.x->widget));
+ XLowerWindow (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget));
#else /* not USE_X_TOOLKIT */
XLowerWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
#endif /* not USE_X_TOOLKIT */
}
static void
-XTframe_raise_lower (f, raise)
+XTframe_raise_lower (f, raise_flag)
FRAME_PTR f;
- int raise;
+ int raise_flag;
{
- if (raise)
+ if (raise_flag)
x_raise_frame (f);
else
x_lower_frame (f);
\f
/* Change of visibility. */
+/* This tries to wait until the frame is really visible.
+ However, if the window manager asks the user where to position
+ the frame, this will return before the user finishes doing that.
+ The frame will not actually be visible at that time,
+ but it will become visible later when the window manager
+ finishes with it. */
+
x_make_frame_visible (f)
struct frame *f;
{
if (! FRAME_VISIBLE_P (f))
{
- if (! FRAME_ICONIFIED_P (f))
- x_set_offset (f, f->display.x->left_pos, f->display.x->top_pos, 0);
+ /* We test FRAME_GARBAGED_P here to make sure we don't
+ call x_set_offset a second time
+ if we get to x_make_frame_visible a second time
+ before the window gets really visible. */
+ if (! FRAME_ICONIFIED_P (f)
+ && ! f->output_data.x->asked_for_visible)
+ x_set_offset (f, f->output_data.x->left_pos, f->output_data.x->top_pos, 0);
+
+ f->output_data.x->asked_for_visible = 1;
if (! EQ (Vx_no_window_manager, Qt))
x_wm_set_window_state (f, NormalState);
#ifdef USE_X_TOOLKIT
/* This was XtPopup, but that did nothing for an iconified frame. */
- XtMapWidget (f->display.x->widget);
+ XtMapWidget (f->output_data.x->widget);
#else /* not USE_X_TOOLKIT */
XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
#endif /* not USE_X_TOOLKIT */
#ifdef USE_X_TOOLKIT
/* Use the frame's outermost window, not the one we normally draw on. */
- window = XtWindow (f->display.x->widget);
+ window = XtWindow (f->output_data.x->widget);
#else /* not USE_X_TOOLKIT */
window = FRAME_X_WINDOW (f);
#endif /* not USE_X_TOOLKIT */
BLOCK_INPUT;
+ FRAME_SAMPLE_VISIBILITY (f);
+
type = x_icon_type (f);
if (!NILP (type))
x_bitmap_icon (f, type);
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);
+ XtMapWidget (f->output_data.x->widget);
+ /* The server won't give us any event to indicate
+ that an invisible frame was changed to an icon,
+ so we have to record it here. */
+ f->iconified = 1;
+ f->async_iconified = 1;
UNBLOCK_INPUT;
return;
}
result = XIconifyWindow (FRAME_X_DISPLAY (f),
- XtWindow (f->display.x->widget),
+ XtWindow (f->output_data.x->widget),
DefaultScreen (FRAME_X_DISPLAY (f)));
UNBLOCK_INPUT;
/* 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);
+ x_set_offset (f, f->output_data.x->left_pos, f->output_data.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. */
BLOCK_INPUT;
- if (f->display.x->icon_desc != 0)
- XDestroyWindow (FRAME_X_DISPLAY (f), f->display.x->icon_desc);
- XDestroyWindow (FRAME_X_DISPLAY (f), f->display.x->window_desc);
+ /* If a display connection is dead, don't try sending more
+ commands to the X server. */
+ if (dpyinfo->display != 0)
+ {
+ if (f->output_data.x->icon_desc != 0)
+ XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
+#ifdef HAVE_X_I18N
+ if (FRAME_XIM (f))
+ {
+ XDestroyIC (FRAME_XIC (f));
+#if ! defined (SOLARIS2) || defined (HAVE_X11R6)
+ /* This line causes crashes on Solaris with Openwin,
+ due to an apparent bug in XCloseIM.
+ X11R6 seems not to have the bug. */
+ XCloseIM (FRAME_XIM (f));
+#endif
+ }
+#endif
+ XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->window_desc);
#ifdef USE_X_TOOLKIT
- XtDestroyWidget (f->display.x->widget);
- free_frame_menubar (f);
+ XtDestroyWidget (f->output_data.x->widget);
+ free_frame_menubar (f);
#endif /* USE_X_TOOLKIT */
- free_frame_faces (f);
- XFlush (FRAME_X_DISPLAY (f));
+ free_frame_faces (f);
+ XFlush (FRAME_X_DISPLAY (f));
+ }
- xfree (f->display.x);
- f->display.x = 0;
+ xfree (f->output_data.x);
+ f->output_data.x = 0;
if (f == dpyinfo->x_focus_frame)
dpyinfo->x_focus_frame = 0;
if (f == dpyinfo->x_focus_event_frame)
Arg al[2];
int ac = 0;
Dimension widget_width, widget_height;
- Window window = XtWindow (f->display.x->widget);
+ Window window = XtWindow (f->output_data.x->widget);
#else /* not USE_X_TOOLKIT */
Window window = FRAME_X_WINDOW (f);
#endif /* not USE_X_TOOLKIT */
flexlines = f->height;
- size_hints.x = f->display.x->left_pos;
- size_hints.y = f->display.x->top_pos;
+ size_hints.x = f->output_data.x->left_pos;
+ size_hints.y = f->output_data.x->top_pos;
#ifdef USE_X_TOOLKIT
XtSetArg (al[ac], XtNwidth, &widget_width); ac++;
XtSetArg (al[ac], XtNheight, &widget_height); ac++;
- XtGetValues (f->display.x->column_widget, al, ac);
+ XtGetValues (f->output_data.x->widget, al, ac);
size_hints.height = widget_height;
size_hints.width = widget_width;
#else /* not USE_X_TOOLKIT */
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.width_inc = FONT_WIDTH (f->output_data.x->font);
+ size_hints.height_inc = f->output_data.x->line_height;
size_hints.max_width
= FRAME_X_DISPLAY_INFO (f)->width - CHAR_TO_PIXEL_WIDTH (f, 0);
size_hints.max_height
= FRAME_X_DISPLAY_INFO (f)->height - CHAR_TO_PIXEL_HEIGHT (f, 0);
+ /* Calculate the base and minimum sizes.
+
+ (When we use the X toolkit, we don't do it here.
+ Instead we copy the values that the widgets are using, below.) */
+#ifndef USE_X_TOOLKIT
{
int base_width, base_height;
int min_rows = 0, min_cols = 0;
#endif
}
+ /* If we don't need the old flags, we don't need the old hint at all. */
if (flags)
- size_hints.flags |= flags;
- else
{
- XSizeHints hints; /* Sometimes I hate X Windows... */
- long supplied_return;
- int value;
+ size_hints.flags |= flags;
+ goto no_read;
+ }
+#endif /* not USE_X_TOOLKIT */
+
+ {
+ XSizeHints hints; /* Sometimes I hate X Windows... */
+ long supplied_return;
+ int value;
#ifdef HAVE_X11R4
- value = XGetWMNormalHints (FRAME_X_DISPLAY (f), window, &hints,
- &supplied_return);
+ value = XGetWMNormalHints (FRAME_X_DISPLAY (f), window, &hints,
+ &supplied_return);
#else
- value = XGetNormalHints (FRAME_X_DISPLAY (f), window, &hints);
+ value = XGetNormalHints (FRAME_X_DISPLAY (f), window, &hints);
#endif
- if (value == 0)
- hints.flags = 0;
- if (hints.flags & PSize)
- size_hints.flags |= PSize;
- if (hints.flags & PPosition)
- size_hints.flags |= PPosition;
- if (hints.flags & USPosition)
- size_hints.flags |= USPosition;
- if (hints.flags & USSize)
- size_hints.flags |= USSize;
- }
+#ifdef USE_X_TOOLKIT
+ size_hints.base_height = hints.base_height;
+ size_hints.base_width = hints.base_width;
+ size_hints.min_height = hints.min_height;
+ size_hints.min_width = hints.min_width;
+#endif
+
+ if (flags)
+ size_hints.flags |= flags;
+ else
+ {
+ if (value == 0)
+ hints.flags = 0;
+ if (hints.flags & PSize)
+ size_hints.flags |= PSize;
+ if (hints.flags & PPosition)
+ size_hints.flags |= PPosition;
+ if (hints.flags & USPosition)
+ size_hints.flags |= USPosition;
+ if (hints.flags & USSize)
+ size_hints.flags |= USSize;
+ }
+ }
+
+ no_read:
#ifdef PWinGravity
- size_hints.win_gravity = f->display.x->win_gravity;
+ size_hints.win_gravity = f->output_data.x->win_gravity;
size_hints.flags |= PWinGravity;
if (user_position)
Arg al[1];
XtSetArg (al[0], XtNinitialState, state);
- XtSetValues (f->display.x->widget, al, 1);
+ XtSetValues (f->output_data.x->widget, al, 1);
#else /* not USE_X_TOOLKIT */
Window window = FRAME_X_WINDOW (f);
- f->display.x->wm_hints.flags |= StateHint;
- f->display.x->wm_hints.initial_state = state;
+ f->output_data.x->wm_hints.flags |= StateHint;
+ f->output_data.x->wm_hints.initial_state = state;
- XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
+ XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
#endif /* not USE_X_TOOLKIT */
}
struct frame *f;
int pixmap_id;
{
+ Pixmap icon_pixmap;
+
#ifdef USE_X_TOOLKIT
- Window window = XtWindow (f->display.x->widget);
+ Window window = XtWindow (f->output_data.x->widget);
#else
Window window = FRAME_X_WINDOW (f);
#endif
if (pixmap_id > 0)
{
- Pixmap icon_pixmap = x_bitmap_pixmap (f, pixmap_id);
- f->display.x->wm_hints.icon_pixmap = icon_pixmap;
+ icon_pixmap = x_bitmap_pixmap (f, pixmap_id);
+ f->output_data.x->wm_hints.icon_pixmap = icon_pixmap;
}
else
- f->display.x->wm_hints.icon_pixmap = None;
+ {
+ /* It seems there is no way to turn off use of an icon pixmap.
+ The following line does it, only if no icon has yet been created,
+ for some window managers. But with mwm it crashes.
+ Some people say it should clear the IconPixmapHint bit in this case,
+ but that doesn't work, and the X consortium said it isn't the
+ right thing at all. Since there is no way to win,
+ best to explicitly give up. */
+#if 0
+ f->output_data.x->wm_hints.icon_pixmap = None;
+#else
+ return;
+#endif
+ }
+
+#ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
- f->display.x->wm_hints.flags |= IconPixmapHint;
- XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
+ {
+ Arg al[1];
+ XtSetArg (al[0], XtNiconPixmap, icon_pixmap);
+ XtSetValues (f->output_data.x->widget, al, 1);
+ }
+
+#else /* not USE_X_TOOLKIT */
+
+ f->output_data.x->wm_hints.flags |= IconPixmapHint;
+ XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
+
+#endif /* not USE_X_TOOLKIT */
}
x_wm_set_icon_position (f, icon_x, icon_y)
int icon_x, icon_y;
{
#ifdef USE_X_TOOLKIT
- Window window = XtWindow (f->display.x->widget);
+ Window window = XtWindow (f->output_data.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;
- f->display.x->wm_hints.icon_y = icon_y;
+ f->output_data.x->wm_hints.flags |= IconPositionHint;
+ f->output_data.x->wm_hints.icon_x = icon_x;
+ f->output_data.x->wm_hints.icon_y = icon_y;
- XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
+ XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
}
\f
x_initialized = 1;
}
+#ifdef HAVE_X_I18N
+ setlocale (LC_ALL, "");
+ /* In case we just overrode what init_lread did, redo it. */
+ setlocale (LC_NUMERIC, "C");
+ setlocale (LC_TIME, "C");
+#endif
+
#ifdef USE_X_TOOLKIT
/* weiner@footloose.sps.mot.com reports that this causes
errors with X11R5:
resource_name, EMACS_CLASS,
emacs_options, XtNumber (emacs_options),
&argc, argv);
+
+#ifdef HAVE_X11XTR6
+ /* I think this is to compensate for XtSetLanguageProc. */
+ setlocale (LC_NUMERIC, "C");
+ setlocale (LC_TIME, "C");
+#endif
}
#else /* not USE_X_TOOLKIT */
= XInternAtom (dpyinfo->display, "WM_MOVED", False);
dpyinfo->Xatom_editres
= XInternAtom (dpyinfo->display, "Editres", False);
+ dpyinfo->Xatom_FONT
+ = XInternAtom (dpyinfo->display, "FONT", False);
dpyinfo->Xatom_CLIPBOARD
= XInternAtom (dpyinfo->display, "CLIPBOARD", False);
dpyinfo->Xatom_TIMESTAMP
init_sigio (connection);
#endif /* ! defined (SIGIO) */
+#ifdef USE_LUCID
+ /* Make sure that we have a valid font for dialog boxes
+ so that Xt does not crash. */
+ {
+ Display *dpy = dpyinfo->display;
+ XrmValue d, fr, to;
+ Font font;
+
+ d.addr = (XPointer)&dpy;
+ d.size = sizeof (Display *);
+ fr.addr = XtDefaultFont;
+ fr.size = sizeof (XtDefaultFont);
+ to.size = sizeof (Font *);
+ to.addr = (XPointer)&font;
+ x_catch_errors (dpy);
+ if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
+ abort ();
+ if (x_had_errors_p (dpy) || !XQueryFont (dpy, font))
+ XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
+ x_uncatch_errors (dpy);
+ }
+#endif
+
+
UNBLOCK_INPUT;
return dpyinfo;
tail->next = tail->next->next;
}
-#ifndef USE_X_TOOLKIT
- /* I'm told Xt does this itself. */
+#ifndef USE_X_TOOLKIT /* I'm told Xt does this itself. */
+#ifndef AIX /* On AIX, XCloseDisplay calls this. */
XrmDestroyDatabase (dpyinfo->xrdb);
#endif
+#endif
#ifdef MULTI_KBOARD
if (--dpyinfo->kboard->reference_count == 0)
delete_kboard (dpyinfo->kboard);
#ifdef USE_X_TOOLKIT
XtToolkitInitialize ();
Xt_app_con = XtCreateApplicationContext ();
+ XtAppSetFallbackResources (Xt_app_con, Xt_default_resources);
#endif
/* Note that there is no real way portable across R3/R4 to get the
staticpro (&Qvendor_specific_keysyms);
Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
+
+ staticpro (&last_mouse_press_frame);
+ last_mouse_press_frame = Qnil;
}
-#endif /* ! defined (HAVE_X_WINDOWS) */
+
+#endif /* not HAVE_X_WINDOWS */