/* X Communication module for terminals which understand the X protocol.
-Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+Copyright (C) 1989, 1993-2011 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <sys/types.h>
#endif /* makedev */
-#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
-#endif /* ! defined (HAVE_SYS_IOCTL_H) */
#include "systime.h"
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
-#ifdef HAVE_UNISTD_H
+
#include <unistd.h>
-#endif
#ifdef USE_GTK
#include "gtkutil.h"
\f
-/* Non-nil means Emacs uses toolkit scroll bars. */
-
-Lisp_Object Vx_toolkit_scroll_bars;
-
/* Non-zero means that a HELP_EVENT has been generated since Emacs
start. */
/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
static Lisp_Object last_window;
-/* Non-zero means make use of UNDERLINE_POSITION font properties. */
-
-int x_use_underline_position_properties;
-
-/* Non-zero means to draw the underline at the same place as the descent line. */
-
-int x_underline_at_descent_line;
-
/* This is a chain of structures for all the X displays currently in
use. */
static int toolkit_scroll_bar_interaction;
-/* Non-zero means to not move point as a result of clicking on a
- frame to focus it (when focus-follows-mouse is nil). */
-
-int x_mouse_click_focus_ignore_position;
-
/* Non-zero timeout value means ignore next mouse click if it arrives
before that timeout elapses (i.e. as part of the same sequence of
events resulting from clicking on a frame to select it). */
static int x_noop_count;
-/* The keysyms to use for the various modifiers. */
-
-Lisp_Object Vx_alt_keysym, Vx_hyper_keysym, Vx_meta_keysym, Vx_super_keysym;
-Lisp_Object Vx_keysym_table;
static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value;
static Lisp_Object Qvendor_specific_keysyms;
/* Some functions take this as char *, not const char *. */
static char emacs_class[] = EMACS_CLASS;
-/* Used in x_flush. */
+enum xembed_info
+ {
+ XEMBED_MAPPED = 1 << 0
+ };
-extern XrmDatabase x_load_resources (Display *, const char *, const char *,
- const char *);
-extern int x_bitmap_mask (FRAME_PTR, int);
+enum xembed_message
+ {
+ XEMBED_EMBEDDED_NOTIFY = 0,
+ XEMBED_WINDOW_ACTIVATE = 1,
+ XEMBED_WINDOW_DEACTIVATE = 2,
+ XEMBED_REQUEST_FOCUS = 3,
+ XEMBED_FOCUS_IN = 4,
+ XEMBED_FOCUS_OUT = 5,
+ XEMBED_FOCUS_NEXT = 6,
+ XEMBED_FOCUS_PREV = 7,
+
+ XEMBED_MODALITY_ON = 10,
+ XEMBED_MODALITY_OFF = 11,
+ XEMBED_REGISTER_ACCELERATOR = 12,
+ XEMBED_UNREGISTER_ACCELERATOR = 13,
+ XEMBED_ACTIVATE_ACCELERATOR = 14
+ };
+
+/* Used in x_flush. */
static int x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
static void x_set_window_size_1 (struct frame *, int, int, int);
static void XTset_terminal_modes (struct terminal *);
static void XTreset_terminal_modes (struct terminal *);
static void x_clear_frame (struct frame *);
+static void x_ins_del_lines (struct frame *, int, int) NO_RETURN;
static void frame_highlight (struct frame *);
static void frame_unhighlight (struct frame *);
static void x_new_focus_frame (struct x_display_info *, struct frame *);
int *, struct input_event *);
/* Don't declare this NO_RETURN because we want no
interference with debugging failing X calls. */
-static SIGTYPE x_connection_closed (Display *, const char *);
+static void x_connection_closed (Display *, const char *);
/* Flush display of frame F, or of all frames if F is null. */
int event_record_index;
-record_event (locus, type)
- char *locus;
- int type;
+void
+record_event (char *locus, int type)
{
if (event_record_index == sizeof (event_record) / sizeof (struct record))
event_record_index = 0;
&data);
if (rc == Success && actual != None)
- if (*(unsigned long *)data == opac)
- {
- XFree ((void *) data);
- x_uncatch_errors ();
- return;
- }
- else
+ {
+ unsigned long value = *(unsigned long *)data;
XFree ((void *) data);
- x_uncatch_errors ();
+ if (value == opac)
+ {
+ x_uncatch_errors ();
+ return;
+ }
+ }
}
- x_catch_errors (dpy);
XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &opac, 1L);
if (p->which)
{
- unsigned char *bits;
+ char *bits;
Pixmap pixmap, clipmask = (Pixmap) 0;
int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
XGCValues gcv;
if (p->wd > 8)
- bits = (unsigned char *)(p->bits + p->dh);
+ bits = (char *) (p->bits + p->dh);
else
- bits = (unsigned char *)p->bits + p->dh;
+ bits = (char *) p->bits + p->dh;
/* Draw the bitmap. I believe these small pixmaps can be cached
by the server. */
static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
static void x_draw_glyph_string_box (struct glyph_string *);
static void x_draw_glyph_string (struct glyph_string *);
+static void x_delete_glyphs (struct frame *, int) NO_RETURN;
static void x_compute_glyph_string_overhangs (struct glyph_string *);
static void x_set_cursor_gc (struct glyph_string *);
static void x_set_mode_line_face_gc (struct glyph_string *);
XRectangle *);
static void x_draw_box_rect (struct glyph_string *, int, int, int, int,
int, int, int, XRectangle *);
+static void x_scroll_bar_clear (struct frame *);
#if GLYPH_DEBUG
static void x_check_font (struct frame *, struct font *);
glyph->u.glyphless.ch)
: XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
if (STRINGP (acronym))
- str = (char *) SDATA (acronym);
+ str = SSDATA (acronym);
}
}
else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
a least-squares matching, which is what X uses for closest
color matching with StaticColor visuals. */
int nearest, i;
- unsigned long nearest_delta = ~0;
+ unsigned long nearest_delta = ~ (unsigned long) 0;
int ncells;
const XColor *cells = x_color_cells (dpy, &ncells);
}
-/* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
- It's necessary to do this instead of just using PIXEL directly to
- get color reference counts right. */
-
-unsigned long
-x_copy_dpy_color (Display *dpy, Colormap cmap, long unsigned int pixel)
-{
- XColor color;
-
- color.pixel = pixel;
- BLOCK_INPUT;
- XQueryColor (dpy, cmap, &color);
- XAllocColor (dpy, cmap, &color);
- UNBLOCK_INPUT;
-#ifdef DEBUG_X_COLORS
- register_color (pixel);
-#endif
- return color.pixel;
-}
-
-
/* Brightness beyond which a color won't have its highlight brightness
boosted.
nothing here for mouse-face. */
if (s->hl == DRAW_CURSOR)
{
- int r = s->img->relief;
- if (r < 0) r = -r;
+ int relief = s->img->relief;
+ if (relief < 0) relief = -relief;
XDrawRectangle (s->display, s->window, s->gc,
- x - r, y - r,
- s->slice.width + r*2 - 1,
- s->slice.height + r*2 - 1);
+ x - relief, y - relief,
+ s->slice.width + relief*2 - 1,
+ s->slice.height + relief*2 - 1);
}
}
}
/* Shift display to make room for inserted glyphs. */
-void
+static void
x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
{
XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
/* We don't set the output cursor here because there will always
follow an explicit cursor_to. */
BLOCK_INPUT;
- XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
- /* We have to clear the scroll bars, too. If we have changed
- colors or something like that, then they should be notified. */
+ /* The following calls have been commented out because they do not
+ seem to accomplish anything, apart from causing flickering during
+ window resize. */
+ /* XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); */
+
+ /* We have to clear the scroll bars. If we have changed colors or
+ something like that, then they should be notified. */
x_scroll_bar_clear (f);
#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
return x.tv_sec < y.tv_sec;
}
-void
+static void
XTflash (struct frame *f)
{
BLOCK_INPUT;
/* Use Gdk routines to draw. This way, we won't draw over scroll bars
when the scroll bars and the edit widget share the same X window. */
GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
+#ifdef HAVE_GTK3
+ cairo_t *cr = gdk_cairo_create (window);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
+#define XFillRectangle(d, win, gc, x, y, w, h) \
+ do { \
+ cairo_rectangle (cr, x, y, w, h); \
+ cairo_fill (cr); \
+ } \
+ while (0)
+#else /* ! HAVE_GTK3 */
GdkGCValues vals;
GdkGC *gc;
vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
&vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
#define XFillRectangle(d, win, gc, x, y, w, h) \
gdk_draw_rectangle (window, gc, TRUE, x, y, w, h)
-#else
+#endif /* ! HAVE_GTK3 */
+#else /* ! USE_GTK */
GC gc;
/* Create a GC that will use the GXxor function to flip foreground
width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
#ifdef USE_GTK
+#ifdef HAVE_GTK3
+ cairo_destroy (cr);
+#else
g_object_unref (G_OBJECT (gc));
+#endif
#undef XFillRectangle
#else
XFreeGC (FRAME_X_DISPLAY (f), gc);
/* Make audible bell. */
-void
+static void
XTring_bell (struct frame *f)
{
if (FRAME_X_DISPLAY (f))
mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
the mouse is over.
- Set *TIME to the server time-stamp for the time at which the mouse
+ Set *TIMESTAMP to the server time-stamp 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.
movement. */
static void
-XTmouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, long unsigned int *time)
+XTmouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
+ enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
+ long unsigned int *timestamp)
{
FRAME_PTR f1;
BLOCK_INPUT;
if (! NILP (last_mouse_scroll_bar) && insist == 0)
- x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
+ x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
else
{
Window root;
*fp = f1;
XSETINT (*x, win_x);
XSETINT (*y, win_y);
- *time = last_mouse_movement_time;
+ *timestamp = last_mouse_movement_time;
}
}
}
return XSCROLL_BAR (bar);
}
- return 0;
+ return NULL;
}
x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
static struct window **scroll_bar_windows;
-static int scroll_bar_windows_size;
+static size_t scroll_bar_windows_size;
/* Send a client message with message type Xatom_Scrollbar for a
XClientMessageEvent *ev = (XClientMessageEvent *) &event;
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
- int i;
+ size_t i;
BLOCK_INPUT;
if (i == scroll_bar_windows_size)
{
- int new_size = max (10, 2 * scroll_bar_windows_size);
+ size_t new_size = max (10, 2 * scroll_bar_windows_size);
size_t nbytes = new_size * sizeof *scroll_bar_windows;
size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows;
+ if ((size_t) -1 / sizeof *scroll_bar_windows < new_size)
+ memory_full ();
scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows,
nbytes);
memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes);
{
XClientMessageEvent *ev = (XClientMessageEvent *) event;
Lisp_Object window;
- struct frame *f;
struct window *w;
w = scroll_bar_windows[ev->data.l[0]];
scroll_bar_windows[ev->data.l[0]] = NULL;
XSETWINDOW (window, w);
- f = XFRAME (w->frame);
ievent->kind = SCROLL_BAR_CLICK_EVENT;
ievent->frame_or_window = window;
#ifdef USE_GTK
ievent->timestamp = CurrentTime;
#else
- ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f));
+ ievent->timestamp =
+ XtLastTimestampProcessed (FRAME_X_DISPLAY (XFRAME (w->frame)));
#endif
ievent->part = ev->data.l[1];
ievent->code = ev->data.l[2];
on the scroll bar. */
static void
-x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, long unsigned int *time)
+x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window,
+ enum scroll_bar_part *part, Lisp_Object *x,
+ Lisp_Object *y, long unsigned int *timestamp)
{
struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
Window w = bar->x_window;
last_mouse_scroll_bar = Qnil;
}
- *time = last_mouse_movement_time;
+ *timestamp = last_mouse_movement_time;
UNBLOCK_INPUT;
}
Clear out the scroll bars, and ask for expose events, so we can
redraw them. */
-void
+static void
x_scroll_bar_clear (FRAME_PTR f)
{
#ifndef USE_TOOLKIT_SCROLL_BARS
#endif /* USE_GTK */
+static void xembed_send_message (struct frame *f, Time time,
+ enum xembed_message message,
+ long detail, long data1, long data2);
+
/* Handles the XEvent EVENT on display DPYINFO.
*FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
We return the number of characters stored into the buffer. */
static int
-handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventp, int *finish, struct input_event *hold_quit)
+handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
+ int *finish, struct input_event *hold_quit)
{
union {
struct input_event ie;
int nbytes = 0;
struct frame *f = NULL;
struct coding_system coding;
- XEvent event = *eventp;
+ XEvent event = *eventptr;
Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
*finish = X_EVENT_NORMAL;
goto OTHER;
#endif /* USE_X_TOOLKIT */
{
- XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
+ XSelectionClearEvent *eventp = &(event.xselectionclear);
inev.ie.kind = SELECTION_CLEAR_EVENT;
SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
goto OTHER;
#endif /* USE_X_TOOLKIT */
{
- XSelectionRequestEvent *eventp
- = (XSelectionRequestEvent *) &event;
+ XSelectionRequestEvent *eventp = &(event.xselectionrequest);
inev.ie.kind = SELECTION_REQUEST_EVENT;
SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
coding_system = Vlocale_coding_system;
nbytes = XmbLookupString (FRAME_XIC (f),
- &event.xkey, copy_bufptr,
+ &event.xkey, (char *) copy_bufptr,
copy_bufsiz, &keysym,
&status_return);
if (status_return == XBufferOverflow)
copy_bufsiz = nbytes + 1;
copy_bufptr = (unsigned char *) alloca (copy_bufsiz);
nbytes = XmbLookupString (FRAME_XIC (f),
- &event.xkey, copy_bufptr,
+ &event.xkey, (char *) copy_bufptr,
copy_bufsiz, &keysym,
&status_return);
}
abort ();
}
else
- nbytes = XLookupString (&event.xkey, copy_bufptr,
+ nbytes = XLookupString (&event.xkey, (char *) copy_bufptr,
copy_bufsiz, &keysym,
&compose_status);
#else
- nbytes = XLookupString (&event.xkey, copy_bufptr,
+ nbytes = XLookupString (&event.xkey, (char *) copy_bufptr,
copy_bufsiz, &keysym,
&compose_status);
#endif
{ /* Raw bytes, not keysym. */
register int i;
- register int c;
int nchars, len;
for (i = 0, nchars = 0; i < nbytes; i++)
{
/* Decode the input data. */
int require;
- unsigned char *p;
/* The input should be decoded with `coding_system'
which depends on which X*LookupString function
character events. */
for (i = 0; i < nbytes; i += len)
{
+ int ch;
if (nchars == nbytes)
- c = copy_bufptr[i], len = 1;
+ ch = copy_bufptr[i], len = 1;
else
- c = STRING_CHAR_AND_LENGTH (copy_bufptr + i, len);
- inev.ie.kind = (SINGLE_BYTE_CHAR_P (c)
+ ch = STRING_CHAR_AND_LENGTH (copy_bufptr + i, len);
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (ch)
? ASCII_KEYSTROKE_EVENT
: MULTIBYTE_CHAR_KEYSTROKE_EVENT);
- inev.ie.code = c;
+ inev.ie.code = ch;
kbd_buffer_store_event_hold (&inev.ie, hold_quit);
}
window = window_from_coordinates (f,
event.xmotion.x, event.xmotion.y,
- 0, 0, 0, 0);
+ 0, 0);
/* Window will be selected only when it is not selected now and
last mouse movement event was not in it. Minibuffer window
int x = event.xbutton.x;
int y = event.xbutton.y;
- window = window_from_coordinates (f, x, y, 0, 0, 0, 1);
+ window = window_from_coordinates (f, x, y, 0, 1);
tool_bar_p = EQ (window, f->tool_bar_window);
if (tool_bar_p && event.xbutton.button < 4)
count++;
}
- *eventp = event;
+ *eventptr = event;
return count;
}
XTread_socket (struct terminal *terminal, int expected, struct input_event *hold_quit)
{
int count = 0;
- XEvent event;
int event_found = 0;
if (interrupt_input_blocked)
++handling_signal;
-#ifdef HAVE_X_SM
- /* Only check session manager input for the primary display. */
- if (terminal->id == 1 && x_session_have_connection ())
- {
- struct input_event inev;
- BLOCK_INPUT;
- /* We don't need to EVENT_INIT (inev) here, as
- x_session_check_input copies an entire input_event. */
- if (x_session_check_input (&inev))
- {
- kbd_buffer_store_event_hold (&inev, hold_quit);
- count++;
- }
- UNBLOCK_INPUT;
- }
-#endif
-
/* For debugging, this gives a way to fake an I/O error. */
if (terminal->display_info.x == XTread_socket_fake_io_error)
{
while (XPending (terminal->display_info.x->display))
{
int finish;
+ XEvent event;
XNextEvent (terminal->display_info.x->display, &event);
goto out;
}
+ out:;
+
#else /* USE_GTK */
/* For GTK we must use the GTK event loop. But XEvents gets passed
}
#endif /* USE_GTK */
- out:;
-
/* On some systems, an X bug causes Emacs to get no more events
when the window is destroyed. Detect that. (1994.) */
if (! event_found)
the bar might not be in the window. */
if (cursor_glyph->type == IMAGE_GLYPH)
{
- struct glyph_row *row;
- row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
- draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
+ struct glyph_row *r;
+ r = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
+ draw_phys_cursor_glyph (w, r, DRAW_CURSOR);
}
else
{
/* If all else fails, use the (black and white) xbm image. */
if (rc == -1)
{
- rc = x_create_bitmap_from_data (f, gnu_xbm_bits,
+ rc = x_create_bitmap_from_data (f, (char *) gnu_xbm_bits,
gnu_xbm_width, gnu_xbm_height);
if (rc == -1)
return 1;
x_catch_errors is in effect. */
static void
-x_error_catcher (Display *display, XErrorEvent *error)
+x_error_catcher (Display *display, XErrorEvent *event)
{
- XGetErrorText (display, error->error_code,
+ XGetErrorText (display, event->error_code,
x_error_message->string,
X_ERROR_MESSAGE_SIZE);
}
Calling x_uncatch_errors resumes the normal error handling. */
-void x_check_errors (Display *dpy, const char *format);
-
void
x_catch_errors (Display *dpy)
{
SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
which will do the appropriate cleanup for us. */
-static SIGTYPE
+static void
x_connection_signal (int signalnum) /* If we don't have an argument, */
/* some compilers complain in signal calls. */
{
static char *error_msg;
-/* Function installed as fatal_error_signal_hook in
- x_connection_closed. Print the X error message, and exit normally,
- instead of dumping core when XtCloseDisplay fails. */
-
-static void
-x_fatal_error_signal (void)
-{
- fprintf (stderr, "%s\n", error_msg);
- exit (70);
-}
-
/* Handle the loss of connection to display DPY. ERROR_MESSAGE is
the text of an error message that lead to the connection loss. */
-static SIGTYPE
+static void
x_connection_closed (Display *dpy, const char *error_message)
{
struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
Lisp_Object frame, tail;
- int index = SPECPDL_INDEX ();
+ int idx = SPECPDL_INDEX ();
error_msg = (char *) alloca (strlen (error_message) + 1);
strcpy (error_msg, error_message);
handling_signal = 0;
- /* Prevent being called recursively because of an error condition
- below. Otherwise, we might end up with printing ``can't find per
- display information'' in the recursive call instead of printing
- the original message here. */
- x_catch_errors (dpy);
-
/* Inhibit redisplay while frames are being deleted. */
specbind (Qinhibit_redisplay, Qt);
{
/* Set this to t so that delete_frame won't get confused
trying to find a replacement. */
- FRAME_KBOARD (XFRAME (frame))->Vdefault_minibuffer_frame = Qt;
+ KVAR (FRAME_KBOARD (XFRAME (frame)), Vdefault_minibuffer_frame) = Qt;
delete_frame (frame, Qnoelisp);
}
first place, so don't try to close it. */
if (dpyinfo)
{
-#ifdef USE_X_TOOLKIT
- /* We have to close the display to inform Xt that it doesn't
- exist anymore. If we don't, Xt will continue to wait for
- events from the display. As a consequence, a sequence of
-
- M-x make-frame-on-display RET :1 RET
- ...kill the new frame, so that we get an IO error...
- M-x make-frame-on-display RET :1 RET
-
- will indefinitely wait in Xt for events for display `:1',
- opened in the first call to make-frame-on-display.
-
- Closing the display is reported to lead to a bus error on
- OpenWindows in certain situations. I suspect that is a bug
- in OpenWindows. I don't know how to circumvent it here. */
- fatal_error_signal_hook = x_fatal_error_signal;
- XtCloseDisplay (dpy);
- fatal_error_signal_hook = NULL;
-#endif /* USE_X_TOOLKIT */
-
+ /* We can not call XtCloseDisplay here because it calls XSync.
+ XSync inside the error handler apparently hangs Emacs. On
+ current Xt versions, this isn't needed either. */
#ifdef USE_GTK
/* A long-standing GTK bug prevents proper disconnect handling
(https://bugzilla.gnome.org/show_bug.cgi?id=85715). Once,
}
}
- x_uncatch_errors ();
-
if (terminal_list == 0)
{
fprintf (stderr, "%s\n", error_msg);
sigunblock (sigmask (SIGALRM));
TOTALLY_UNBLOCK_INPUT;
- unbind_to (index, Qnil);
+ unbind_to (idx, Qnil);
clear_waiting_for_input ();
+
+ /* Tell GCC not to suggest attribute 'noreturn' for this function. */
+ IF_LINT (if (! terminal_list) return; )
+
/* Here, we absolutely have to use a non-local exit (e.g. signal, throw,
longjmp), because returning from this function would get us back into
Xlib's code which will directly call `exit'. */
It calls x_error_quitter or x_error_catcher. */
static int
-x_error_handler (Display *display, XErrorEvent *error)
+x_error_handler (Display *display, XErrorEvent *event)
{
if (x_error_message)
- x_error_catcher (display, error);
+ x_error_catcher (display, event);
else
- x_error_quitter (display, error);
+ x_error_quitter (display, event);
return 0;
}
after x_error_handler prevents inlining into the former. */
static void NO_INLINE
-x_error_quitter (Display *display, XErrorEvent *error)
+x_error_quitter (Display *display, XErrorEvent *event)
{
char buf[256], buf1[356];
/* Ignore BadName errors. They can happen because of fonts
or colors that are not defined. */
- if (error->error_code == BadName)
+ if (event->error_code == BadName)
return;
/* 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));
+ XGetErrorText (display, event->error_code, buf, sizeof (buf));
sprintf (buf1, "X protocol error: %s on protocol request %d",
- buf, error->request_code);
+ buf, event->request_code);
x_connection_closed (display, buf1);
}
&& (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
{
BLOCK_INPUT;
- xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
+ xic_set_xfontset (f, SSDATA (fontset_ascii (fontset)));
UNBLOCK_INPUT;
}
#endif
/* Calculate the absolute position in frame F
from its current recorded position values and gravity. */
-void
+static void
x_calc_absolute_position (struct frame *f)
{
int flags = f->size_hint_flags;
STICKY is set to 1 if the sticky state is set, 0 if not. */
static void
-get_current_vm_state (struct frame *f,
+get_current_wm_state (struct frame *f,
Window window,
int *size_state,
int *sticky)
for (i = 0; i < actual_size; ++i)
{
Atom a = ((Atom*)tmp_data)[i];
- if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
+ if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
{
if (*size_state == FULLSCREEN_HEIGHT)
*size_state = FULLSCREEN_MAXIMIZED;
{
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
int have_net_atom = wm_supports (f, dpyinfo->Xatom_net_wm_state);
- Lisp_Object lval = get_frame_param (f, Qfullscreen);
int cur, dummy;
- get_current_vm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy);
+ get_current_wm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy);
/* Some window managers don't say they support _NET_WM_STATE, but they do say
they support _NET_WM_STATE_FULLSCREEN. Try that also. */
Lisp_Object lval;
int sticky = 0;
- get_current_vm_state (f, event->window, &value, &sticky);
+ get_current_wm_state (f, event->window, &value, &sticky);
lval = Qnil;
switch (value)
{
if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
return; /* Only fullscreen without WM or with EWM hints (above). */
+ /* Setting fullscreen to nil doesn't do anything. We could save the
+ last non-fullscreen size and restore it, but it seems like a
+ lot of work for this unusual case (no window manager running). */
+
if (f->want_fullscreen != FULLSCREEN_NONE)
{
- int width = FRAME_COLS (f), height = FRAME_LINES (f);
+ int width = FRAME_PIXEL_WIDTH (f), height = FRAME_PIXEL_HEIGHT (f);
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
switch (f->want_fullscreen)
height = x_display_pixel_height (dpyinfo);
}
- if (FRAME_COLS (f) != width || FRAME_LINES (f) != height)
- {
- change_frame_size (f, height, width, 0, 1, 0);
- SET_FRAME_GARBAGED (f);
- cancel_mouse_face (f);
- }
+ XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+ width, height);
}
}
UNBLOCK_INPUT;
}
\f
-/* focus shifting, raising and lowering. */
-
-void
-x_focus_on_frame (struct frame *f)
-{
-#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
- doing with this code, do it to x_unfocus_frame too. */
- XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- RevertToPointerRoot, CurrentTime);
-#endif /* ! 0 */
-}
-
-void
-x_unfocus_frame (struct frame *f)
-{
-#if 0
- /* Look at the remarks in x_focus_on_frame. */
- if (FRAME_X_DISPLAY_INFO (f)->x_focus_frame == f)
- XSetInputFocus (FRAME_X_DISPLAY (f), PointerRoot,
- RevertToPointerRoot, CurrentTime);
-#endif /* ! 0 */
-}
-
/* Raise frame F. */
void
\f
/* XEmbed implementation. */
-void
+#if defined USE_X_TOOLKIT || ! defined USE_GTK
+
+/* XEmbed implementation. */
+
+#define XEMBED_VERSION 0
+
+static void
xembed_set_info (struct frame *f, enum xembed_info flags)
{
- Atom atom;
unsigned long data[2];
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
dpyinfo->Xatom_XEMBED_INFO, dpyinfo->Xatom_XEMBED_INFO,
32, PropModeReplace, (unsigned char *) data, 2);
}
+#endif /* defined USE_X_TOOLKIT || ! defined USE_GTK */
-void
-xembed_send_message (struct frame *f, Time time, enum xembed_message message, long int detail, long int data1, long int data2)
+static void
+xembed_send_message (struct frame *f, Time t, enum xembed_message msg,
+ long int detail, long int data1, long int data2)
{
XEvent event;
event.xclient.window = FRAME_X_OUTPUT (f)->parent_desc;
event.xclient.message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_XEMBED;
event.xclient.format = 32;
- event.xclient.data.l[0] = time;
- event.xclient.data.l[1] = message;
+ event.xclient.data.l[0] = t;
+ event.xclient.data.l[1] = msg;
event.xclient.data.l[2] = detail;
event.xclient.data.l[3] = data1;
event.xclient.data.l[4] = data2;
unknown reason, the call to XtMapWidget is completely ignored.
Mapping the widget a second time works. */
- if (!FRAME_VISIBLE_P (f) && --retry_count > 0)
+ if (!FRAME_VISIBLE_P (f) && --retry_count != 0)
goto retry;
}
}
void
x_iconify_frame (struct frame *f)
{
+#ifdef USE_X_TOOLKIT
int result;
+#endif
Lisp_Object type;
/* Don't keep the highlight on an invisible frame. */
/* X11R4: send a ClientMessage to the window manager using the
WM_CHANGE_STATE type. */
{
- XEvent message;
+ XEvent msg;
- message.xclient.window = FRAME_X_WINDOW (f);
- message.xclient.type = ClientMessage;
- message.xclient.message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_change_state;
- message.xclient.format = 32;
- message.xclient.data.l[0] = IconicState;
+ msg.xclient.window = FRAME_X_WINDOW (f);
+ msg.xclient.type = ClientMessage;
+ msg.xclient.message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_change_state;
+ msg.xclient.format = 32;
+ msg.xclient.data.l[0] = IconicState;
if (! XSendEvent (FRAME_X_DISPLAY (f),
DefaultRootWindow (FRAME_X_DISPLAY (f)),
False,
SubstructureRedirectMask | SubstructureNotifyMask,
- &message))
+ &msg))
{
UNBLOCK_INPUT_RESIGNAL;
error ("Can't notify window manager of iconification");
x_free_frame_resources (struct frame *f)
{
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
+#ifdef USE_X_TOOLKIT
Lisp_Object bar;
struct scroll_bar *b;
- Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
+#endif
BLOCK_INPUT;
static int x_initialized;
-#ifdef HAVE_X_SM
-static int x_session_initialized;
-#endif
-
/* Test whether two display-name strings agree up to the dot that separates
the screen number from the server number. */
static int
same_x_server (const char *name1, const char *name2)
{
int seen_colon = 0;
- const unsigned char *system_name = SDATA (Vsystem_name);
+ const char *system_name = SSDATA (Vsystem_name);
int system_name_length = strlen (system_name);
int length_until_period = 0;
for (; *name1 != '\0' && *name1 == *name2; name1++, name2++)
{
if (*name1 == ':')
- seen_colon++;
+ seen_colon = 1;
if (seen_colon && *name1 == '.')
return 1;
}
#ifdef USE_GTK
static void
-my_log_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
+my_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
+ const gchar *msg, gpointer user_data)
{
- if (!strstr (message, "g_set_prgname"))
- fprintf (stderr, "%s-WARNING **: %s\n", log_domain, message);
+ if (!strstr (msg, "g_set_prgname"))
+ fprintf (stderr, "%s-WARNING **: %s\n", log_domain, msg);
}
#endif
++x_initialized;
}
- if (! x_display_ok (SDATA (display_name)))
- error ("Display %s can't be opened", SDATA (display_name));
+ if (! x_display_ok (SSDATA (display_name)))
+ error ("Display %s can't be opened", SSDATA (display_name));
#ifdef USE_GTK
{
if (x_initialized++ > 1)
{
- xg_display_open (SDATA (display_name), &dpy);
+ xg_display_open (SSDATA (display_name), &dpy);
}
else
{
static char display_opt[] = "--display";
static char name_opt[] = "--name";
-
+
for (argc = 0; argc < NUM_ARGV; ++argc)
argv[argc] = 0;
if (! NILP (display_name))
{
argv[argc++] = display_opt;
- argv[argc++] = SDATA (display_name);
+ argv[argc++] = SSDATA (display_name);
}
argv[argc++] = name_opt;
XSetLocaleModifiers ("");
+ /* Emacs can only handle core input events, so make sure
+ Gtk doesn't use Xinput or Xinput2 extensions. */
+ {
+ static char fix_events[] = "GDK_CORE_DEVICE_EVENTS=1";
+ putenv (fix_events);
+ }
+
/* Work around GLib bug that outputs a faulty warning. See
https://bugzilla.gnome.org/show_bug.cgi?id=563627. */
id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL
fixup_locale ();
xg_initialize ();
- dpy = GDK_DISPLAY ();
+ dpy = DEFAULT_GDK_DISPLAY ();
/* NULL window -> events for all windows go to our function */
gdk_window_add_filter (NULL, event_handler_gdk, NULL);
+#if GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION <= 90
/* Load our own gtkrc if it exists. */
{
const char *file = "~/.emacs.d/gtkrc";
abs_file = Fexpand_file_name (s, Qnil);
if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file)))
- gtk_rc_parse (SDATA (abs_file));
+ gtk_rc_parse (SSDATA (abs_file));
}
+#endif
XSetErrorHandler (x_error_handler);
XSetIOErrorHandler (x_io_error_quitter);
argv[argc++] = xrm_option;
}
turn_on_atimers (0);
- dpy = XtOpenDisplay (Xt_app_con, SDATA (display_name),
+ dpy = XtOpenDisplay (Xt_app_con, SSDATA (display_name),
resource_name, EMACS_CLASS,
emacs_options, XtNumber (emacs_options),
&argc, argv);
#else /* not USE_X_TOOLKIT */
XSetLocaleModifiers ("");
- dpy = XOpenDisplay (SDATA (display_name));
+ dpy = XOpenDisplay (SSDATA (display_name));
#endif /* not USE_X_TOOLKIT */
#endif /* not USE_GTK*/
for (share = x_display_list, tail = x_display_name_list; share;
share = share->next, tail = XCDR (tail))
- if (same_x_server (SDATA (XCAR (XCAR (tail))),
- SDATA (display_name)))
+ if (same_x_server (SSDATA (XCAR (XCAR (tail))),
+ SSDATA (display_name)))
break;
if (share)
terminal->kboard = share->terminal->kboard;
{
terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
init_kboard (terminal->kboard);
- terminal->kboard->Vwindow_system = Qx;
+ KVAR (terminal->kboard, Vwindow_system) = Qx;
/* Add the keyboard to the list before running Lisp code (via
Qvendor_specific_keysyms below), since these are not traced
/* Temporarily hide the partially initialized terminal. */
terminal_list = terminal->next_terminal;
UNBLOCK_INPUT;
- terminal->kboard->Vsystem_key_alist
+ KVAR (terminal->kboard, Vsystem_key_alist)
= call1 (Qvendor_specific_keysyms,
vendor ? build_string (vendor) : empty_unibyte_string);
BLOCK_INPUT;
/* Set the name of the terminal. */
terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
- strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
+ strncpy (terminal->name, SSDATA (display_name), SBYTES (display_name));
terminal->name[SBYTES (display_name)] = 0;
#if 0
+ SBYTES (Vsystem_name)
+ 2);
sprintf (dpyinfo->x_id_name, "%s@%s",
- SDATA (Vinvocation_name), SDATA (Vsystem_name));
+ SSDATA (Vinvocation_name), SSDATA (Vsystem_name));
/* Figure out which modifier bits mean what. */
x_find_modifier_meanings (dpyinfo);
build_string ("PrivateColormap"),
Qnil, Qnil);
if (STRINGP (value)
- && (!strcmp (SDATA (value), "true")
- || !strcmp (SDATA (value), "on")))
+ && (!strcmp (SSDATA (value), "true")
+ || !strcmp (SSDATA (value), "on")))
dpyinfo->cmap = XCopyColormapAndFree (dpyinfo->display, dpyinfo->cmap);
}
}
build_string ("Synchronous"),
Qnil, Qnil);
if (STRINGP (value)
- && (!strcmp (SDATA (value), "true")
- || !strcmp (SDATA (value), "on")))
+ && (!strcmp (SSDATA (value), "true")
+ || !strcmp (SSDATA (value), "on")))
XSynchronize (dpyinfo->display, True);
}
Qnil, Qnil);
#ifdef USE_XIM
if (STRINGP (value)
- && (!strcmp (SDATA (value), "false")
- || !strcmp (SDATA (value), "off")))
+ && (!strcmp (SSDATA (value), "false")
+ || !strcmp (SSDATA (value), "off")))
use_xim = 0;
#else
if (STRINGP (value)
- && (!strcmp (SDATA (value), "true")
- || !strcmp (SDATA (value), "on")))
+ && (!strcmp (SSDATA (value), "true")
+ || !strcmp (SSDATA (value), "on")))
use_xim = 1;
#endif
}
last_tool_bar_item = -1;
any_help_event_p = 0;
ignore_next_mouse_click_timeout = 0;
-#ifdef HAVE_X_SM
- x_session_initialized = 0;
-#endif
#ifdef USE_GTK
current_count = -1;
#endif
DEFVAR_BOOL ("x-use-underline-position-properties",
- &x_use_underline_position_properties,
+ x_use_underline_position_properties,
doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
A value of nil means ignore them. If you encounter fonts with bogus
UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
x_use_underline_position_properties = 1;
DEFVAR_BOOL ("x-underline-at-descent-line",
- &x_underline_at_descent_line,
+ x_underline_at_descent_line,
doc: /* *Non-nil means to draw the underline at the same place as the descent line.
A value of nil means to draw the underline according to the value of the
variable `x-use-underline-position-properties', which is usually at the
x_underline_at_descent_line = 0;
DEFVAR_BOOL ("x-mouse-click-focus-ignore-position",
- &x_mouse_click_focus_ignore_position,
+ x_mouse_click_focus_ignore_position,
doc: /* Non-nil means that a mouse click to focus a frame does not move point.
This variable is only used when the window manager requires that you
click on a frame to select it (give it focus). In that case, a value
selected window or cursor position is preserved. */);
x_mouse_click_focus_ignore_position = 0;
- DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
+ DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
doc: /* Which toolkit scroll bars Emacs uses, if any.
A value of nil means Emacs doesn't use toolkit scroll bars.
With the X Window system, the value is a symbol describing the
Qsuper = intern_c_string ("super");
Fput (Qsuper, Qmodifier_value, make_number (super_modifier));
- DEFVAR_LISP ("x-alt-keysym", &Vx_alt_keysym,
+ DEFVAR_LISP ("x-alt-keysym", Vx_alt_keysym,
doc: /* Which keys Emacs uses for the alt modifier.
This should be one of the symbols `alt', `hyper', `meta', `super'.
For example, `alt' means use the Alt_L and Alt_R keysyms. The default
is nil, which is the same as `alt'. */);
Vx_alt_keysym = Qnil;
- DEFVAR_LISP ("x-hyper-keysym", &Vx_hyper_keysym,
+ DEFVAR_LISP ("x-hyper-keysym", Vx_hyper_keysym,
doc: /* Which keys Emacs uses for the hyper modifier.
This should be one of the symbols `alt', `hyper', `meta', `super'.
For example, `hyper' means use the Hyper_L and Hyper_R keysyms. The
default is nil, which is the same as `hyper'. */);
Vx_hyper_keysym = Qnil;
- DEFVAR_LISP ("x-meta-keysym", &Vx_meta_keysym,
+ DEFVAR_LISP ("x-meta-keysym", Vx_meta_keysym,
doc: /* Which keys Emacs uses for the meta modifier.
This should be one of the symbols `alt', `hyper', `meta', `super'.
For example, `meta' means use the Meta_L and Meta_R keysyms. The
default is nil, which is the same as `meta'. */);
Vx_meta_keysym = Qnil;
- DEFVAR_LISP ("x-super-keysym", &Vx_super_keysym,
+ DEFVAR_LISP ("x-super-keysym", Vx_super_keysym,
doc: /* Which keys Emacs uses for the super modifier.
This should be one of the symbols `alt', `hyper', `meta', `super'.
For example, `super' means use the Super_L and Super_R keysyms. The
default is nil, which is the same as `super'. */);
Vx_super_keysym = Qnil;
- DEFVAR_LISP ("x-keysym-table", &Vx_keysym_table,
+ DEFVAR_LISP ("x-keysym-table", Vx_keysym_table,
doc: /* Hash table of character codes indexed by X keysym codes. */);
Vx_keysym_table = make_hash_table (Qeql, make_number (900),
make_float (DEFAULT_REHASH_SIZE),
}
#endif /* HAVE_X_WINDOWS */
-