#include "events-mod.h"
static void enqueue_Xt_dispatch_event (Lisp_Object event);
+static void handle_focus_event_1 (struct frame *f, int in_p);
static struct event_stream *Xt_event_stream;
len = XmImMbLookupString (XtWindowToWidget (event->display, event->window),
event, bufptr, bufsiz, &keysym, &status);
#else /* XIM_XLIB */
- len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status);
+ if (xic)
+ len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status);
#endif /* HAVE_XIM */
#ifdef DEBUG_XEMACS
{
XButtonEvent *ev = &x_event->xbutton;
struct frame *frame = x_window_to_frame (d, ev->window);
+
if (! frame)
return 0; /* not for us */
XSETFRAME (emacs_event->channel, frame);
emacs_event->event.button.button = ev->button;
emacs_event->event.button.x = ev->x;
emacs_event->event.button.y = ev->y;
-
+ /* because we don't seem to get a FocusIn event for button clicks
+ when a widget-glyph is selected we will assume that we want the
+ focus if a button gets pressed. */
+ if (x_event->type == ButtonPress)
+ handle_focus_event_1 (frame, 1);
}
}
break;
static void
handle_focus_event_1 (struct frame *f, int in_p)
{
+#if XtSpecificationRelease > 5
+ Widget focus_widget = XtGetKeyboardFocusWidget (FRAME_X_TEXT_WIDGET (f));
+#endif
#ifdef HAVE_XIM
XIM_focus_event (f, in_p);
#endif /* HAVE_XIM */
Actually, we half handle it: we handle it as far as changing the
box cursor for redisplay, but we don't call any hooks or do any
select-frame stuff until after the sit-for.
- */
+
+ Unfortunately native widgets break the model because they grab
+ the keyboard focus and nothing sets it back again. I cannot find
+ any reasonable way to do this elsewhere so we assert here that
+ the keyboard focus is on the emacs text widget. Menus and dialogs
+ do this in their selection callback, but we don't want that since
+ a button having focus is legitimate. An edit field having focus
+ is mandatory. Weirdly you get a FocusOut event when you click in
+ a widget-glyph but you don't get a correspondng FocusIn when you
+ click in the frame. Why is this? */
+ if (in_p
+#if XtSpecificationRelease > 5
+ && FRAME_X_TEXT_WIDGET (f) != focus_widget
+#endif
+ )
+ {
+ lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f),
+ FRAME_X_TEXT_WIDGET (f));
+ }
+ /* do the generic event-stream stuff. */
{
Lisp_Object frm;
Lisp_Object conser;
/* Bleagh!!!!!! Apparently some window managers (e.g. MWM)
send synthetic MapNotify events when a window is first
- created, EVENT IF IT'S CREATED ICONIFIED OR INVISIBLE.
+ created, EVEN IF IT'S CREATED ICONIFIED OR INVISIBLE.
Or something like that. We initially tried a different
solution below, but that ran into a different window-
manager bug.
break;
case Expose:
- x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
- event->xexpose.width, event->xexpose.height);
+ if (!check_for_ignored_expose (f, event->xexpose.x, event->xexpose.y,
+ event->xexpose.width, event->xexpose.height)
+ &&
+ !find_matching_subwindow (f, event->xexpose.x, event->xexpose.y,
+ event->xexpose.width, event->xexpose.height))
+ x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
+ event->xexpose.width, event->xexpose.height);
break;
case GraphicsExpose: /* This occurs when an XCopyArea's source area was
case FocusIn:
case FocusOut:
+
#ifdef EXTERNAL_WIDGET
/* External widget lossage: Ben said:
YUCK. The only way to make focus changes work properly is to
/* Xt interval id's might not fit into an int (they're pointers, as it
happens), so we need to provide a conversion list. */
-struct Xt_timeout
+static struct Xt_timeout
{
int id;
XtIntervalId interval_id;
struct Xt_timeout *next;
} *pending_timeouts, *completed_timeouts;
-struct Xt_timeout_blocktype
+static struct Xt_timeout_blocktype
{
Blocktype_declare (struct Xt_timeout);
} *the_Xt_timeout_blocktype;
Xt_process_to_emacs_event (struct Lisp_Event *emacs_event)
{
int i;
- Lisp_Object process;
assert (process_events_occurred > 0);
+
for (i = 0; i < MAXDESC; i++)
{
- process = filedesc_with_input[i];
+ Lisp_Object process = filedesc_with_input[i];
if (PROCESSP (process))
- break;
+ {
+ filedesc_with_input[i] = Qnil;
+ process_events_occurred--;
+ /* process events have nil as channel */
+ emacs_event->event_type = process_event;
+ emacs_event->timestamp = 0; /* #### */
+ emacs_event->event.process.process = process;
+ return;
+ }
}
- assert (i < MAXDESC);
- filedesc_with_input[i] = Qnil;
- process_events_occurred--;
- /* process events have nil as channel */
- emacs_event->event_type = process_event;
- emacs_event->timestamp = 0; /* #### */
- emacs_event->event.process.process = process;
+ abort ();
}
static void
{
Lisp_Object console;
int infd;
-#ifdef HAVE_GPM
- int mousefd;
-#endif
if (CONSOLE_X_P (con))
return; /* X consoles are automatically selected for when we
infd = event_stream_unixoid_select_console (con);
XSETCONSOLE (console, con);
select_filedesc (infd, console);
-#ifdef HAVE_GPM
- /* On a stream device (ie: noninteractive), bad things can happen. */
- if (EQ (CONSOLE_TYPE (con), Qtty)) {
- mousefd = CONSOLE_TTY_MOUSE_FD (con);
- /* We check filedesc_to_what_closure[fd] here because if you run
- ** XEmacs from a TTY, it will fire up GPM, select the mouse fd, then
- ** if you run gnuattach to connect to another TTY, it will fire up
- ** GPM again, and try to reselect the mouse fd. GPM uses the same
- ** fd for every connection apparently, and select_filedesc will
- ** fail its assertion if we try to select it twice.
- */
- if ((mousefd >= 0) && !filedesc_to_what_closure[mousefd]) {
- select_filedesc (mousefd, console);
- }
- }
-#endif
}
static void
{
Lisp_Object console;
int infd;
-#ifdef HAVE_GPM
- int mousefd;
-#endif
if (CONSOLE_X_P (con))
return; /* X consoles are automatically selected for when we
infd = event_stream_unixoid_unselect_console (con);
XSETCONSOLE (console, con);
unselect_filedesc (infd);
-#ifdef HAVE_GPM
- /* On a stream device (ie: noninteractive), bad things can happen. */
- if (EQ (CONSOLE_TYPE (con), Qtty)) {
- mousefd = CONSOLE_TTY_MOUSE_FD (con);
- if (mousefd >= 0) {
- unselect_filedesc (mousefd);
- }
- }
-#endif
}
/* read an event from a tty, if one is available. Returns non-zero
}
void
-vars_of_event_Xt (void)
+reinit_vars_of_event_Xt (void)
{
- dispatch_event_queue = Qnil;
- staticpro (&dispatch_event_queue);
- dispatch_event_queue_tail = Qnil;
-
- /* this function only makes safe calls */
- init_what_input_once ();
-
Xt_event_stream = xnew (struct event_stream);
Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p;
Xt_event_stream->next_event_cb = emacs_Xt_next_event;
Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair;
Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair;
+ the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
+
+ last_quit_check_signal_tick_count = 0;
+
+ /* this function only makes safe calls */
+ init_what_input_once ();
+}
+
+void
+vars_of_event_Xt (void)
+{
+ reinit_vars_of_event_Xt ();
+
+ dispatch_event_queue = Qnil;
+ staticpro (&dispatch_event_queue);
+ dispatch_event_queue_tail = Qnil;
+ pdump_wire (&dispatch_event_queue_tail);
+
DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /*
*Non-nil makes modifier keys sticky.
This means that you can release the modifier key before pressing down
*/ );
x_debug_events = 0;
#endif
-
- the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
-
- last_quit_check_signal_tick_count = 0;
}
/* This mess is a hack that patches the shell widget to treat visual inheritance