#include "termhooks.h"
#include "termopts.h"
#include "termchar.h"
-#include "gnu.h"
+#include "emacs-icon.h"
#include "disptab.h"
#include "buffer.h"
#include "window.h"
}
IF_DEBUG (x_check_font (s->f, s->font));
+#ifdef USE_FONT_BACKEND
+ if (enable_font_backend)
+ xgcv.font = FRAME_X_DISPLAY_INFO (s->f)->font->fid;
+ else
+#endif
xgcv.font = s->font->fid;
xgcv.graphics_exposures = False;
mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
xgcv.background = s->face->background;
xgcv.foreground = s->face->foreground;
IF_DEBUG (x_check_font (s->f, s->font));
+#ifdef USE_FONT_BACKEND
+ if (enable_font_backend)
+ xgcv.font = FRAME_X_DISPLAY_INFO (s->f)->font->fid;
+ else
+#endif
xgcv.font = s->font->fid;
xgcv.graphics_exposures = False;
mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
FOCUS_IMPLICIT : FOCUS_EXPLICIT),
dpyinfo, frame, bufp);
break;
+
+ case ClientMessage:
+ if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
+ {
+ enum xembed_message msg = event->xclient.data.l[1];
+ x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
+ FOCUS_EXPLICIT, dpyinfo, frame, bufp);
+ }
+ break;
}
}
}
#endif /* USE_TOOLKIT_SCROLL_BARS */
+ /* XEmbed messages from the embedder (if any). */
+ if (event.xclient.message_type
+ == dpyinfo->Xatom_XEMBED)
+ {
+ enum xembed_message msg = event.xclient.data.l[1];
+ if (msg == XEMBED_FOCUS_IN || msg == XEMBED_FOCUS_OUT)
+ x_detect_focus_change (dpyinfo, &event, &inev.ie);
+
+ *finish = X_EVENT_GOTO_OUT;
+ goto done;
+ }
+
f = x_any_window_to_frame (dpyinfo, event.xclient.window);
if (!f)
goto OTHER;
kbd_buffer_store_event_hold (&inev.ie, hold_quit);
}
- /* Previous code updated count by nchars rather than nbytes,
- but that seems bogus to me. ++kfs */
- count += nbytes;
+ count += nchars;
inev.ie.kind = NO_EVENT; /* Already stored above. */
case ConfigureNotify:
f = x_top_window_to_frame (dpyinfo, event.xconfigure.window);
+#ifdef USE_GTK
+ if (!f
+ && (f = x_any_window_to_frame (dpyinfo, event.xconfigure.window))
+ && event.xconfigure.window == FRAME_X_WINDOW (f))
+ {
+ xg_frame_resized (f, event.xconfigure.width,
+ event.xconfigure.height);
+ f = 0;
+ }
+#endif
if (f)
{
#ifndef USE_X_TOOLKIT
-#ifdef USE_GTK
- xg_resize_widgets (f, event.xconfigure.width,
- event.xconfigure.height);
-#else /* not USE_GTK */
+#ifndef USE_GTK
/* If there is a pending resize for fullscreen, don't
do this one, the right one will come later.
The toolkit version doesn't seem to need this, but we
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
}
-#endif /* not USE_GTK */
-#endif
FRAME_PIXEL_WIDTH (f) = event.xconfigure.width;
FRAME_PIXEL_HEIGHT (f) = event.xconfigure.height;
+#endif /* not USE_GTK */
+#endif
#ifdef USE_GTK
/* GTK creates windows but doesn't map them.
else
construct_mouse_click (&inev.ie, &event.xbutton, f);
}
+ if (FRAME_X_EMBEDDED_P (f))
+ xembed_send_message (f, event.xbutton.time,
+ XEMBED_REQUEST_FOCUS, 0, 0, 0);
}
else
{
We return as soon as there are no more events to be read.
We return the number of characters stored into the buffer,
- thus pretending to be `read'.
+ thus pretending to be `read' (except the characters we store
+ in the keyboard buffer can be multibyte, so are not necessarily
+ C chars).
EXPECTED is nonzero if the caller knows input is available. */
int count = 0;
XEvent event;
int event_found = 0;
+#if 0
struct x_display_info *dpyinfo;
+#endif
if (interrupt_input_blocked)
{
if (terminal->display_info.x == XTread_socket_fake_io_error)
{
XTread_socket_fake_io_error = 0;
- x_io_error_quitter (dpyinfo->display);
+ x_io_error_quitter (terminal->display_info.x->display);
}
#if 0 /* This loop is a noop now. */
&& FRAME_X_P (XFRAME (minibuf_frame))
&& ! EQ (frame, minibuf_frame)
&& FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo)
- Fdelete_frame (frame, Qt);
+ Fdelete_frame (frame, Qnoelisp);
}
/* Now delete all remaining frames on the dead display.
/* Set this to t so that Fdelete_frame won't get confused
trying to find a replacement. */
FRAME_KBOARD (XFRAME (frame))->Vdefault_minibuffer_frame = Qt;
- Fdelete_frame (frame, Qt);
+ Fdelete_frame (frame, Qnoelisp);
}
/* We have to close the display to inform Xt that it doesn't
M-x make-frame-on-display RET :1 RET
will indefinitely wait in Xt for events for display `:1', opened
- in the first class to make-frame-on-display.
+ 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. */
-#ifdef USE_X_TOOLKIT
- /* If DPYINFO is null, this means we didn't open the display
- in the first place, so don't try to close it. */
if (dpyinfo)
{
- extern void (*fatal_error_signal_hook) P_ ((void));
- fatal_error_signal_hook = x_fatal_error_signal;
- XtCloseDisplay (dpy);
- fatal_error_signal_hook = NULL;
- }
+#ifdef USE_X_TOOLKIT
+ /* If DPYINFO is null, this means we didn't open the display
+ in the first place, so don't try to close it. */
+ {
+ extern void (*fatal_error_signal_hook) P_ ((void));
+ fatal_error_signal_hook = x_fatal_error_signal;
+ XtCloseDisplay (dpy);
+ fatal_error_signal_hook = NULL;
+ }
#endif
#ifdef USE_GTK
- if (dpyinfo)
- xg_display_close (dpyinfo->display);
+ /* Due to bugs in some Gtk+ versions, just exit here if this
+ is the last display/terminal. */
+ if (terminal_list->next_terminal == NULL)
+ {
+ fprintf (stderr, "%s\n", error_msg);
+ shut_down_emacs (0, 0, Qnil);
+ exit (70);
+ }
+ xg_display_close (dpyinfo->display);
#endif
- if (dpyinfo)
- {
/* Indicate that this display is dead. */
dpyinfo->display = 0;
/* We have just closed all frames on this display. */
abort ();
- x_delete_display (dpyinfo);
+ {
+ Lisp_Object tmp;
+ XSETTERMINAL (tmp, dpyinfo->terminal);
+ Fdelete_terminal (tmp, Qnoelisp);
+ }
}
x_uncatch_errors ();
unbind_to (index, Qnil);
clear_waiting_for_input ();
- /* FIXME: This is an asynchronous interrupt w.r.t elisp, so signalling an
- error might not be the best thing to do. I'd vote for creating an
- elisp event and stuffing it in the queue so people can bind to it via
- the global map. --Stef */
+ /* 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'. */
error ("%s", error_msg);
}
/* Now make the frame display the given font. */
if (FRAME_X_WINDOW (f) != 0)
{
- XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
- FRAME_FONT (f)->fid);
- XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc,
- FRAME_FONT (f)->fid);
- XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc,
- FRAME_FONT (f)->fid);
+ Font fid;
+
+#ifdef USE_FONT_BACKEND
+ if (enable_font_backend)
+ fid = FRAME_X_DISPLAY_INFO (f)->font->fid;
+ else
+#endif
+ fid = FRAME_FONT (f)->fid;
+ XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc, fid);
+ XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc, fid);
+ XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, fid);
/* Don't change the size of a tip frame; there's no point in
doing it because it's done in Fx_show_tip, and it leads to
{
int modified_top, modified_left;
- if (change_gravity != 0)
+ if (change_gravity > 0)
{
FRAME_X_OUTPUT (f)->left_before_move = f->left_pos;
FRAME_X_OUTPUT (f)->top_before_move = f->top_pos;
x_lower_frame (f);
}
\f
+/* XEmbed implementation. */
+
+void
+xembed_set_info (f, flags)
+ struct frame *f;
+ enum xembed_info flags;
+{
+ Atom atom;
+ unsigned long data[2];
+
+ atom = XInternAtom (FRAME_X_DISPLAY (f), "_XEMBED_INFO", False);
+
+ data[0] = XEMBED_VERSION;
+ data[1] = flags;
+
+ XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), atom, atom,
+ 32, PropModeReplace, (unsigned char *) data, 2);
+}
+
+void
+xembed_send_message (f, time, message, detail, data1, data2)
+ struct frame *f;
+ Time time;
+ enum xembed_message message;
+ long detail;
+ long data1;
+ long data2;
+{
+ XEvent event;
+
+ event.xclient.type = ClientMessage;
+ 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[2] = detail;
+ event.xclient.data.l[3] = data1;
+ event.xclient.data.l[4] = data2;
+
+ XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_OUTPUT (f)->parent_desc,
+ False, NoEventMask, &event);
+ XSync (FRAME_X_DISPLAY (f), False);
+}
+\f
/* Change of visibility. */
/* This tries to wait until the frame is really visible.
if we get to x_make_frame_visible a second time
before the window gets really visible. */
if (! FRAME_ICONIFIED_P (f)
+ && ! FRAME_X_EMBEDDED_P (f)
&& ! f->output_data.x->asked_for_visible)
x_set_offset (f, f->left_pos, f->top_pos, 0);
if (! EQ (Vx_no_window_manager, Qt))
x_wm_set_window_state (f, NormalState);
#ifdef USE_X_TOOLKIT
- /* This was XtPopup, but that did nothing for an iconified frame. */
- XtMapWidget (f->output_data.x->widget);
+ if (FRAME_X_EMBEDDED_P (f))
+ xembed_set_info (f, XEMBED_MAPPED);
+ else
+ {
+ /* This was XtPopup, but that did nothing for an iconified frame. */
+ XtMapWidget (f->output_data.x->widget);
+ }
#else /* not USE_X_TOOLKIT */
#ifdef USE_GTK
gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
gtk_window_deiconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
#else
- XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+ if (FRAME_X_EMBEDDED_P (f))
+ xembed_set_info (f, XEMBED_MAPPED);
+ else
+ XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
#endif /* not USE_GTK */
#endif /* not USE_X_TOOLKIT */
#if 0 /* This seems to bring back scroll bars in the wrong places
because the window manager may choose the position
and we don't want to override it. */
- if (! FRAME_VISIBLE_P (f) && ! FRAME_ICONIFIED_P (f)
+ if (! FRAME_VISIBLE_P (f)
+ && ! FRAME_ICONIFIED_P (f)
+ && ! FRAME_X_EMBEDDED_P (f)
&& f->win_gravity == NorthWestGravity
&& previously_visible)
{
if (FRAME_GTK_OUTER_WIDGET (f))
gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
else
+#else
+ if (FRAME_X_EMBEDDED_P (f))
+ xembed_set_info (f, 0);
+ else
#endif
{
/* Make sure the X server knows where the window should be positioned,
in case the user deiconifies with the window manager. */
- if (! FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f))
+ if (! FRAME_VISIBLE_P (f)
+ && ! FRAME_ICONIFIED_P (f)
+ && ! FRAME_X_EMBEDDED_P (f))
x_set_offset (f, f->left_pos, f->top_pos, 0);
/* Since we don't know which revision of X we're running, we'll use both
dpyinfo->font_table = NULL;
dpyinfo->n_fonts = 0;
dpyinfo->font_table_size = 0;
+#ifdef USE_FONT_BACKEND
+ dpyinfo->font = XLoadQueryFont (dpyinfo->display, "fixed");
+ if (! dpyinfo->font)
+ dpyinfo->font = XLoadQueryFont (dpyinfo->display, "*");
+ if (! dpyinfo->font)
+ abort ();
+#endif /* USE_FONT_BACKEND */
dpyinfo->bitmaps = 0;
dpyinfo->bitmaps_size = 0;
dpyinfo->bitmaps_last = 0;
dpyinfo->x_focus_frame = 0;
dpyinfo->x_focus_event_frame = 0;
dpyinfo->x_highlight_frame = 0;
- dpyinfo->image_cache = make_image_cache ();
+ dpyinfo->terminal->image_cache = make_image_cache ();
dpyinfo->wm_type = X_WMTYPE_UNKNOWN;
/* See if we can construct pixel values from RGB values. */
dpyinfo->Xatom_Scrollbar = XInternAtom (dpyinfo->display, "SCROLLBAR",
False);
+ dpyinfo->Xatom_XEMBED = XInternAtom (dpyinfo->display, "_XEMBED",
+ False);
+
dpyinfo->cut_buffers_initialized = 0;
dpyinfo->x_dnd_atoms_size = 8;
add_keyboard_wait_descriptor (connection);
#endif
-#ifndef F_SETOWN_BUG
#ifdef F_SETOWN
-#ifdef F_SETOWN_SOCK_NEG
- /* stdin is a socket here */
- fcntl (connection, F_SETOWN, -getpid ());
-#else /* ! defined (F_SETOWN_SOCK_NEG) */
fcntl (connection, F_SETOWN, getpid ());
-#endif /* ! defined (F_SETOWN_SOCK_NEG) */
#endif /* ! defined (F_SETOWN) */
-#endif /* F_SETOWN_BUG */
#ifdef SIGIO
if (interrupt_input)
return;
BLOCK_INPUT;
+ /* If called from x_connection_closed, the display may already be closed
+ and dpyinfo->display was set to 0 to indicate that. */
+ if (dpyinfo->display)
+ {
#ifdef USE_FONT_BACKEND
- if (! enable_font_backend)
+ if (enable_font_backend)
+ XFreeFont (dpyinfo->display, dpyinfo->font);
+ else
#endif
- /* Free the fonts in the font table. */
- for (i = 0; i < dpyinfo->n_fonts; i++)
- if (dpyinfo->font_table[i].name)
- {
- XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font);
- }
+ /* Free the fonts in the font table. */
+ for (i = 0; i < dpyinfo->n_fonts; i++)
+ if (dpyinfo->font_table[i].name)
+ {
+ XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font);
+ }
- x_destroy_all_bitmaps (dpyinfo);
- XSetCloseDownMode (dpyinfo->display, DestroyAll);
+ x_destroy_all_bitmaps (dpyinfo);
+ XSetCloseDownMode (dpyinfo->display, DestroyAll);
#ifdef USE_GTK
- xg_display_close (dpyinfo->display);
+ xg_display_close (dpyinfo->display);
#else
#ifdef USE_X_TOOLKIT
- XtCloseDisplay (dpyinfo->display);
+ XtCloseDisplay (dpyinfo->display);
#else
- XCloseDisplay (dpyinfo->display);
+ XCloseDisplay (dpyinfo->display);
#endif
#endif /* ! USE_GTK */
+ }
x_delete_display (dpyinfo);
UNBLOCK_INPUT;