Mercurial > hg > xemacs-beta
comparison 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 |
comparison
equal
deleted
inserted
replaced
441:72a7cfa4a488 | 442:abe6d1db359e |
---|---|
63 | 63 |
64 #if defined (HAVE_OFFIX_DND) | 64 #if defined (HAVE_OFFIX_DND) |
65 #include "offix.h" | 65 #include "offix.h" |
66 #endif | 66 #endif |
67 | 67 |
68 #ifdef WINDOWSNT | |
69 /* Hmm, under unix we want X modifiers, under NT we want X modifiers if | |
70 we are running X and Windows modifiers otherwise. | |
71 gak. This is a kludge until we support multiple native GUIs! | |
72 */ | |
73 #undef MOD_ALT | |
74 #undef MOD_CONTROL | |
75 #undef MOD_SHIFT | |
76 #endif | |
77 | |
78 #include "events-mod.h" | 68 #include "events-mod.h" |
79 | 69 |
80 static void enqueue_Xt_dispatch_event (Lisp_Object event); | |
81 static void handle_focus_event_1 (struct frame *f, int in_p); | 70 static void handle_focus_event_1 (struct frame *f, int in_p); |
82 | 71 |
83 static struct event_stream *Xt_event_stream; | 72 static struct event_stream *Xt_event_stream; |
84 | 73 |
85 /* With the new event model, all events go through XtDispatchEvent() | 74 /* With the new event model, all events go through XtDispatchEvent() |
95 XtAppContext Xt_app_con; | 84 XtAppContext Xt_app_con; |
96 | 85 |
97 /* Do we accept events sent by other clients? */ | 86 /* Do we accept events sent by other clients? */ |
98 int x_allow_sendevents; | 87 int x_allow_sendevents; |
99 | 88 |
100 int modifier_keys_are_sticky; | |
101 | |
102 #ifdef DEBUG_XEMACS | 89 #ifdef DEBUG_XEMACS |
103 int x_debug_events; | 90 int debug_x_events; |
104 #endif | 91 #endif |
105 | 92 |
106 static int process_events_occurred; | 93 static int process_events_occurred; |
107 static int tty_events_occurred; | 94 static int tty_events_occurred; |
108 | 95 |
109 /* Mask of bits indicating the descriptors that we wait for input on */ | 96 /* Mask of bits indicating the descriptors that we wait for input on */ |
110 extern SELECT_TYPE input_wait_mask, process_only_mask, tty_only_mask; | 97 extern SELECT_TYPE input_wait_mask, process_only_mask, tty_only_mask; |
111 | 98 |
112 static CONST String x_fallback_resources[] = | 99 static const String x_fallback_resources[] = |
113 { | 100 { |
114 /* This file is automatically generated from the app-defaults file | 101 /* This file is automatically generated from the app-defaults file |
115 in ../etc/Emacs.ad. These resources are consulted only if no | 102 in ../etc/Emacs.ad. These resources are consulted only if no |
116 app-defaults file is found at all. | 103 app-defaults file is found at all. |
117 */ | 104 */ |
334 KeySym upper_lower[2]; | 321 KeySym upper_lower[2]; |
335 int j; | 322 int j; |
336 | 323 |
337 if (keysym < 0x80) /* Optimize for ASCII keysyms */ | 324 if (keysym < 0x80) /* Optimize for ASCII keysyms */ |
338 return; | 325 return; |
339 /* If you do: xmodmap -e 'keysym NN = scaron' | 326 |
327 /* If you execute: | |
328 xmodmap -e 'keysym NN = scaron' | |
340 and then press (Shift scaron), X11 will return the different | 329 and then press (Shift scaron), X11 will return the different |
341 keysym Scaron, but xmodmap -pke might not even mention Scaron. | 330 keysym `Scaron', but `xmodmap -pke' might not even mention `Scaron'. |
342 So we `register' both scaron and Scaron. */ | 331 So we "register" both `scaron' and `Scaron'. */ |
332 #ifdef HAVE_XCONVERTCASE | |
343 XConvertCase (keysym, &upper_lower[0], &upper_lower[1]); | 333 XConvertCase (keysym, &upper_lower[0], &upper_lower[1]); |
334 #else | |
335 upper_lower[0] = upper_lower[1] = keysym; | |
336 #endif | |
344 | 337 |
345 for (j = 0; j < (upper_lower[0] == upper_lower[1] ? 1 : 2); j++) | 338 for (j = 0; j < (upper_lower[0] == upper_lower[1] ? 1 : 2); j++) |
346 { | 339 { |
347 char *name; | 340 char *name; |
348 keysym = upper_lower[j]; | 341 keysym = upper_lower[j]; |
413 x_has_keysym (keysym[j], hash_table, 1); | 406 x_has_keysym (keysym[j], hash_table, 1); |
414 } | 407 } |
415 } | 408 } |
416 } | 409 } |
417 | 410 |
418 static CONST char * | 411 static const char * |
419 index_to_name (int indice) | 412 index_to_name (int indice) |
420 { | 413 { |
421 switch (indice) | 414 switch (indice) |
422 { | 415 { |
423 case ShiftMapIndex: return "ModShift"; | 416 case ShiftMapIndex: return "ModShift"; |
568 interpret that bit as Meta, because we can't make XLookupString() | 561 interpret that bit as Meta, because we can't make XLookupString() |
569 not interpret it as Mode_switch; and interpreting it as both would | 562 not interpret it as Mode_switch; and interpreting it as both would |
570 be totally wrong. */ | 563 be totally wrong. */ |
571 if (mode_bit) | 564 if (mode_bit) |
572 { | 565 { |
573 CONST char *warn = 0; | 566 const char *warn = 0; |
574 if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0; | 567 if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0; |
575 else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0; | 568 else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0; |
576 else if (mode_bit == super_bit) warn = "Super", super_bit = 0; | 569 else if (mode_bit == super_bit) warn = "Super", super_bit = 0; |
577 else if (mode_bit == alt_bit) warn = "Alt", alt_bit = 0; | 570 else if (mode_bit == alt_bit) warn = "Alt", alt_bit = 0; |
578 if (warn) | 571 if (warn) |
949 { | 942 { |
950 KeySym keysym = 0; | 943 KeySym keysym = 0; |
951 | 944 |
952 #ifdef HAVE_XIM | 945 #ifdef HAVE_XIM |
953 int len; | 946 int len; |
954 char buffer[64]; | 947 /* Some implementations of XmbLookupString don't return |
948 XBufferOverflow correctly, so increase the size of the xim input | |
949 buffer from 64 to the more reasonable size 513, as Emacs has done. | |
950 From Kenichi Handa. */ | |
951 char buffer[513]; | |
955 char *bufptr = buffer; | 952 char *bufptr = buffer; |
956 int bufsiz = sizeof (buffer); | 953 int bufsiz = sizeof (buffer); |
957 Status status; | 954 Status status; |
958 #ifdef XIM_XLIB | 955 #ifdef XIM_XLIB |
959 XIC xic = FRAME_X_XIC (x_any_window_to_frame | 956 XIC xic = FRAME_X_XIC (x_any_window_to_frame |
987 if (xic) | 984 if (xic) |
988 len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status); | 985 len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status); |
989 #endif /* HAVE_XIM */ | 986 #endif /* HAVE_XIM */ |
990 | 987 |
991 #ifdef DEBUG_XEMACS | 988 #ifdef DEBUG_XEMACS |
992 if (x_debug_events > 0) | 989 if (debug_x_events > 0) |
993 { | 990 { |
994 stderr_out (" status="); | 991 stderr_out (" status="); |
995 #define print_status_when(S) if (status == S) stderr_out (#S) | 992 #define print_status_when(S) if (status == S) stderr_out (#S) |
996 print_status_when (XLookupKeySym); | 993 print_status_when (XLookupKeySym); |
997 print_status_when (XLookupBoth); | 994 print_status_when (XLookupBoth); |
1116 | 1113 |
1117 case KeyPress: | 1114 case KeyPress: |
1118 case ButtonPress: | 1115 case ButtonPress: |
1119 case ButtonRelease: | 1116 case ButtonRelease: |
1120 { | 1117 { |
1121 unsigned int modifiers = 0; | 1118 int modifiers = 0; |
1122 int shift_p, lock_p; | 1119 int shift_p, lock_p; |
1123 Bool key_event_p = (x_event->type == KeyPress); | 1120 Bool key_event_p = (x_event->type == KeyPress); |
1124 unsigned int *state = | 1121 unsigned int *state = |
1125 key_event_p ? &x_event->xkey.state : &x_event->xbutton.state; | 1122 key_event_p ? &x_event->xkey.state : &x_event->xbutton.state; |
1126 | 1123 |
1143 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d) = | 1140 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d) = |
1144 key_event_p ? x_event->xkey.time : x_event->xbutton.time; | 1141 key_event_p ? x_event->xkey.time : x_event->xbutton.time; |
1145 | 1142 |
1146 x_handle_sticky_modifiers (x_event, d); | 1143 x_handle_sticky_modifiers (x_event, d); |
1147 | 1144 |
1148 if (*state & ControlMask) modifiers |= MOD_CONTROL; | 1145 if (*state & ControlMask) modifiers |= XEMACS_MOD_CONTROL; |
1149 if (*state & xd->MetaMask) modifiers |= MOD_META; | 1146 if (*state & xd->MetaMask) modifiers |= XEMACS_MOD_META; |
1150 if (*state & xd->SuperMask) modifiers |= MOD_SUPER; | 1147 if (*state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER; |
1151 if (*state & xd->HyperMask) modifiers |= MOD_HYPER; | 1148 if (*state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER; |
1152 if (*state & xd->AltMask) modifiers |= MOD_ALT; | 1149 if (*state & xd->AltMask) modifiers |= XEMACS_MOD_ALT; |
1150 { | |
1151 int numero_de_botao = -1; | |
1152 | |
1153 if (!key_event_p) | |
1154 numero_de_botao = x_event->xbutton.button; | |
1155 | |
1156 /* the button gets noted either in the button or the modifiers | |
1157 field, but not both. */ | |
1158 if (numero_de_botao != 1 && (*state & Button1Mask)) | |
1159 modifiers |= XEMACS_MOD_BUTTON1; | |
1160 if (numero_de_botao != 2 && (*state & Button2Mask)) | |
1161 modifiers |= XEMACS_MOD_BUTTON2; | |
1162 if (numero_de_botao != 3 && (*state & Button3Mask)) | |
1163 modifiers |= XEMACS_MOD_BUTTON3; | |
1164 if (numero_de_botao != 4 && (*state & Button4Mask)) | |
1165 modifiers |= XEMACS_MOD_BUTTON4; | |
1166 if (numero_de_botao != 5 && (*state & Button5Mask)) | |
1167 modifiers |= XEMACS_MOD_BUTTON5; | |
1168 } | |
1153 | 1169 |
1154 /* Ignore the Caps_Lock key if: | 1170 /* Ignore the Caps_Lock key if: |
1155 - any other modifiers are down, so that Caps_Lock doesn't | 1171 - any other modifiers are down, so that Caps_Lock doesn't |
1156 turn C-x into C-X, which would suck. | 1172 turn C-x into C-X, which would suck. |
1157 - the event was a mouse event. */ | 1173 - the event was a mouse event. */ |
1160 | 1176 |
1161 shift_p = *state & ShiftMask; | 1177 shift_p = *state & ShiftMask; |
1162 lock_p = *state & LockMask; | 1178 lock_p = *state & LockMask; |
1163 | 1179 |
1164 if (shift_p || lock_p) | 1180 if (shift_p || lock_p) |
1165 modifiers |= MOD_SHIFT; | 1181 modifiers |= XEMACS_MOD_SHIFT; |
1166 | 1182 |
1167 if (key_event_p) | 1183 if (key_event_p) |
1168 { | 1184 { |
1169 Lisp_Object keysym; | 1185 Lisp_Object keysym; |
1170 XKeyEvent *ev = &x_event->xkey; | 1186 XKeyEvent *ev = &x_event->xkey; |
1192 /* !!#### maybe fix for Mule */ | 1208 /* !!#### maybe fix for Mule */ |
1193 if (lock_p && !shift_p && | 1209 if (lock_p && !shift_p && |
1194 ! (CHAR_OR_CHAR_INTP (keysym) | 1210 ! (CHAR_OR_CHAR_INTP (keysym) |
1195 && keysym_obeys_caps_lock_p | 1211 && keysym_obeys_caps_lock_p |
1196 ((KeySym) XCHAR_OR_CHAR_INT (keysym), d))) | 1212 ((KeySym) XCHAR_OR_CHAR_INT (keysym), d))) |
1197 modifiers &= (~MOD_SHIFT); | 1213 modifiers &= (~XEMACS_MOD_SHIFT); |
1198 | 1214 |
1199 /* If this key contains two distinct keysyms, that is, | 1215 /* If this key contains two distinct keysyms, that is, |
1200 "shift" generates a different keysym than the | 1216 "shift" generates a different keysym than the |
1201 non-shifted key, then don't apply the shift modifier | 1217 non-shifted key, then don't apply the shift modifier |
1202 bit: it's implicit. Otherwise, if there would be no | 1218 bit: it's implicit. Otherwise, if there would be no |
1204 and unshifted version of this key, apply the shift bit. | 1220 and unshifted version of this key, apply the shift bit. |
1205 Non-graphics, like Backspace and F1 get the shift bit | 1221 Non-graphics, like Backspace and F1 get the shift bit |
1206 in the modifiers slot. Neither the characters "a", | 1222 in the modifiers slot. Neither the characters "a", |
1207 "A", "2", nor "@" normally have the shift bit set. | 1223 "A", "2", nor "@" normally have the shift bit set. |
1208 However, "F1" normally does. */ | 1224 However, "F1" normally does. */ |
1209 if (modifiers & MOD_SHIFT) | 1225 if (modifiers & XEMACS_MOD_SHIFT) |
1210 { | 1226 { |
1211 int Mode_switch_p = *state & xd->ModeMask; | 1227 int Mode_switch_p = *state & xd->ModeMask; |
1212 KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0); | 1228 KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0); |
1213 KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1); | 1229 KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1); |
1214 if (top && bot && top != bot) | 1230 if (top && bot && top != bot) |
1215 modifiers &= ~MOD_SHIFT; | 1231 modifiers &= ~XEMACS_MOD_SHIFT; |
1216 } | 1232 } |
1217 emacs_event->event_type = key_press_event; | 1233 emacs_event->event_type = key_press_event; |
1218 emacs_event->timestamp = ev->time; | 1234 emacs_event->timestamp = ev->time; |
1219 emacs_event->event.key.modifiers = modifiers; | 1235 emacs_event->event.key.modifiers = modifiers; |
1220 emacs_event->event.key.keysym = keysym; | 1236 emacs_event->event.key.keysym = keysym; |
1247 | 1263 |
1248 case MotionNotify: | 1264 case MotionNotify: |
1249 { | 1265 { |
1250 XMotionEvent *ev = &x_event->xmotion; | 1266 XMotionEvent *ev = &x_event->xmotion; |
1251 struct frame *frame = x_window_to_frame (d, ev->window); | 1267 struct frame *frame = x_window_to_frame (d, ev->window); |
1252 unsigned int modifiers = 0; | 1268 int modifiers = 0; |
1253 XMotionEvent event2; | 1269 XMotionEvent event2; |
1254 | 1270 |
1255 if (! frame) | 1271 if (! frame) |
1256 return 0; /* not for us */ | 1272 return 0; /* not for us */ |
1257 | 1273 |
1276 XSETFRAME (emacs_event->channel, frame); | 1292 XSETFRAME (emacs_event->channel, frame); |
1277 emacs_event->event_type = pointer_motion_event; | 1293 emacs_event->event_type = pointer_motion_event; |
1278 emacs_event->timestamp = ev->time; | 1294 emacs_event->timestamp = ev->time; |
1279 emacs_event->event.motion.x = ev->x; | 1295 emacs_event->event.motion.x = ev->x; |
1280 emacs_event->event.motion.y = ev->y; | 1296 emacs_event->event.motion.y = ev->y; |
1281 if (ev->state & ShiftMask) modifiers |= MOD_SHIFT; | 1297 if (ev->state & ShiftMask) modifiers |= XEMACS_MOD_SHIFT; |
1282 if (ev->state & ControlMask) modifiers |= MOD_CONTROL; | 1298 if (ev->state & ControlMask) modifiers |= XEMACS_MOD_CONTROL; |
1283 if (ev->state & xd->MetaMask) modifiers |= MOD_META; | 1299 if (ev->state & xd->MetaMask) modifiers |= XEMACS_MOD_META; |
1284 if (ev->state & xd->SuperMask) modifiers |= MOD_SUPER; | 1300 if (ev->state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER; |
1285 if (ev->state & xd->HyperMask) modifiers |= MOD_HYPER; | 1301 if (ev->state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER; |
1286 if (ev->state & xd->AltMask) modifiers |= MOD_ALT; | 1302 if (ev->state & xd->AltMask) modifiers |= XEMACS_MOD_ALT; |
1303 if (ev->state & Button1Mask) modifiers |= XEMACS_MOD_BUTTON1; | |
1304 if (ev->state & Button2Mask) modifiers |= XEMACS_MOD_BUTTON2; | |
1305 if (ev->state & Button3Mask) modifiers |= XEMACS_MOD_BUTTON3; | |
1306 if (ev->state & Button4Mask) modifiers |= XEMACS_MOD_BUTTON4; | |
1307 if (ev->state & Button5Mask) modifiers |= XEMACS_MOD_BUTTON5; | |
1287 /* Currently ignores Shift_Lock but probably shouldn't | 1308 /* Currently ignores Shift_Lock but probably shouldn't |
1288 (but it definitely should ignore Caps_Lock). */ | 1309 (but it definitely should ignore Caps_Lock). */ |
1289 emacs_event->event.motion.modifiers = modifiers; | 1310 emacs_event->event.motion.modifiers = modifiers; |
1290 } | 1311 } |
1291 break; | 1312 break; |
1297 explicitly prohibits. */ | 1318 explicitly prohibits. */ |
1298 XClientMessageEvent *ev = &x_event->xclient; | 1319 XClientMessageEvent *ev = &x_event->xclient; |
1299 #ifdef HAVE_OFFIX_DND | 1320 #ifdef HAVE_OFFIX_DND |
1300 if (DndIsDropMessage(x_event)) | 1321 if (DndIsDropMessage(x_event)) |
1301 { | 1322 { |
1302 unsigned int state, modifiers = 0, button=0; | 1323 unsigned int state; |
1324 int modifiers = 0; | |
1325 unsigned int button=0; | |
1303 struct frame *frame = x_any_window_to_frame (d, ev->window); | 1326 struct frame *frame = x_any_window_to_frame (d, ev->window); |
1304 Extbyte *data; | 1327 Extbyte *data; |
1305 unsigned long size, dtype; | 1328 unsigned long size, dtype; |
1306 Lisp_Object l_type = Qnil, l_data = Qnil; | 1329 Lisp_Object l_type = Qnil, l_data = Qnil; |
1307 Lisp_Object l_dndlist = Qnil, l_item = Qnil; | 1330 Lisp_Object l_dndlist = Qnil, l_item = Qnil; |
1316 emacs_event->event_type = misc_user_event; | 1339 emacs_event->event_type = misc_user_event; |
1317 emacs_event->timestamp = DEVICE_X_LAST_SERVER_TIMESTAMP (d); | 1340 emacs_event->timestamp = DEVICE_X_LAST_SERVER_TIMESTAMP (d); |
1318 | 1341 |
1319 state=DndDragButtons(x_event); | 1342 state=DndDragButtons(x_event); |
1320 | 1343 |
1321 if (state & ShiftMask) modifiers |= MOD_SHIFT; | 1344 if (state & ShiftMask) modifiers |= XEMACS_MOD_SHIFT; |
1322 if (state & ControlMask) modifiers |= MOD_CONTROL; | 1345 if (state & ControlMask) modifiers |= XEMACS_MOD_CONTROL; |
1323 if (state & xd->MetaMask) modifiers |= MOD_META; | 1346 if (state & xd->MetaMask) modifiers |= XEMACS_MOD_META; |
1324 if (state & xd->SuperMask) modifiers |= MOD_SUPER; | 1347 if (state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER; |
1325 if (state & xd->HyperMask) modifiers |= MOD_HYPER; | 1348 if (state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER; |
1326 if (state & xd->AltMask) modifiers |= MOD_ALT; | 1349 if (state & xd->AltMask) modifiers |= XEMACS_MOD_ALT; |
1350 if (state & Button1Mask) modifiers |= XEMACS_MOD_BUTTON1; | |
1351 if (state & Button2Mask) modifiers |= XEMACS_MOD_BUTTON2; | |
1352 if (state & Button3Mask) modifiers |= XEMACS_MOD_BUTTON3; | |
1353 if (state & Button4Mask) modifiers |= XEMACS_MOD_BUTTON4; | |
1354 if (state & Button5Mask) modifiers |= XEMACS_MOD_BUTTON5; | |
1327 | 1355 |
1328 if (state & Button5Mask) button = Button5; | 1356 if (state & Button5Mask) button = Button5; |
1329 if (state & Button4Mask) button = Button4; | 1357 if (state & Button4Mask) button = Button4; |
1330 if (state & Button3Mask) button = Button3; | 1358 if (state & Button3Mask) button = Button3; |
1331 if (state & Button2Mask) button = Button2; | 1359 if (state & Button2Mask) button = Button2; |
1455 case EnterNotify: | 1483 case EnterNotify: |
1456 case LeaveNotify: FROB(xcrossing, window); break; | 1484 case LeaveNotify: FROB(xcrossing, window); break; |
1457 case FocusIn: | 1485 case FocusIn: |
1458 case FocusOut: FROB(xfocus, window); break; | 1486 case FocusOut: FROB(xfocus, window); break; |
1459 case VisibilityNotify: FROB(xvisibility, window); break; | 1487 case VisibilityNotify: FROB(xvisibility, window); break; |
1488 case CreateNotify: FROB(xcreatewindow, window); break; | |
1460 default: | 1489 default: |
1461 w = x_event->xany.window; | 1490 w = x_event->xany.window; |
1462 *x_event_copy = *x_event; | 1491 *x_event_copy = *x_event; |
1463 break; | 1492 break; |
1464 } | 1493 } |
1490 Widget focus_widget = XtGetKeyboardFocusWidget (FRAME_X_TEXT_WIDGET (f)); | 1519 Widget focus_widget = XtGetKeyboardFocusWidget (FRAME_X_TEXT_WIDGET (f)); |
1491 #endif | 1520 #endif |
1492 #ifdef HAVE_XIM | 1521 #ifdef HAVE_XIM |
1493 XIM_focus_event (f, in_p); | 1522 XIM_focus_event (f, in_p); |
1494 #endif /* HAVE_XIM */ | 1523 #endif /* HAVE_XIM */ |
1495 | |
1496 /* On focus change, clear all memory of sticky modifiers | 1524 /* On focus change, clear all memory of sticky modifiers |
1497 to avoid non-intuitive behavior. */ | 1525 to avoid non-intuitive behavior. */ |
1498 clear_sticky_modifiers (XDEVICE (FRAME_DEVICE (f))); | 1526 clear_sticky_modifiers (XDEVICE (FRAME_DEVICE (f))); |
1499 | 1527 |
1500 /* We don't want to handle the focus change now, because we might | 1528 /* We don't want to handle the focus change now, because we might |
1510 any reasonable way to do this elsewhere so we assert here that | 1538 any reasonable way to do this elsewhere so we assert here that |
1511 the keyboard focus is on the emacs text widget. Menus and dialogs | 1539 the keyboard focus is on the emacs text widget. Menus and dialogs |
1512 do this in their selection callback, but we don't want that since | 1540 do this in their selection callback, but we don't want that since |
1513 a button having focus is legitimate. An edit field having focus | 1541 a button having focus is legitimate. An edit field having focus |
1514 is mandatory. Weirdly you get a FocusOut event when you click in | 1542 is mandatory. Weirdly you get a FocusOut event when you click in |
1515 a widget-glyph but you don't get a correspondng FocusIn when you | 1543 a widget-glyph but you don't get a corresponding FocusIn when you |
1516 click in the frame. Why is this? */ | 1544 click in the frame. Why is this? */ |
1517 if (in_p | 1545 if (in_p |
1518 #if XtSpecificationRelease > 5 | 1546 #if XtSpecificationRelease > 5 |
1519 && FRAME_X_TEXT_WIDGET (f) != focus_widget | 1547 && FRAME_X_TEXT_WIDGET (f) != focus_widget |
1520 #endif | 1548 #endif |
1714 #endif | 1742 #endif |
1715 } | 1743 } |
1716 } | 1744 } |
1717 | 1745 |
1718 static void | 1746 static void |
1747 emacs_Xt_force_event_pending (struct frame* f) | |
1748 { | |
1749 XEvent event; | |
1750 | |
1751 Display* dpy = DEVICE_X_DISPLAY (XDEVICE (FRAME_DEVICE (f))); | |
1752 event.xclient.type = ClientMessage; | |
1753 event.xclient.display = dpy; | |
1754 event.xclient.message_type = XInternAtom (dpy, "BumpQueue", False); | |
1755 event.xclient.format = 32; | |
1756 event.xclient.window = 0; | |
1757 | |
1758 /* Send the drop message */ | |
1759 XSendEvent(dpy, XtWindow (FRAME_X_SHELL_WIDGET (f)), | |
1760 True, NoEventMask, &event); | |
1761 /* Force event pending to check the X queue. */ | |
1762 quit_check_signal_tick_count++; | |
1763 } | |
1764 | |
1765 static void | |
1719 emacs_Xt_handle_magic_event (Lisp_Event *emacs_event) | 1766 emacs_Xt_handle_magic_event (Lisp_Event *emacs_event) |
1720 { | 1767 { |
1721 /* This function can GC */ | 1768 /* This function can GC */ |
1722 XEvent *event = &emacs_event->event.magic.underlying_x_event; | 1769 XEvent *event = &emacs_event->event.magic.underlying_x_event; |
1723 struct frame *f = XFRAME (EVENT_CHANNEL (emacs_event)); | 1770 struct frame *f = XFRAME (EVENT_CHANNEL (emacs_event)); |
1824 | 1871 |
1825 case ConfigureNotify: | 1872 case ConfigureNotify: |
1826 #ifdef HAVE_XIM | 1873 #ifdef HAVE_XIM |
1827 XIM_SetGeometry (f); | 1874 XIM_SetGeometry (f); |
1828 #endif | 1875 #endif |
1876 break; | |
1877 | |
1878 case CreateNotify: | |
1829 break; | 1879 break; |
1830 | 1880 |
1831 default: | 1881 default: |
1832 break; | 1882 break; |
1833 } | 1883 } |
2287 if (f) | 2337 if (f) |
2288 { | 2338 { |
2289 char *buf = alloca_array (char, XSTRING_LENGTH (f->name) + 4); | 2339 char *buf = alloca_array (char, XSTRING_LENGTH (f->name) + 4); |
2290 sprintf (buf, " \"%s\"", XSTRING_DATA (f->name)); | 2340 sprintf (buf, " \"%s\"", XSTRING_DATA (f->name)); |
2291 write_string_to_stdio_stream (stderr, 0, (Bufbyte *) buf, 0, | 2341 write_string_to_stdio_stream (stderr, 0, (Bufbyte *) buf, 0, |
2292 strlen (buf), Qterminal); | 2342 strlen (buf), Qterminal, 1); |
2293 } | 2343 } |
2294 stderr_out ("\n"); | 2344 stderr_out ("\n"); |
2295 } | 2345 } |
2296 | 2346 |
2297 static CONST char * | 2347 static const char * |
2298 XEvent_mode_to_string (int mode) | 2348 XEvent_mode_to_string (int mode) |
2299 { | 2349 { |
2300 switch (mode) | 2350 switch (mode) |
2301 { | 2351 { |
2302 case NotifyNormal: return "Normal"; | 2352 case NotifyNormal: return "Normal"; |
2305 case NotifyWhileGrabbed: return "WhileGrabbed"; | 2355 case NotifyWhileGrabbed: return "WhileGrabbed"; |
2306 default: return "???"; | 2356 default: return "???"; |
2307 } | 2357 } |
2308 } | 2358 } |
2309 | 2359 |
2310 static CONST char * | 2360 static const char * |
2311 XEvent_detail_to_string (int detail) | 2361 XEvent_detail_to_string (int detail) |
2312 { | 2362 { |
2313 switch (detail) | 2363 switch (detail) |
2314 { | 2364 { |
2315 case NotifyAncestor: return "Ancestor"; | 2365 case NotifyAncestor: return "Ancestor"; |
2321 case NotifyDetailNone: return "DetailNone"; | 2371 case NotifyDetailNone: return "DetailNone"; |
2322 default: return "???"; | 2372 default: return "???"; |
2323 } | 2373 } |
2324 } | 2374 } |
2325 | 2375 |
2326 static CONST char * | 2376 static const char * |
2327 XEvent_visibility_to_string (int state) | 2377 XEvent_visibility_to_string (int state) |
2328 { | 2378 { |
2329 switch (state) | 2379 switch (state) |
2330 { | 2380 { |
2331 case VisibilityFullyObscured: return "FullyObscured"; | 2381 case VisibilityFullyObscured: return "FullyObscured"; |
2383 stderr_out (" keycode: 0x%x\n", ev->keycode); | 2433 stderr_out (" keycode: 0x%x\n", ev->keycode); |
2384 } | 2434 } |
2385 break; | 2435 break; |
2386 | 2436 |
2387 case Expose: | 2437 case Expose: |
2388 if (x_debug_events > 1) | 2438 if (debug_x_events > 1) |
2389 { | 2439 { |
2390 XExposeEvent *ev = &event->xexpose; | 2440 XExposeEvent *ev = &event->xexpose; |
2391 describe_event_window (ev->window, ev->display); | 2441 describe_event_window (ev->window, ev->display); |
2392 stderr_out (" region: x=%d y=%d width=%d height=%d\n", | 2442 stderr_out (" region: x=%d y=%d width=%d height=%d\n", |
2393 ev->x, ev->y, ev->width, ev->height); | 2443 ev->x, ev->y, ev->width, ev->height); |
2396 else | 2446 else |
2397 stderr_out ("\n"); | 2447 stderr_out ("\n"); |
2398 break; | 2448 break; |
2399 | 2449 |
2400 case GraphicsExpose: | 2450 case GraphicsExpose: |
2401 if (x_debug_events > 1) | 2451 if (debug_x_events > 1) |
2402 { | 2452 { |
2403 XGraphicsExposeEvent *ev = &event->xgraphicsexpose; | 2453 XGraphicsExposeEvent *ev = &event->xgraphicsexpose; |
2404 describe_event_window (ev->drawable, ev->display); | 2454 describe_event_window (ev->drawable, ev->display); |
2405 stderr_out (" major: %s\n", | 2455 stderr_out (" major: %s\n", |
2406 (ev ->major_code == X_CopyArea ? "CopyArea" : | 2456 (ev ->major_code == X_CopyArea ? "CopyArea" : |
2413 stderr_out ("\n"); | 2463 stderr_out ("\n"); |
2414 break; | 2464 break; |
2415 | 2465 |
2416 case EnterNotify: | 2466 case EnterNotify: |
2417 case LeaveNotify: | 2467 case LeaveNotify: |
2418 if (x_debug_events > 1) | 2468 if (debug_x_events > 1) |
2419 { | 2469 { |
2420 XCrossingEvent *ev = &event->xcrossing; | 2470 XCrossingEvent *ev = &event->xcrossing; |
2421 describe_event_window (ev->window, ev->display); | 2471 describe_event_window (ev->window, ev->display); |
2422 #if 0 | 2472 #if 0 |
2423 stderr_out(" subwindow: 0x%x\n", ev->subwindow); | 2473 stderr_out(" subwindow: 0x%x\n", ev->subwindow); |
2434 else | 2484 else |
2435 stderr_out("\n"); | 2485 stderr_out("\n"); |
2436 break; | 2486 break; |
2437 | 2487 |
2438 case ConfigureNotify: | 2488 case ConfigureNotify: |
2439 if (x_debug_events > 1) | 2489 if (debug_x_events > 1) |
2440 { | 2490 { |
2441 XConfigureEvent *ev = &event->xconfigure; | 2491 XConfigureEvent *ev = &event->xconfigure; |
2442 describe_event_window (ev->window, ev->display); | 2492 describe_event_window (ev->window, ev->display); |
2443 stderr_out(" above: 0x%lx\n", ev->above); | 2493 stderr_out(" above: 0x%lx\n", ev->above); |
2444 stderr_out(" size: %d %d %d %d\n", ev->x, ev->y, | 2494 stderr_out(" size: %d %d %d %d\n", ev->x, ev->y, |
2448 else | 2498 else |
2449 stderr_out("\n"); | 2499 stderr_out("\n"); |
2450 break; | 2500 break; |
2451 | 2501 |
2452 case VisibilityNotify: | 2502 case VisibilityNotify: |
2453 if (x_debug_events > 1) | 2503 if (debug_x_events > 1) |
2454 { | 2504 { |
2455 XVisibilityEvent *ev = &event->xvisibility; | 2505 XVisibilityEvent *ev = &event->xvisibility; |
2456 describe_event_window (ev->window, ev->display); | 2506 describe_event_window (ev->window, ev->display); |
2457 stderr_out(" state: %s\n", XEvent_visibility_to_string(ev->state)); | 2507 stderr_out(" state: %s\n", XEvent_visibility_to_string(ev->state)); |
2458 } | 2508 } |
2490 /* get the next event from Xt */ | 2540 /* get the next event from Xt */ |
2491 /************************************************************************/ | 2541 /************************************************************************/ |
2492 | 2542 |
2493 static Lisp_Object dispatch_event_queue, dispatch_event_queue_tail; | 2543 static Lisp_Object dispatch_event_queue, dispatch_event_queue_tail; |
2494 | 2544 |
2495 static void | 2545 void |
2496 enqueue_Xt_dispatch_event (Lisp_Object event) | 2546 enqueue_Xt_dispatch_event (Lisp_Object event) |
2497 { | 2547 { |
2498 enqueue_event (event, &dispatch_event_queue, &dispatch_event_queue_tail); | 2548 enqueue_event (event, &dispatch_event_queue, &dispatch_event_queue_tail); |
2499 } | 2549 } |
2500 | 2550 |
2611 Boolean *continue_to_dispatch /* unused */) | 2661 Boolean *continue_to_dispatch /* unused */) |
2612 { | 2662 { |
2613 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 2663 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
2614 | 2664 |
2615 #ifdef DEBUG_XEMACS | 2665 #ifdef DEBUG_XEMACS |
2616 if (x_debug_events > 0) | 2666 if (debug_x_events > 0) |
2617 { | 2667 { |
2618 describe_event (event); | 2668 describe_event (event); |
2619 } | 2669 } |
2620 #endif /* DEBUG_XEMACS */ | 2670 #endif /* DEBUG_XEMACS */ |
2621 if (x_event_to_emacs_event (event, XEVENT (emacs_event))) | 2671 if (x_event_to_emacs_event (event, XEVENT (emacs_event))) |
2895 } | 2945 } |
2896 | 2946 |
2897 return 0; | 2947 return 0; |
2898 } | 2948 } |
2899 | 2949 |
2950 static int | |
2951 emacs_Xt_current_event_timestamp (struct console *c) | |
2952 { | |
2953 /* semi-yuck. */ | |
2954 Lisp_Object devs = CONSOLE_DEVICE_LIST (c); | |
2955 | |
2956 if (NILP (devs)) | |
2957 return 0; | |
2958 else | |
2959 { | |
2960 struct device *d = XDEVICE (XCAR (devs)); | |
2961 return DEVICE_X_LAST_SERVER_TIMESTAMP (d); | |
2962 } | |
2963 } | |
2964 | |
2900 | 2965 |
2901 /************************************************************************/ | 2966 /************************************************************************/ |
2902 /* replacement for standard string-to-pixel converter */ | 2967 /* replacement for standard string-to-pixel converter */ |
2903 /************************************************************************/ | 2968 /************************************************************************/ |
2904 | 2969 |
2992 | 3057 |
2993 /* Originally called XAllocNamedColor() here. */ | 3058 /* Originally called XAllocNamedColor() here. */ |
2994 if ((d = get_device_from_display_1(dpy))) { | 3059 if ((d = get_device_from_display_1(dpy))) { |
2995 visual = DEVICE_X_VISUAL(d); | 3060 visual = DEVICE_X_VISUAL(d); |
2996 if (colormap != DEVICE_X_COLORMAP(d)) { | 3061 if (colormap != DEVICE_X_COLORMAP(d)) { |
2997 XtAppWarningMsg(the_app_con, "wierdColormap", "cvtStringToPixel", | 3062 XtAppWarningMsg(the_app_con, "weirdColormap", "cvtStringToPixel", |
2998 "XtToolkitWarning", | 3063 "XtToolkitWarning", |
2999 "The colormap passed to cvtStringToPixel doesn't match the one registerd to the device.\n", | 3064 "The colormap passed to cvtStringToPixel doesn't match the one registered to the device.\n", |
3000 NULL, 0); | 3065 NULL, 0); |
3001 status = XAllocNamedColor(dpy, colormap, (char*)str, &screenColor, &exactColor); | 3066 status = XAllocNamedColor(dpy, colormap, (char*)str, &screenColor, &exactColor); |
3002 } else { | 3067 } else { |
3003 status = XParseColor (dpy, colormap, (char*)str, &screenColor); | 3068 status = XParseColor (dpy, colormap, (char*)str, &screenColor); |
3004 if (status) { | 3069 if (status) { |
3056 } | 3121 } |
3057 } | 3122 } |
3058 | 3123 |
3059 | 3124 |
3060 /************************************************************************/ | 3125 /************************************************************************/ |
3126 /* handle focus changes for native widgets */ | |
3127 /************************************************************************/ | |
3128 static void | |
3129 emacs_Xt_event_widget_focus_in (Widget w, | |
3130 XEvent *event, | |
3131 String *params, | |
3132 Cardinal *num_params) | |
3133 { | |
3134 struct frame* f = | |
3135 x_any_widget_or_parent_to_frame (get_device_from_display (event->xany.display), w); | |
3136 | |
3137 XtSetKeyboardFocus (FRAME_X_SHELL_WIDGET (f), w); | |
3138 } | |
3139 | |
3140 static void | |
3141 emacs_Xt_event_widget_focus_out (Widget w, | |
3142 XEvent *event, | |
3143 String *params, | |
3144 Cardinal *num_params) | |
3145 { | |
3146 } | |
3147 | |
3148 static XtActionsRec widgetActionsList[] = | |
3149 { | |
3150 {"widget-focus-in", emacs_Xt_event_widget_focus_in }, | |
3151 {"widget-focus-out", emacs_Xt_event_widget_focus_out }, | |
3152 }; | |
3153 | |
3154 static void | |
3155 emacs_Xt_event_add_widget_actions (XtAppContext ctx) | |
3156 { | |
3157 XtAppAddActions (ctx, widgetActionsList, 2); | |
3158 } | |
3159 | |
3160 | |
3161 /************************************************************************/ | |
3061 /* initialization */ | 3162 /* initialization */ |
3062 /************************************************************************/ | 3163 /************************************************************************/ |
3063 | 3164 |
3064 void | 3165 void |
3065 syms_of_event_Xt (void) | 3166 syms_of_event_Xt (void) |
3072 void | 3173 void |
3073 reinit_vars_of_event_Xt (void) | 3174 reinit_vars_of_event_Xt (void) |
3074 { | 3175 { |
3075 Xt_event_stream = xnew (struct event_stream); | 3176 Xt_event_stream = xnew (struct event_stream); |
3076 Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p; | 3177 Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p; |
3178 Xt_event_stream->force_event_pending = emacs_Xt_force_event_pending; | |
3077 Xt_event_stream->next_event_cb = emacs_Xt_next_event; | 3179 Xt_event_stream->next_event_cb = emacs_Xt_next_event; |
3078 Xt_event_stream->handle_magic_event_cb = emacs_Xt_handle_magic_event; | 3180 Xt_event_stream->handle_magic_event_cb = emacs_Xt_handle_magic_event; |
3079 Xt_event_stream->add_timeout_cb = emacs_Xt_add_timeout; | 3181 Xt_event_stream->add_timeout_cb = emacs_Xt_add_timeout; |
3080 Xt_event_stream->remove_timeout_cb = emacs_Xt_remove_timeout; | 3182 Xt_event_stream->remove_timeout_cb = emacs_Xt_remove_timeout; |
3081 Xt_event_stream->select_console_cb = emacs_Xt_select_console; | 3183 Xt_event_stream->select_console_cb = emacs_Xt_select_console; |
3083 Xt_event_stream->select_process_cb = emacs_Xt_select_process; | 3185 Xt_event_stream->select_process_cb = emacs_Xt_select_process; |
3084 Xt_event_stream->unselect_process_cb = emacs_Xt_unselect_process; | 3186 Xt_event_stream->unselect_process_cb = emacs_Xt_unselect_process; |
3085 Xt_event_stream->quit_p_cb = emacs_Xt_quit_p; | 3187 Xt_event_stream->quit_p_cb = emacs_Xt_quit_p; |
3086 Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair; | 3188 Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair; |
3087 Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair; | 3189 Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair; |
3190 Xt_event_stream->current_event_timestamp_cb = | |
3191 emacs_Xt_current_event_timestamp; | |
3088 | 3192 |
3089 the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype); | 3193 the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype); |
3090 | 3194 |
3091 last_quit_check_signal_tick_count = 0; | 3195 last_quit_check_signal_tick_count = 0; |
3092 | 3196 |
3101 | 3205 |
3102 dispatch_event_queue = Qnil; | 3206 dispatch_event_queue = Qnil; |
3103 staticpro (&dispatch_event_queue); | 3207 staticpro (&dispatch_event_queue); |
3104 dispatch_event_queue_tail = Qnil; | 3208 dispatch_event_queue_tail = Qnil; |
3105 pdump_wire (&dispatch_event_queue_tail); | 3209 pdump_wire (&dispatch_event_queue_tail); |
3106 | |
3107 DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /* | |
3108 *Non-nil makes modifier keys sticky. | |
3109 This means that you can release the modifier key before pressing down | |
3110 the key that you wish to be modified. Although this is non-standard | |
3111 behavior, it is recommended because it reduces the strain on your hand, | |
3112 thus reducing the incidence of the dreaded Emacs-pinky syndrome. | |
3113 */ ); | |
3114 modifier_keys_are_sticky = 0; | |
3115 | 3210 |
3116 DEFVAR_BOOL ("x-allow-sendevents", &x_allow_sendevents /* | 3211 DEFVAR_BOOL ("x-allow-sendevents", &x_allow_sendevents /* |
3117 *Non-nil means to allow synthetic events. Nil means they are ignored. | 3212 *Non-nil means to allow synthetic events. Nil means they are ignored. |
3118 Beware: allowing emacs to process SendEvents opens a big security hole. | 3213 Beware: allowing emacs to process SendEvents opens a big security hole. |
3119 */ ); | 3214 */ ); |
3120 x_allow_sendevents = 0; | 3215 x_allow_sendevents = 0; |
3121 | 3216 |
3122 #ifdef DEBUG_XEMACS | 3217 #ifdef DEBUG_XEMACS |
3123 DEFVAR_INT ("x-debug-events", &x_debug_events /* | 3218 DEFVAR_INT ("debug-x-events", &debug_x_events /* |
3124 If non-zero, display debug information about X events that XEmacs sees. | 3219 If non-zero, display debug information about X events that XEmacs sees. |
3125 Information is displayed on stderr. Currently defined values are: | 3220 Information is displayed on stderr. Currently defined values are: |
3126 | 3221 |
3127 1 == non-verbose output | 3222 1 == non-verbose output |
3128 2 == verbose output | 3223 2 == verbose output |
3129 */ ); | 3224 */ ); |
3130 x_debug_events = 0; | 3225 debug_x_events = 0; |
3131 #endif | 3226 #endif |
3132 } | 3227 } |
3133 | 3228 |
3134 /* This mess is a hack that patches the shell widget to treat visual inheritance | 3229 /* This mess is a hack that patches the shell widget to treat visual inheritance |
3135 the same as colormap and depth inheritance */ | 3230 the same as colormap and depth inheritance */ |
3168 | 3263 |
3169 XtToolkitInitialize (); | 3264 XtToolkitInitialize (); |
3170 Xt_app_con = XtCreateApplicationContext (); | 3265 Xt_app_con = XtCreateApplicationContext (); |
3171 XtAppSetFallbackResources (Xt_app_con, (String *) x_fallback_resources); | 3266 XtAppSetFallbackResources (Xt_app_con, (String *) x_fallback_resources); |
3172 | 3267 |
3173 /* In xselect.c */ | 3268 /* In select-x.c */ |
3174 x_selection_timeout = (XtAppGetSelectionTimeout (Xt_app_con) / 1000); | 3269 x_selection_timeout = (XtAppGetSelectionTimeout (Xt_app_con) / 1000); |
3175 XSetErrorHandler (x_error_handler); | 3270 XSetErrorHandler (x_error_handler); |
3176 XSetIOErrorHandler (x_IO_error_handler); | 3271 XSetIOErrorHandler (x_IO_error_handler); |
3177 | 3272 |
3178 #ifndef WINDOWSNT | 3273 #ifndef WIN32_NATIVE |
3179 XtAppAddInput (Xt_app_con, signal_event_pipe[0], | 3274 XtAppAddInput (Xt_app_con, signal_event_pipe[0], |
3180 (XtPointer) (XtInputReadMask /* | XtInputExceptMask */), | 3275 (XtPointer) (XtInputReadMask /* | XtInputExceptMask */), |
3181 Xt_what_callback, 0); | 3276 Xt_what_callback, 0); |
3182 #endif | 3277 #endif |
3183 | 3278 |
3190 XtAppSetTypeConverter (Xt_app_con, XtRString, XtRXimStyles, | 3285 XtAppSetTypeConverter (Xt_app_con, XtRString, XtRXimStyles, |
3191 EmacsXtCvtStringToXIMStyles, | 3286 EmacsXtCvtStringToXIMStyles, |
3192 NULL, 0, | 3287 NULL, 0, |
3193 XtCacheByDisplay, EmacsFreeXIMStyles); | 3288 XtCacheByDisplay, EmacsFreeXIMStyles); |
3194 #endif /* XIM_XLIB */ | 3289 #endif /* XIM_XLIB */ |
3290 /* Add extra actions to native widgets to handle focus and friends. */ | |
3291 emacs_Xt_event_add_widget_actions (Xt_app_con); | |
3195 | 3292 |
3196 /* insert the visual inheritance patch/hack described above */ | 3293 /* insert the visual inheritance patch/hack described above */ |
3197 orig_shell_init_proc = shellClassRec.core_class.initialize; | 3294 orig_shell_init_proc = shellClassRec.core_class.initialize; |
3198 shellClassRec.core_class.initialize = ShellVisualPatch; | 3295 shellClassRec.core_class.initialize = ShellVisualPatch; |
3199 | 3296 |