Mercurial > hg > xemacs-beta
diff src/event-Xt.c @ 442:abe6d1db359e r21-2-36
Import from CVS: tag r21-2-36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:35:02 +0200 |
parents | 8de8e3f6228a |
children | 576fb035e263 |
line wrap: on
line diff
--- a/src/event-Xt.c Mon Aug 13 11:33:40 2007 +0200 +++ b/src/event-Xt.c Mon Aug 13 11:35:02 2007 +0200 @@ -65,19 +65,8 @@ #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; @@ -97,10 +86,8 @@ /* 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; @@ -109,7 +96,7 @@ /* Mask of bits indicating the descriptors that we wait for input on */ extern SELECT_TYPE input_wait_mask, process_only_mask, tty_only_mask; -static CONST String x_fallback_resources[] = +static const String x_fallback_resources[] = { /* This file is automatically generated from the app-defaults file in ../etc/Emacs.ad. These resources are consulted only if no @@ -336,11 +323,17 @@ if (keysym < 0x80) /* Optimize for ASCII keysyms */ return; - /* If you do: xmodmap -e 'keysym NN = scaron' + + /* If you execute: + xmodmap -e 'keysym NN = scaron' and then press (Shift scaron), X11 will return the different - keysym Scaron, but xmodmap -pke might not even mention Scaron. - So we `register' both scaron and Scaron. */ + keysym `Scaron', but `xmodmap -pke' might not even mention `Scaron'. + So we "register" both `scaron' and `Scaron'. */ +#ifdef HAVE_XCONVERTCASE XConvertCase (keysym, &upper_lower[0], &upper_lower[1]); +#else + upper_lower[0] = upper_lower[1] = keysym; +#endif for (j = 0; j < (upper_lower[0] == upper_lower[1] ? 1 : 2); j++) { @@ -415,7 +408,7 @@ } } -static CONST char * +static const char * index_to_name (int indice) { switch (indice) @@ -570,7 +563,7 @@ be totally wrong. */ if (mode_bit) { - CONST char *warn = 0; + const char *warn = 0; if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0; else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0; else if (mode_bit == super_bit) warn = "Super", super_bit = 0; @@ -951,7 +944,11 @@ #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; @@ -989,7 +986,7 @@ #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) @@ -1118,7 +1115,7 @@ 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 = @@ -1145,11 +1142,30 @@ 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 @@ -1162,7 +1178,7 @@ lock_p = *state & LockMask; if (shift_p || lock_p) - modifiers |= MOD_SHIFT; + modifiers |= XEMACS_MOD_SHIFT; if (key_event_p) { @@ -1194,7 +1210,7 @@ ! (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 @@ -1206,13 +1222,13 @@ 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; @@ -1249,7 +1265,7 @@ { 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) @@ -1278,12 +1294,17 @@ 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; @@ -1299,7 +1320,9 @@ #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; @@ -1318,12 +1341,17 @@ 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; @@ -1457,6 +1485,7 @@ 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; @@ -1492,7 +1521,6 @@ #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))); @@ -1512,7 +1540,7 @@ 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 @@ -1716,6 +1744,25 @@ } 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 */ @@ -1828,6 +1875,9 @@ #endif break; + case CreateNotify: + break; + default: break; } @@ -2289,12 +2339,12 @@ 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"); } -static CONST char * +static const char * XEvent_mode_to_string (int mode) { switch (mode) @@ -2307,7 +2357,7 @@ } } -static CONST char * +static const char * XEvent_detail_to_string (int detail) { switch (detail) @@ -2323,7 +2373,7 @@ } } -static CONST char * +static const char * XEvent_visibility_to_string (int state) { switch (state) @@ -2385,7 +2435,7 @@ break; case Expose: - if (x_debug_events > 1) + if (debug_x_events > 1) { XExposeEvent *ev = &event->xexpose; describe_event_window (ev->window, ev->display); @@ -2398,7 +2448,7 @@ break; case GraphicsExpose: - if (x_debug_events > 1) + if (debug_x_events > 1) { XGraphicsExposeEvent *ev = &event->xgraphicsexpose; describe_event_window (ev->drawable, ev->display); @@ -2415,7 +2465,7 @@ 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); @@ -2436,7 +2486,7 @@ break; case ConfigureNotify: - if (x_debug_events > 1) + if (debug_x_events > 1) { XConfigureEvent *ev = &event->xconfigure; describe_event_window (ev->window, ev->display); @@ -2450,7 +2500,7 @@ break; case VisibilityNotify: - if (x_debug_events > 1) + if (debug_x_events > 1) { XVisibilityEvent *ev = &event->xvisibility; describe_event_window (ev->window, ev->display); @@ -2492,7 +2542,7 @@ 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); @@ -2613,7 +2663,7 @@ Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); #ifdef DEBUG_XEMACS - if (x_debug_events > 0) + if (debug_x_events > 0) { describe_event (event); } @@ -2897,6 +2947,21 @@ 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); + } +} + /************************************************************************/ /* replacement for standard string-to-pixel converter */ @@ -2994,9 +3059,9 @@ 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 { @@ -3058,6 +3123,42 @@ /************************************************************************/ +/* 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); +} + + +/************************************************************************/ /* initialization */ /************************************************************************/ @@ -3074,6 +3175,7 @@ { 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; @@ -3085,6 +3187,8 @@ 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); @@ -3104,15 +3208,6 @@ 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. @@ -3120,14 +3215,14 @@ 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 } @@ -3170,12 +3265,12 @@ 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); @@ -3192,6 +3287,8 @@ 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;