#include "offix.h"
#endif
-#ifdef WINDOWSNT
-/* Hmm, under unix we want X modifiers, under NT we want X modifiers if
- we are running X and Windows modifiers otherwise.
- gak. This is a kludge until we support multiple native GUIs!
-*/
-#undef MOD_ALT
-#undef MOD_CONTROL
-#undef MOD_SHIFT
-#endif
-
#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;
/* Do we accept events sent by other clients? */
int x_allow_sendevents;
-int modifier_keys_are_sticky;
-
#ifdef DEBUG_XEMACS
-int x_debug_events;
+int debug_x_events;
#endif
static int process_events_occurred;
{ /* Not a modifier key */
Bool key_event_p = (type == KeyPress || type == KeyRelease);
- if (type == KeyPress && !xd->last_downkey)
- xd->last_downkey = keycode;
- else if (type == ButtonPress ||
- (type == KeyPress && xd->last_downkey &&
- (keycode != xd->last_downkey ||
- ev->xkey.time != xd->release_time)))
+ if (type == ButtonPress
+ || (type == KeyPress
+ && ((xd->last_downkey
+ && ((keycode != xd->last_downkey
+ || ev->xkey.time != xd->release_time)))
+ || (INTP (Vmodifier_keys_sticky_time)
+ && ev->xkey.time
+ > (xd->modifier_release_time
+ + XINT (Vmodifier_keys_sticky_time))))))
{
xd->need_to_add_mask = 0;
xd->last_downkey = 0;
}
+ else if (type == KeyPress && !xd->last_downkey)
+ xd->last_downkey = keycode;
+
if (type == KeyPress)
xd->release_time = 0;
if (type == KeyPress || type == ButtonPress)
- xd->down_mask = 0;
+ {
+ xd->down_mask = 0;
+ xd->modifier_release_time = 0;
+ }
if (key_event_p)
ev->xkey.state |= xd->need_to_add_mask;
So we assume that if the release and the next press
occur at the same time, the key was actually auto-
repeated. Under Open-Windows, at least, this works. */
- xd->release_time = key_event_p ? ev->xkey.time : ev->xbutton.time;
+ xd->modifier_release_time = xd->release_time
+ = key_event_p ? ev->xkey.time : ev->xbutton.time;
}
else /* Modifier key pressed */
{
xd->need_to_add_mask = 0;
}
+ if (xd->modifier_release_time
+ && INTP (Vmodifier_keys_sticky_time)
+ && (ev->xkey.time
+ > xd->modifier_release_time + XINT (Vmodifier_keys_sticky_time)))
+ {
+ xd->need_to_add_mask = 0;
+ xd->down_mask = 0;
+ }
+
#define FROB(mask) \
do { \
if (type == KeyPress) \
xd->need_to_add_mask |= mask; \
} \
} \
+ xd->modifier_release_time = ev->xkey.time; \
} while (0)
for (i = 0; i < xd->x_keysym_map_keysyms_per_code; i++)
#ifdef HAVE_XIM
int len;
- char buffer[64];
+ /* Some implementations of XmbLookupString don't return
+ XBufferOverflow correctly, so increase the size of the xim input
+ buffer from 64 to the more reasonable size 513, as Emacs has done.
+ From Kenichi Handa. */
+ char buffer[513];
char *bufptr = buffer;
int bufsiz = sizeof (buffer);
Status status;
#endif /* HAVE_XIM */
#ifdef DEBUG_XEMACS
- if (x_debug_events > 0)
+ if (debug_x_events > 0)
{
stderr_out (" status=");
#define print_status_when(S) if (status == S) stderr_out (#S)
case ButtonPress:
case ButtonRelease:
{
- unsigned int modifiers = 0;
+ int modifiers = 0;
int shift_p, lock_p;
Bool key_event_p = (x_event->type == KeyPress);
unsigned int *state =
x_handle_sticky_modifiers (x_event, d);
- if (*state & ControlMask) modifiers |= MOD_CONTROL;
- if (*state & xd->MetaMask) modifiers |= MOD_META;
- if (*state & xd->SuperMask) modifiers |= MOD_SUPER;
- if (*state & xd->HyperMask) modifiers |= MOD_HYPER;
- if (*state & xd->AltMask) modifiers |= MOD_ALT;
+ if (*state & ControlMask) modifiers |= XEMACS_MOD_CONTROL;
+ if (*state & xd->MetaMask) modifiers |= XEMACS_MOD_META;
+ if (*state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER;
+ if (*state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER;
+ if (*state & xd->AltMask) modifiers |= XEMACS_MOD_ALT;
+ {
+ int numero_de_botao = -1;
+
+ if (!key_event_p)
+ numero_de_botao = x_event->xbutton.button;
+
+ /* the button gets noted either in the button or the modifiers
+ field, but not both. */
+ if (numero_de_botao != 1 && (*state & Button1Mask))
+ modifiers |= XEMACS_MOD_BUTTON1;
+ if (numero_de_botao != 2 && (*state & Button2Mask))
+ modifiers |= XEMACS_MOD_BUTTON2;
+ if (numero_de_botao != 3 && (*state & Button3Mask))
+ modifiers |= XEMACS_MOD_BUTTON3;
+ if (numero_de_botao != 4 && (*state & Button4Mask))
+ modifiers |= XEMACS_MOD_BUTTON4;
+ if (numero_de_botao != 5 && (*state & Button5Mask))
+ modifiers |= XEMACS_MOD_BUTTON5;
+ }
/* Ignore the Caps_Lock key if:
- any other modifiers are down, so that Caps_Lock doesn't
lock_p = *state & LockMask;
if (shift_p || lock_p)
- modifiers |= MOD_SHIFT;
+ modifiers |= XEMACS_MOD_SHIFT;
if (key_event_p)
{
! (CHAR_OR_CHAR_INTP (keysym)
&& keysym_obeys_caps_lock_p
((KeySym) XCHAR_OR_CHAR_INT (keysym), d)))
- modifiers &= (~MOD_SHIFT);
+ modifiers &= (~XEMACS_MOD_SHIFT);
/* If this key contains two distinct keysyms, that is,
"shift" generates a different keysym than the
in the modifiers slot. Neither the characters "a",
"A", "2", nor "@" normally have the shift bit set.
However, "F1" normally does. */
- if (modifiers & MOD_SHIFT)
+ if (modifiers & XEMACS_MOD_SHIFT)
{
int Mode_switch_p = *state & xd->ModeMask;
KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0);
KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1);
if (top && bot && top != bot)
- modifiers &= ~MOD_SHIFT;
+ modifiers &= ~XEMACS_MOD_SHIFT;
}
emacs_event->event_type = key_press_event;
emacs_event->timestamp = ev->time;
{
XMotionEvent *ev = &x_event->xmotion;
struct frame *frame = x_window_to_frame (d, ev->window);
- unsigned int modifiers = 0;
+ int modifiers = 0;
XMotionEvent event2;
if (! frame)
emacs_event->timestamp = ev->time;
emacs_event->event.motion.x = ev->x;
emacs_event->event.motion.y = ev->y;
- if (ev->state & ShiftMask) modifiers |= MOD_SHIFT;
- if (ev->state & ControlMask) modifiers |= MOD_CONTROL;
- if (ev->state & xd->MetaMask) modifiers |= MOD_META;
- if (ev->state & xd->SuperMask) modifiers |= MOD_SUPER;
- if (ev->state & xd->HyperMask) modifiers |= MOD_HYPER;
- if (ev->state & xd->AltMask) modifiers |= MOD_ALT;
+ if (ev->state & ShiftMask) modifiers |= XEMACS_MOD_SHIFT;
+ if (ev->state & ControlMask) modifiers |= XEMACS_MOD_CONTROL;
+ if (ev->state & xd->MetaMask) modifiers |= XEMACS_MOD_META;
+ if (ev->state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER;
+ if (ev->state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER;
+ if (ev->state & xd->AltMask) modifiers |= XEMACS_MOD_ALT;
+ if (ev->state & Button1Mask) modifiers |= XEMACS_MOD_BUTTON1;
+ if (ev->state & Button2Mask) modifiers |= XEMACS_MOD_BUTTON2;
+ if (ev->state & Button3Mask) modifiers |= XEMACS_MOD_BUTTON3;
+ if (ev->state & Button4Mask) modifiers |= XEMACS_MOD_BUTTON4;
+ if (ev->state & Button5Mask) modifiers |= XEMACS_MOD_BUTTON5;
/* Currently ignores Shift_Lock but probably shouldn't
(but it definitely should ignore Caps_Lock). */
emacs_event->event.motion.modifiers = modifiers;
#ifdef HAVE_OFFIX_DND
if (DndIsDropMessage(x_event))
{
- unsigned int state, modifiers = 0, button=0;
+ unsigned int state;
+ int modifiers = 0;
+ unsigned int button=0;
struct frame *frame = x_any_window_to_frame (d, ev->window);
Extbyte *data;
unsigned long size, dtype;
Lisp_Object l_dndlist = Qnil, l_item = Qnil;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
- GCPRO4 (l_type, l_data, l_dndlist, l_item);
-
if (! frame)
return 0; /* not for us */
+
+ GCPRO4 (l_type, l_data, l_dndlist, l_item);
XSETFRAME (emacs_event->channel, frame);
emacs_event->event_type = misc_user_event;
state=DndDragButtons(x_event);
- if (state & ShiftMask) modifiers |= MOD_SHIFT;
- if (state & ControlMask) modifiers |= MOD_CONTROL;
- if (state & xd->MetaMask) modifiers |= MOD_META;
- if (state & xd->SuperMask) modifiers |= MOD_SUPER;
- if (state & xd->HyperMask) modifiers |= MOD_HYPER;
- if (state & xd->AltMask) modifiers |= MOD_ALT;
+ if (state & ShiftMask) modifiers |= XEMACS_MOD_SHIFT;
+ if (state & ControlMask) modifiers |= XEMACS_MOD_CONTROL;
+ if (state & xd->MetaMask) modifiers |= XEMACS_MOD_META;
+ if (state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER;
+ if (state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER;
+ if (state & xd->AltMask) modifiers |= XEMACS_MOD_ALT;
+ if (state & Button1Mask) modifiers |= XEMACS_MOD_BUTTON1;
+ if (state & Button2Mask) modifiers |= XEMACS_MOD_BUTTON2;
+ if (state & Button3Mask) modifiers |= XEMACS_MOD_BUTTON3;
+ if (state & Button4Mask) modifiers |= XEMACS_MOD_BUTTON4;
+ if (state & Button5Mask) modifiers |= XEMACS_MOD_BUTTON5;
if (state & Button5Mask) button = Button5;
if (state & Button4Mask) button = Button4;
case FocusIn:
case FocusOut: FROB(xfocus, window); break;
case VisibilityNotify: FROB(xvisibility, window); break;
+ case CreateNotify: FROB(xcreatewindow, window); break;
default:
w = x_event->xany.window;
*x_event_copy = *x_event;
#ifdef HAVE_XIM
XIM_focus_event (f, in_p);
#endif /* HAVE_XIM */
-
/* On focus change, clear all memory of sticky modifiers
to avoid non-intuitive behavior. */
clear_sticky_modifiers (XDEVICE (FRAME_DEVICE (f)));
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
+ a widget-glyph but you don't get a corresponding FocusIn when you
click in the frame. Why is this? */
if (in_p
#if XtSpecificationRelease > 5
}
static void
+emacs_Xt_force_event_pending (struct frame* f)
+{
+ XEvent event;
+
+ Display* dpy = DEVICE_X_DISPLAY (XDEVICE (FRAME_DEVICE (f)));
+ event.xclient.type = ClientMessage;
+ event.xclient.display = dpy;
+ event.xclient.message_type = XInternAtom (dpy, "BumpQueue", False);
+ event.xclient.format = 32;
+ event.xclient.window = 0;
+
+ /* Send the drop message */
+ XSendEvent(dpy, XtWindow (FRAME_X_SHELL_WIDGET (f)),
+ True, NoEventMask, &event);
+ /* Force event pending to check the X queue. */
+ quit_check_signal_tick_count++;
+}
+
+static void
emacs_Xt_handle_magic_event (Lisp_Event *emacs_event)
{
/* This function can GC */
#endif
break;
+ case CreateNotify:
+ break;
+
default:
break;
}
char *buf = alloca_array (char, XSTRING_LENGTH (f->name) + 4);
sprintf (buf, " \"%s\"", XSTRING_DATA (f->name));
write_string_to_stdio_stream (stderr, 0, (Bufbyte *) buf, 0,
- strlen (buf), Qterminal);
+ strlen (buf), Qterminal, 1);
}
stderr_out ("\n");
}
break;
case Expose:
- if (x_debug_events > 1)
+ if (debug_x_events > 1)
{
XExposeEvent *ev = &event->xexpose;
describe_event_window (ev->window, ev->display);
break;
case GraphicsExpose:
- if (x_debug_events > 1)
+ if (debug_x_events > 1)
{
XGraphicsExposeEvent *ev = &event->xgraphicsexpose;
describe_event_window (ev->drawable, ev->display);
case EnterNotify:
case LeaveNotify:
- if (x_debug_events > 1)
+ if (debug_x_events > 1)
{
XCrossingEvent *ev = &event->xcrossing;
describe_event_window (ev->window, ev->display);
break;
case ConfigureNotify:
- if (x_debug_events > 1)
+ if (debug_x_events > 1)
{
XConfigureEvent *ev = &event->xconfigure;
describe_event_window (ev->window, ev->display);
break;
case VisibilityNotify:
- if (x_debug_events > 1)
+ if (debug_x_events > 1)
{
XVisibilityEvent *ev = &event->xvisibility;
describe_event_window (ev->window, ev->display);
static Lisp_Object dispatch_event_queue, dispatch_event_queue_tail;
-static void
+void
enqueue_Xt_dispatch_event (Lisp_Object event)
{
enqueue_event (event, &dispatch_event_queue, &dispatch_event_queue_tail);
Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
#ifdef DEBUG_XEMACS
- if (x_debug_events > 0)
+ if (debug_x_events > 0)
{
describe_event (event);
}
return 0;
}
+static int
+emacs_Xt_current_event_timestamp (struct console *c)
+{
+ /* semi-yuck. */
+ Lisp_Object devs = CONSOLE_DEVICE_LIST (c);
+
+ if (NILP (devs))
+ return 0;
+ else
+ {
+ struct device *d = XDEVICE (XCAR (devs));
+ return DEVICE_X_LAST_SERVER_TIMESTAMP (d);
+ }
+}
+
\f
/************************************************************************/
/* replacement for standard string-to-pixel converter */
if ((d = get_device_from_display_1(dpy))) {
visual = DEVICE_X_VISUAL(d);
if (colormap != DEVICE_X_COLORMAP(d)) {
- XtAppWarningMsg(the_app_con, "wierdColormap", "cvtStringToPixel",
+ XtAppWarningMsg(the_app_con, "weirdColormap", "cvtStringToPixel",
"XtToolkitWarning",
- "The colormap passed to cvtStringToPixel doesn't match the one registerd to the device.\n",
+ "The colormap passed to cvtStringToPixel doesn't match the one registered to the device.\n",
NULL, 0);
status = XAllocNamedColor(dpy, colormap, (char*)str, &screenColor, &exactColor);
} else {
\f
/************************************************************************/
+/* handle focus changes for native widgets */
+/************************************************************************/
+static void
+emacs_Xt_event_widget_focus_in (Widget w,
+ XEvent *event,
+ String *params,
+ Cardinal *num_params)
+{
+ struct frame* f =
+ x_any_widget_or_parent_to_frame (get_device_from_display (event->xany.display), w);
+
+ XtSetKeyboardFocus (FRAME_X_SHELL_WIDGET (f), w);
+}
+
+static void
+emacs_Xt_event_widget_focus_out (Widget w,
+ XEvent *event,
+ String *params,
+ Cardinal *num_params)
+{
+}
+
+static XtActionsRec widgetActionsList[] =
+{
+ {"widget-focus-in", emacs_Xt_event_widget_focus_in },
+ {"widget-focus-out", emacs_Xt_event_widget_focus_out },
+};
+
+static void
+emacs_Xt_event_add_widget_actions (XtAppContext ctx)
+{
+ XtAppAddActions (ctx, widgetActionsList, 2);
+}
+
+\f
+/************************************************************************/
/* initialization */
/************************************************************************/
{
Xt_event_stream = xnew (struct event_stream);
Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p;
+ Xt_event_stream->force_event_pending = emacs_Xt_force_event_pending;
Xt_event_stream->next_event_cb = emacs_Xt_next_event;
Xt_event_stream->handle_magic_event_cb = emacs_Xt_handle_magic_event;
Xt_event_stream->add_timeout_cb = emacs_Xt_add_timeout;
Xt_event_stream->quit_p_cb = emacs_Xt_quit_p;
Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair;
Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair;
+ Xt_event_stream->current_event_timestamp_cb =
+ emacs_Xt_current_event_timestamp;
the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
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
-the key that you wish to be modified. Although this is non-standard
-behavior, it is recommended because it reduces the strain on your hand,
-thus reducing the incidence of the dreaded Emacs-pinky syndrome.
-*/ );
- modifier_keys_are_sticky = 0;
-
DEFVAR_BOOL ("x-allow-sendevents", &x_allow_sendevents /*
*Non-nil means to allow synthetic events. Nil means they are ignored.
Beware: allowing emacs to process SendEvents opens a big security hole.
x_allow_sendevents = 0;
#ifdef DEBUG_XEMACS
- DEFVAR_INT ("x-debug-events", &x_debug_events /*
+ DEFVAR_INT ("debug-x-events", &debug_x_events /*
If non-zero, display debug information about X events that XEmacs sees.
Information is displayed on stderr. Currently defined values are:
1 == non-verbose output
2 == verbose output
*/ );
- x_debug_events = 0;
+ debug_x_events = 0;
#endif
}
Xt_app_con = XtCreateApplicationContext ();
XtAppSetFallbackResources (Xt_app_con, (String *) x_fallback_resources);
- /* In xselect.c */
+ /* In select-x.c */
x_selection_timeout = (XtAppGetSelectionTimeout (Xt_app_con) / 1000);
XSetErrorHandler (x_error_handler);
XSetIOErrorHandler (x_IO_error_handler);
-#ifndef WINDOWSNT
+#ifndef WIN32_NATIVE
XtAppAddInput (Xt_app_con, signal_event_pipe[0],
(XtPointer) (XtInputReadMask /* | XtInputExceptMask */),
Xt_what_callback, 0);
NULL, 0,
XtCacheByDisplay, EmacsFreeXIMStyles);
#endif /* XIM_XLIB */
+ /* Add extra actions to native widgets to handle focus and friends. */
+ emacs_Xt_event_add_widget_actions (Xt_app_con);
/* insert the visual inheritance patch/hack described above */
orig_shell_init_proc = shellClassRec.core_class.initialize;