*/
+/* Xt features made by Fred Pierresteguy. */
+
#define NEW_SELECTIONS
/* On 4.3 these lose if they come after xterm.h. */
#include <stdio.h>
#include <signal.h>
-#include "config.h"
+#include <config.h>
+
+/* Need syssignal.h for various externs and definitions that may be required
+ by some configurations for calls to signal later in this source file. */
+#include "syssignal.h"
#ifdef HAVE_X_WINDOWS
#include "buffer.h"
#include "window.h"
+#ifdef USE_X_TOOLKIT
+extern XtAppContext Xt_app_con;
+extern Widget Xt_app_shell;
+#endif /* USE_X_TOOLKIT */
+
#ifdef HAVE_X11
#define XMapWindow XMapRaised /* Raise them when mapping. */
#else /* ! defined (HAVE_X11) */
/*#include <X/Xproto.h> */
#endif /* ! defined (HAVE_X11) */
+#ifdef FD_SET
+/* We could get this from param.h, but better not to depend on finding that.
+ And better not to risk that it might define other symbols used in this
+ file. */
+#ifdef FD_SETSIZE
+#define MAXDESC FD_SETSIZE
+#else
+#define MAXDESC 64
+#endif
+#define SELECT_TYPE fd_set
+#else /* no FD_SET */
+#define MAXDESC 32
+#define SELECT_TYPE int
+
+/* Define the macros to access a single-int bitmap of descriptors. */
+#define FD_SET(n, p) (*(p) |= (1 << (n)))
+#define FD_CLR(n, p) (*(p) &= ~(1 << (n)))
+#define FD_ISSET(n, p) (*(p) & (1 << (n)))
+#define FD_ZERO(p) (*(p) = 0)
+#endif /* no FD_SET */
+
/* For sending Meta-characters. Do we need this? */
#define METABIT 0200
#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.
static struct event_queue x_expose_queue;
-/* ButtonPressed and ButtonReleased events, when received,
+/* ButtonPress and ButtonReleased events, when received,
are copied into this queue for later processing. */
struct event_queue x_mouse_queue;
static int curs_x;
static int curs_y;
+/* Mouse movement.
+
+ In order to avoid asking for motion events and then throwing most
+ of them away or busy-polling the server for mouse positions, we ask
+ the server for pointer motion hints. This means that we get only
+ one event per group of mouse movements. "Groups" are delimited by
+ other kinds of events (focus changes and button clicks, for
+ example), or by XQueryPointer calls; when one of these happens, we
+ get another MotionNotify event the next time the mouse moves. This
+ is at least as efficient as getting motion events when mouse
+ tracking is on, and I suspect only negligibly worse when tracking
+ is off.
+
+ 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. */
+
+/* Where the mouse was last time we reported a mouse event. */
+static FRAME_PTR last_mouse_frame;
+static XRectangle last_mouse_glyph;
+
+/* The scroll bar in which the last X motion event occurred.
+
+ If the last X motion event occurred in a scroll bar, we set this
+ so XTmouse_position can know whether to report a scroll bar motion or
+ an ordinary motion.
+
+ If the last X motion event didn't occur in a scroll bar, we set this
+ to Qnil, to tell XTmouse_position to return an ordinary motion event. */
+static Lisp_Object last_mouse_scroll_bar;
+
+/* Record which buttons are currently pressed. */
+unsigned int x_mouse_grabbed;
+
+/* This is a hack. We would really prefer that XTmouse_position would
+ return the time associated with the position it returns, but there
+ doesn't seem to be any way to wrest the timestamp from the server
+ along with the position query. So, we just keep track of the time
+ of the last movement we received, and return that in hopes that
+ it's somewhat accurate. */
+static Time last_mouse_movement_time;
+
#ifdef HAVE_X11
/* `t' if a mouse button is depressed. */
extern FONT_TYPE *XOpenFont ();
static void flashback ();
+static void redraw_previous_char ();
+static unsigned int x_x_to_emacs_modifiers ();
#ifndef HAVE_X11
static void dumpqueue ();
of the frame being updated, so that the XT... functions do not
need to take a frame as argument. Most of the XT... functions
should never be called except during an update, the only exceptions
- being XTcursor_to, XTwrite_char and XTreassert_line_highlight. */
+ being XTcursor_to, XTwrite_glyphs and XTreassert_line_highlight. */
extern int mouse_track_top, mouse_track_left, mouse_track_width;
{
int mask;
- if (updating_frame == 0
- || updating_frame != f)
- abort ();
-
BLOCK_INPUT;
#ifndef HAVE_X11
dumpqueue ();
Since the display generation code is responsible for calling
compute_char_face and compute_glyph_face on everything it puts in
the display structure, we can assume that the face code on each
- glyph is a valid index into FRAME_FACES (f), and the one to which
- we can actually apply intern_face. */
+ glyph is a valid index into FRAME_COMPUTED_FACES (f), and the one
+ to which we can actually apply intern_face.
+ Call this function with input blocked. */
#if 1
/* This is the multi-face code. */
/* First look at the face of the text itself. */
if (cf != 0)
{
- /* The face codes on the glyphs must be valid indices into the
- frame's face table. */
- if (cf < 0 || cf >= FRAME_N_FACES (f))
- abort ();
+ /* It's possible for the display table to specify
+ a face code that is out of range. Use 0 in that case. */
+ if (cf < 0 || cf >= FRAME_N_COMPUTED_FACES (f)
+ || FRAME_COMPUTED_FACES (f) [cf] == 0)
+ cf = 0;
if (cf == 1)
face = FRAME_MODE_LINE_FACE (f);
else
- face = intern_face (f, FRAME_FACES (f) [cf]);
+ face = intern_face (f, FRAME_COMPUTED_FACES (f) [cf]);
font = FACE_FONT (face);
gc = FACE_GC (face);
defaulted = 0;
CHAR_TO_PIXEL_ROW (f, curs_y),
FONT_WIDTH (f->display.x->font) * (first_unused - curs_x),
FONT_HEIGHT (f->display.x->font), False);
-
+#if 0
+ redraw_previous_char (f, curs_x, curs_y);
+#endif
#else /* ! defined (HAVE_X11) */
XPixSet (FRAME_X_WINDOW (f),
CHAR_TO_PIXEL_COL (f, curs_x),
UNBLOCK_INPUT;
}
+/* Erase the character (if any) at the position just before X, Y in frame F,
+ then redraw it and the character before it.
+ This is necessary when we erase starting at X,
+ in case the character after X overlaps into the one before X.
+ Call this function with input blocked. */
+
+static void
+redraw_previous_char (f, x, y)
+ FRAME_PTR f;
+ int x, y;
+{
+ /* Erase the character before the new ones, in case
+ what was here before overlaps it.
+ Reoutput that character, and the previous character
+ (in case the previous character overlaps it). */
+ if (x > 0)
+ {
+ int start_x = x - 2;
+ if (start_x < 0)
+ start_x = 0;
+ XClearArea (x_current_display, FRAME_X_WINDOW (f),
+ CHAR_TO_PIXEL_COL (f, x - 1),
+ CHAR_TO_PIXEL_ROW (f, y),
+ FONT_WIDTH (f->display.x->font),
+ FONT_HEIGHT (f->display.x->font), False);
+
+ dumpglyphs (f, CHAR_TO_PIXEL_COL (f, start_x),
+ CHAR_TO_PIXEL_ROW (f, y),
+ &FRAME_CURRENT_GLYPHS (f)->glyphs[y][start_x],
+ x - start_x, highlight);
+ }
+}
+
static
XTclear_frame ()
{
{
struct timeval wakeup, now;
- gettimeofday (&wakeup, (struct timezone *) 0);
+ EMACS_GET_TIME (wakeup);
/* Compute time to wait until, propagating carry from usecs. */
wakeup.tv_usec += 150000;
{
struct timeval timeout;
- gettimeofday (&timeout, (struct timezone *)0);
+ EMACS_GET_TIME (timeout);
/* In effect, timeout = wakeup - timeout.
Break if result would be negative. */
/* Make audible bell. */
#ifdef HAVE_X11
-#define XRINGBELL XBell(x_current_display, 0)
+#define XRINGBELL XBell (x_current_display, 0)
#else /* ! defined (HAVE_X11) */
-#define XRINGBELL XFeep(0);
+#define XRINGBELL XFeep (0);
#endif /* ! defined (HAVE_X11) */
XTring_bell ()
/* Output into a rectangle of an X-window (for frame F)
the characters in f->phys_lines that overlap that rectangle.
TOP and LEFT are the position of the upper left corner of the rectangle.
- ROWS and COLS are the size of the rectangle. */
+ ROWS and COLS are the size of the rectangle.
+ Call this function with input blocked. */
static void
dumprectangle (f, left, top, cols, rows)
frame_highlight (frame)
struct frame *frame;
{
- if (! EQ (Vx_no_window_manager, Qnil))
- XSetWindowBorder (x_current_display, FRAME_X_WINDOW (frame),
- frame->display.x->border_pixel);
+ /* We used to only do this if Vx_no_window_manager was non-nil, but
+ the ICCCM (section 4.1.6) says that the window's border pixmap
+ and border pixel are window attributes which are "private to the
+ client", so we can always change it to whatever we want. */
+ BLOCK_INPUT;
+ XSetWindowBorder (x_current_display, FRAME_X_WINDOW (frame),
+ frame->display.x->border_pixel);
+ UNBLOCK_INPUT;
x_display_cursor (frame, 1);
}
frame_unhighlight (frame)
struct frame *frame;
{
- if (! EQ (Vx_no_window_manager, Qnil))
- XSetWindowBorderPixmap (x_current_display, FRAME_X_WINDOW (frame),
- frame->display.x->border_tile);
+ /* We used to only do this if Vx_no_window_manager was non-nil, but
+ the ICCCM (section 4.1.6) says that the window's border pixmap
+ and border pixel are window attributes which are "private to the
+ client", so we can always change it to whatever we want. */
+ BLOCK_INPUT;
+ XSetWindowBorderPixmap (x_current_display, FRAME_X_WINDOW (frame),
+ frame->display.x->border_tile);
+ UNBLOCK_INPUT;
x_display_cursor (frame, 1);
}
#else /* ! defined (HAVE_X11) */
XFreeModifiermap (mods);
}
+/* Prepare a menu-event in *RESULT for placement in the input queue. */
+
+static Lisp_Object
+construct_menu_click (result, event, f)
+ struct input_event *result;
+ XButtonEvent *event;
+ struct frame *f;
+{
+ /* Make the event type no_event; we'll change that when we decide
+ otherwise. */
+ result->kind = mouse_click;
+ XSET (result->code, Lisp_Int, event->button - Button1);
+ result->timestamp = event->time;
+ result->modifiers = (x_x_to_emacs_modifiers (event->state)
+ | (event->type == ButtonRelease
+ ? up_modifier
+ : down_modifier));
+
+ {
+ XFASTINT (result->x) = event->x;
+ XFASTINT (result->y) = -1; /* special meaning for menubar */
+ XSET (result->frame_or_window, Lisp_Frame, f);
+ }
+}
/* Convert between the modifier bits X uses and the modifier bits
Emacs uses. */
/* Given a pixel position (PIX_X, PIX_Y) on the frame F, return
glyph co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle
- that the glyph at X, Y occupies, if BOUNDS != 0. */
+ that the glyph at X, Y occupies, if BOUNDS != 0.
+ If NOCLIP is nonzero, do not force the value into range. */
+
static void
-pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds)
+pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
FRAME_PTR f;
- register unsigned int pix_x, pix_y;
+ register int pix_x, pix_y;
register int *x, *y;
XRectangle *bounds;
+ int noclip;
{
+ /* 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;
+ if (pix_y < 0)
+ pix_y -= FONT_HEIGHT ((f)->display.x->font) - 1;
+
pix_x = PIXEL_TO_CHAR_COL (f, pix_x);
pix_y = PIXEL_TO_CHAR_ROW (f, pix_y);
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;
-
- if (pix_y < 0) pix_y = 0;
- else if (pix_y > f->height) pix_y = f->height;
+ if (!noclip)
+ {
+ if (pix_x < 0)
+ pix_x = 0;
+ else if (pix_x > f->width)
+ pix_x = f->width;
+
+ if (pix_y < 0)
+ pix_y = 0;
+ else if (pix_y > f->height)
+ pix_y = f->height;
+ }
*x = pix_x;
*y = pix_y;
}
-/* Any buttons grabbed. */
-unsigned int x_mouse_grabbed;
-
/* Prepare a mouse-event in *RESULT for placement in the input queue.
If the event is a button press, then note that we have grabbed
/* Make the event type no_event; we'll change that when we decide
otherwise. */
result->kind = mouse_click;
- XSET (result->code, Lisp_Int, event->button - Button1);
+ result->code = event->button - Button1;
result->timestamp = event->time;
result->modifiers = (x_x_to_emacs_modifiers (event->state)
| (event->type == ButtonRelease
if (! x_mouse_grabbed)
Vmouse_depressed = Qt;
x_mouse_grabbed |= (1 << event->button);
+ last_mouse_frame = f;
}
else if (event->type == ButtonRelease)
{
{
int row, column;
- pixel_to_glyph_coords (f, event->x, event->y, &column, &row, NULL);
+ pixel_to_glyph_coords (f, event->x, event->y, &column, &row, NULL, 0);
XFASTINT (result->x) = column;
XFASTINT (result->y) = row;
XSET (result->frame_or_window, Lisp_Frame, f);
}
}
-
-
-/* Mouse movement. Rah.
-
- In order to avoid asking for motion events and then throwing most
- of them away or busy-polling the server for mouse positions, we ask
- the server for pointer motion hints. This means that we get only
- one event per group of mouse movements. "Groups" are delimited by
- other kinds of events (focus changes and button clicks, for
- example), or by XQueryPointer calls; when one of these happens, we
- get another MotionNotify event the next time the mouse moves. This
- is at least as efficient as getting motion events when mouse
- tracking is on, and I suspect only negligibly worse when tracking
- is off.
-
- 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. */
-
-/* Where the mouse was last time we reported a mouse event. */
-static FRAME_PTR last_mouse_frame;
-static XRectangle last_mouse_glyph;
-
-/* The scroll bar in which the last X motion event occurred.
-
- If the last X motion event occurred in a scroll bar, we set this
- so XTmouse_position can know whether to report a scroll bar motion or
- an ordinary motion.
-
- If the last X motion event didn't occur in a scroll bar, we set this
- to Qnil, to tell XTmouse_position to return an ordinary motion event. */
-static Lisp_Object last_mouse_scroll_bar;
-
-/* This is a hack. We would really prefer that XTmouse_position would
- return the time associated with the position it returns, but there
- doesn't seem to be any way to wrest the timestamp from the server
- along with the position query. So, we just keep track of the time
- of the last movement we received, and return that in hopes that
- it's somewhat accurate. */
-static Time last_mouse_movement_time;
-
+\f
/* Function to report a mouse movement to the mainstream Emacs code.
The input handler calls this.
Set *time to the server timestamp for the time at which the mouse
was at this position.
+ 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
Lisp_Object *x, *y;
unsigned long *time;
{
+ FRAME_PTR f1;
+
BLOCK_INPUT;
if (! NILP (last_mouse_scroll_bar))
int parent_x, parent_y;
win = root;
- for (;;)
+
+ if (x_mouse_grabbed)
{
+ /* If mouse was grabbed on a frame, give coords for that frame
+ even if the mouse is now outside it. */
XTranslateCoordinates (x_current_display,
-
+
/* From-window, to-window. */
- root, win,
+ root, FRAME_X_WINDOW (last_mouse_frame),
/* From-position, to-position. */
root_x, root_y, &win_x, &win_y,
/* Child of win. */
&child);
+ f1 = last_mouse_frame;
+ }
+ else
+ {
+ while (1)
+ {
+ XTranslateCoordinates (x_current_display,
- if (child == None)
- break;
+ /* From-window, to-window. */
+ root, win,
- win = child;
- parent_x = win_x;
- parent_y = win_y;
- }
+ /* From-position, to-position. */
+ root_x, root_y, &win_x, &win_y,
+
+ /* Child of win. */
+ &child);
- /* Now we know that:
- win is the innermost window containing the pointer
- (XTC says it has no child containing the pointer),
- win_x and win_y are the pointer's position in it
- (XTC did this the last time through), and
- parent_x and parent_y are the pointer's position in win's parent.
- (They are what win_x and win_y were when win was child.
- If win is the root window, it has no parent, and
- parent_{x,y} are invalid, but that's okay, because we'll
- never use them in that case.) */
-
- /* Is win one of our frames? */
- *f = x_window_to_frame (win);
+ if (child == None)
+ break;
+
+ win = child;
+ parent_x = win_x;
+ parent_y = win_y;
+ }
+
+ /* Now we know that:
+ win is the innermost window containing the pointer
+ (XTC says it has no child containing the pointer),
+ win_x and win_y are the pointer's position in it
+ (XTC did this the last time through), and
+ parent_x and parent_y are the pointer's position in win's parent.
+ (They are what win_x and win_y were when win was child.
+ If win is the root window, it has no parent, and
+ parent_{x,y} are invalid, but that's okay, because we'll
+ never use them in that case.) */
+
+ /* Is win one of our frames? */
+ f1 = x_window_to_frame (win);
+ }
/* If not, is it one of our scroll bars? */
- if (! *f)
+ if (! f1)
{
struct scroll_bar *bar = x_window_to_scroll_bar (win);
if (bar)
{
- *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+ f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
win_x = parent_x;
win_y = parent_y;
}
}
- if (*f)
+ if (f1)
{
- pixel_to_glyph_coords (*f, win_x, win_y, &win_x, &win_y,
- &last_mouse_glyph);
+ /* Ok, we found a frame. Convert from pixels to characters
+ and store all the values. */
+
+ pixel_to_glyph_coords (f1, win_x, win_y, &win_x, &win_y,
+ &last_mouse_glyph, x_mouse_grabbed);
*bar_window = Qnil;
*part = 0;
+ *f = f1;
XSET (*x, Lisp_Int, win_x);
XSET (*y, Lisp_Int, win_y);
*time = last_mouse_movement_time;
! GC_NILP (bar) || (bar = condemned,
condemned = Qnil,
! GC_NILP (bar));
- bar = XSCROLL_BAR(bar)->next)
+ bar = XSCROLL_BAR (bar)->next)
if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)) == window_id)
return XSCROLL_BAR (bar);
}
{
XSetWindowAttributes a;
unsigned long mask;
-
a.background_pixel = frame->display.x->background_pixel;
a.event_mask = (ButtonPressMask | ButtonReleaseMask
| ButtonMotionMask | PointerMotionHintMask
mask = (CWBackPixel | CWEventMask | CWCursor);
- SET_SCROLL_BAR_X_WINDOW
+#if 0
+
+ ac = 0;
+ XtSetArg (al[ac], XtNx, left); ac++;
+ XtSetArg (al[ac], XtNy, top); ac++;
+ XtSetArg (al[ac], XtNwidth, width); ac++;
+ XtSetArg (al[ac], XtNheight, height); ac++;
+ XtSetArg (al[ac], XtNborderWidth, 0); ac++;
+ sb_widget = XtCreateManagedWidget ("box",
+ boxWidgetClass,
+ frame->display.x->edit_widget, al, ac);
+ SET_SCROLL_BAR_X_WINDOW
+ (bar, sb_widget->core.window);
+#endif
+ SET_SCROLL_BAR_X_WINDOW
(bar,
XCreateWindow (x_current_display, FRAME_X_WINDOW (frame),
x_scroll_bar_set_handle (bar, 0, top_range, 0);
else
{
- int start = (position * top_range) / whole;
- int end = ((position + portion) * top_range) / whole;
+ int start = ((double) position * top_range) / whole;
+ int end = ((double) (position + portion) * top_range) / whole;
x_scroll_bar_set_handle (bar, start, end, 0);
}
abort ();
emacs_event->kind = scroll_bar_click;
- XSET (emacs_event->code, Lisp_Int, event->xbutton.button - Button1);
+ emacs_event->code = event->xbutton.button - Button1;
emacs_event->modifiers =
(x_x_to_emacs_modifiers (event->xbutton.state)
| (event->type == ButtonRelease
0, 0, 0, 0, True);
}
+/* This processes Expose events from the menubar specific X event
+ loop in menubar.c. This allows to redisplay the frame if necessary
+ when handling menubar or popup items. */
+
+void
+process_expose_from_menu (event)
+ XEvent event;
+{
+ FRAME_PTR f;
+
+ BLOCK_INPUT;
+
+ f = x_window_to_frame (event.xexpose.window);
+ if (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
+ {
+ struct scroll_bar *bar
+ = x_window_to_scroll_bar (event.xexpose.window);
+
+ if (bar)
+ x_scroll_bar_expose (bar, &event);
+ }
+
+ UNBLOCK_INPUT;
+}
\f
/* The main X event-reading loop - XTread_socket. */
int items_pending; /* How many items are in the X queue. */
XEvent event;
struct frame *f;
- int event_found;
+ int event_found = 0;
int prefix;
Lisp_Object part;
{
if (event.xclient.data.l[0] == Xatom_wm_take_focus)
{
+#ifdef USE_X_TOOLKIT
+ /* f = x_any_window_to_frame (event.xclient.window); */
+ f = x_window_to_frame (event.xclient.window);
+#else
f = x_window_to_frame (event.xclient.window);
+#endif
if (f)
x_focus_on_frame (f);
/* Not certain about handling scroll bars here */
struct frame *f = x_window_to_frame (event.xclient.window);
if (f)
- if (numchars > 0)
- {
- }
+ {
+ if (numchars == 0)
+ abort ();
+
+ bufp->kind = delete_window_event;
+ XSET (bufp->frame_or_window, Lisp_Frame, f);
+ bufp++;
+
+ count += 1;
+ numchars -= 1;
+ }
}
}
else if (event.xclient.message_type == Xatom_wm_configure_denied)
else if (event.xclient.message_type == 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];
+
+ if (f)
+ {
+ f->display.x->left_pos = new_x;
+ f->display.x->top_pos = new_y;
+ }
}
}
break;
#ifdef NEW_SELECTIONS
case SelectionNotify:
+#ifdef USE_X_TOOLKIT
+ if (x_window_to_frame (event.xselection.requestor))
+ x_handle_selection_notify (&event);
+ else
+ goto OTHER;
+#else /* not USE_X_TOOLKIT */
x_handle_selection_notify (&event);
+#endif /* not USE_X_TOOLKIT */
break;
-#endif
+#endif /* NEW_SELECTIONS */
case SelectionClear: /* Someone has grabbed ownership. */
#ifdef NEW_SELECTIONS
{
+#ifdef USE_X_TOOLKIT
+ if (x_window_to_frame (event.xselectionclear.window))
+ {
+#endif /* USE_X_TOOLKIT */
XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
if (numchars == 0)
count += 1;
numchars -= 1;
+#ifdef USE_X_TOOLKIT
}
-#else
+ else
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
+ }
+#else /* not NEW_SELECTIONS */
x_disown_selection (event.xselectionclear.window,
event.xselectionclear.selection,
event.xselectionclear.time);
-#endif
+#endif /* not NEW_SELECTIONS */
break;
case SelectionRequest: /* Someone wants our selection. */
#ifdef NEW_SELECTIONS
{
+#ifdef USE_X_TOOLKIT
+ if (x_window_to_frame (event.xselectionrequest.owner))
+ {
+#endif /* USE_X_TOOLKIT */
XSelectionRequestEvent *eventp = (XSelectionRequestEvent *) &event;
if (numchars == 0)
count += 1;
numchars -= 1;
+#ifdef USE_X_TOOLKIT
}
-#else
+ else
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
+ }
+#else /* not NEW_SELECTIONS */
x_answer_selection_request (event);
-#endif
+#endif /* not NEW_SELECTIONS */
break;
case PropertyNotify:
#ifdef NEW_SELECTIONS
+#ifdef USE_X_TOOLKIT
+ if (x_any_window_to_frame (event.xproperty.window))
+ x_handle_property_notify (&event);
+ else
+ goto OTHER;
+#else /* not USE_X_TOOLKIT */
x_handle_property_notify (&event);
-#else
+#endif /* not USE_X_TOOLKIT */
+#else /* not NEW_SELECTIONS */
/* If we're being told about a root window property, then it's
a cut buffer change. */
if (event.xproperty.window == ROOT_WINDOW)
about re-selecting. */
x_send_incremental (event);
}
-#endif
+#endif /* not NEW_SELECTIONS */
break;
case ReparentNotify:
{
struct scroll_bar *bar
= x_window_to_scroll_bar (event.xexpose.window);
-
+
if (bar)
- x_scroll_bar_expose (bar, &event);
+ x_scroll_bar_expose (bar, &event);
+#ifdef USE_X_TOOLKIT
+ else
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
}
break;
event.xgraphicsexpose.width,
event.xgraphicsexpose.height);
}
+#ifdef USE_X_TOOLKIT
+ else
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
break;
case NoExpose: /* This occurs when an XCopyArea's
/* The window manager never makes a window invisible
("withdrawn"); all it does is switch between visible
and iconified. Frames get into the invisible state
- only through x_make_frame_invisible.
+ only through x_make_frame_invisible. */
if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
f->async_iconified = 1;
}
+#ifdef USE_X_TOOLKIT
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
break;
case MapNotify:
+#ifdef USE_X_TOOLKIT
+ f = x_any_window_to_frame (event.xmap.window);
+#else /* not USE_X_TOOLKIT */
f = x_window_to_frame (event.xmap.window);
+#endif /* not USE_X_TOOLKIT */
if (f)
{
f->async_visible = 1;
the frame's display structures. */
SET_FRAME_GARBAGED (f);
}
- break;
+#ifdef USE_X_TOOLKIT
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
+ break;
/* Turn off processing if we become fully obscured. */
case VisibilityNotify:
if (f != 0)
{
KeySym keysym, orig_keysym;
- char copy_buffer[80];
+ /* 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
if (numchars > 1)
{
- if ((keysym >= XK_BackSpace && keysym <= XK_Escape)
- || keysym == XK_Delete
- || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
- || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
+ 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. */
- || (!IsModifierKey (orig_keysym)
- && (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
+#endif
+#ifdef XK_dead_grave
+ || orig_keysym == XK_dead_grave
+#endif
+#ifdef XK_dead_tilde
+ || orig_keysym == XK_dead_tilde
+#endif
+#ifdef XK_dead_diaeresis
+ || orig_keysym == XK_dead_diaeresis
#endif
- || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
- || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
- || x_is_vendor_fkey (orig_keysym)) /* wherever */
+#ifdef XK_dead_macron
+ || orig_keysym == XK_dead_macron
+#endif
+#ifdef XK_dead_degree
+ || orig_keysym == XK_dead_degree
+#endif
+#ifdef XK_dead_acute
+ || orig_keysym == XK_dead_acute
+#endif
+#ifdef XK_dead_cedilla
+ || orig_keysym == XK_dead_cedilla
+#endif
+#ifdef XK_dead_breve
+ || orig_keysym == XK_dead_breve
+#endif
+#ifdef XK_dead_ogonek
+ || orig_keysym == XK_dead_ogonek
+#endif
+#ifdef XK_dead_caron
+ || orig_keysym == XK_dead_caron
+#endif
+#ifdef XK_dead_doubleacute
+ || orig_keysym == XK_dead_doubleacute
+#endif
+#ifdef XK_dead_abovedot
+ || orig_keysym == XK_dead_abovedot
+#endif
+ || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
+ || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
+ || x_is_vendor_fkey (orig_keysym))
+ && ! (IsModifierKey (orig_keysym)
+#ifndef HAVE_X11R5
+#ifdef XK_Mode_switch
+ || ((unsigned)(orig_keysym) == XK_Mode_switch)
+#endif
+#ifdef 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;
- XSET (bufp->code, Lisp_Int, (unsigned) keysym - 0xff00);
+ bufp->code = keysym;
XSET (bufp->frame_or_window, Lisp_Frame, f);
bufp->modifiers = x_x_to_emacs_modifiers (modifiers);
bufp->timestamp = event.xkey.time;
temp_index = 0;
temp_buffer[temp_index++] = copy_buffer[i];
bufp->kind = ascii_keystroke;
- XSET (bufp->code, Lisp_Int, copy_buffer[i]);
+ bufp->code = copy_buffer[i];
XSET (bufp->frame_or_window, Lisp_Frame, f);
bufp->modifiers = x_x_to_emacs_modifiers (modifiers);
bufp->timestamp = event.xkey.time;
for (i = 0; i < nbytes; i++)
{
bufp->kind = ascii_keystroke;
- XSET (bufp->code, Lisp_Int, where_mapping[i]);
+ bufp->code = where_mapping[i];
XSET (bufp->time, Lisp_Int, event.xkey.time);
XSET (bufp->frame_or_window, Lisp_Frame, f);
bufp++;
}
else if (f == x_focus_frame)
x_new_focus_frame (0);
-
+#ifdef USE_X_TOOLKIT
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
break;
case FocusIn:
x_focus_event_frame = f;
if (f)
x_new_focus_frame (f);
+#ifdef USE_X_TOOLKIT
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
break;
if (f == x_focus_frame)
x_new_focus_frame (0);
}
+#ifdef USE_X_TOOLKIT
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
break;
case FocusOut:
x_focus_event_frame = 0;
if (f && f == x_focus_frame)
x_new_focus_frame (0);
+#ifdef USE_X_TOOLKIT
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
break;
#else /* ! defined (HAVE_X11) */
#ifdef HAVE_X11
case MotionNotify:
{
- f = x_window_to_frame (event.xmotion.window);
+ if (x_mouse_grabbed)
+ 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);
+ struct scroll_bar *bar
+ = x_window_to_scroll_bar (event.xmotion.window);
if (bar)
x_scroll_bar_note_movement (bar, &event);
}
}
+#ifdef USE_X_TOOLKIT
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
break;
case ConfigureNotify:
+#ifdef USE_X_TOOLKIT
+ /* process done in widget.c */
+ goto OTHER;
+#else /* not USE_X_TOOLKIT */
f = x_window_to_frame (event.xconfigure.window);
if (f)
{
Window win, child;
int win_x, win_y;
- /* Coords are relative to the parent.
- Convert them to root-relative. */
+ /* 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 (x_current_display,
/* From-window, to-window. */
- f->display.x->parent_desc,
+ f->display.x->window_desc,
ROOT_WINDOW,
/* From-position, to-position. */
- event.xconfigure.x,
- event.xconfigure.y,
+ -event.xconfigure.border_width,
+ -event.xconfigure.border_width,
&win_x, &win_y,
/* Child of win. */
f->display.x->left_pos = event.xconfigure.x;
f->display.x->top_pos = event.xconfigure.y;
}
+#endif /* not USE_X_TOOLKIT */
break;
case ButtonPress:
if (f)
{
if (!x_focus_frame || (f == x_focus_frame))
- construct_mouse_click (&emacs_event,
- &event, f);
+ construct_mouse_click (&emacs_event, &event, f);
}
else
{
if (bar)
x_scroll_bar_handle_click (bar, &event, &emacs_event);
+#ifdef USE_X_TOOLKIT
+ else
+ {
+ f = x_any_window_to_frame (event.xbutton.window);
+ if (f && event.type == ButtonPress)
+ construct_menu_click (&emacs_event,
+ &event, f);
+ }
+#endif /* USE_X_TOOLKIT */
}
if (numchars >= 1 && emacs_event.kind != no_event)
count++;
numchars--;
}
+
+#ifdef USE_X_TOOLKIT
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
}
break;
if (numchars >= 2)
{
bufp->kind = ascii_keystroke;
- bufp->code = (char) 'X' & 037; /* C-x */
+ bufp->code = 'X' & 037; /* C-x */
XSET (bufp->frame_or_window, Lisp_Frame, f);
XSET (bufp->time, Lisp_Int, event.xkey.time);
bufp++;
bufp->kind = ascii_keystroke;
- bufp->code = (char) 0; /* C-@ */
+ bufp->code = 0; /* C-@ */
XSET (bufp->frame_or_window, Lisp_Frame, f);
XSET (bufp->time, Lisp_Int, event.xkey.time);
bufp++;
case MappingKeyboard:
XRefreshKeyboardMapping (&event.xmapping);
}
+#ifdef USE_X_TOOLKIT
+ goto OTHER;
+#endif /* USE_X_TOOLKIT */
break;
default:
+#ifdef USE_X_TOOLKIT
+ OTHER:
+ BLOCK_INPUT;
+ XtDispatchEvent (&event);
+ UNBLOCK_INPUT;
+#endif /* USE_X_TOOLKIT */
break;
}
}
-#if 0
+#ifdef X_IO_BUG
+ if (! event_found)
+ /* On some systems, an X bug causes Emacs to get no more events
+ when the window is destroyed. Detect that. */
+ XNoOp (x_current_display);
+#endif /* X_IO_BUG */
+
#ifdef HAVE_SELECT
if (expected && ! event_found)
{
/* AOJ 880406: if select returns true but XPending doesn't, it means that
there is an EOF condition; in other words, that X has died.
Act as if there had been a hangup. */
-
int fd = ConnectionNumber (x_current_display);
- int mask = 1 << fd;
-
- if (0 != select (fd + 1, &mask, (long *) 0, (long *) 0,
- (EMACS_TIME) 0)
+ SELECT_TYPE mask, junk1, junk2;
+ EMACS_TIME timeout;
+
+ FD_ZERO (&mask);
+ FD_SET (fd, &mask);
+ EMACS_SET_SECS_USECS (timeout, 0, 0);
+ FD_ZERO (&junk1);
+ FD_ZERO (&junk2);
+ if (0 != select (fd + 1, &mask, &junk1, &junk2, &timeout)
&& !XStuffPending ())
kill (getpid (), SIGHUP);
}
-#endif /* ! defined (HAVE_SELECT) */
-#endif /* ! 0 */
+#endif /* HAVE_SELECT */
#ifndef HAVE_X11
if (updating_frame == 0)
struct frame *f;
int on;
{
+ BLOCK_INPUT;
+
if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
x_display_box_cursor (f, on);
else if (FRAME_DESIRED_CURSOR (f) == bar_cursor)
else
/* Those are the only two we have implemented! */
abort ();
+
+ UNBLOCK_INPUT;
}
\f
/* Icons. */
if (_Xdebug)
abort ();
- shut_down_emacs (0, 1);
+ shut_down_emacs (0, 1, Qnil);
exit (70);
}
fprintf (stderr, "X protocol error: %s on protocol request %d\n",
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 ();
}
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
x_connection_closed ();
}
Calling x_uncatch_errors resumes the normal error handling. */
-void x_catch_errors(), x_check_errors (), x_uncatch_errors ();
+void x_catch_errors (), x_check_errors (), x_uncatch_errors ();
void
x_catch_errors ()
#ifdef HAVE_X11
+struct font_info
+{
+ XFontStruct *font;
+ char *name;
+};
+
/* A table of all the fonts we have already loaded. */
-static XFontStruct **x_font_table;
+static struct font_info *x_font_table;
/* The current capacity of x_font_table. */
static int x_font_table_size;
/* Get a list of all the fonts that match this name. Once we
have a list of matching fonts, we compare them against the fonts
we already have by comparing font ids. */
- font_names = (char **) XListFontsWithInfo (x_current_display, fontname,
- 1024, &n_matching_fonts,
- &font_info);
+ font_names = (char **) XListFonts (x_current_display, fontname,
+ 1024, &n_matching_fonts);
+ /* Apparently it doesn't set n_matching_fonts to zero when it can't
+ find any matches; font_names == 0 is the only clue. */
+ if (! font_names)
+ n_matching_fonts = 0;
+
/* Don't just give up if n_matching_fonts is 0.
Apparently there's a bug on Suns: XListFontsWithInfo can
fail to find a font, but XLoadQueryFont may still find it. */
for (i = 0; i < n_fonts; i++)
for (j = 0; j < n_matching_fonts; j++)
- if (x_font_table[i]->fid == font_info[j].fid)
+ if (!strcmp (x_font_table[i].name, font_names[j]))
{
already_loaded = i;
fontname = font_names[j];
found_font:
/* If we have, just return it from the table. */
- if (already_loaded > 0)
- f->display.x->font = x_font_table[already_loaded];
+ if (already_loaded >= 0)
+ f->display.x->font = x_font_table[already_loaded].font;
/* Otherwise, load the font and add it to the table. */
else
font = (XFontStruct *) XLoadQueryFont (x_current_display, fontname);
if (! font)
{
- /* Free the information from XListFontsWithInfo. */
+ /* Free the information from XListFonts. */
if (n_matching_fonts)
- XFreeFontInfo (font_names, font_info, n_matching_fonts);
+ XFreeFontNames (font_names);
return Qnil;
}
{
x_font_table_size = 16;
x_font_table
- = (XFontStruct **) xmalloc (x_font_table_size
- * sizeof (x_font_table[0]));
+ = (struct font_info *) xmalloc (x_font_table_size
+ * sizeof (x_font_table[0]));
}
/* Do we need to grow the table? */
else if (n_fonts >= x_font_table_size)
{
x_font_table_size *= 2;
x_font_table
- = (XFontStruct **) xrealloc (x_font_table,
- (x_font_table_size
- * sizeof (x_font_table[0])));
+ = (struct font_info *) xrealloc (x_font_table,
+ (x_font_table_size
+ * sizeof (x_font_table[0])));
}
- f->display.x->font = x_font_table[n_fonts++] = font;
+ x_font_table[n_fonts].name = (char *) xmalloc (strlen (fontname) + 1);
+ bcopy (fontname, x_font_table[n_fonts].name, strlen (fontname) + 1);
+ f->display.x->font = x_font_table[n_fonts++].font = font;
}
-
+
/* Now make the frame display the given font. */
if (FRAME_X_WINDOW (f) != 0)
{
XSetFont (x_current_display, f->display.x->cursor_gc,
f->display.x->font->fid);
- x_set_window_size (f, f->width, f->height);
+ x_set_window_size (f, 0, f->width, f->height);
}
{
Lisp_Object lispy_name = build_string (fontname);
- /* Free the information from XListFontsWithInfo. The data
+ /* Free the information from XListFonts. The data
we actually retain comes from XLoadQueryFont. */
- XFreeFontInfo (font_names, font_info, n_matching_fonts);
+ XFreeFontNames (font_names);
return lispy_name;
}
f->display.x->font = temp;
if (FRAME_X_WINDOW (f) != 0)
- x_set_window_size (f, f->width, f->height);
+ x_set_window_size (f, 0, f->width, f->height);
return 0;
}
#endif /* ! defined (HAVE_X11) */
\f
-/* X Window sizes and positions. */
-
x_calc_absolute_position (f)
struct frame *f;
{
#ifdef HAVE_X11
+ Window win, child;
+ int win_x = 0, win_y = 0;
+
+ /* 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 != ROOT_WINDOW)
+ {
+ BLOCK_INPUT;
+ XTranslateCoordinates (x_current_display,
+
+ /* From-window, to-window. */
+ f->display.x->window_desc,
+ f->display.x->parent_desc,
+
+ /* From-position, to-position. */
+ 0, 0, &win_x, &win_y,
+
+ /* Child of win. */
+ &child);
+ UNBLOCK_INPUT;
+ }
+
+ /* Treat negative positions as relative to the leftmost bottommost
+ position that fits on the screen. */
if (f->display.x->left_pos < 0)
- f->display.x->left_pos
- = x_screen_width - PIXEL_WIDTH (f) + f->display.x->left_pos;
+ f->display.x->left_pos = (x_screen_width
+ - 2 * f->display.x->border_width - win_x
+ - PIXEL_WIDTH (f)
+ + f->display.x->left_pos);
if (f->display.x->top_pos < 0)
- f->display.x->top_pos
- = x_screen_height - PIXEL_HEIGHT (f) + f->display.x->top_pos;
+ f->display.x->top_pos = (x_screen_height
+ - 2 * f->display.x->border_width - win_y
+ - PIXEL_HEIGHT (f)
+ + f->display.x->top_pos);
+
#else /* ! defined (HAVE_X11) */
WINDOWINFO_TYPE parentinfo;
x_calc_absolute_position (f);
BLOCK_INPUT;
+#ifdef USE_X_TOOLKIT
+ XMoveWindow (XDISPLAY XtWindow (f->display.x->widget),
+ f->display.x->left_pos, f->display.x->top_pos);
+#else /* not USE_X_TOOLKIT */
XMoveWindow (XDISPLAY FRAME_X_WINDOW (f),
f->display.x->left_pos, f->display.x->top_pos);
+#endif /* not USE_X_TOOLKIT */
#ifdef HAVE_X11
- x_wm_set_size_hint (f, 0);
+ x_wm_set_size_hint (f, 0, 1, xoff, yoff);
#endif /* ! defined (HAVE_X11) */
UNBLOCK_INPUT;
}
-/* Call this to change the size of frame F's x-window. */
+/* Call this to change the size of frame F's x-window.
+ If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
+ for this size change and subsequent size changes.
+ Otherwise we leave the window gravity unchanged. */
-x_set_window_size (f, cols, rows)
+x_set_window_size (f, change_gravity, cols, rows)
struct frame *f;
+ int change_gravity;
int cols, rows;
{
int pixelwidth, pixelheight;
int mask;
+#ifdef USE_X_TOOLKIT
+ BLOCK_INPUT;
+ EmacsFrameSetCharSize (f->display.x->edit_widget, cols, rows);
+ UNBLOCK_INPUT;
+
+#else /* not USE_X_TOOLKIT */
+
BLOCK_INPUT;
check_frame_size (f, &rows, &cols);
- f->display.x->vertical_scroll_bar_extra =
- (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
- ? VERTICAL_SCROLL_BAR_PIXEL_WIDTH (f)
- : 0);
+ f->display.x->vertical_scroll_bar_extra
+ = (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
+ ? VERTICAL_SCROLL_BAR_PIXEL_WIDTH (f)
+ : 0);
pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
#ifdef HAVE_X11
- x_wm_set_size_hint (f, 0);
+ x_wm_set_size_hint (f, 0, change_gravity, 0, 0);
#endif /* ! defined (HAVE_X11) */
XChangeWindowSize (FRAME_X_WINDOW (f), pixelwidth, pixelheight);
XFlushQueue ();
UNBLOCK_INPUT;
+#endif /* not USE_X_TOOLKIT */
}
#ifndef HAVE_X11
{
int pix_x, pix_y;
+#if 0 /* Let the user ask for this if he wants it. */
x_raise_frame (f);
+#endif
pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH (f->display.x->font) / 2;
pix_y = CHAR_TO_PIXEL_ROW (f, y) + FONT_HEIGHT (f->display.x->font) / 2;
x_focus_on_frame (f)
struct frame *f;
{
+#if 0 /* This proves to be unpleasant. */
x_raise_frame (f);
+#endif
#if 0
/* I don't think that the ICCCM allows programs to do things like this
without the interaction of the window manager. Whatever you end up
if (f->async_visible)
{
BLOCK_INPUT;
+#ifdef USE_X_TOOLKIT
+ XRaiseWindow (XDISPLAY XtWindow (f->display.x->widget));
+#else /* not USE_X_TOOLKIT */
XRaiseWindow (XDISPLAY FRAME_X_WINDOW (f));
+#endif /* not USE_X_TOOLKIT */
XFlushQueue ();
UNBLOCK_INPUT;
}
if (f->async_visible)
{
BLOCK_INPUT;
+#ifdef USE_X_TOOLKIT
+ XLowerWindow (XDISPLAY XtWindow (f->display.x->widget));
+#else /* not USE_X_TOOLKIT */
XLowerWindow (XDISPLAY FRAME_X_WINDOW (f));
+#endif /* not USE_X_TOOLKIT */
XFlushQueue ();
UNBLOCK_INPUT;
}
#ifdef HAVE_X11
if (! EQ (Vx_no_window_manager, Qt))
x_wm_set_window_state (f, NormalState);
-
+#ifdef USE_X_TOOLKIT
+ XtPopup (f->display.x->widget, XtGrabNone);
+#else /* not USE_X_TOOLKIT */
XMapWindow (XDISPLAY FRAME_X_WINDOW (f));
+#endif /* not USE_X_TOOLKIT */
if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
XMapSubwindows (x_current_display, FRAME_X_WINDOW (f));
#else /* ! defined (HAVE_X11) */
#ifdef HAVE_X11R4
+#ifdef USE_X_TOOLKIT
+ if (! XWithdrawWindow (x_current_display, XtWindow (f->display.x->widget),
+ DefaultScreen (x_current_display)))
+#else /* not USE_X_TOOLKIT */
if (! XWithdrawWindow (x_current_display, FRAME_X_WINDOW (f),
DefaultScreen (x_current_display)))
+#endif /* not USE_X_TOOLKIT */
{
UNBLOCK_INPUT_RESIGNAL;
error ("can't notify window manager of window withdrawal");
XEvent unmap;
unmap.xunmap.type = UnmapNotify;
+#ifdef USE_X_TOOLKIT
+ unmap.xunmap.window = XtWindow (f->display.x->widget);
+#else /* not USE_X_TOOLKIT */
unmap.xunmap.window = FRAME_X_WINDOW (f);
+#endif /* not USE_X_TOOLKIT */
unmap.xunmap.event = DefaultRootWindow (x_current_display);
unmap.xunmap.from_configure = False;
if (! XSendEvent (x_current_display,
}
/* Unmap the window ourselves. Cheeky! */
+#ifdef USE_X_TOOLKIT
+ XUnmapWindow (x_current_display, XtWindow (f->display.x->widget));
+#else /* not USE_X_TOOLKIT */
XUnmapWindow (x_current_display, FRAME_X_WINDOW (f));
-
+#endif /* not USE_X_TOOLKIT */
#else /* ! defined (HAVE_X11) */
XUnmapWindow (FRAME_X_WINDOW (f));
struct frame *f;
{
int mask;
+ int result;
/* Don't keep the highlight on an invisible frame. */
if (x_highlight_frame == f)
if (f->async_iconified)
return;
+#ifdef USE_X_TOOLKIT
+ BLOCK_INPUT;
+ result = XIconifyWindow (x_current_display,
+ XtWindow (f->display.x->widget),
+ DefaultScreen (x_current_display));
+ UNBLOCK_INPUT;
+
+ if (!result)
+ error ("Can't notify window manager of iconification.");
+
+ f->async_iconified = 1;
+
+ BLOCK_INPUT;
+ XFlushQueue ();
+ UNBLOCK_INPUT;
+#else /* not USE_X_TOOLKIT */
+
BLOCK_INPUT;
#ifdef HAVE_X11
IconicState. */
x_wm_set_window_state (f, IconicState);
+ if (!FRAME_VISIBLE_P (f))
+ {
+ /* If the frame was withdrawn, before, we must map it. */
+ XMapWindow (XDISPLAY FRAME_X_WINDOW (f));
+ if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+ XMapSubwindows (x_current_display, FRAME_X_WINDOW (f));
+ }
+
f->async_iconified = 1;
#else /* ! defined (HAVE_X11) */
XUnmapWindow (XDISPLAY FRAME_X_WINDOW (f));
XFlushQueue ();
UNBLOCK_INPUT;
+#endif /* not USE_X_TOOLKIT */
}
/* Destroy the X window of frame F. */
if (f->display.x->icon_desc != 0)
XDestroyWindow (XDISPLAY f->display.x->icon_desc);
XDestroyWindow (XDISPLAY f->display.x->window_desc);
+#ifdef USE_X_TOOLKIT
+ XtDestroyWidget (f->display.x->widget);
+#endif /* USE_X_TOOLKIT */
+
free_frame_faces (f);
XFlushQueue ();
of certain kinds into our private queues.
All ExposeRegion events are put in x_expose_queue.
- All ButtonPressed and ButtonReleased events are put in x_mouse_queue. */
+ All ButtonPress and ButtonRelease events are put in x_mouse_queue. */
/* Write the event *P_XREP into the event queue *QUEUE.
#ifdef HAVE_X11
-x_wm_set_size_hint (f, prompting)
+/* Record the gravity used previously, in case CHANGE_GRAVITY is 0. */
+static int previous_gravity;
+
+/* SPEC_X and SPEC_Y are the specified positions.
+ We look only at their sign, to decide the gravity.
+ If CHANGE_GRAVITY is 0, we ignore SPEC_X and SPEC_Y
+ and leave the gravity unchanged. */
+
+x_wm_set_size_hint (f, prompting, change_gravity, spec_x, spec_y)
struct frame *f;
long prompting;
+ int change_gravity;
+ int spec_x, spec_y;
{
XSizeHints size_hints;
+
+#ifdef USE_X_TOOLKIT
+ Window window = XtWindow (f->display.x->widget);
+#else /* not USE_X_TOOLKIT */
Window window = FRAME_X_WINDOW (f);
+#endif /* not USE_X_TOOLKIT */
size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
if (hints.flags & USSize)
size_hints.flags |= USSize;
}
+#if defined (PWinGravity)
+ if (change_gravity)
+ {
+ switch (((spec_x < 0) << 1) + (spec_y < 0))
+ {
+ case 0:
+ size_hints.win_gravity = NorthWestGravity;
+ break;
+ case 1:
+ size_hints.win_gravity = NorthEastGravity;
+ break;
+ case 2:
+ size_hints.win_gravity = SouthWestGravity;
+ break;
+ case 3:
+ size_hints.win_gravity = SouthEastGravity;
+ break;
+ }
+ previous_gravity = size_hints.win_gravity;
+ }
+ else
+ size_hints.win_gravity = previous_gravity;
+
+ size_hints.flags |= PWinGravity;
+#endif /* PWinGravity */
#ifdef HAVE_X11R4
XSetWMNormalHints (x_current_display, window, &size_hints);
struct frame *f;
int state;
{
+#ifdef USE_X_TOOLKIT
+ Window window = XtWindow (f->display.x->widget);
+#else /* not USE_X_TOOLKIT */
Window window = FRAME_X_WINDOW (f);
+#endif /* not USE_X_TOOLKIT */
f->display.x->wm_hints.flags |= StateHint;
f->display.x->wm_hints.initial_state = state;
\f
/* Initialization. */
+#ifdef USE_X_TOOLKIT
+static XrmOptionDescRec emacs_options[] = {
+ {"-geometry", ".geometry", XrmoptionSepArg, NULL},
+ {"-iconic", ".iconic", XrmoptionNoArg, (XtPointer) "yes"},
+
+ {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
+ XrmoptionSepArg, NULL},
+ {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL},
+
+ {"-T", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
+ {"-wn", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
+ {"-title", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
+ {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
+ {"-in", "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
+ {"-mc", "*pointerColor", XrmoptionSepArg, (XtPointer) NULL},
+ {"-cr", "*cursorColor", XrmoptionSepArg, (XtPointer) NULL}
+};
+#endif /* USE_X_TOOLKIT */
+
void
x_term_init (display_name)
char *display_name;
{
Lisp_Object frame;
char *defaultvalue;
+ int argc = 0;
+ char** argv = 0;
+#ifndef F_SETOWN_BUG
#ifdef F_SETOWN
extern int old_fcntl_owner;
#endif /* ! defined (F_SETOWN) */
+#endif /* F_SETOWN_BUG */
x_focus_frame = x_highlight_frame = 0;
+#ifdef USE_X_TOOLKIT
+ argv = (char **) XtMalloc (3 * sizeof (char *));
+ argv [0] = "";
+ argv [1] = "-display";
+ argv [2] = display_name;
+ argc = 3;
+ Xt_app_shell = XtAppInitialize (&Xt_app_con, "Emacs",
+ emacs_options, XtNumber (emacs_options),
+ &argc, argv,
+ NULL, NULL, 0);
+ XtFree (argv);
+ x_current_display = XtDisplay (Xt_app_shell);
+
+#else /* not USE_X_TOOLKIT */
x_current_display = XOpenDisplay (display_name);
+#endif /* not USE_X_TOOLKIT */
if (x_current_display == 0)
- fatal ("X server %s not responding; check the DISPLAY environment variable or use \"-d\"\n",
+ fatal ("X server %s not responding.\n\
+Check the DISPLAY environment variable or use \"-d\"\n",
display_name);
#ifdef HAVE_X11
{
- int hostname_size = 256;
-
- hostname = (char *) xmalloc (hostname_size);
-
#if 0
XSetAfterFunction (x_current_display, x_trace_wire);
#endif /* ! 0 */
-
- /* Try to get the host name; if the buffer is too short, try
- again. Apparently, the only indication gethostname gives of
- whether the buffer was large enough is the presence or absence
- of a '\0' in the string. Eech. */
- for (;;)
- {
- gethostname (hostname, hostname_size - 1);
- hostname[hostname_size - 1] = '\0';
-
- /* Was the buffer large enough for gethostname to store the '\0'? */
- if (strlen (hostname) < hostname_size - 1)
- break;
-
- hostname_size <<= 1;
- hostname = (char *) xrealloc (hostname, hostname_size);
- }
+ hostname = get_system_name ();
x_id_name = (char *) xmalloc (XSTRING (Vinvocation_name)->size
+ strlen (hostname)
+ 2);
#endif
if (ConnectionNumber (x_current_display) != 0)
- {
- dup2 (ConnectionNumber (x_current_display), 0);
-
-#ifndef SYSV_STREAMS
- /* Streams somehow keeps track of which descriptor number
- is being used to talk to X. So it is not safe to substitute
- descriptor 0. But it is safe to make descriptor 0 a copy of it. */
- close (ConnectionNumber (x_current_display));
- ConnectionNumber (x_current_display) = 0; /* Looks a little strange?
- * check the def of the macro;
- * it is a genuine lvalue */
-#endif /* SYSV_STREAMS */
- }
+ change_keyboard_wait_descriptor (ConnectionNumber (x_current_display));
+ change_input_fd (ConnectionNumber (x_current_display));
#endif /* ! defined (HAVE_X11) */
+#ifndef F_SETOWN_BUG
#ifdef F_SETOWN
- old_fcntl_owner = fcntl (0, F_GETOWN, 0);
+ old_fcntl_owner = fcntl (ConnectionNumber (x_current_display), F_GETOWN, 0);
#ifdef F_SETOWN_SOCK_NEG
- fcntl (0, F_SETOWN, -getpid ()); /* stdin is a socket here */
+ /* stdin is a socket here */
+ fcntl (ConnectionNumber (x_current_display), F_SETOWN, -getpid ());
#else /* ! defined (F_SETOWN_SOCK_NEG) */
- fcntl (0, F_SETOWN, getpid ());
+ fcntl (ConnectionNumber (x_current_display), F_SETOWN, getpid ());
#endif /* ! defined (F_SETOWN_SOCK_NEG) */
#endif /* ! defined (F_SETOWN) */
+#endif /* F_SETOWN_BUG */
#ifdef SIGIO
init_sigio ();
#endif /* ! defined (SIGIO) */
- /* Must use interrupt input because we cannot otherwise
- arrange for C-g to be noticed immediately.
- We cannot connect it to SIGINT. */
- Fset_input_mode (Qt, Qnil, Qt, Qnil);
-
expose_all_windows = 0;
clear_frame_hook = XTclear_frame;
off the bottom */
baud_rate = 19200;
+ /* Try to use interrupt input; if we can't, then start polling. */
+ Fset_input_mode (Qt, Qnil, Qt, Qnil);
+
/* Note that there is no real way portable across R3/R4 to get the
original error handler. */
XHandleError (x_error_quitter);
syms_of_xterm ()
{
staticpro (&last_mouse_scroll_bar);
+ last_mouse_scroll_bar = Qnil;
}
#endif /* ! defined (HAVE_X11) */
#endif /* ! defined (HAVE_X_WINDOWS) */