#include <sys/stat.h>
#include <sys/param.h>
+#include "frame.h"
#include "dispextern.h"
#include "termhooks.h"
#include "termopts.h"
#include "sinkmask.h"
#endif /* ! 0 */
#include "gnu.h"
-#include "frame.h"
#include "disptab.h"
#include "buffer.h"
#include "window.h"
#define min(a,b) ((a)<(b) ? (a) : (b))
#define max(a,b) ((a)>(b) ? (a) : (b))
\f
-/* Nonzero means we must reprint all windows
- because 1) we received an ExposeWindow event
- or 2) we received too many ExposeRegion events to record.
-
- This is never needed under X11. */
-static int expose_all_windows;
-
-/* Nonzero means we must reprint all icon windows. */
-
-static int expose_all_icons;
-
-#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, Vsystem_name;
char *x_id_name;
-/* Initial values of argv and argc. */
-extern char **initial_argv;
-extern int initial_argc;
-
-/* For now, we have just one x_display structure since we only support
- one X display. */
-static struct x_display_info the_x_screen;
-
/* This is a chain of structures for all the X displays currently in use. */
struct x_display_info *x_display_list;
-/* The cursor to use for vertical scroll bars on x_current_display. */
-static Cursor x_vertical_scroll_bar_cursor;
+/* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
+ one for each element of x_display_list and in the same order.
+ NAME is the name of the frame.
+ FONT-LIST-CACHE records previous values returned by x-list-fonts. */
+Lisp_Object x_display_name_list;
/* Frame being updated by update_frame. This is declared in term.c.
This is set by update_begin and looked at by all the
minibuffer. */
static struct frame *x_highlight_frame;
-/* From .Xdefaults, the value of "emacs.WarpMouse". If non-zero,
- mouse is moved to inside of frame when frame is de-iconified. */
-
-static int warp_mouse_on_deiconify;
-
/* During an update, maximum vpos for ins/del line operations to affect. */
static int flexlines;
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
it's somewhat accurate. */
static Time last_mouse_movement_time;
-/* These variables describe the range of text currently shown
- 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_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;
-
-/* 1 if a mouse motion event came and we didn't handle it right away because
- gc was in progress. */
-static int mouse_face_deferred_gc;
-
-/* 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;
-
/* Incremented by XTread_socket whenever it really tries to read events. */
#ifdef __STDC__
static int volatile input_signal_count;
static int input_signal_count;
#endif
-/* Tells if a window manager is present or not. */
+/* Used locally within XTread_socket. */
+static int x_noop_count;
-extern Lisp_Object Vx_no_window_manager;
+/* Initial values of argv and argc. */
+extern char **initial_argv;
+extern int initial_argc;
-/* Timestamp that we requested selection data was made. */
-extern Time requestor_time;
+extern Lisp_Object Vcommand_line_args, Vsystem_name;
-/* ID of the window requesting selection data. */
-extern Window requestor_window;
+/* Tells if a window manager is present or not. */
+
+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;
-static int x_noop_count;
-
extern int errno;
/* A mask of extra modifier bits to put into every keyboard char. */
extern int extra_keyboard_modifiers;
-extern Display *XOpenDisplay ();
-extern Window XCreateWindow ();
-
-extern Cursor XCreateCursor ();
-extern XFontStruct *XOpenFont ();
extern XrmDatabase x_load_resources ();
+void x_delete_display ();
+
static void flashback ();
static void redraw_previous_char ();
static void redraw_following_char ();
static void show_mouse_face ();
static void do_line_dance ();
-void dumpborder ();
static int XTcursor_to ();
static int XTclear_end_of_line ();
+static int x_io_error_quitter ();
\f
/* Return the struct x_display_info corresponding to DPY. */
should never be called except during an update, the only exceptions
being XTcursor_to, XTwrite_glyphs and XTreassert_line_highlight. */
-extern int mouse_track_top, mouse_track_left, mouse_track_width;
-
static
XTupdate_begin (f)
struct frame *f;
BLOCK_INPUT;
- if (f == mouse_face_mouse_frame)
+ if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
{
/* Don't do highlighting for mouse motion during the update. */
- mouse_face_defer = 1;
- if (!NILP (mouse_face_window))
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 1;
+ if (!NILP (FRAME_X_DISPLAY_INFO (f)->mouse_face_window))
{
int firstline, lastline, i;
- struct window *w = XWINDOW (mouse_face_window);
+ struct window *w = XWINDOW (FRAME_X_DISPLAY_INFO (f)->mouse_face_window);
/* Find the first, and the last+1, lines affected by redisplay. */
for (firstline = 0; firstline < f->height; firstline++)
if (! (firstline > (XFASTINT (w->top) + window_internal_height (w))
|| lastline < XFASTINT (w->top)))
/* Otherwise turn off the mouse highlight now. */
- clear_mouse_face ();
+ clear_mouse_face (FRAME_X_DISPLAY_INFO (f));
}
}
do_line_dance ();
x_display_cursor (f, 1);
- if (f == mouse_face_mouse_frame)
- mouse_face_defer = 0;
+ if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
+ 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
have no relation to the contents of the window-buffer.
I don't know a clean way to check
for that case. window_end_valid isn't set up yet. */
- if (f == mouse_face_mouse_frame)
- note_mouse_highlight (f, mouse_face_mouse_x, mouse_face_mouse_y);
+ if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
+ note_mouse_highlight (f, FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_x,
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
#endif
XFlush (FRAME_X_DISPLAY (f));
XTframe_up_to_date (f)
FRAME_PTR f;
{
- if (mouse_face_deferred_gc || f == mouse_face_mouse_frame)
+ if (FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc
+ || f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
{
- note_mouse_highlight (mouse_face_mouse_frame,
- mouse_face_mouse_x, mouse_face_mouse_y);
- mouse_face_deferred_gc = 0;
+ note_mouse_highlight (FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame,
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_x,
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc = 0;
}
}
\f
/* HL = 3 means use a mouse face previously chosen. */
if (hl == 3)
- cf = mouse_face_face_id;
+ cf = FRAME_X_DISPLAY_INFO (f)->mouse_face_face_id;
/* First look at the face of the text itself. */
if (cf != 0)
xgcv.font = face->font->fid;
xgcv.graphics_exposures = 0;
mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
- if (scratch_cursor_gc)
- XChangeGC (FRAME_X_DISPLAY (f), scratch_cursor_gc, mask, &xgcv);
+ if (FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc)
+ XChangeGC (FRAME_X_DISPLAY (f),
+ FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc,
+ mask, &xgcv);
else
- scratch_cursor_gc
+ FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc
= XCreateGC (FRAME_X_DISPLAY (f), window, mask, &xgcv);
- gc = scratch_cursor_gc;
+ gc = FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc;
#if 0
/* If this code is restored, it must also reset to the default stipple
if necessary. */
flexlines = n;
}
\f
+/* These variables need not be per frame
+ because redisplay is done on a frame-by-frame basis
+ and the line dance for one frame is finished before
+ anything is done for anoter frame. */
+
/* Array of line numbers from cached insert/delete operations.
line_dance[i] is the old position of the line that we want
to move to line i, or -1 if we want a blank line there. */
if (disable_mouse_highlight)
return;
- mouse_face_mouse_x = x;
- mouse_face_mouse_y = y;
- mouse_face_mouse_frame = f;
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_x = x;
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y = y;
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame = f;
- if (mouse_face_defer)
+ if (FRAME_X_DISPLAY_INFO (f)->mouse_face_defer)
return;
if (gc_in_progress)
{
- mouse_face_deferred_gc = 1;
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc = 1;
return;
}
w = XWINDOW (window);
/* If we were displaying active text in another window, clear that. */
- if (! EQ (window, mouse_face_window))
- clear_mouse_face ();
+ if (! EQ (window, FRAME_X_DISPLAY_INFO (f)->mouse_face_window))
+ clear_mouse_face (FRAME_X_DISPLAY_INFO (f));
/* Are we in a window whose display is up to date?
And verify the buffer's text has not changed. */
pos = ptr[i];
/* Is it outside the displayed active region (if any)? */
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)))
+ clear_mouse_face (FRAME_X_DISPLAY_INFO (f));
+ else if (! (EQ (window, FRAME_X_DISPLAY_INFO (f)->mouse_face_window)
+ && row >= FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
+ && row <= FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
+ && (row > FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
+ || column >= FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col)
+ && (row < FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
+ || column < FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col
+ || FRAME_X_DISPLAY_INFO (f)->mouse_face_past_end)))
{
Lisp_Object mouse_face, overlay, position;
Lisp_Object *overlay_vec;
ZV = Z;
/* Yes. Clear the display of the old active region, if any. */
- clear_mouse_face ();
+ clear_mouse_face (FRAME_X_DISPLAY_INFO (f));
/* Is this char mouse-active? */
XSETINT (position, pos);
before = Foverlay_start (overlay);
after = Foverlay_end (overlay);
/* Record this as the current active region. */
- 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);
+ fast_find_position (window, 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,
+ &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_X_DISPLAY_INFO (f)->mouse_face_face_id
+ = compute_char_face (f, w, pos, 0, 0,
+ &ignore, pos + 1, 1);
/* Display it as active. */
- show_mouse_face (1);
+ show_mouse_face (FRAME_X_DISPLAY_INFO (f), 1);
}
/* Handle the text property case. */
else if (! NILP (mouse_face))
= Fnext_single_property_change (position, Qmouse_face,
w->buffer, end);
/* Record this as the current active region. */
- 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
+ fast_find_position (window, 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,
+ &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_X_DISPLAY_INFO (f)->mouse_face_face_id
= compute_char_face (f, w, pos, 0, 0,
&ignore, pos + 1, 1);
/* Display it as active. */
- show_mouse_face (1);
+ show_mouse_face (FRAME_X_DISPLAY_INFO (f), 1);
}
BEGV = obegv;
ZV = ozv;
in its mouse-face if HL > 0, in its normal face if HL = 0. */
static void
-show_mouse_face (hl)
+show_mouse_face (dpyinfo, hl)
+ struct x_display_info *dpyinfo;
int hl;
{
- struct window *w = XWINDOW (mouse_face_window);
+ struct window *w = XWINDOW (dpyinfo->mouse_face_window);
int width = window_internal_width (w);
FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
int i;
curs_x = f->phys_cursor_x;
curs_y = f->phys_cursor_y;
- for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++)
+ 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 == mouse_face_beg_row ? mouse_face_beg_col : w->left);
- int endcolumn = (i == mouse_face_end_row ? mouse_face_end_col : w->left + width);
+ int column = (i == FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
+ ? FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col
+ : w->left);
+ int endcolumn = (i == FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
+ ? FRAME_X_DISPLAY_INFO (f)->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 >= mouse_face_beg_col - 1 && curs_x <= mouse_face_end_col)
+ && curs_x >= FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col - 1
+ && curs_x <= FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col)
{
x_display_cursor (f, 0);
cursor_off = 1;
Redraw it unhighlighted first. */
static void
-clear_mouse_face ()
+clear_mouse_face (dpyinfo)
+ struct x_display_info *dpyinfo;
{
- if (! NILP (mouse_face_window))
- show_mouse_face (0);
+ if (! NILP (dpyinfo->mouse_face_window))
+ show_mouse_face (dpyinfo, 0);
- mouse_face_beg_row = mouse_face_beg_col = -1;
- mouse_face_end_row = mouse_face_end_col = -1;
- mouse_face_window = Qnil;
+ 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;
}
\f
static struct scroll_bar *x_window_to_scroll_bar ();
a.event_mask = (ButtonPressMask | ButtonReleaseMask
| ButtonMotionMask | PointerMotionHintMask
| ExposureMask);
- a.cursor = x_vertical_scroll_bar_cursor;
+ a.cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
mask = (CWBackPixel | CWEventMask | CWCursor);
/* Mouse buttons and modifier keys. */
&dummy_mask))
- *fp = 0;
+ ;
else
{
int inside_height
win_y = top_range;
*fp = f;
- *bar_window = w;
+ *bar_window = bar->window;
if (! NILP (bar->dragging))
*part = scroll_bar_handle;
int temp_index;
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;
+
/* 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.
interrupt_input_pending = 0;
BLOCK_INPUT;
- /* Find the display we are supposed to read input for.
- It's the one communicating on descriptor SD. */
- for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
- if (dpyinfo->connection == sd)
- break;
- if (dpyinfo == 0)
- abort ();
-
/* So people can tell when we have read the available input. */
input_signal_count++;
if (numchars <= 0)
abort (); /* Don't think this happens. */
+ /* Find the display we are supposed to read input for.
+ It's the one communicating on descriptor SD. */
+ for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
+ {
+#if 0 /* This ought to be unnecessary; let's verify it. */
#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,
- a read returns 0, which Xlib interprets as equivalent to EPIPE. */
- fcntl (sd, F_SETFL, 0);
+ /* 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,
+ a read returns 0, which Xlib interprets as equivalent to EPIPE. */
+ fcntl (dpyinfo->connection, F_SETFL, 0);
#endif /* ! defined (FIOSNBIO) */
+#endif
+#if 0 /* This code can't be made to work, with multiple displays,
+ and appears not to be used on any system any more.
+ Also keyboard.c doesn't turn O_NDELAY on and off
+ for X connections. */
#ifndef SIGIO
#ifndef HAVE_SELECT
- if (! (fcntl (sd, F_GETFL, 0) & O_NDELAY))
- {
- extern int read_alarm_should_throw;
- read_alarm_should_throw = 1;
- XPeekEvent (dpyinfo->display, &event);
- read_alarm_should_throw = 0;
- }
+ if (! (fcntl (dpyinfo->connection, F_GETFL, 0) & O_NDELAY))
+ {
+ extern int read_alarm_should_throw;
+ read_alarm_should_throw = 1;
+ XPeekEvent (dpyinfo->display, &event);
+ read_alarm_should_throw = 0;
+ }
#endif /* HAVE_SELECT */
#endif /* SIGIO */
+#endif
- while (XPending (dpyinfo->display) != 0)
- {
- XNextEvent (dpyinfo->display, &event);
- event_found = 1;
+ /* For debugging, this gives a way to fake an I/O error. */
+ if (dpyinfo == XTread_socket_fake_io_error)
+ {
+ XTread_socket_fake_io_error = 0;
+ x_io_error_quitter (dpyinfo->display);
+ }
- switch (event.type)
+ while (XPending (dpyinfo->display) != 0)
{
- case ClientMessage:
- {
- if (event.xclient.message_type
- == dpyinfo->Xatom_wm_protocols
- && event.xclient.format == 32)
+ XNextEvent (dpyinfo->display, &event);
+ event_found = 1;
+
+ switch (event.type)
+ {
+ case ClientMessage:
{
- if (event.xclient.data.l[0]
- == dpyinfo->Xatom_wm_take_focus)
+ if (event.xclient.message_type
+ == dpyinfo->Xatom_wm_protocols
+ && event.xclient.format == 32)
{
- f = x_window_to_frame (event.xclient.window);
- /* 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)
- XSetInputFocus (event.xclient.display,
- event.xclient.window,
- RevertToPointerRoot,
- event.xclient.data.l[1]);
- /* Not certain about handling scroll bars here */
- }
- else if (event.xclient.data.l[0]
- == dpyinfo->Xatom_wm_save_yourself)
- {
- /* Save state modify the WM_COMMAND property to
- something which can reinstate us. This notifies
- the session manager, who's looking for such a
- PropertyNotify. Can restart processing when
- a keyboard or mouse event arrives. */
- if (numchars > 0)
+ if (event.xclient.data.l[0]
+ == dpyinfo->Xatom_wm_take_focus)
{
- f = x_top_window_to_frame (event.xclient.window);
-
- /* This is just so we only give real data once
- for a single Emacs process. */
- if (f == selected_frame)
- XSetCommand (FRAME_X_DISPLAY (f),
- event.xclient.window,
- initial_argv, initial_argc);
- else
- XSetCommand (FRAME_X_DISPLAY (f),
- event.xclient.window,
- 0, 0);
+ f = x_window_to_frame (event.xclient.window);
+ /* 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)
+ XSetInputFocus (event.xclient.display,
+ event.xclient.window,
+ RevertToPointerRoot,
+ event.xclient.data.l[1]);
+ /* Not certain about handling scroll bars here */
}
- }
- else if (event.xclient.data.l[0]
- == dpyinfo->Xatom_wm_delete_window)
- {
- struct frame *f = x_any_window_to_frame (event.xclient.window);
-
- if (f)
+ else if (event.xclient.data.l[0]
+ == dpyinfo->Xatom_wm_save_yourself)
+ {
+ /* Save state modify the WM_COMMAND property to
+ something which can reinstate us. This notifies
+ the session manager, who's looking for such a
+ PropertyNotify. Can restart processing when
+ a keyboard or mouse event arrives. */
+ if (numchars > 0)
+ {
+ f = x_top_window_to_frame (event.xclient.window);
+
+ /* This is just so we only give real data once
+ for a single Emacs process. */
+ if (f == selected_frame)
+ XSetCommand (FRAME_X_DISPLAY (f),
+ event.xclient.window,
+ initial_argv, initial_argc);
+ else
+ XSetCommand (FRAME_X_DISPLAY (f),
+ event.xclient.window,
+ 0, 0);
+ }
+ }
+ else if (event.xclient.data.l[0]
+ == dpyinfo->Xatom_wm_delete_window)
{
- if (numchars == 0)
- abort ();
+ struct frame *f = x_any_window_to_frame (event.xclient.window);
- bufp->kind = delete_window_event;
- XSETFRAME (bufp->frame_or_window, f);
- bufp++;
+ if (f)
+ {
+ if (numchars == 0)
+ abort ();
- count += 1;
- numchars -= 1;
+ bufp->kind = delete_window_event;
+ XSETFRAME (bufp->frame_or_window, f);
+ bufp++;
+
+ count += 1;
+ numchars -= 1;
+ }
}
}
- }
- else if (event.xclient.message_type
- == dpyinfo->Xatom_wm_configure_denied)
- {
- }
- else if (event.xclient.message_type
- == dpyinfo->Xatom_wm_window_moved)
- {
- int new_x, new_y;
- struct frame *f = x_window_to_frame (event.xclient.window);
+ else if (event.xclient.message_type
+ == dpyinfo->Xatom_wm_configure_denied)
+ {
+ }
+ else if (event.xclient.message_type
+ == dpyinfo->Xatom_wm_window_moved)
+ {
+ int new_x, new_y;
+ struct frame *f = x_window_to_frame (event.xclient.window);
- new_x = event.xclient.data.s[0];
- new_y = event.xclient.data.s[1];
+ new_x = event.xclient.data.s[0];
+ new_y = event.xclient.data.s[1];
- if (f)
- {
- f->display.x->left_pos = new_x;
- f->display.x->top_pos = new_y;
+ if (f)
+ {
+ f->display.x->left_pos = new_x;
+ f->display.x->top_pos = new_y;
+ }
}
- }
#if defined (USE_X_TOOLKIT) && defined (HAVE_X11R5)
- else if (event.xclient.message_type
- == dpyinfo->Xatom_editres)
- {
- struct frame *f = x_any_window_to_frame (event.xclient.window);
- _XEditResCheckMessages (f->display.x->widget, NULL, &event, NULL);
- }
+ else if (event.xclient.message_type
+ == dpyinfo->Xatom_editres)
+ {
+ struct frame *f = x_any_window_to_frame (event.xclient.window);
+ _XEditResCheckMessages (f->display.x->widget, NULL, &event, NULL);
+ }
#endif /* USE_X_TOOLKIT and HAVE_X11R5 */
- }
- break;
+ }
+ break;
- case SelectionNotify:
+ case SelectionNotify:
#ifdef USE_X_TOOLKIT
- if (! x_window_to_frame (event.xselection.requestor))
- goto OTHER;
+ if (! x_window_to_frame (event.xselection.requestor))
+ goto OTHER;
#endif /* not USE_X_TOOLKIT */
- x_handle_selection_notify (&event);
- break;
+ x_handle_selection_notify (&event);
+ break;
- case SelectionClear: /* Someone has grabbed ownership. */
+ case SelectionClear: /* Someone has grabbed ownership. */
#ifdef USE_X_TOOLKIT
- if (! x_window_to_frame (event.xselectionclear.window))
- goto OTHER;
+ if (! x_window_to_frame (event.xselectionclear.window))
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
- {
- XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
+ {
+ XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
- if (numchars == 0)
- abort ();
+ if (numchars == 0)
+ abort ();
- bufp->kind = selection_clear_event;
- SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
- SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
- SELECTION_EVENT_TIME (bufp) = eventp->time;
- bufp++;
+ bufp->kind = selection_clear_event;
+ SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
+ SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
+ SELECTION_EVENT_TIME (bufp) = eventp->time;
+ bufp++;
- count += 1;
- numchars -= 1;
- }
- break;
+ count += 1;
+ numchars -= 1;
+ }
+ break;
- case SelectionRequest: /* Someone wants our selection. */
+ case SelectionRequest: /* Someone wants our selection. */
#ifdef USE_X_TOOLKIT
- if (!x_window_to_frame (event.xselectionrequest.owner))
- goto OTHER;
+ if (!x_window_to_frame (event.xselectionrequest.owner))
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
- if (x_queue_selection_requests)
- x_queue_event (x_window_to_frame (event.xselectionrequest.owner),
- &event);
- else
- {
- XSelectionRequestEvent *eventp = (XSelectionRequestEvent *) &event;
-
- 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++;
-
- count += 1;
- numchars -= 1;
- }
- break;
+ if (x_queue_selection_requests)
+ x_queue_event (x_window_to_frame (event.xselectionrequest.owner),
+ &event);
+ else
+ {
+ XSelectionRequestEvent *eventp = (XSelectionRequestEvent *) &event;
- case PropertyNotify:
+ 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++;
+
+ count += 1;
+ numchars -= 1;
+ }
+ break;
+
+ case PropertyNotify:
#ifdef USE_X_TOOLKIT
- if (!x_any_window_to_frame (event.xproperty.window))
- goto OTHER;
+ if (!x_any_window_to_frame (event.xproperty.window))
+ goto OTHER;
#endif /* not USE_X_TOOLKIT */
- x_handle_property_notify (&event);
- break;
+ x_handle_property_notify (&event);
+ break;
- case ReparentNotify:
- f = x_top_window_to_frame (event.xreparent.window);
- if (f)
- {
- 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 ReparentNotify:
+ f = x_top_window_to_frame (event.xreparent.window);
+ if (f)
+ {
+ 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:
- f = x_window_to_frame (event.xexpose.window);
- if (f)
- {
- if (f->async_visible == 0)
+ case Expose:
+ f = x_window_to_frame (event.xexpose.window);
+ if (f)
{
- f->async_visible = 1;
- f->async_iconified = 0;
- SET_FRAME_GARBAGED (f);
+ if (f->async_visible == 0)
+ {
+ f->async_visible = 1;
+ f->async_iconified = 0;
+ SET_FRAME_GARBAGED (f);
+ }
+ else
+ dumprectangle (x_window_to_frame (event.xexpose.window),
+ event.xexpose.x, event.xexpose.y,
+ event.xexpose.width, event.xexpose.height);
}
else
- dumprectangle (x_window_to_frame (event.xexpose.window),
- event.xexpose.x, event.xexpose.y,
- event.xexpose.width, event.xexpose.height);
- }
- else
- {
- struct scroll_bar *bar
- = x_window_to_scroll_bar (event.xexpose.window);
+ {
+ struct scroll_bar *bar
+ = x_window_to_scroll_bar (event.xexpose.window);
- if (bar)
- x_scroll_bar_expose (bar, &event);
+ if (bar)
+ x_scroll_bar_expose (bar, &event);
#ifdef USE_X_TOOLKIT
- else
- goto OTHER;
+ else
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
- }
- break;
+ }
+ break;
- case GraphicsExpose: /* This occurs when an XCopyArea's
- source area was obscured or not
- available.*/
- f = x_window_to_frame (event.xgraphicsexpose.drawable);
- if (f)
- {
- dumprectangle (f,
- event.xgraphicsexpose.x, event.xgraphicsexpose.y,
- event.xgraphicsexpose.width,
- event.xgraphicsexpose.height);
- }
+ case GraphicsExpose: /* This occurs when an XCopyArea's
+ source area was obscured or not
+ available.*/
+ f = x_window_to_frame (event.xgraphicsexpose.drawable);
+ if (f)
+ {
+ dumprectangle (f,
+ event.xgraphicsexpose.x, event.xgraphicsexpose.y,
+ event.xgraphicsexpose.width,
+ event.xgraphicsexpose.height);
+ }
#ifdef USE_X_TOOLKIT
- else
- goto OTHER;
+ else
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
- break;
+ break;
- case NoExpose: /* This occurs when an XCopyArea's
- source area was completely
- available */
- break;
+ case NoExpose: /* This occurs when an XCopyArea's
+ source area was completely
+ available */
+ break;
- case UnmapNotify:
- f = x_any_window_to_frame (event.xunmap.window);
- if (f) /* F may no longer exist if
- the frame was deleted. */
- {
- /* While a frame is unmapped, display generation is
- disabled; you don't want to spend time updating a
- display that won't ever be seen. */
- f->async_visible = 0;
- /* 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. */
- if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
- f->async_iconified = 1;
- }
+ case UnmapNotify:
+ f = x_any_window_to_frame (event.xunmap.window);
+ if (f) /* F may no longer exist if
+ the frame was deleted. */
+ {
+ /* While a frame is unmapped, display generation is
+ disabled; you don't want to spend time updating a
+ display that won't ever be seen. */
+ f->async_visible = 0;
+ /* 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. */
+ if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
+ f->async_iconified = 1;
+ }
#ifdef USE_X_TOOLKIT
- goto OTHER;
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
- break;
+ break;
- case MapNotify:
- /* We use x_top_window_to_frame because map events can come
- for subwindows and they don't mean that the frame is visible. */
- f = x_top_window_to_frame (event.xmap.window);
- if (f)
- {
- f->async_visible = 1;
- f->async_iconified = 0;
+ case MapNotify:
+ /* We use x_top_window_to_frame because map events can come
+ for subwindows and they don't mean that the frame is visible. */
+ f = x_top_window_to_frame (event.xmap.window);
+ if (f)
+ {
+ f->async_visible = 1;
+ f->async_iconified = 0;
- /* wait_reading_process_input will notice this and update
- the frame's display structures. */
- SET_FRAME_GARBAGED (f);
- }
+ /* wait_reading_process_input will notice this and update
+ the frame's display structures. */
+ SET_FRAME_GARBAGED (f);
+ }
#ifdef USE_X_TOOLKIT
- goto OTHER;
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
- break;
+ break;
- /* Turn off processing if we become fully obscured. */
- case VisibilityNotify:
- break;
+ /* Turn off processing if we become fully obscured. */
+ case VisibilityNotify:
+ break;
- case KeyPress:
- f = x_any_window_to_frame (event.xkey.window);
+ case KeyPress:
+ f = x_any_window_to_frame (event.xkey.window);
- if (f != 0)
- {
- KeySym keysym, orig_keysym;
- /* al%imercury@uunet.uu.net says that making this 81 instead of
- 80 fixed a bug whereby meta chars made his Emacs hang. */
- unsigned char copy_buffer[81];
- int modifiers;
+ if (f != 0)
+ {
+ KeySym keysym, orig_keysym;
+ /* al%imercury@uunet.uu.net says that making this 81 instead of
+ 80 fixed a bug whereby meta chars made his Emacs hang. */
+ unsigned char copy_buffer[81];
+ int modifiers;
- event.xkey.state
- |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f),
- extra_keyboard_modifiers);
- modifiers = event.xkey.state;
+ event.xkey.state
+ |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f),
+ extra_keyboard_modifiers);
+ modifiers = event.xkey.state;
- /* This will have to go some day... */
+ /* This will have to go some day... */
- /* make_lispy_event turns chars into control chars.
- Don't do it here because XLookupString is too eager. */
- event.xkey.state &= ~ControlMask;
- nbytes =
- XLookupString (&event.xkey, copy_buffer, 80, &keysym,
- &compose_status);
+ /* make_lispy_event turns chars into control chars.
+ Don't do it here because XLookupString is too eager. */
+ event.xkey.state &= ~ControlMask;
+ nbytes =
+ XLookupString (&event.xkey, copy_buffer, 80, &keysym,
+ &compose_status);
- orig_keysym = keysym;
+ orig_keysym = keysym;
- if (numchars > 1)
- {
- if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
- || keysym == XK_Delete
- || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
- || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
+ if (numchars > 1)
+ {
+ if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
+ || keysym == XK_Delete
+ || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
+ || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
#ifdef HPUX
- /* This recognizes the "extended function keys".
- It seems there's no cleaner way.
- Test IsModifierKey to avoid handling mode_switch
- incorrectly. */
- || ((unsigned) (keysym) >= XK_Select
- && (unsigned)(keysym) < XK_KP_Space)
+ /* This recognizes the "extended function keys".
+ It seems there's no cleaner way.
+ Test IsModifierKey to avoid handling mode_switch
+ incorrectly. */
+ || ((unsigned) (keysym) >= XK_Select
+ && (unsigned)(keysym) < XK_KP_Space)
#endif
#ifdef XK_dead_circumflex
- || orig_keysym == XK_dead_circumflex
+ || orig_keysym == XK_dead_circumflex
#endif
#ifdef XK_dead_grave
- || orig_keysym == XK_dead_grave
+ || orig_keysym == XK_dead_grave
#endif
#ifdef XK_dead_tilde
- || orig_keysym == XK_dead_tilde
+ || orig_keysym == XK_dead_tilde
#endif
#ifdef XK_dead_diaeresis
- || orig_keysym == XK_dead_diaeresis
+ || orig_keysym == XK_dead_diaeresis
#endif
#ifdef XK_dead_macron
- || orig_keysym == XK_dead_macron
+ || orig_keysym == XK_dead_macron
#endif
#ifdef XK_dead_degree
- || orig_keysym == XK_dead_degree
+ || orig_keysym == XK_dead_degree
#endif
#ifdef XK_dead_acute
- || orig_keysym == XK_dead_acute
+ || orig_keysym == XK_dead_acute
#endif
#ifdef XK_dead_cedilla
- || orig_keysym == XK_dead_cedilla
+ || orig_keysym == XK_dead_cedilla
#endif
#ifdef XK_dead_breve
- || orig_keysym == XK_dead_breve
+ || orig_keysym == XK_dead_breve
#endif
#ifdef XK_dead_ogonek
- || orig_keysym == XK_dead_ogonek
+ || orig_keysym == XK_dead_ogonek
#endif
#ifdef XK_dead_caron
- || orig_keysym == XK_dead_caron
+ || orig_keysym == XK_dead_caron
#endif
#ifdef XK_dead_doubleacute
- || orig_keysym == XK_dead_doubleacute
+ || orig_keysym == XK_dead_doubleacute
#endif
#ifdef XK_dead_abovedot
- || orig_keysym == XK_dead_abovedot
+ || orig_keysym == XK_dead_abovedot
#endif
- || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
- || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
- /* Any "vendor-specific" key is ok. */
- || (orig_keysym & (1 << 28)))
- && ! (IsModifierKey (orig_keysym)
+ || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
+ || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
+ /* Any "vendor-specific" key is ok. */
+ || (orig_keysym & (1 << 28)))
+ && ! (IsModifierKey (orig_keysym)
#ifndef HAVE_X11R5
#ifdef XK_Mode_switch
- || ((unsigned)(orig_keysym) == XK_Mode_switch)
+ || ((unsigned)(orig_keysym) == XK_Mode_switch)
#endif
#ifdef XK_Num_Lock
- || ((unsigned)(orig_keysym) == XK_Num_Lock)
+ || ((unsigned)(orig_keysym) == XK_Num_Lock)
#endif
#endif /* not HAVE_X11R5 */
- ))
- {
- if (temp_index == sizeof temp_buffer / sizeof (short))
- temp_index = 0;
- temp_buffer[temp_index++] = keysym;
- bufp->kind = non_ascii_keystroke;
- bufp->code = keysym;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->modifiers
- = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
- modifiers);
- bufp->timestamp = event.xkey.time;
- bufp++;
- count++;
- numchars--;
- }
- else if (numchars > nbytes)
- {
- register int i;
-
- for (i = 0; i < nbytes; i++)
+ ))
{
if (temp_index == sizeof temp_buffer / sizeof (short))
temp_index = 0;
- temp_buffer[temp_index++] = copy_buffer[i];
- bufp->kind = ascii_keystroke;
- bufp->code = copy_buffer[i];
+ temp_buffer[temp_index++] = keysym;
+ bufp->kind = non_ascii_keystroke;
+ bufp->code = keysym;
XSETFRAME (bufp->frame_or_window, f);
bufp->modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
modifiers);
bufp->timestamp = event.xkey.time;
bufp++;
+ count++;
+ numchars--;
}
-
- count += nbytes;
- numchars -= nbytes;
+ else if (numchars > nbytes)
+ {
+ register int i;
+
+ for (i = 0; i < nbytes; i++)
+ {
+ if (temp_index == sizeof temp_buffer / sizeof (short))
+ temp_index = 0;
+ temp_buffer[temp_index++] = copy_buffer[i];
+ bufp->kind = ascii_keystroke;
+ bufp->code = copy_buffer[i];
+ XSETFRAME (bufp->frame_or_window, f);
+ bufp->modifiers
+ = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
+ modifiers);
+ bufp->timestamp = event.xkey.time;
+ bufp++;
+ }
+
+ count += nbytes;
+ numchars -= nbytes;
+ }
+ else
+ abort ();
}
else
abort ();
}
- else
- abort ();
- }
- break;
+ break;
- /* Here's a possible interpretation of the whole
- FocusIn-EnterNotify FocusOut-LeaveNotify mess. If you get a
- FocusIn event, you have to get a FocusOut event before you
- relinquish the focus. If you haven't received a FocusIn event,
- then a mere LeaveNotify is enough to free you. */
+ /* Here's a possible interpretation of the whole
+ FocusIn-EnterNotify FocusOut-LeaveNotify mess. If you get a
+ FocusIn event, you have to get a FocusOut event before you
+ relinquish the focus. If you haven't received a FocusIn event,
+ then a mere LeaveNotify is enough to free you. */
- case EnterNotify:
- f = x_any_window_to_frame (event.xcrossing.window);
+ case EnterNotify:
+ f = x_any_window_to_frame (event.xcrossing.window);
- if (event.xcrossing.focus) /* Entered Window */
- {
- /* Avoid nasty pop/raise loops. */
- if (f && (!(f->auto_raise)
- || !(f->auto_lower)
- || (event.xcrossing.time - enter_timestamp) > 500))
+ if (event.xcrossing.focus) /* Entered Window */
{
- x_new_focus_frame (f);
- enter_timestamp = event.xcrossing.time;
+ /* Avoid nasty pop/raise loops. */
+ if (f && (!(f->auto_raise)
+ || !(f->auto_lower)
+ || (event.xcrossing.time - enter_timestamp) > 500))
+ {
+ x_new_focus_frame (f);
+ enter_timestamp = event.xcrossing.time;
+ }
}
- }
- 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);
+ 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;
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
- break;
+ break;
- case FocusIn:
- f = x_any_window_to_frame (event.xfocus.window);
- if (event.xfocus.detail != NotifyPointer)
- x_focus_event_frame = f;
- if (f)
- x_new_focus_frame (f);
+ case FocusIn:
+ f = x_any_window_to_frame (event.xfocus.window);
+ if (event.xfocus.detail != NotifyPointer)
+ x_focus_event_frame = f;
+ if (f)
+ x_new_focus_frame (f);
#ifdef USE_X_TOOLKIT
- goto OTHER;
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
- break;
-
+ break;
- case LeaveNotify:
- f = x_top_window_to_frame (event.xcrossing.window);
- if (f)
- {
- 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)
+ case LeaveNotify:
+ f = x_top_window_to_frame (event.xcrossing.window);
+ if (f)
{
- if (! x_focus_event_frame)
- x_new_focus_frame (0);
+ if (f == dpyinfo->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 (dpyinfo);
+
+ if (event.xcrossing.focus)
+ {
+ if (! x_focus_event_frame)
+ x_new_focus_frame (0);
+ else
+ x_new_focus_frame (f);
+ }
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);
+ {
+ 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;
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
- break;
+ break;
- case FocusOut:
- f = x_any_window_to_frame (event.xfocus.window);
- if (event.xfocus.detail != NotifyPointer
- && f == x_focus_event_frame)
- x_focus_event_frame = 0;
- if (f && f == x_focus_frame)
- x_new_focus_frame (0);
+ case FocusOut:
+ f = x_any_window_to_frame (event.xfocus.window);
+ if (event.xfocus.detail != NotifyPointer
+ && f == x_focus_event_frame)
+ x_focus_event_frame = 0;
+ if (f && f == x_focus_frame)
+ x_new_focus_frame (0);
#ifdef USE_X_TOOLKIT
- goto OTHER;
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
- break;
+ break;
- case MotionNotify:
- {
- if (dpyinfo->grabbed && last_mouse_frame
- && FRAME_LIVE_P (last_mouse_frame))
- f = last_mouse_frame;
- else
- f = x_window_to_frame (event.xmotion.window);
- if (f)
- note_mouse_movement (f, &event.xmotion);
- else
+ case MotionNotify:
{
- struct scroll_bar *bar
- = x_window_to_scroll_bar (event.xmotion.window);
+ if (dpyinfo->grabbed && last_mouse_frame
+ && FRAME_LIVE_P (last_mouse_frame))
+ f = last_mouse_frame;
+ else
+ f = x_window_to_frame (event.xmotion.window);
+ if (f)
+ note_mouse_movement (f, &event.xmotion);
+ else
+ {
+ struct scroll_bar *bar
+ = x_window_to_scroll_bar (event.xmotion.window);
- if (bar)
- x_scroll_bar_note_movement (bar, &event);
+ if (bar)
+ x_scroll_bar_note_movement (bar, &event);
- /* If we move outside the frame,
- then we're certainly no longer on any text in the frame. */
- clear_mouse_face ();
+ /* If we move outside the frame,
+ then we're certainly no longer on any text in the frame. */
+ clear_mouse_face (dpyinfo);
+ }
}
- }
#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. */
+ 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;
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
#endif
- break;
+ break;
- case ConfigureNotify:
- f = x_any_window_to_frame (event.xconfigure.window);
+ case ConfigureNotify:
+ f = x_any_window_to_frame (event.xconfigure.window);
#ifdef USE_X_TOOLKIT
- if (f
+ if (f
#if 0
- && ! event.xconfigure.send_event
+ && ! event.xconfigure.send_event
#endif
- && (event.xconfigure.window == XtWindow (f->display.x->widget)))
- {
- Window win, child;
- int win_x, win_y;
-
- /* Find the position of the outside upper-left corner of
- the window, in the root coordinate system. Don't
- refer to the parent window here; we may be processing
- this event after the window manager has changed our
- parent, but before we have reached the ReparentNotify. */
- XTranslateCoordinates (FRAME_X_DISPLAY (f),
-
- /* From-window, to-window. */
- XtWindow (f->display.x->widget),
- FRAME_X_DISPLAY_INFO (f)->root_window,
-
- /* From-position, to-position. */
- -event.xconfigure.border_width,
- -event.xconfigure.border_width,
- &win_x, &win_y,
-
- /* Child of win. */
- &child);
- event.xconfigure.x = win_x;
- 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;
-
- /* 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 */
- if (f)
- {
- int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height);
- int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width);
-
- /* Even if the number of character rows and columns has
- not changed, the font size may have changed, so we need
- to check the pixel dimensions as well. */
- if (columns != f->width
- || rows != f->height
- || event.xconfigure.width != f->display.x->pixel_width
- || event.xconfigure.height != f->display.x->pixel_height)
- {
- change_frame_size (f, rows, columns, 0, 1);
- SET_FRAME_GARBAGED (f);
- }
-
- if (! event.xconfigure.send_event)
+ && (event.xconfigure.window == XtWindow (f->display.x->widget)))
{
Window win, child;
int win_x, win_y;
XTranslateCoordinates (FRAME_X_DISPLAY (f),
/* From-window, to-window. */
- f->display.x->window_desc,
+ XtWindow (f->display.x->widget),
FRAME_X_DISPLAY_INFO (f)->root_window,
/* From-position, to-position. */
&child);
event.xconfigure.x = win_x;
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;
+
+ /* 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 */
+ if (f)
+ {
+ int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height);
+ int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width);
+
+ /* Even if the number of character rows and columns has
+ not changed, the font size may have changed, so we need
+ to check the pixel dimensions as well. */
+ if (columns != f->width
+ || rows != f->height
+ || event.xconfigure.width != f->display.x->pixel_width
+ || event.xconfigure.height != f->display.x->pixel_height)
+ {
+ change_frame_size (f, rows, columns, 0, 1);
+ SET_FRAME_GARBAGED (f);
+ }
- 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;
+ if (! event.xconfigure.send_event)
+ {
+ Window win, child;
+ int win_x, win_y;
+
+ /* Find the position of the outside upper-left corner of
+ the window, in the root coordinate system. Don't
+ refer to the parent window here; we may be processing
+ this event after the window manager has changed our
+ parent, but before we have reached the ReparentNotify. */
+ XTranslateCoordinates (FRAME_X_DISPLAY (f),
+
+ /* From-window, to-window. */
+ f->display.x->window_desc,
+ FRAME_X_DISPLAY_INFO (f)->root_window,
+
+ /* From-position, to-position. */
+ -event.xconfigure.border_width,
+ -event.xconfigure.border_width,
+ &win_x, &win_y,
+
+ /* Child of win. */
+ &child);
+ event.xconfigure.x = win_x;
+ event.xconfigure.y = win_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)
+ 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;
+
+ /* What we have now is the position of Emacs's own window.
+ Convert that to the position of the window manager window. */
{
- /* 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);
+ 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;
+ break;
- case ButtonPress:
- case ButtonRelease:
- {
- /* If we decide we want to generate an event to be seen
- by the rest of Emacs, we put it here. */
- struct input_event emacs_event;
- emacs_event.kind = no_event;
+ case ButtonPress:
+ case ButtonRelease:
+ {
+ /* If we decide we want to generate an event to be seen
+ by the rest of Emacs, we put it here. */
+ struct input_event emacs_event;
+ emacs_event.kind = no_event;
- bzero (&compose_status, sizeof (compose_status));
+ bzero (&compose_status, sizeof (compose_status));
- f = x_window_to_frame (event.xbutton.window);
- if (f)
- {
- if (!x_focus_frame || (f == x_focus_frame))
- construct_mouse_click (&emacs_event, &event, f);
- }
- else
- {
- struct scroll_bar *bar
- = x_window_to_scroll_bar (event.xbutton.window);
+ f = x_window_to_frame (event.xbutton.window);
+ if (f)
+ {
+ if (!x_focus_frame || (f == x_focus_frame))
+ construct_mouse_click (&emacs_event, &event, f);
+ }
+ else
+ {
+ struct scroll_bar *bar
+ = x_window_to_scroll_bar (event.xbutton.window);
- if (bar)
- x_scroll_bar_handle_click (bar, &event, &emacs_event);
+ if (bar)
+ x_scroll_bar_handle_click (bar, &event, &emacs_event);
#ifdef USE_X_TOOLKIT
+ else
+ {
+ /* 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)
+ {
+ dpyinfo->grabbed |= (1 << event.xbutton.button);
+ last_mouse_frame = f;
+ }
else
{
- /* Assume we have a menubar button press. A bad
- assumption should behave benignly. */
- popup_get_selection (&event);
- break;
+ dpyinfo->grabbed &= ~(1 << event.xbutton.button);
}
-#endif /* USE_X_TOOLKIT */
- }
-
- if (event.type == ButtonPress)
- {
- dpyinfo->grabbed |= (1 << event.xbutton.button);
- last_mouse_frame = f;
- }
- else
- {
- dpyinfo->grabbed &= ~(1 << event.xbutton.button);
- }
- if (numchars >= 1 && emacs_event.kind != no_event)
- {
- bcopy (&emacs_event, bufp, sizeof (struct input_event));
- bufp++;
- count++;
- numchars--;
- }
+ if (numchars >= 1 && emacs_event.kind != no_event)
+ {
+ bcopy (&emacs_event, bufp, sizeof (struct input_event));
+ bufp++;
+ count++;
+ numchars--;
+ }
#ifdef USE_X_TOOLKIT
- goto OTHER;
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
- }
- break;
+ }
+ break;
- case CirculateNotify:
- break;
- case CirculateRequest:
- break;
+ case CirculateNotify:
+ break;
+ case CirculateRequest:
+ break;
- case MappingNotify:
- /* Someone has changed the keyboard mapping - update the
- local cache. */
- switch (event.xmapping.request)
- {
- case MappingModifier:
- x_find_modifier_meanings (dpyinfo);
- /* This is meant to fall through. */
- case MappingKeyboard:
- XRefreshKeyboardMapping (&event.xmapping);
- }
+ case MappingNotify:
+ /* Someone has changed the keyboard mapping - update the
+ local cache. */
+ switch (event.xmapping.request)
+ {
+ case MappingModifier:
+ x_find_modifier_meanings (dpyinfo);
+ /* This is meant to fall through. */
+ case MappingKeyboard:
+ XRefreshKeyboardMapping (&event.xmapping);
+ }
#ifdef USE_X_TOOLKIT
- goto OTHER;
+ goto OTHER;
#endif /* USE_X_TOOLKIT */
- break;
+ break;
- default:
+ default:
#ifdef USE_X_TOOLKIT
- OTHER:
- BLOCK_INPUT;
- XtDispatchEvent (&event);
- UNBLOCK_INPUT;
+ OTHER:
+ BLOCK_INPUT;
+ XtDispatchEvent (&event);
+ UNBLOCK_INPUT;
#endif /* USE_X_TOOLKIT */
- break;
+ break;
+ }
}
}
if (x_noop_count >= 100)
{
x_noop_count=0;
- XNoOp (dpyinfo->display);
+ /* Use the first display in the list. Why not? */
+ XNoOp (x_display_list->display);
}
}
/* If the focus was just given to an autoraising frame,
raise it now. */
+ /* ??? This ought to be able to handle more than one such frame. */
if (pending_autoraise_frame)
{
x_raise_frame (pending_autoraise_frame);
/* If the cursor is in the mouse face area, redisplay that when
we clear the cursor. */
- if (f == mouse_face_mouse_frame
+ if (f == FRAME_X_DISPLAY_INFO (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 > FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
+ || (f->phys_cursor_y == FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
+ && f->phys_cursor_x >= FRAME_X_DISPLAY_INFO (f)->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)))
+ (f->phys_cursor_y < FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
+ || (f->phys_cursor_y == FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
+ && f->phys_cursor_x < FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col)))
mouse_face_here = 1;
/* If the font is not as tall as a whole line,
\f
/* Handling X errors. */
-/* Shut down Emacs in an orderly fashion, because of a SIGPIPE on the
- X server's connection, or an error reported via the X protocol. */
+/* Handle the loss of connection to display DISPLAY. */
static SIGTYPE
-x_connection_closed ()
+x_connection_closed (display, error_message)
+ Display *display;
+ char *error_message;
{
+ struct x_display_info *dpyinfo = x_display_info_for_display (display);
+ Lisp_Object frame, tail;
+
if (_Xdebug)
abort ();
- shut_down_emacs (0, 1, Qnil);
+ /* First delete frames whose minibuffers are on frames
+ that are on the dead display. */
+ FOR_EACH_FRAME (tail, frame)
+ {
+ Lisp_Object minibuf_frame;
+ minibuf_frame
+ = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame))));
+ if (! EQ (frame, minibuf_frame)
+ && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
+ Fdelete_frame (frame, Qt);
+ }
+
+ /* Now delete all remaining frames on the dead display.
+ We are now sure none of these is used as the minibuffer
+ for another frame that we need to delete. */
+ FOR_EACH_FRAME (tail, frame)
+ if (FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
+ Fdelete_frame (frame, Qt);
+
+ x_delete_display (dpyinfo);
+
+ if (x_display_list == 0)
+ {
+ fprintf (stderr, "%s", error_message);
+ shut_down_emacs (0, 0, Qnil);
+ exit (70);
+ }
- exit (70);
+ /* Ordinary stack unwind doesn't deal with these. */
+#ifdef SIGIO
+ sigunblock (sigmask (SIGIO));
+#endif
+ sigunblock (sigmask (SIGALRM));
+ TOTALLY_UNBLOCK_INPUT;
+
+ error ("%s", error_message);
}
-/* An X error handler which prints an error message and then kills
- Emacs. This is what's normally installed as Xlib's handler for
- protocol errors. */
+/* This is the usual handler for X protocol errors.
+ It kills all frames on the display that we got the error for.
+ If that was the only one, it prints an error message and kills Emacs. */
+
static int
x_error_quitter (display, error)
Display *display;
XErrorEvent *error;
{
- char buf[256];
+ char buf[256], buf1[356];
/* Note that there is no real way portable across R3/R4 to get the
original error handler. */
XGetErrorText (display, error->error_code, buf, sizeof (buf));
- fprintf (stderr, "X protocol error: %s on protocol request %d\n",
+ sprintf (buf1, "X protocol error: %s on protocol request %d",
buf, error->request_code);
-
-#if 0
- /* While we're testing Emacs 19, we'll just dump core whenever we
- get an X error, so we can figure out why it happened. */
- abort ();
-#endif
-
- x_connection_closed ();
+ x_connection_closed (display, buf1);
}
-/* A handler for X IO errors which prints an error message and then
- kills Emacs. This is what is always installed as Xlib's handler
- for I/O errors. */
+/* This is the handler for X IO errors, always.
+ It kills all frames on the display that we lost touch with.
+ If that was the only one, it prints an error message and kills Emacs. */
+
static int
x_io_error_quitter (display)
Display *display;
{
- fprintf (stderr, "Connection to X server %s lost.\n",
- XDisplayName (DisplayString (display)));
-
-#if 0
- /* While we're testing Emacs 19, we'll just dump core whenever we
- get an X error, so we can figure out why it happened. */
- abort ();
-#endif
+ char buf[256];
- x_connection_closed ();
+ sprintf (buf, "Connection lost to X server `%s'", DisplayString (display));
+ x_connection_closed (display, buf);
}
-
+\f
/* A buffer for storing X error messages. */
static char *x_caught_error_message;
#define X_CAUGHT_ERROR_MESSAGE_SIZE 200
/* An X error handler which stores the error message in
x_caught_error_message. This is what's installed when
x_catch_errors is in effect. */
+
static int
x_error_catcher (display, error)
Display *display;
}
-/* Begin trapping X errors for frame F.
- Actually we trap X errors for all frames, but F should be the frame
- you are actually operating on.
+/* Begin trapping X errors for display DPY. Actually we trap X errors
+ for all displays, but DPY should be the display you are actually
+ operating on.
After calling this function, X protocol errors no longer cause
Emacs to exit; instead, they are recorded in x_cfc_error_message.
void x_catch_errors (), x_check_errors (), x_uncatch_errors ();
void
-x_catch_errors (f)
- FRAME_PTR f;
+x_catch_errors (dpy)
+ Display *dpy;
{
/* Make sure any errors from previous requests have been dealt with. */
- XSync (FRAME_X_DISPLAY (f), False);
+ XSync (dpy, False);
/* Set up the error buffer. */
x_caught_error_message
sprintf (a buffer, FORMAT, the x error message text) as the text. */
void
-x_check_errors (f, format)
- FRAME_PTR f;
+x_check_errors (dpy, format)
+ Display *dpy;
char *format;
{
/* Make sure to catch any errors incurred so far. */
- XSync (FRAME_X_DISPLAY (f), False);
+ XSync (dpy, False);
if (x_caught_error_message[0])
{
char buf[X_CAUGHT_ERROR_MESSAGE_SIZE + 56];
sprintf (buf, format, x_caught_error_message);
- x_uncatch_errors (f);
+ x_uncatch_errors (dpy);
error (buf);
}
}
/* Nonzero if we had any X protocol errors since we did x_catch_errors. */
int
-x_had_errors_p (f)
- FRAME_PTR f;
+x_had_errors_p (dpy)
+ Display *dpy;
{
/* Make sure to catch any errors incurred so far. */
- XSync (FRAME_X_DISPLAY (f), False);
+ XSync (dpy, False);
return x_caught_error_message[0] != 0;
}
/* Stop catching X protocol errors and let them make Emacs die. */
void
-x_uncatch_errors (f)
- FRAME_PTR f;
+x_uncatch_errors (dpy)
+ Display *dpy;
{
xfree (x_caught_error_message);
x_caught_error_message = 0;
\f
/* Changing the font of the frame. */
-/* Set the font of the x-window specified by frame F
- to the font named NEWNAME. This is safe to use
- even before F has an actual x-window. */
-
-struct font_info
-{
- XFontStruct *font;
- char *name;
- char *full_name;
-};
-
-/* A table of all the fonts we have already loaded. */
-static struct font_info *x_font_table;
-
-/* The current capacity of x_font_table. */
-static int x_font_table_size;
-
-/* The number of fonts actually stored in x_font_table.
- x_font_table[n] is used and valid iff 0 <= n < n_fonts.
- 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.
{
int i, j;
- for (i = 0; i < n_fonts; i++)
+ for (i = 0; i < FRAME_X_DISPLAY_INFO (f)->n_fonts; i++)
for (j = 0; j < n_matching_fonts; j++)
- if (!strcmp (x_font_table[i].name, font_names[j])
- || !strcmp (x_font_table[i].full_name, font_names[j]))
+ if (!strcmp (FRAME_X_DISPLAY_INFO (f)->font_table[i].name, font_names[j])
+ || !strcmp (FRAME_X_DISPLAY_INFO (f)->font_table[i].full_name, font_names[j]))
{
already_loaded = i;
- fontname = x_font_table[i].full_name;
+ fontname = FRAME_X_DISPLAY_INFO (f)->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;
+ f->display.x->font = FRAME_X_DISPLAY_INFO (f)->font_table[already_loaded].font;
/* Otherwise, load the font and add it to the table. */
else
{
int i;
char *full_name;
XFontStruct *font;
+ int n_fonts;
/* Try to find a character-cell font in the list. */
#if 0
}
/* Do we need to create the table? */
- if (x_font_table_size == 0)
+ if (FRAME_X_DISPLAY_INFO (f)->font_table_size == 0)
{
- x_font_table_size = 16;
- x_font_table
- = (struct font_info *) xmalloc (x_font_table_size
- * sizeof (x_font_table[0]));
+ FRAME_X_DISPLAY_INFO (f)->font_table_size = 16;
+ FRAME_X_DISPLAY_INFO (f)->font_table
+ = (struct font_info *) xmalloc (FRAME_X_DISPLAY_INFO (f)->font_table_size
+ * sizeof (struct font_info));
}
/* Do we need to grow the table? */
- else if (n_fonts >= x_font_table_size)
+ else if (FRAME_X_DISPLAY_INFO (f)->n_fonts
+ >= FRAME_X_DISPLAY_INFO (f)->font_table_size)
{
- x_font_table_size *= 2;
- x_font_table
- = (struct font_info *) xrealloc (x_font_table,
- (x_font_table_size
- * sizeof (x_font_table[0])));
+ FRAME_X_DISPLAY_INFO (f)->font_table_size *= 2;
+ FRAME_X_DISPLAY_INFO (f)->font_table
+ = (struct font_info *) xrealloc (FRAME_X_DISPLAY_INFO (f)->font_table,
+ (FRAME_X_DISPLAY_INFO (f)->font_table_size
+ * sizeof (struct font_info)));
}
/* Try to get the full name of FONT. Put it in full_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);
+ n_fonts = FRAME_X_DISPLAY_INFO (f)->n_fonts;
+ FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].name = (char *) xmalloc (strlen (fontname) + 1);
+ bcopy (fontname, FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].name, strlen (fontname) + 1);
if (full_name != 0)
- x_font_table[n_fonts].full_name = full_name;
+ FRAME_X_DISPLAY_INFO (f)->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;
+ 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;
+ FRAME_X_DISPLAY_INFO (f)->n_fonts++;
if (full_name)
fontname = full_name;
if (f == x_highlight_frame)
x_highlight_frame = 0;
- if (f == mouse_face_mouse_frame)
+ if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
{
- mouse_face_beg_row = mouse_face_beg_col = -1;
- mouse_face_end_row = mouse_face_end_col = -1;
- mouse_face_window = Qnil;
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
+ = FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col = -1;
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
+ = FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col = -1;
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_window = Qnil;
}
UNBLOCK_INPUT;
if (pixmap_id > 0)
{
- Pixmap icon_pixmap = x_lookup_pixmap (pixmap_id);
+ Pixmap icon_pixmap = x_bitmap_pixmap (f, pixmap_id);
f->display.x->wm_hints.icon_pixmap = icon_pixmap;
f->display.x->wm_hints.flags |= IconPixmapHint;
}
};
#endif /* USE_X_TOOLKIT */
+static int x_initialized;
+
struct x_display_info *
x_term_init (display_name, xrm_option, resource_name)
Lisp_Object display_name;
int argc = 0;
char** argv = 0;
int connection;
+ Display *dpy;
struct x_display_info *dpyinfo;
XrmDatabase xrdb;
-#ifndef F_SETOWN_BUG
-#ifdef F_SETOWN
- extern int old_fcntl_owner;
-#endif /* ! defined (F_SETOWN) */
-#endif /* F_SETOWN_BUG */
-
- dpyinfo = &the_x_screen;
-
- /* Put our one and only display on the chain. */
- x_display_list = dpyinfo;
- dpyinfo->next = 0;
-
- dpyinfo->name = display_name;
-
- x_noop_count = 0;
-
- x_focus_frame = x_highlight_frame = 0;
+ if (!x_initialized)
+ {
+ x_initialize ();
+ x_initialized = 1;
+ }
#ifdef USE_X_TOOLKIT
#ifdef HAVE_X11R5
&argc, argv,
NULL, NULL, 0);
XtFree ((char *)argv);
- dpyinfo->display = XtDisplay (Xt_app_shell);
+ dpy = XtDisplay (Xt_app_shell);
#else /* not USE_X_TOOLKIT */
#ifdef HAVE_X11R5
XSetLocaleModifiers ("");
#endif
- dpyinfo->display = XOpenDisplay (XSTRING (display_name)->data);
+ dpy = XOpenDisplay (XSTRING (display_name)->data);
#endif /* not USE_X_TOOLKIT */
- if (dpyinfo->display == 0)
- fatal ("X server %s not responding.\n\
-Check the DISPLAY environment variable or use \"-d\"\n",
- XSTRING (display_name)->data);
+ /* Detect failure. */
+ if (dpy == 0)
+ return 0;
+
+ /* We have definitely succeeded. Record the new connection. */
+
+ dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info));
+
+ /* Put this display on the chain. */
+ dpyinfo->next = x_display_list;
+ x_display_list = dpyinfo;
+
+ /* Put it on x_display_name_list as well, to keep them parallel. */
+ x_display_name_list = Fcons (Fcons (display_name, Qnil),
+ x_display_name_list);
+ dpyinfo->name_list_element = XCONS (x_display_name_list)->car;
+
+ dpyinfo->display = dpy;
- {
#if 0
- XSetAfterFunction (x_current_display, x_trace_wire);
+ XSetAfterFunction (x_current_display, x_trace_wire);
#endif /* ! 0 */
- x_id_name = (char *) xmalloc (XSTRING (Vinvocation_name)->size
- + XSTRING (Vsystem_name)->size
- + 2);
- sprintf (x_id_name, "%s@%s",
- XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
- }
+
+ dpyinfo->x_id_name
+ = (char *) xmalloc (XSTRING (Vinvocation_name)->size
+ + XSTRING (Vsystem_name)->size
+ + 2);
+ sprintf (dpyinfo->x_id_name, "%s@%s",
+ XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
/* Figure out which modifier bits mean what. */
x_find_modifier_meanings (dpyinfo);
/* Get the scroll bar cursor. */
- x_vertical_scroll_bar_cursor
+ dpyinfo->vertical_scroll_bar_cursor
= XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow);
-#if 0
- /* Watch for PropertyNotify events on the root window; we use them
- to figure out when to invalidate our cache of the cut buffers. */
- x_watch_cut_buffer_cache ();
-#endif
-
xrdb = x_load_resources (dpyinfo->display, xrm_option,
resource_name, EMACS_CLASS);
#ifdef HAVE_XRMSETDATABASE
#else
dpyinfo->display->db = xrdb;
#endif
+ /* Put thr rdb where we can find it in a way that works on
+ all versions. */
+ dpyinfo->xrdb = xrdb;
dpyinfo->screen = ScreenOfDisplay (dpyinfo->display,
DefaultScreen (dpyinfo->display));
dpyinfo->grabbed = 0;
dpyinfo->reference_count = 0;
dpyinfo->icon_bitmap_id = -1;
+ dpyinfo->n_fonts = 0;
+ dpyinfo->font_table_size = 0;
+ dpyinfo->bitmaps = 0;
+ dpyinfo->bitmaps_size = 0;
+ dpyinfo->bitmaps_last = 0;
+ dpyinfo->scratch_cursor_gc = 0;
+ dpyinfo->mouse_face_mouse_frame = 0;
+ dpyinfo->mouse_face_deferred_gc = 0;
+ 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_face_id = 0;
+ dpyinfo->mouse_face_window = Qnil;
+ dpyinfo->mouse_face_mouse_x = dpyinfo->mouse_face_mouse_y = 0;
+ dpyinfo->mouse_face_defer = 0;
dpyinfo->Xatom_wm_protocols
= XInternAtom (dpyinfo->display, "WM_PROTOCOLS", False);
#ifdef subprocesses
/* This is only needed for distinguishing keyboard and process input. */
if (connection != 0)
- change_keyboard_wait_descriptor (connection);
+ add_keyboard_wait_descriptor (connection);
#endif
- change_input_fd (connection);
#ifndef F_SETOWN_BUG
#ifdef F_SETOWN
- old_fcntl_owner = fcntl (connection, F_GETOWN, 0);
#ifdef F_SETOWN_SOCK_NEG
/* stdin is a socket here */
fcntl (connection, F_SETOWN, -getpid ());
#endif /* F_SETOWN_BUG */
#ifdef SIGIO
- init_sigio ();
+ init_sigio (connection);
#endif /* ! defined (SIGIO) */
- expose_all_windows = 0;
+ return dpyinfo;
+}
+\f
+/* Get rid of display DPYINFO, assuming all frames are already gone,
+ and without sending any more commands to the X server. */
+void
+x_delete_display (dpyinfo)
+ struct x_display_info *dpyinfo;
+{
+ delete_keyboard_wait_descriptor (dpyinfo->connection);
+
+ /* Discard this display from x_display_name_list and x_display_list.
+ We can't use Fdelq because that can quit. */
+ if (! NILP (x_display_name_list)
+ && EQ (XCONS (x_display_name_list)->car, dpyinfo->name_list_element))
+ x_display_name_list = XCONS (x_display_name_list)->cdr;
+ else
+ {
+ Lisp_Object tail;
+
+ tail = x_display_name_list;
+ while (CONSP (tail) && CONSP (XCONS (tail)->cdr))
+ {
+ if (EQ (XCONS (XCONS (tail)->cdr)->car,
+ dpyinfo->name_list_element))
+ {
+ XCONS (tail)->cdr = XCONS (XCONS (tail)->cdr)->cdr;
+ break;
+ }
+ tail = XCONS (tail)->cdr;
+ }
+ }
+
+ if (x_display_list == dpyinfo)
+ x_display_list = dpyinfo->next;
+ {
+ struct x_display_info *tail;
+
+ for (tail = x_display_list; tail; tail = tail->next)
+ if (tail->next == dpyinfo)
+ tail->next = tail->next->next;
+ }
+
+ /* ??? Should free the xrdb slot somehow? */
+ free (dpyinfo->font_table);
+ free (dpyinfo->x_id_name);
+ free (dpyinfo);
+}
+\f
+/* Set up use of X before we make the first connection. */
+
+x_initialize ()
+{
clear_frame_hook = XTclear_frame;
clear_end_of_line_hook = XTclear_end_of_line;
ins_del_lines_hook = XTins_del_lines;
off the bottom */
baud_rate = 19200;
+ x_noop_count = 0;
+
+ x_focus_frame = x_highlight_frame = 0;
+
/* Try to use interrupt input; if we can't, then start polling. */
Fset_input_mode (Qt, Qnil, Qt, Qnil);
void
syms_of_xterm ()
{
- the_x_screen.font_list_cache = Qnil;
- the_x_screen.name = Qnil;
- staticpro (&the_x_screen.font_list_cache);
- staticpro (&the_x_screen.name);
+ staticpro (&x_display_name_list);
+ x_display_name_list = Qnil;
staticpro (&last_mouse_scroll_bar);
last_mouse_scroll_bar = Qnil;
- staticpro (&mouse_face_window);
- mouse_face_window = Qnil;
}
#endif /* ! defined (HAVE_X_WINDOWS) */