462
+ − 1 /* The event_stream interface for X11 with gtk, and/or tty frames.
+ − 2 Copyright (C) 1991-5, 1997 Free Software Foundation, Inc.
+ − 3 Copyright (C) 1995 Sun Microsystems, Inc.
1268
+ − 4 Copyright (C) 1996, 2001, 2002, 2003 Ben Wing.
462
+ − 5 Copyright (C) 2000 William Perry.
+ − 6
+ − 7 This file is part of XEmacs.
+ − 8
+ − 9 XEmacs is free software; you can redistribute it and/or modify it
+ − 10 under the terms of the GNU General Public License as published by the
+ − 11 Free Software Foundation; either version 2, or (at your option) any
+ − 12 later version.
+ − 13
+ − 14 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 17 for more details.
+ − 18
+ − 19 You should have received a copy of the GNU General Public License
+ − 20 along with XEmacs; see the file COPYING. If not, write to
+ − 21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 22 Boston, MA 02111-1307, USA. */
+ − 23
+ − 24 /* This file is heavily based upon event-Xt.c */
+ − 25
+ − 26 /* Synched up with: Not in FSF. */
+ − 27
+ − 28 #include <config.h>
+ − 29 #include "lisp.h"
+ − 30
+ − 31 #include "blocktype.h"
+ − 32 #include "buffer.h"
+ − 33 #include "commands.h"
+ − 34 #include "console.h"
872
+ − 35 #include "device-impl.h"
+ − 36 #include "elhash.h"
462
+ − 37 #include "events.h"
872
+ − 38 #include "file-coding.h"
+ − 39 #include "frame-impl.h"
+ − 40 #include "lstream.h"
462
+ − 41 #include "process.h"
+ − 42 #include "redisplay.h"
809
+ − 43 #include "window.h"
872
+ − 44
+ − 45 #include "console-tty.h"
+ − 46
+ − 47 #include "console-gtk-impl.h"
+ − 48 #include "objects-gtk.h"
462
+ − 49
+ − 50 #include "gtk-xemacs.h"
+ − 51
+ − 52 #include "systime.h"
+ − 53 #include "sysproc.h" /* for MAXDESC */
+ − 54
+ − 55 #include <gdk/gdkkeysyms.h>
+ − 56
+ − 57 #ifdef HAVE_DRAGNDROP
+ − 58 #include "dragdrop.h"
+ − 59 #endif
+ − 60
2081
+ − 61 #ifdef HAVE_MENUBARS
+ − 62 # include "menubar.h"
+ − 63 #endif
+ − 64
462
+ − 65 #if defined (HAVE_OFFIX_DND)
+ − 66 #include "offix.h"
+ − 67 #endif
+ − 68
778
+ − 69 #include <gdk/gdkx.h>
462
+ − 70
778
+ − 71 #include "event-gtk.h"
462
+ − 72
+ − 73 static struct event_stream *gtk_event_stream;
+ − 74
1292
+ − 75 #ifdef WIN32_ANY
+ − 76 extern int mswindows_is_blocking;
+ − 77 #endif
+ − 78
462
+ − 79 /* Do we accept events sent by other clients? */
+ − 80 int gtk_allow_sendevents;
+ − 81
+ − 82 static int process_events_occurred;
+ − 83 static int tty_events_occurred;
+ − 84
+ − 85 /* Mask of bits indicating the descriptors that we wait for input on */
1415
+ − 86 extern SELECT_TYPE input_wait_mask, non_fake_input_wait_mask;
+ − 87 extern SELECT_TYPE process_only_mask, tty_only_mask;
462
+ − 88
2054
+ − 89 static Lisp_Object gtk_keysym_to_emacs_keysym (guint keysym, int simple_p);
462
+ − 90 void debug_process_finalization (struct Lisp_Process *p);
+ − 91 gboolean emacs_gtk_event_handler (GtkWidget *wid /* unused */,
+ − 92 GdkEvent *event,
+ − 93 gpointer closure /* unused */);
+ − 94
+ − 95 static int last_quit_check_signal_tick_count;
+ − 96
+ − 97 Lisp_Object Qsans_modifiers;
+ − 98
2489
+ − 99 /*
+ − 100 * Identify if the keysym is a modifier. This implementation mirrors x.org's
+ − 101 * IsModifierKey(), but for GDK keysyms.
+ − 102 */
+ − 103 #ifdef GDK_ISO_Lock
+ − 104 #define IS_MODIFIER_KEY(keysym) \
+ − 105 ((((keysym) >= GDK_Shift_L) && ((keysym) <= GDK_Hyper_R)) \
+ − 106 || (((keysym) >= GDK_ISO_Lock) && \
+ − 107 ((keysym) <= GDK_ISO_Last_Group_Lock)) \
+ − 108 || ((keysym) == GDK_Mode_switch) \
+ − 109 || ((keysym) == GDK_Num_Lock))
+ − 110 #else
462
+ − 111 #define IS_MODIFIER_KEY(keysym) \
+ − 112 ((((keysym) >= GDK_Shift_L) && ((keysym) <= GDK_Hyper_R)) \
+ − 113 || ((keysym) == GDK_Mode_switch) \
+ − 114 || ((keysym) == GDK_Num_Lock))
2489
+ − 115 #endif
462
+ − 116
1268
+ − 117 #define THIS_IS_GTK
+ − 118 #include "event-xlike-inc.c"
462
+ − 119
+ − 120
+ − 121 /************************************************************************/
+ − 122 /* magic-event handling */
+ − 123 /************************************************************************/
+ − 124 static void
+ − 125 handle_focus_event_1 (struct frame *f, int in_p)
+ − 126 {
+ − 127 /* We don't want to handle the focus change now, because we might
+ − 128 be in an accept-process-output, sleep-for, or sit-for. So
+ − 129 we enqueue it.
+ − 130
+ − 131 Actually, we half handle it: we handle it as far as changing the
+ − 132 box cursor for redisplay, but we don't call any hooks or do any
+ − 133 select-frame stuff until after the sit-for.
+ − 134 */
+ − 135
+ − 136 if (in_p)
+ − 137 {
+ − 138 GTK_WIDGET_SET_FLAGS (FRAME_GTK_TEXT_WIDGET (f), GTK_HAS_FOCUS);
+ − 139 }
+ − 140 else
+ − 141 {
+ − 142 GTK_WIDGET_UNSET_FLAGS (FRAME_GTK_TEXT_WIDGET (f), GTK_HAS_FOCUS);
+ − 143 }
+ − 144 gtk_widget_grab_focus (FRAME_GTK_TEXT_WIDGET (f));
+ − 145 gtk_widget_draw_focus (FRAME_GTK_TEXT_WIDGET (f));
+ − 146
+ − 147 {
+ − 148 Lisp_Object frm;
+ − 149 Lisp_Object conser;
+ − 150 struct gcpro gcpro1;
+ − 151
793
+ − 152 frm = wrap_frame (f);
462
+ − 153 conser = Fcons (frm, Fcons (FRAME_DEVICE (f), in_p ? Qt : Qnil));
+ − 154 GCPRO1 (conser);
+ − 155
+ − 156 emacs_handle_focus_change_preliminary (conser);
+ − 157 enqueue_magic_eval_event (emacs_handle_focus_change_final,
+ − 158 conser);
+ − 159 UNGCPRO;
+ − 160 }
+ − 161 }
+ − 162
+ − 163 /* both GDK_MAP and GDK_VISIBILITY_NOTIFY can cause this
+ − 164 JV is_visible has the same semantics as f->visible*/
+ − 165 static void
+ − 166 change_frame_visibility (struct frame *f, int is_visible)
+ − 167 {
793
+ − 168 Lisp_Object frame = wrap_frame (f);
462
+ − 169
+ − 170
+ − 171 if (!FRAME_VISIBLE_P (f) && is_visible)
+ − 172 {
+ − 173 FRAME_VISIBLE_P (f) = is_visible;
872
+ − 174 /* [[ This improves the double flicker when uniconifying a frame
462
+ − 175 some. A lot of it is not showing a buffer which has changed
+ − 176 while the frame was iconified. To fix it further requires
872
+ − 177 the good 'ol double redisplay structure. ]] -- comment is
+ − 178 invalid, obviously predates 19.12, when the double redisplay
+ − 179 structure (i.e. current + desired) was put back in. --ben */
462
+ − 180 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
+ − 181 va_run_hook_with_args (Qmap_frame_hook, 1, frame);
+ − 182 }
+ − 183 else if (FRAME_VISIBLE_P (f) && !is_visible)
+ − 184 {
+ − 185 FRAME_VISIBLE_P (f) = 0;
+ − 186 va_run_hook_with_args (Qunmap_frame_hook, 1, frame);
+ − 187 }
+ − 188 else if (FRAME_VISIBLE_P (f) * is_visible < 0)
+ − 189 {
+ − 190 FRAME_VISIBLE_P(f) = - FRAME_VISIBLE_P(f);
+ − 191 if (FRAME_REPAINT_P (f))
+ − 192 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
+ − 193 va_run_hook_with_args (Qmap_frame_hook, 1, frame);
+ − 194 }
+ − 195 }
+ − 196
+ − 197 static void
+ − 198 handle_map_event (struct frame *f, GdkEvent *event)
+ − 199 {
793
+ − 200 Lisp_Object frame = wrap_frame (f);
462
+ − 201
+ − 202 if (event->any.type == GDK_MAP)
+ − 203 {
+ − 204 FRAME_GTK_TOTALLY_VISIBLE_P (f) = 1;
+ − 205 change_frame_visibility (f, 1);
+ − 206 }
+ − 207 else
+ − 208 {
+ − 209 FRAME_GTK_TOTALLY_VISIBLE_P (f) = 0;
+ − 210 change_frame_visibility (f, 0);
+ − 211 /* Calling Fframe_iconified_p is the only way we have to
+ − 212 correctly update FRAME_ICONIFIED_P */
+ − 213 Fframe_iconified_p (frame);
+ − 214 }
+ − 215 }
+ − 216
+ − 217 static void
+ − 218 handle_client_message (struct frame *f, GdkEvent *event)
+ − 219 {
+ − 220 /* The event-Xt code used to handle WM_DELETE_WINDOW here, but we
+ − 221 handle that directly in frame-gtk.c */
+ − 222
+ − 223 if (event->client.message_type == gdk_atom_intern ("WM_PROTOCOLS", 0) &&
+ − 224 (GdkAtom) event->client.data.l[0] == gdk_atom_intern ("WM_TAKE_FOCUS", 0))
+ − 225 {
+ − 226 handle_focus_event_1 (f, 1);
+ − 227 }
+ − 228 }
+ − 229
+ − 230 static void
788
+ − 231 emacs_gtk_format_magic_event (Lisp_Event *emacs_event, Lisp_Object pstream)
+ − 232 {
789
+ − 233 Lisp_Object console = CDFW_CONSOLE (EVENT_CHANNEL (emacs_event));
788
+ − 234 if (CONSOLE_GTK_P (XCONSOLE (console)))
826
+ − 235 write_c_string
+ − 236 (pstream,
1204
+ − 237 gtk_event_name (EVENT_MAGIC_GDK_EVENT (emacs_event).type));
788
+ − 238 }
+ − 239
+ − 240 static int
+ − 241 emacs_gtk_compare_magic_event (Lisp_Event *e1, Lisp_Event *e2)
+ − 242 {
+ − 243 if (CONSOLE_GTK_P (XCONSOLE (CDFW_CONSOLE (EVENT_CHANNEL (e1)))) &&
+ − 244 CONSOLE_GTK_P (XCONSOLE (CDFW_CONSOLE (EVENT_CHANNEL (e2)))))
1204
+ − 245 return (!memcmp (&EVENT_MAGIC_GDK_EVENT (e1),
+ − 246 &EVENT_MAGIC_GDK_EVENT (e2),
788
+ − 247 sizeof (GdkEvent)));
+ − 248 if (CONSOLE_GTK_P (XCONSOLE (CDFW_CONSOLE (EVENT_CHANNEL (e1)))) ||
+ − 249 CONSOLE_GTK_P (XCONSOLE (CDFW_CONSOLE (EVENT_CHANNEL (e2)))))
+ − 250 return 0;
+ − 251 return 1;
+ − 252 }
+ − 253
+ − 254 static Hashcode
+ − 255 emacs_gtk_hash_magic_event (Lisp_Event *e)
+ − 256 {
+ − 257 Lisp_Object console = CDFW_CONSOLE (EVENT_CHANNEL (e));
+ − 258 if (CONSOLE_GTK_P (XCONSOLE (console)))
1204
+ − 259 return memory_hash (&EVENT_MAGIC_GDK_EVENT (e),
788
+ − 260 sizeof (GdkEvent));
+ − 261 return 0;
+ − 262 }
+ − 263
+ − 264 static void
462
+ − 265 emacs_gtk_handle_magic_event (struct Lisp_Event *emacs_event)
+ − 266 {
+ − 267 /* This function can GC */
1204
+ − 268 GdkEvent *event = &EVENT_MAGIC_GDK_EVENT (emacs_event);
462
+ − 269 struct frame *f = XFRAME (EVENT_CHANNEL (emacs_event));
+ − 270
+ − 271 if (!FRAME_LIVE_P (f))
+ − 272 return;
+ − 273
+ − 274 switch (event->any.type)
+ − 275 {
+ − 276 case GDK_CLIENT_EVENT:
+ − 277 handle_client_message (f, event);
+ − 278 break;
+ − 279
+ − 280 case GDK_FOCUS_CHANGE:
+ − 281 handle_focus_event_1 (f, event->focus_change.in);
+ − 282 break;
+ − 283
+ − 284 case GDK_MAP:
+ − 285 case GDK_UNMAP:
+ − 286 handle_map_event (f, event);
+ − 287 break;
+ − 288
+ − 289 case GDK_ENTER_NOTIFY:
+ − 290 if (event->crossing.detail != GDK_NOTIFY_INFERIOR)
+ − 291 {
793
+ − 292 Lisp_Object frame = wrap_frame (f);
462
+ − 293
+ − 294 /* FRAME_X_MOUSE_P (f) = 1; */
+ − 295 va_run_hook_with_args (Qmouse_enter_frame_hook, 1, frame);
+ − 296 }
+ − 297 break;
+ − 298
+ − 299 case GDK_LEAVE_NOTIFY:
+ − 300 if (event->crossing.detail != GDK_NOTIFY_INFERIOR)
+ − 301 {
793
+ − 302 Lisp_Object frame = wrap_frame (f);
462
+ − 303
+ − 304 /* FRAME_X_MOUSE_P (f) = 0; */
+ − 305 va_run_hook_with_args (Qmouse_leave_frame_hook, 1, frame);
+ − 306 }
+ − 307 break;
+ − 308
+ − 309 case GDK_VISIBILITY_NOTIFY: /* window visiblity has changed */
+ − 310 if (event->visibility.window == GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f)))
+ − 311 {
+ − 312 FRAME_GTK_TOTALLY_VISIBLE_P (f) =
+ − 313 (event->visibility.state == GDK_VISIBILITY_UNOBSCURED);
+ − 314 /* Note that the fvwm pager only sends VisibilityNotify when
+ − 315 changing pages. Is this all we need to do ? JV */
+ − 316 /* Nope. We must at least trigger a redisplay here.
+ − 317 Since this case seems similar to MapNotify, I've
+ − 318 factored out some code to change_frame_visibility().
+ − 319 This triggers the necessary redisplay and runs
+ − 320 (un)map-frame-hook. - dkindred@cs.cmu.edu */
+ − 321 /* Changed it again to support the tristate visibility flag */
+ − 322 change_frame_visibility (f, (event->visibility.state
+ − 323 != GDK_VISIBILITY_FULLY_OBSCURED) ? 1 : -1);
+ − 324 }
+ − 325 break;
+ − 326
+ − 327 default:
+ − 328 break;
+ − 329 }
+ − 330 }
+ − 331
+ − 332 /************************************************************************/
+ − 333 /* Gtk to Emacs event conversion */
+ − 334 /************************************************************************/
+ − 335
+ − 336 static int
+ − 337 keysym_obeys_caps_lock_p (guint sym, struct device *d)
+ − 338 {
+ − 339 struct gtk_device *gd = DEVICE_GTK_DATA (d);
+ − 340 /* Eeeeevil hack. Don't apply Caps_Lock to things that aren't alphabetic
+ − 341 characters, where "alphabetic" means something more than simply A-Z.
+ − 342 That is, if Caps_Lock is down, typing ESC doesn't produce Shift-ESC.
+ − 343 But if shift-lock is down, then it does. */
+ − 344 if (gd->lock_interpretation == GDK_Shift_Lock)
+ − 345 return 1;
+ − 346
+ − 347 return
+ − 348 ((sym >= GDK_A) && (sym <= GDK_Z)) ||
+ − 349 ((sym >= GDK_a) && (sym <= GDK_z)) ||
+ − 350 ((sym >= GDK_Agrave) && (sym <= GDK_Odiaeresis)) ||
+ − 351 ((sym >= GDK_agrave) && (sym <= GDK_odiaeresis)) ||
+ − 352 ((sym >= GDK_Ooblique) && (sym <= GDK_Thorn)) ||
+ − 353 ((sym >= GDK_oslash) && (sym <= GDK_thorn));
+ − 354 }
+ − 355
+ − 356 static void
+ − 357 set_last_server_timestamp (struct device *d, GdkEvent *gdk_event)
+ − 358 {
+ − 359 guint32 t;
+ − 360 switch (gdk_event->type)
+ − 361 {
+ − 362 case GDK_KEY_PRESS:
+ − 363 case GDK_KEY_RELEASE: t = gdk_event->key.time; break;
+ − 364 case GDK_BUTTON_PRESS:
+ − 365 case GDK_2BUTTON_PRESS:
+ − 366 case GDK_3BUTTON_PRESS:
+ − 367 case GDK_BUTTON_RELEASE: t = gdk_event->button.time; break;
+ − 368 case GDK_ENTER_NOTIFY:
+ − 369 case GDK_LEAVE_NOTIFY: t = gdk_event->crossing.time; break;
+ − 370 case GDK_MOTION_NOTIFY: t = gdk_event->motion.time; break;
+ − 371 case GDK_PROPERTY_NOTIFY: t = gdk_event->property.time; break;
+ − 372 case GDK_SELECTION_CLEAR:
+ − 373 case GDK_SELECTION_REQUEST:
+ − 374 case GDK_SELECTION_NOTIFY: t = gdk_event->selection.time; break;
+ − 375 default: return;
+ − 376 }
+ − 377 DEVICE_GTK_LAST_SERVER_TIMESTAMP (d) = t;
+ − 378 }
+ − 379
+ − 380 static Lisp_Object
+ − 381 gtk_keysym_to_emacs_keysym (guint keysym, int simple_p)
+ − 382 {
+ − 383 char *name;
+ − 384 if (keysym >= GDK_exclam && keysym <= GDK_asciitilde)
+ − 385 /* We must assume that the X keysym numbers for the ASCII graphic
+ − 386 characters are the same as their ASCII codes. */
+ − 387 return make_char (keysym);
+ − 388
+ − 389 switch (keysym)
+ − 390 {
+ − 391 /* These would be handled correctly by the default case, but by
+ − 392 special-casing them here we don't garbage a string or call
+ − 393 intern(). */
+ − 394 case GDK_BackSpace: return QKbackspace;
+ − 395 case GDK_Tab: return QKtab;
+ − 396 case GDK_Linefeed: return QKlinefeed;
+ − 397 case GDK_Return: return QKreturn;
+ − 398 case GDK_Escape: return QKescape;
+ − 399 case GDK_space: return QKspace;
+ − 400 case GDK_Delete: return QKdelete;
+ − 401 case 0: return Qnil;
+ − 402 default:
+ − 403 if (simple_p) return Qnil;
+ − 404 /* !!#### not Mule-ized */
+ − 405 name = gdk_keyval_name (keysym);
+ − 406 if (!name || !name[0])
+ − 407 /* This happens if there is a mismatch between the Xlib of
+ − 408 XEmacs and the Xlib of the X server...
+ − 409
+ − 410 Let's hard-code in some knowledge of common keysyms introduced
+ − 411 in recent X11 releases. Snarfed from X11/keysymdef.h
+ − 412
+ − 413 Probably we should add some stuff here for X11R6. */
+ − 414 switch (keysym)
+ − 415 {
+ − 416 case 0xFF95: return KEYSYM ("kp-home");
+ − 417 case 0xFF96: return KEYSYM ("kp-left");
+ − 418 case 0xFF97: return KEYSYM ("kp-up");
+ − 419 case 0xFF98: return KEYSYM ("kp-right");
+ − 420 case 0xFF99: return KEYSYM ("kp-down");
+ − 421 case 0xFF9A: return KEYSYM ("kp-prior");
+ − 422 case 0xFF9B: return KEYSYM ("kp-next");
+ − 423 case 0xFF9C: return KEYSYM ("kp-end");
+ − 424 case 0xFF9D: return KEYSYM ("kp-begin");
+ − 425 case 0xFF9E: return KEYSYM ("kp-insert");
+ − 426 case 0xFF9F: return KEYSYM ("kp-delete");
+ − 427
+ − 428 case 0x1005FF10: return KEYSYM ("SunF36"); /* labeled F11 */
+ − 429 case 0x1005FF11: return KEYSYM ("SunF37"); /* labeled F12 */
+ − 430 default:
+ − 431 {
+ − 432 char buf [64];
+ − 433 sprintf (buf, "unknown-keysym-0x%X", (int) keysym);
+ − 434 return KEYSYM (buf);
+ − 435 }
+ − 436 }
+ − 437 /* If it's got a one-character name, that's good enough. */
+ − 438 if (!name[1])
+ − 439 return make_char (name[0]);
+ − 440
+ − 441 /* If it's in the "Keyboard" character set, downcase it.
+ − 442 The case of those keysyms is too totally random for us to
+ − 443 force anyone to remember them.
+ − 444 The case of the other character sets is significant, however.
+ − 445 */
+ − 446 if ((((unsigned int) keysym) & (~0x1FF)) == ((unsigned int) 0xFE00))
+ − 447 {
+ − 448 char buf [255];
+ − 449 char *s1, *s2;
+ − 450 for (s1 = name, s2 = buf; *s1; s1++, s2++) {
+ − 451 if (*s1 == '_') {
+ − 452 *s2 = '-';
+ − 453 } else {
+ − 454 *s2 = tolower (* (unsigned char *) s1);
+ − 455 }
+ − 456 }
+ − 457 *s2 = 0;
+ − 458 return KEYSYM (buf);
+ − 459 }
+ − 460 return KEYSYM (name);
+ − 461 }
+ − 462 }
+ − 463
+ − 464 static Lisp_Object
+ − 465 gtk_to_emacs_keysym (struct device *d, GdkEventKey *event, int simple_p)
+ − 466 /* simple_p means don't try too hard (ASCII only) */
+ − 467 {
+ − 468 if (event->length != 1)
771
+ − 469 {
462
+ − 470 /* Generate multiple emacs events */
867
+ − 471 Ichar ch;
462
+ − 472 Lisp_Object instream, fb_instream;
+ − 473 Lstream *istr;
+ − 474 struct gcpro gcpro1, gcpro2;
+ − 475
+ − 476 fb_instream =
771
+ − 477 make_fixed_buffer_input_stream ((unsigned char *) event->string, event->length);
462
+ − 478
771
+ − 479 /* #### Use get_coding_system_for_text_file
+ − 480 (Vcomposed_input_coding_system, 0) */
462
+ − 481 instream =
771
+ − 482 make_coding_input_stream (XLSTREAM (fb_instream),
800
+ − 483 Qundecided, CODING_DECODE, 0);
462
+ − 484
+ − 485 istr = XLSTREAM (instream);
+ − 486
+ − 487 GCPRO2 (instream, fb_instream);
867
+ − 488 while ((ch = Lstream_get_ichar (istr)) != EOF)
771
+ − 489 {
462
+ − 490 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
1204
+ − 491 Lisp_Event *ev = XEVENT (emacs_event);
+ − 492 ev->channel = DEVICE_CONSOLE (d);
462
+ − 493 ev->timestamp = event->time;
1204
+ − 494 XSET_EVENT_TYPE (emacs_event, key_press_event);
+ − 495 XSET_EVENT_KEY_MODIFIERS (emacs_event, 0);
+ − 496 XSET_EVENT_KEY_KEYSYM (emacs_event, make_char (ch));
+ − 497 enqueue_dispatch_event (emacs_event);
771
+ − 498 }
462
+ − 499 Lstream_close (istr);
+ − 500 UNGCPRO;
+ − 501 Lstream_delete (istr);
+ − 502 Lstream_delete (XLSTREAM (fb_instream));
+ − 503 if (IS_MODIFIER_KEY (event->keyval) || (event->keyval == GDK_Mode_switch))
771
+ − 504 return (Qnil);
462
+ − 505 return (gtk_keysym_to_emacs_keysym (event->keyval, simple_p));
771
+ − 506 }
462
+ − 507 else
771
+ − 508 {
462
+ − 509 if (IS_MODIFIER_KEY (event->keyval) || (event->keyval == GDK_Mode_switch))
771
+ − 510 return (Qnil);
462
+ − 511 return (gtk_keysym_to_emacs_keysym (event->keyval, simple_p));
771
+ − 512 }
462
+ − 513 }
+ − 514
+ − 515
+ − 516 /************************************************************************/
+ − 517 /* timeout events */
+ − 518 /************************************************************************/
+ − 519
+ − 520 static int timeout_id_tick;
+ − 521
853
+ − 522 struct GTK_timeout
+ − 523 {
+ − 524 int id;
+ − 525 guint timeout_id;
+ − 526 struct GTK_timeout *next;
462
+ − 527 } *pending_timeouts, *completed_timeouts;
+ − 528
+ − 529 struct GTK_timeout_blocktype
+ − 530 {
+ − 531 Blocktype_declare (struct GTK_timeout);
+ − 532 } *the_GTK_timeout_blocktype;
+ − 533
+ − 534 /* called by the gtk main loop */
+ − 535 static gint
+ − 536 gtk_timeout_callback (gpointer closure)
+ − 537 {
+ − 538 struct GTK_timeout *timeout = (struct GTK_timeout *) closure;
+ − 539 struct GTK_timeout *t2 = pending_timeouts;
+ − 540
+ − 541 /* Remove this one from the list of pending timeouts */
+ − 542 if (t2 == timeout)
+ − 543 pending_timeouts = pending_timeouts->next;
+ − 544 else
+ − 545 {
+ − 546 while (t2->next && t2->next != timeout) t2 = t2->next;
+ − 547 assert (t2->next);
+ − 548 t2->next = t2->next->next;
+ − 549 }
+ − 550 /* Add this one to the list of completed timeouts */
+ − 551 timeout->next = completed_timeouts;
+ − 552 completed_timeouts = timeout;
853
+ − 553 return FALSE;
462
+ − 554 }
+ − 555
+ − 556 static int
+ − 557 emacs_gtk_add_timeout (EMACS_TIME thyme)
+ − 558 {
+ − 559 struct GTK_timeout *timeout = Blocktype_alloc (the_GTK_timeout_blocktype);
+ − 560 EMACS_TIME current_time;
+ − 561 int milliseconds;
+ − 562
+ − 563 timeout->id = timeout_id_tick++;
+ − 564 timeout->next = pending_timeouts;
+ − 565 pending_timeouts = timeout;
+ − 566 EMACS_GET_TIME (current_time);
+ − 567 EMACS_SUB_TIME (thyme, thyme, current_time);
+ − 568 milliseconds = EMACS_SECS (thyme) * 1000 +
+ − 569 EMACS_USECS (thyme) / 1000;
+ − 570 if (milliseconds < 1)
+ − 571 milliseconds = 1;
+ − 572 timeout->timeout_id = gtk_timeout_add (milliseconds,
+ − 573 gtk_timeout_callback,
+ − 574 (gpointer) timeout);
+ − 575 return timeout->id;
+ − 576 }
+ − 577
+ − 578 static void
+ − 579 emacs_gtk_remove_timeout (int id)
+ − 580 {
+ − 581 struct GTK_timeout *timeout, *t2;
+ − 582
+ − 583 timeout = NULL;
+ − 584
+ − 585 /* Find the timeout on the list of pending ones, if it's still there. */
+ − 586 if (pending_timeouts)
+ − 587 {
+ − 588 if (id == pending_timeouts->id)
+ − 589 {
+ − 590 timeout = pending_timeouts;
+ − 591 pending_timeouts = pending_timeouts->next;
+ − 592 }
+ − 593 else
+ − 594 {
+ − 595 t2 = pending_timeouts;
+ − 596 while (t2->next && t2->next->id != id) t2 = t2->next;
+ − 597 if ( t2->next) /*found it */
+ − 598 {
+ − 599 timeout = t2->next;
+ − 600 t2->next = t2->next->next;
+ − 601 }
+ − 602 }
+ − 603 /* if it was pending, we have removed it from the list */
+ − 604 if (timeout)
+ − 605 gtk_timeout_remove (timeout->timeout_id);
+ − 606 }
+ − 607
+ − 608 /* It could be that the call back was already called but we didn't convert
+ − 609 into an Emacs event yet */
+ − 610 if (!timeout && completed_timeouts)
+ − 611 {
+ − 612 /* Code duplication! */
+ − 613 if (id == completed_timeouts->id)
+ − 614 {
+ − 615 timeout = completed_timeouts;
+ − 616 completed_timeouts = completed_timeouts->next;
+ − 617 }
+ − 618 else
+ − 619 {
+ − 620 t2 = completed_timeouts;
+ − 621 while (t2->next && t2->next->id != id) t2 = t2->next;
+ − 622 if ( t2->next) /*found it */
+ − 623 {
+ − 624 timeout = t2->next;
+ − 625 t2->next = t2->next->next;
+ − 626 }
+ − 627 }
+ − 628 }
+ − 629
+ − 630 /* If we found the thing on the lists of timeouts,
+ − 631 and removed it, deallocate
+ − 632 */
+ − 633 if (timeout)
+ − 634 Blocktype_free (the_GTK_timeout_blocktype, timeout);
+ − 635 }
+ − 636
+ − 637 static void
+ − 638 gtk_timeout_to_emacs_event (struct Lisp_Event *emacs_event)
+ − 639 {
+ − 640 struct GTK_timeout *timeout = completed_timeouts;
+ − 641 assert (timeout);
+ − 642 completed_timeouts = completed_timeouts->next;
+ − 643 /* timeout events have nil as channel */
1204
+ − 644 set_event_type (emacs_event, timeout_event);
+ − 645 SET_EVENT_TIMESTAMP_ZERO (emacs_event); /* #### wrong!! */
+ − 646 SET_EVENT_TIMEOUT_INTERVAL_ID (emacs_event, timeout->id);
+ − 647 SET_EVENT_TIMEOUT_FUNCTION (emacs_event, Qnil);
+ − 648 SET_EVENT_TIMEOUT_OBJECT (emacs_event, Qnil);
462
+ − 649 Blocktype_free (the_GTK_timeout_blocktype, timeout);
+ − 650 }
+ − 651
+ − 652
+ − 653 /************************************************************************/
+ − 654 /* process and tty events */
+ − 655 /************************************************************************/
+ − 656
+ − 657 struct what_is_ready_closure
+ − 658 {
+ − 659 int fd;
+ − 660 Lisp_Object what;
+ − 661 gint id;
+ − 662 };
+ − 663
+ − 664 static Lisp_Object *filedesc_with_input;
+ − 665 static struct what_is_ready_closure **filedesc_to_what_closure;
+ − 666
+ − 667 static void
+ − 668 init_what_input_once (void)
+ − 669 {
+ − 670 int i;
+ − 671
+ − 672 filedesc_with_input = xnew_array (Lisp_Object, MAXDESC);
+ − 673 filedesc_to_what_closure =
+ − 674 xnew_array (struct what_is_ready_closure *, MAXDESC);
+ − 675
+ − 676 for (i = 0; i < MAXDESC; i++)
+ − 677 {
+ − 678 filedesc_to_what_closure[i] = 0;
+ − 679 filedesc_with_input[i] = Qnil;
+ − 680 }
+ − 681
+ − 682 process_events_occurred = 0;
+ − 683 tty_events_occurred = 0;
+ − 684 }
+ − 685
+ − 686 static void
+ − 687 mark_what_as_being_ready (struct what_is_ready_closure *closure)
+ − 688 {
+ − 689 if (NILP (filedesc_with_input[closure->fd]))
+ − 690 {
+ − 691 SELECT_TYPE temp_mask;
+ − 692 FD_ZERO (&temp_mask);
+ − 693 FD_SET (closure->fd, &temp_mask);
+ − 694 /* Check to make sure there's *really* input available.
+ − 695 Sometimes things seem to get confused and this gets called
+ − 696 for the tty fd when there's really only input available
+ − 697 on some process's fd. (It will subsequently get called
+ − 698 for that process's fd, so returning without setting any
+ − 699 flags will take care of it.) To see the problem, uncomment
+ − 700 the stderr_out below, turn NORMAL_QUIT_CHECK_TIMEOUT_MSECS
+ − 701 down to 25, do sh -c 'xemacs -nw -q -f shell 2>/tmp/log'
+ − 702 and press return repeatedly. (Seen under AIX & Linux.)
+ − 703 -dkindred@cs.cmu.edu */
+ − 704 if (!poll_fds_for_input (temp_mask))
+ − 705 {
+ − 706 #if 0
+ − 707 stderr_out ("mark_what_as_being_ready: no input available (fd=%d)\n",
+ − 708 closure->fd);
+ − 709 #endif
+ − 710 return;
+ − 711 }
+ − 712 filedesc_with_input[closure->fd] = closure->what;
+ − 713 if (PROCESSP (closure->what))
853
+ − 714 /* Don't increment this if the current process is already marked
+ − 715 * as having input. */
+ − 716 process_events_occurred++;
462
+ − 717 else
853
+ − 718 tty_events_occurred++;
462
+ − 719 }
+ − 720 }
+ − 721
+ − 722 static void
2286
+ − 723 gtk_what_callback (gpointer closure, gint UNUSED (source),
+ − 724 GdkInputCondition UNUSED (why))
462
+ − 725 {
+ − 726 /* If closure is 0, then we got a fake event from a signal handler.
+ − 727 The only purpose of this is to make XtAppProcessEvent() stop
+ − 728 blocking. */
+ − 729 if (closure)
+ − 730 mark_what_as_being_ready ((struct what_is_ready_closure *) closure);
+ − 731 else
+ − 732 {
+ − 733 fake_event_occurred++;
+ − 734 drain_signal_event_pipe ();
+ − 735 }
+ − 736 }
+ − 737
+ − 738 static void
+ − 739 select_filedesc (int fd, Lisp_Object what)
+ − 740 {
+ − 741 struct what_is_ready_closure *closure;
+ − 742
+ − 743 /* If somebody is trying to select something that's already selected
+ − 744 for, then something went wrong. The generic routines ought to
+ − 745 detect this and error before here. */
+ − 746 assert (!filedesc_to_what_closure[fd]);
+ − 747
+ − 748 closure = xnew (struct what_is_ready_closure);
+ − 749 closure->fd = fd;
+ − 750 closure->what = what;
+ − 751 closure->id = gdk_input_add (fd, GDK_INPUT_READ,
+ − 752 (GdkInputFunction) gtk_what_callback, closure);
+ − 753 filedesc_to_what_closure[fd] = closure;
+ − 754 }
+ − 755
+ − 756 static void
+ − 757 unselect_filedesc (int fd)
+ − 758 {
+ − 759 struct what_is_ready_closure *closure = filedesc_to_what_closure[fd];
+ − 760
+ − 761 assert (closure);
+ − 762 if (!NILP (filedesc_with_input[fd]))
+ − 763 {
+ − 764 /* We are unselecting this process before we have drained the rest of
+ − 765 the input from it, probably from status_notify() in the command loop.
+ − 766 This can happen like so:
+ − 767
+ − 768 - We are waiting in XtAppNextEvent()
+ − 769 - Process generates output
+ − 770 - Process is marked as being ready
+ − 771 - Process dies, SIGCHLD gets generated before we return (!?)
+ − 772 It could happen I guess.
+ − 773 - sigchld_handler() marks process as dead
+ − 774 - Somehow we end up getting a new KeyPress event on the queue
+ − 775 at the same time (I'm really so sure how that happens but I'm
+ − 776 not sure it can't either so let's assume it can...).
+ − 777 - Key events have priority so we return that instead of the proc.
+ − 778 - Before dispatching the lisp key event we call status_notify()
+ − 779 - Which deselects the process that SIGCHLD marked as dead.
+ − 780
+ − 781 Thus we never remove it from _with_input and turn it into a lisp
+ − 782 event, so we need to do it here. But this does not mean that we're
+ − 783 throwing away the last block of output - status_notify() has already
+ − 784 taken care of running the proc filter or whatever.
+ − 785 */
+ − 786 filedesc_with_input[fd] = Qnil;
+ − 787 if (PROCESSP (closure->what))
+ − 788 {
+ − 789 assert (process_events_occurred > 0);
+ − 790 process_events_occurred--;
+ − 791 }
+ − 792 else
+ − 793 {
+ − 794 assert (tty_events_occurred > 0);
+ − 795 tty_events_occurred--;
+ − 796 }
+ − 797 }
+ − 798 gdk_input_remove (closure->id);
1726
+ − 799 xfree (closure, struct what_is_ready_closure *);
462
+ − 800 filedesc_to_what_closure[fd] = 0;
+ − 801 }
+ − 802
+ − 803 static void
853
+ − 804 emacs_gtk_select_process (Lisp_Process *process, int doin, int doerr)
462
+ − 805 {
853
+ − 806 Lisp_Object proc;
+ − 807 int infd, errfd;
+ − 808
+ − 809 event_stream_unixoid_select_process (process, doin, doerr, &infd, &errfd);
+ − 810
+ − 811 proc = wrap_process (process);
+ − 812 if (doin)
+ − 813 select_filedesc (infd, proc);
+ − 814 if (doerr)
+ − 815 select_filedesc (errfd, proc);
+ − 816 }
462
+ − 817
853
+ − 818 static void
+ − 819 emacs_gtk_unselect_process (Lisp_Process *process, int doin, int doerr)
+ − 820 {
+ − 821 int infd, errfd;
+ − 822
+ − 823 event_stream_unixoid_unselect_process (process, doin, doerr, &infd, &errfd);
+ − 824
+ − 825 if (doin)
+ − 826 unselect_filedesc (infd);
+ − 827 if (doerr)
+ − 828 unselect_filedesc (errfd);
462
+ − 829 }
+ − 830
+ − 831 static void
853
+ − 832 emacs_gtk_create_io_streams (void *inhandle, void *outhandle,
+ − 833 void *errhandle, Lisp_Object *instream,
+ − 834 Lisp_Object *outstream,
+ − 835 Lisp_Object *errstream,
+ − 836 USID *in_usid,
+ − 837 USID *err_usid,
+ − 838 int flags)
462
+ − 839 {
853
+ − 840 event_stream_unixoid_create_io_streams
+ − 841 (inhandle, outhandle, errhandle, instream, outstream,
+ − 842 errstream, in_usid, err_usid, flags);
+ − 843 if (*in_usid != USID_ERROR)
+ − 844 *in_usid = USID_DONTHASH;
+ − 845 if (*err_usid != USID_ERROR)
+ − 846 *err_usid = USID_DONTHASH;
462
+ − 847 }
+ − 848
853
+ − 849 static void
+ − 850 emacs_gtk_delete_io_streams (Lisp_Object instream,
+ − 851 Lisp_Object outstream,
+ − 852 Lisp_Object errstream,
+ − 853 USID *in_usid,
+ − 854 USID *err_usid)
462
+ − 855 {
853
+ − 856 event_stream_unixoid_delete_io_streams
+ − 857 (instream, outstream, errstream, in_usid, err_usid);
+ − 858 *in_usid = USID_DONTHASH;
+ − 859 *err_usid = USID_DONTHASH;
462
+ − 860 }
+ − 861
+ − 862 /* This is called from GC when a process object is about to be freed.
+ − 863 If we've still got pointers to it in this file, we're gonna lose hard.
+ − 864 */
+ − 865 void
2286
+ − 866 debug_process_finalization (struct Lisp_Process *UNUSED (p))
462
+ − 867 {
+ − 868 #if 0 /* #### */
+ − 869 int i;
+ − 870 Lisp_Object instr, outstr;
+ − 871
+ − 872 get_process_streams (p, &instr, &outstr);
+ − 873 /* if it still has fds, then it hasn't been killed yet. */
+ − 874 assert (NILP(instr));
+ − 875 assert (NILP(outstr));
+ − 876 /* Better not still be in the "with input" table; we know it's got no fds. */
+ − 877 for (i = 0; i < MAXDESC; i++)
+ − 878 {
+ − 879 Lisp_Object process = filedesc_fds_with_input [i];
+ − 880 assert (!PROCESSP (process) || XPROCESS (process) != p);
+ − 881 }
+ − 882 #endif
+ − 883 }
+ − 884
+ − 885 static void
+ − 886 gtk_process_to_emacs_event (struct Lisp_Event *emacs_event)
+ − 887 {
+ − 888 int i;
+ − 889
+ − 890 assert (process_events_occurred > 0);
1204
+ − 891
462
+ − 892 for (i = 0; i < MAXDESC; i++)
+ − 893 {
1204
+ − 894 Lisp_Object process = filedesc_with_input[i];
462
+ − 895 if (PROCESSP (process))
1204
+ − 896 {
+ − 897 filedesc_with_input[i] = Qnil;
+ − 898 process_events_occurred--;
+ − 899 /* process events have nil as channel */
+ − 900 set_event_type (emacs_event, process_event);
+ − 901 SET_EVENT_TIMESTAMP_ZERO (emacs_event); /* #### */
+ − 902 SET_EVENT_PROCESS_PROCESS (emacs_event, process);
+ − 903 return;
+ − 904 }
462
+ − 905 }
2500
+ − 906 ABORT ();
462
+ − 907 }
+ − 908
+ − 909 static void
+ − 910 emacs_gtk_select_console (struct console *con)
+ − 911 {
+ − 912 Lisp_Object console;
+ − 913 int infd;
+ − 914
+ − 915 if (CONSOLE_GTK_P (con))
+ − 916 return; /* Gtk consoles are automatically selected for when we initialize them */
+ − 917 infd = event_stream_unixoid_select_console (con);
793
+ − 918 console = wrap_console (con);
462
+ − 919 select_filedesc (infd, console);
+ − 920 }
+ − 921
+ − 922 static void
+ − 923 emacs_gtk_unselect_console (struct console *con)
+ − 924 {
+ − 925 Lisp_Object console;
+ − 926 int infd;
+ − 927
+ − 928 if (CONSOLE_GTK_P (con))
+ − 929 return; /* X consoles are automatically selected for when we initialize them */
+ − 930 infd = event_stream_unixoid_unselect_console (con);
793
+ − 931 console = wrap_console (con);
462
+ − 932 unselect_filedesc (infd);
+ − 933 }
+ − 934
+ − 935 /* read an event from a tty, if one is available. Returns non-zero
+ − 936 if an event was available. Note that when this function is
+ − 937 called, there should always be a tty marked as ready for input.
+ − 938 However, the input condition might actually be EOF, so there
+ − 939 may not really be any input available. (In this case,
+ − 940 read_event_from_tty_or_stream_desc() will arrange for the TTY device
+ − 941 to be deleted.) */
+ − 942
+ − 943 static int
+ − 944 gtk_tty_to_emacs_event (struct Lisp_Event *emacs_event)
+ − 945 {
+ − 946 int i;
+ − 947
+ − 948 assert (tty_events_occurred > 0);
+ − 949 for (i = 0; i < MAXDESC; i++)
+ − 950 {
+ − 951 Lisp_Object console = filedesc_with_input[i];
+ − 952 if (CONSOLEP (console))
+ − 953 {
+ − 954 assert (tty_events_occurred > 0);
+ − 955 tty_events_occurred--;
+ − 956 filedesc_with_input[i] = Qnil;
771
+ − 957 if (read_event_from_tty_or_stream_desc (emacs_event,
+ − 958 XCONSOLE (console)))
462
+ − 959 return 1;
+ − 960 }
+ − 961 }
+ − 962
+ − 963 return 0;
+ − 964 }
+ − 965
+ − 966
+ − 967 /************************************************************************/
+ − 968 /* Drag 'n Drop handling */
+ − 969 /************************************************************************/
+ − 970 #ifdef HAVE_DRAGNDROP
+ − 971 #define TARGET_URI_LIST 0x00
+ − 972 #define TARGET_TEXT_PLAIN 0x01
+ − 973 #define TARGET_FILE_NAME 0x02
+ − 974 #define TARGET_NETSCAPE 0x03
+ − 975
+ − 976 static GdkAtom preferred_targets[10];
+ − 977
+ − 978 void
+ − 979 dragndrop_data_received (GtkWidget *widget,
+ − 980 GdkDragContext *context,
+ − 981 gint x,
+ − 982 gint y,
+ − 983 GtkSelectionData *data,
2286
+ − 984 guint UNUSED (info),
462
+ − 985 guint time)
+ − 986 {
+ − 987 Lisp_Object event = Fmake_event (Qnil, Qnil);
+ − 988 struct device *d = gtk_any_window_to_device (widget->window);
+ − 989 struct frame *f = gtk_any_widget_or_parent_to_frame (d, widget);
+ − 990 struct Lisp_Event *ev = XEVENT (event);
+ − 991 Lisp_Object l_type = Qnil, l_data = Qnil;
+ − 992 Lisp_Object l_dndlist = Qnil, l_item = Qnil;
+ − 993 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+ − 994
+ − 995 GCPRO4 (l_type, l_data, l_dndlist, l_item);
+ − 996
1204
+ − 997 set_event_type (ev, misc_user_event);
+ − 998 SET_EVENT_CHANNEL (ev, wrap_frame (f));
+ − 999 SET_EVENT_TIMESTAMP (ev, time);
+ − 1000 SET_EVENT_MISC_USER_X (ev, x);
+ − 1001 SET_EVENT_MISC_USER_Y (ev, y);
462
+ − 1002
+ − 1003 if (data->type == preferred_targets[TARGET_URI_LIST])
+ − 1004 {
+ − 1005 /* newline-separated list of URLs */
+ − 1006 int start, end;
+ − 1007 const char *string_data = (char *) data->data;
+ − 1008
+ − 1009 l_type = Qdragdrop_URL;
+ − 1010
+ − 1011 for (start = 0, end = 0; string_data && string_data[end]; end++)
+ − 1012 {
+ − 1013 if ((string_data[end] == '\r') && (string_data[end+1] == '\n'))
+ − 1014 {
+ − 1015 l_item = make_string (&string_data[start], end - start);
+ − 1016 l_dndlist = Fcons (l_item, l_dndlist);
+ − 1017 ++end;
+ − 1018 start = ++end;
+ − 1019 }
+ − 1020 }
+ − 1021 }
+ − 1022 else if (data->type == preferred_targets[TARGET_TEXT_PLAIN])
+ − 1023 {
+ − 1024 /* Arbitrary string */
+ − 1025 l_type = Qdragdrop_MIME;
+ − 1026 l_dndlist = list1 (list3 (list1 (build_string ("text/plain")),
+ − 1027 build_string ("8_bit"),
+ − 1028 make_ext_string (data->data,
+ − 1029 strlen ((char *)data->data),
+ − 1030 Qctext)));
+ − 1031 }
+ − 1032 else if (data->type == preferred_targets[TARGET_FILE_NAME])
+ − 1033 {
+ − 1034 /* Random filename */
+ − 1035 char *hurl = dnd_url_hexify_string (data->data, "file:");
+ − 1036
867
+ − 1037 l_dndlist = list1 (make_string ((Ibyte *)hurl, strlen (hurl)));
462
+ − 1038 l_type = Qdragdrop_URL;
+ − 1039
1726
+ − 1040 xfree (hurl, char *);
462
+ − 1041 }
+ − 1042 else if (data->type == preferred_targets[TARGET_NETSCAPE])
+ − 1043 {
+ − 1044 /* Single URL */
+ − 1045 l_dndlist = list1 (make_string ((Extbyte *)data->data,
+ − 1046 strlen ((char *)data->data)));
+ − 1047 l_type = Qdragdrop_URL;
+ − 1048 }
+ − 1049 else
+ − 1050 {
+ − 1051 /* Unknown type - what to do?
+ − 1052 We just pass it up to lisp - we already have a mime type.
+ − 1053 */
+ − 1054 l_type = Qdragdrop_MIME;
+ − 1055 l_dndlist = list1 (list3 (list1 (build_string (gdk_atom_name (data->type))),
+ − 1056 build_string ("8bit"),
+ − 1057 make_ext_string ((Extbyte *) data->data,
+ − 1058 data->length, Qbinary)));
+ − 1059 }
+ − 1060
1204
+ − 1061
+ − 1062 SET_EVENT_MISC_USER_FUNCTION (ev, Qdragdrop_drop_dispatch);
+ − 1063 SET_EVENT_MISC_USER_OBJECT (ev, Fcons (l_type, l_dndlist));
462
+ − 1064
+ − 1065 UNGCPRO;
+ − 1066
+ − 1067 gtk_drag_finish (context, TRUE, FALSE, time);
1204
+ − 1068 enqueue_dispatch_event (event);
462
+ − 1069 }
+ − 1070
+ − 1071 gboolean
2286
+ − 1072 dragndrop_dropped (GtkWidget *UNUSED (widget),
462
+ − 1073 GdkDragContext *drag_context,
2286
+ − 1074 gint UNUSED (x),
+ − 1075 gint UNUSED (y),
462
+ − 1076 guint time,
+ − 1077 gpointer user_data)
+ − 1078 {
+ − 1079 /* Netscape drops things like:
+ − 1080 STRING
+ − 1081 _SGI_ICON
+ − 1082 _SGI_ICON_TYPE
+ − 1083 SGI_FILE
+ − 1084 FILE_NAME
+ − 1085 _NETSCAPE_URL
+ − 1086
+ − 1087 gmc drops things like
+ − 1088 application/x-mc-desktop-icon
+ − 1089 text/uri-list
+ − 1090 text/plain
+ − 1091 _NETSCAPE_URL
+ − 1092
+ − 1093 We prefer:
+ − 1094 text/uri-list
+ − 1095 text/plain
+ − 1096 FILE_NAME
+ − 1097 _NETSCAPE_URL
+ − 1098 first one
+ − 1099 */
+ − 1100 GdkAtom found = 0;
+ − 1101 GList *list = drag_context->targets;
+ − 1102
+ − 1103 int i;
+ − 1104
+ − 1105 if (!preferred_targets[0])
+ − 1106 {
+ − 1107 preferred_targets[TARGET_URI_LIST] = gdk_atom_intern ("text/uri-list", FALSE);
+ − 1108 preferred_targets[TARGET_TEXT_PLAIN] = gdk_atom_intern ("text/plain", FALSE);
+ − 1109 preferred_targets[TARGET_FILE_NAME] = gdk_atom_intern ("FILE_NAME", FALSE);
+ − 1110 preferred_targets[TARGET_NETSCAPE] = gdk_atom_intern ("_NETSCAPE_URL", FALSE);
+ − 1111 }
+ − 1112
+ − 1113 #if 0
+ − 1114 stderr_out ("Drop info available in the following formats: \n");
+ − 1115 while (list)
+ − 1116 {
+ − 1117 stderr_out ("\t%s\n", gdk_atom_name ((GdkAtom)list->data));
+ − 1118 list = list->next;
+ − 1119 }
+ − 1120 list = drag_context->targets;
+ − 1121 #endif
+ − 1122
+ − 1123 while (list && !found)
+ − 1124 {
+ − 1125 for (i = 0; preferred_targets[i] && !found; i++)
+ − 1126 {
+ − 1127 if ((GdkAtom) list->data == preferred_targets[i])
+ − 1128 {
+ − 1129 found = (GdkAtom) list->data;
+ − 1130 }
+ − 1131 }
+ − 1132 list = list->next;
+ − 1133 }
+ − 1134
+ − 1135 if (!found)
+ − 1136 {
+ − 1137 found = (GdkAtom) drag_context->targets->data;
+ − 1138 }
+ − 1139
+ − 1140 gtk_drag_get_data (GTK_WIDGET (user_data), drag_context, found, time);
+ − 1141 return (TRUE);
+ − 1142 }
+ − 1143 #endif /* HAVE_DRAGNDROP */
+ − 1144
+ − 1145
+ − 1146 /************************************************************************/
+ − 1147 /* get the next event from gtk */
+ − 1148 /************************************************************************/
+ − 1149
+ − 1150 /* This business exists because menu events "happen" when
+ − 1151 menubar_selection_callback() is called from somewhere deep
+ − 1152 within XtAppProcessEvent in emacs_Xt_next_event(). The
+ − 1153 callback needs to terminate the modal loop in that function
+ − 1154 or else it will continue waiting until another event is
+ − 1155 received.
+ − 1156
+ − 1157 Same business applies to scrollbar events. */
+ − 1158
+ − 1159 void
+ − 1160 signal_special_gtk_user_event (Lisp_Object channel, Lisp_Object function,
+ − 1161 Lisp_Object object)
+ − 1162 {
+ − 1163 Lisp_Object event = Fmake_event (Qnil, Qnil);
+ − 1164
1204
+ − 1165 XSET_EVENT_TYPE (event, misc_user_event);
+ − 1166 XSET_EVENT_CHANNEL (event, channel);
+ − 1167 XSET_EVENT_MISC_USER_FUNCTION (event, function);
+ − 1168 XSET_EVENT_MISC_USER_OBJECT (event, object);
+ − 1169 enqueue_dispatch_event (event);
462
+ − 1170 }
+ − 1171
+ − 1172 static void
+ − 1173 emacs_gtk_next_event (struct Lisp_Event *emacs_event)
+ − 1174 {
+ − 1175 we_didnt_get_an_event:
+ − 1176
+ − 1177 while (NILP (dispatch_event_queue) &&
+ − 1178 !completed_timeouts &&
+ − 1179 !fake_event_occurred &&
+ − 1180 !process_events_occurred &&
+ − 1181 !tty_events_occurred)
+ − 1182 {
1292
+ − 1183 #ifdef WIN32_ANY
+ − 1184 mswindows_is_blocking = 1;
+ − 1185 #endif
+ − 1186 gtk_main_iteration ();
+ − 1187 #ifdef WIN32_ANY
+ − 1188 mswindows_is_blocking = 0;
+ − 1189 #endif
462
+ − 1190 }
+ − 1191
+ − 1192 if (!NILP (dispatch_event_queue))
+ − 1193 {
+ − 1194 Lisp_Object event, event2;
793
+ − 1195 event2 = wrap_event (emacs_event);
1204
+ − 1196 event = dequeue_dispatch_event ();
462
+ − 1197 Fcopy_event (event, event2);
+ − 1198 Fdeallocate_event (event);
+ − 1199 }
+ − 1200 else if (tty_events_occurred)
+ − 1201 {
+ − 1202 if (!gtk_tty_to_emacs_event (emacs_event))
+ − 1203 goto we_didnt_get_an_event;
+ − 1204 }
+ − 1205 else if (completed_timeouts)
+ − 1206 gtk_timeout_to_emacs_event (emacs_event);
+ − 1207 else if (fake_event_occurred)
+ − 1208 {
+ − 1209 /* A dummy event, so that a cycle of the command loop will occur. */
+ − 1210 fake_event_occurred = 0;
+ − 1211 /* eval events have nil as channel */
1204
+ − 1212 set_event_type (emacs_event, eval_event);
+ − 1213 SET_EVENT_EVAL_FUNCTION (emacs_event, Qidentity);
+ − 1214 SET_EVENT_EVAL_OBJECT (emacs_event, Qnil);
462
+ − 1215 }
+ − 1216 else /* if (process_events_occurred) */
+ − 1217 gtk_process_to_emacs_event (emacs_event);
+ − 1218 }
+ − 1219
+ − 1220 int
+ − 1221 gtk_event_to_emacs_event (struct frame *frame, GdkEvent *gdk_event, struct Lisp_Event *emacs_event)
+ − 1222 {
+ − 1223 struct device *d = NULL;
+ − 1224 struct gtk_device *gd = NULL;
+ − 1225 gboolean accept_any_window = FALSE;
+ − 1226
872
+ − 1227 /* #### Under what circumstances can this happen???? Hunt out the code that
+ − 1228 sets frame to 0 and fix it instead. */
462
+ − 1229 if (!frame)
+ − 1230 {
872
+ − 1231 frame = XFRAME (Fselected_frame (get_default_device (Qgtk)));
462
+ − 1232 accept_any_window = TRUE;
+ − 1233 }
+ − 1234
+ − 1235 d = XDEVICE (FRAME_DEVICE (frame));
+ − 1236 gd = DEVICE_GTK_DATA (d);
+ − 1237
+ − 1238 set_last_server_timestamp (d, gdk_event);
+ − 1239
+ − 1240 switch (gdk_event->type)
+ − 1241 {
+ − 1242 /* XEmacs handles double and triple clicking on its own, and if
+ − 1243 we capture these events, it royally confuses the code in
+ − 1244 ../lisp/mouse.el */
+ − 1245 case GDK_2BUTTON_PRESS:
+ − 1246 case GDK_3BUTTON_PRESS:
+ − 1247 return (0);
+ − 1248
+ − 1249 case GDK_BUTTON_PRESS:
+ − 1250 case GDK_BUTTON_RELEASE:
+ − 1251 /* We need to ignore button events outside our main window or
+ − 1252 things get ugly. The standard scrollbars in Gtk try to be
+ − 1253 nice and pass the button press events up to the parent
+ − 1254 widget. This causes us no end of grief though. Effects
+ − 1255 range from setting point to the wrong place to selecting
+ − 1256 new windows. */
+ − 1257 {
+ − 1258 GdkWindow *w = gdk_window_at_pointer (NULL, NULL);
+ − 1259
+ − 1260 /* If you press mouse button and drag it around, and release
+ − 1261 it outside the window, you will get a NULL GdkWindow at
+ − 1262 pointer. We need to forward these events on to XEmacs so
+ − 1263 that the mouse selection voodoo works.
+ − 1264 */
+ − 1265 if (w && (w != gdk_window_lookup (GDK_ROOT_WINDOW ())))
+ − 1266 {
+ − 1267 GdkEvent ev;
+ − 1268 GtkWidget *wid = NULL;
+ − 1269
+ − 1270 ev.any.window = w;
+ − 1271 wid = gtk_get_event_widget (&ev);
+ − 1272
+ − 1273 if (!GTK_IS_XEMACS (wid) && !accept_any_window)
+ − 1274 {
+ − 1275 return (0);
+ − 1276 }
+ − 1277 }
+ − 1278 if (!accept_any_window)
+ − 1279 gtk_widget_grab_focus (FRAME_GTK_TEXT_WIDGET (frame));
+ − 1280 }
+ − 1281 /* Fall through */
+ − 1282 case GDK_KEY_PRESS:
+ − 1283 {
+ − 1284 unsigned int modifiers = 0;
+ − 1285 int shift_p, lock_p;
+ − 1286 gboolean key_event_p = (gdk_event->type == GDK_KEY_PRESS);
+ − 1287 unsigned int *state =
+ − 1288 key_event_p ? &gdk_event->key.state : &gdk_event->button.state;
+ − 1289
+ − 1290 /* If this is a synthetic KeyPress or Button event, and the user
+ − 1291 has expressed a disinterest in this security hole, then drop
+ − 1292 it on the floor. */
+ − 1293 /* #### BILL!!! Should this be a generic check for ANY synthetic
+ − 1294 event? */
+ − 1295 if ((gdk_event->any.send_event) && !gtk_allow_sendevents)
+ − 1296 return 0;
+ − 1297
+ − 1298 DEVICE_GTK_MOUSE_TIMESTAMP (d) =
+ − 1299 DEVICE_GTK_GLOBAL_MOUSE_TIMESTAMP (d) =
+ − 1300 key_event_p ? gdk_event->key.time : gdk_event->button.time;
+ − 1301
+ − 1302 if (*state & GDK_CONTROL_MASK) modifiers |= XEMACS_MOD_CONTROL;
+ − 1303 if (*state & gd->MetaMask) modifiers |= XEMACS_MOD_META;
+ − 1304 if (*state & gd->SuperMask) modifiers |= XEMACS_MOD_SUPER;
+ − 1305 if (*state & gd->HyperMask) modifiers |= XEMACS_MOD_HYPER;
+ − 1306 if (*state & gd->AltMask) modifiers |= XEMACS_MOD_ALT;
+ − 1307
589
+ − 1308 {
+ − 1309 int numero_de_botao = -1;
+ − 1310
+ − 1311 if (!key_event_p)
+ − 1312 numero_de_botao = gdk_event->button.button;
+ − 1313
+ − 1314 /* the button gets noted either in the button or the modifiers
+ − 1315 field, but not both. */
+ − 1316 if (numero_de_botao != 1 && (*state & GDK_BUTTON1_MASK))
+ − 1317 modifiers |= XEMACS_MOD_BUTTON1;
+ − 1318 if (numero_de_botao != 2 && (*state & GDK_BUTTON2_MASK))
+ − 1319 modifiers |= XEMACS_MOD_BUTTON2;
+ − 1320 if (numero_de_botao != 3 && (*state & GDK_BUTTON3_MASK))
+ − 1321 modifiers |= XEMACS_MOD_BUTTON3;
+ − 1322 if (numero_de_botao != 4 && (*state & GDK_BUTTON4_MASK))
+ − 1323 modifiers |= XEMACS_MOD_BUTTON4;
+ − 1324 if (numero_de_botao != 5 && (*state & GDK_BUTTON5_MASK))
+ − 1325 modifiers |= XEMACS_MOD_BUTTON5;
+ − 1326 }
+ − 1327
462
+ − 1328 /* Ignore the Caps_Lock key if:
+ − 1329 - any other modifiers are down, so that Caps_Lock doesn't
+ − 1330 turn C-x into C-X, which would suck.
+ − 1331 - the event was a mouse event. */
+ − 1332 if (modifiers || ! key_event_p)
+ − 1333 *state &= (~GDK_LOCK_MASK);
+ − 1334
+ − 1335 shift_p = *state & GDK_SHIFT_MASK;
+ − 1336 lock_p = *state & GDK_LOCK_MASK;
+ − 1337
+ − 1338 if (shift_p || lock_p)
+ − 1339 modifiers |= XEMACS_MOD_SHIFT;
+ − 1340
+ − 1341 if (key_event_p)
+ − 1342 {
+ − 1343 GdkEventKey *key_event = &gdk_event->key;
+ − 1344 Lisp_Object keysym;
+ − 1345
2081
+ − 1346 #ifdef HAVE_MENUBARS
+ − 1347 /* If the user wants see if the event is a menu bar accelerator.
+ − 1348 The process of checking absorbs the event and starts menu
+ − 1349 processing so send a null event into XEmacs to make sure it
+ − 1350 does nothing.
+ − 1351 */
+ − 1352 if (!NILP (Vmenu_accelerator_enabled)
+ − 1353 && gtk_accel_groups_activate(GTK_OBJECT (FRAME_GTK_SHELL_WIDGET(frame)),
+ − 1354 key_event->keyval,
+ − 1355 (GdkModifierType) *state))
+ − 1356 {
+ − 1357 zero_event(emacs_event);
+ − 1358 return 1;
+ − 1359 }
+ − 1360 #endif
+ − 1361
462
+ − 1362 /* This used to compute the frame from the given X window and
+ − 1363 store it here, but we really don't care about the frame. */
+ − 1364 emacs_event->channel = DEVICE_CONSOLE (d);
+ − 1365
+ − 1366 /* Keysym mucking has already been done inside the
+ − 1367 GdkEventKey parsing */
+ − 1368 keysym = gtk_to_emacs_keysym (d, key_event, 0);
+ − 1369
+ − 1370 /* If the emacs keysym is nil, then that means that the X
+ − 1371 keysym was either a Modifier or NoSymbol, which
+ − 1372 probably means that we're in the midst of reading a
+ − 1373 Multi_key sequence, or a "dead" key prefix, or XIM
+ − 1374 input. Ignore it. */
+ − 1375 if (NILP (keysym))
+ − 1376 return 0;
+ − 1377
+ − 1378 /* More Caps_Lock garbage: Caps_Lock should *only* add the
+ − 1379 shift modifier to two-case keys (that is, A-Z and
+ − 1380 related characters). So at this point (after looking up
+ − 1381 the keysym) if the keysym isn't a dual-case alphabetic,
+ − 1382 and if the caps lock key was down but the shift key
+ − 1383 wasn't, then turn off the shift modifier. Gag barf */
+ − 1384 /* #### type lossage: assuming equivalence of emacs and
+ − 1385 X keysyms */
+ − 1386 /* !!#### maybe fix for Mule */
+ − 1387 if (lock_p && !shift_p &&
+ − 1388 ! (CHAR_OR_CHAR_INTP (keysym)
+ − 1389 && keysym_obeys_caps_lock_p
+ − 1390 ((guint) XCHAR_OR_CHAR_INT (keysym), d)))
+ − 1391 modifiers &= (~XEMACS_MOD_SHIFT);
+ − 1392
+ − 1393 /* If this key contains two distinct keysyms, that is,
+ − 1394 "shift" generates a different keysym than the
+ − 1395 non-shifted key, then don't apply the shift modifier
+ − 1396 bit: it's implicit. Otherwise, if there would be no
+ − 1397 other way to tell the difference between the shifted
+ − 1398 and unshifted version of this key, apply the shift bit.
+ − 1399 Non-graphics, like Backspace and F1 get the shift bit
+ − 1400 in the modifiers slot. Neither the characters "a",
+ − 1401 "A", "2", nor "@" normally have the shift bit set.
+ − 1402 However, "F1" normally does. */
+ − 1403 if (modifiers & XEMACS_MOD_SHIFT)
+ − 1404 {
+ − 1405 if (CHAR_OR_CHAR_INTP (keysym))
+ − 1406 {
+ − 1407 modifiers &= ~XEMACS_MOD_SHIFT;
+ − 1408 }
+ − 1409 }
+ − 1410
1204
+ − 1411 set_event_type (emacs_event, key_press_event);
+ − 1412 SET_EVENT_TIMESTAMP (emacs_event, key_event->time);
+ − 1413 SET_EVENT_KEY_MODIFIERS (emacs_event, modifiers);
+ − 1414 SET_EVENT_KEY_KEYSYM (emacs_event, keysym);
462
+ − 1415 }
+ − 1416 else /* Mouse press/release event */
+ − 1417 {
+ − 1418 GdkEventButton *button_event = &gdk_event->button;
+ − 1419
1204
+ − 1420 set_event_type (emacs_event,
+ − 1421 button_event->type == GDK_BUTTON_RELEASE ?
+ − 1422 button_release_event : button_press_event);
+ − 1423 SET_EVENT_CHANNEL (emacs_event, wrap_frame (frame));
462
+ − 1424
1204
+ − 1425 SET_EVENT_BUTTON_MODIFIERS (emacs_event, modifiers);
+ − 1426 SET_EVENT_TIMESTAMP (emacs_event, button_event->time);
+ − 1427 SET_EVENT_BUTTON_BUTTON (emacs_event, button_event->button);
2054
+ − 1428 SET_EVENT_BUTTON_X (emacs_event, (int) button_event->x);
+ − 1429 SET_EVENT_BUTTON_Y (emacs_event, (int) button_event->y);
462
+ − 1430 }
+ − 1431 }
+ − 1432 break;
+ − 1433 case GDK_KEY_RELEASE:
+ − 1434 return 0;
+ − 1435 break;
+ − 1436 case GDK_MOTION_NOTIFY:
+ − 1437 {
+ − 1438 GdkEventMotion *ev = &gdk_event->motion;
+ − 1439 unsigned int modifiers = 0;
+ − 1440 gint x,y;
+ − 1441 GdkModifierType mask;
+ − 1442
+ − 1443 /* We use MOTION_HINT_MASK, so we will get only one motion
+ − 1444 event until the next time we call gdk_window_get_pointer or
+ − 1445 the user clicks the mouse. So call gdk_window_get_pointer
+ − 1446 now (meaning that the event will be in sync with the server
+ − 1447 just before Fnext_event() returns). If the mouse is still
+ − 1448 in motion, then the server will immediately generate
+ − 1449 exactly one more motion event, which will be on the queue
+ − 1450 waiting for us next time around. */
+ − 1451 gdk_window_get_pointer (ev->window, &x, &y, &mask);
+ − 1452
+ − 1453 DEVICE_GTK_MOUSE_TIMESTAMP (d) = ev->time;
+ − 1454
1204
+ − 1455 SET_EVENT_CHANNEL (emacs_event, wrap_frame (frame));
+ − 1456 set_event_type (emacs_event, pointer_motion_event);
+ − 1457 SET_EVENT_TIMESTAMP (emacs_event, ev->time);
+ − 1458 SET_EVENT_MOTION_X (emacs_event, x);
+ − 1459 SET_EVENT_MOTION_Y (emacs_event, y);
+ − 1460
462
+ − 1461 if (mask & GDK_SHIFT_MASK) modifiers |= XEMACS_MOD_SHIFT;
+ − 1462 if (mask & GDK_CONTROL_MASK) modifiers |= XEMACS_MOD_CONTROL;
+ − 1463 if (mask & gd->MetaMask) modifiers |= XEMACS_MOD_META;
+ − 1464 if (mask & gd->SuperMask) modifiers |= XEMACS_MOD_SUPER;
+ − 1465 if (mask & gd->HyperMask) modifiers |= XEMACS_MOD_HYPER;
+ − 1466 if (mask & gd->AltMask) modifiers |= XEMACS_MOD_ALT;
589
+ − 1467 if (mask & GDK_BUTTON1_MASK) modifiers |= XEMACS_MOD_BUTTON1;
+ − 1468 if (mask & GDK_BUTTON2_MASK) modifiers |= XEMACS_MOD_BUTTON2;
+ − 1469 if (mask & GDK_BUTTON3_MASK) modifiers |= XEMACS_MOD_BUTTON3;
+ − 1470 if (mask & GDK_BUTTON4_MASK) modifiers |= XEMACS_MOD_BUTTON4;
+ − 1471 if (mask & GDK_BUTTON5_MASK) modifiers |= XEMACS_MOD_BUTTON5;
+ − 1472
462
+ − 1473 /* Currently ignores Shift_Lock but probably shouldn't
+ − 1474 (but it definitely should ignore Caps_Lock). */
1204
+ − 1475 SET_EVENT_MOTION_MODIFIERS (emacs_event, modifiers);
462
+ − 1476 }
+ − 1477 break;
+ − 1478
+ − 1479 default: /* it's a magic event */
+ − 1480 return (0);
+ − 1481 break;
+ − 1482 }
+ − 1483 return 1;
+ − 1484 }
+ − 1485
+ − 1486 static const char *event_name (GdkEvent *);
+ − 1487
+ − 1488 static gboolean
+ − 1489 generic_event_handler (GtkWidget *widget, GdkEvent *event)
+ − 1490 {
+ − 1491 Lisp_Object emacs_event = Qnil;
+ − 1492 if (!GTK_IS_XEMACS (widget))
+ − 1493 {
+ − 1494 stderr_out ("Got a %s event for a non-XEmacs widget\n",event_name (event));
+ − 1495 return (FALSE);
+ − 1496 }
+ − 1497
+ − 1498 emacs_event = Fmake_event (Qnil, Qnil);
+ − 1499
+ − 1500 if (gtk_event_to_emacs_event (GTK_XEMACS_FRAME (widget), event, XEVENT (emacs_event)))
+ − 1501 {
1204
+ − 1502 enqueue_dispatch_event (emacs_event);
462
+ − 1503 return (TRUE);
+ − 1504 }
+ − 1505 else
+ − 1506 {
+ − 1507 Fdeallocate_event (emacs_event);
+ − 1508 }
+ − 1509 return (FALSE);
+ − 1510 }
+ − 1511
1416
+ − 1512 gint
+ − 1513 emacs_gtk_key_event_handler (GtkWidget *widget, GdkEventKey *event)
462
+ − 1514 {
+ − 1515 return (generic_event_handler (widget, (GdkEvent *) event));
+ − 1516 }
+ − 1517
1416
+ − 1518 gint
+ − 1519 emacs_gtk_button_event_handler (GtkWidget *widget, GdkEventButton *event)
462
+ − 1520 {
+ − 1521 return (generic_event_handler (widget, (GdkEvent *) event));
+ − 1522 }
+ − 1523
1416
+ − 1524 gint
+ − 1525 emacs_gtk_motion_event_handler (GtkWidget *widget, GdkEventMotion *event)
462
+ − 1526 {
+ − 1527 return (generic_event_handler (widget, (GdkEvent *) event));
+ − 1528 }
+ − 1529
+ − 1530 gboolean
2286
+ − 1531 emacs_shell_event_handler (GtkWidget *UNUSED (wid),
462
+ − 1532 GdkEvent *event,
+ − 1533 gpointer closure)
+ − 1534 {
+ − 1535 struct frame *frame = (struct frame *) closure;
+ − 1536 Lisp_Object lisp_event = Fmake_event (Qnil, Qnil);
+ − 1537 struct Lisp_Event *emacs_event = XEVENT (lisp_event);
1204
+ − 1538 GdkEvent *gdk_event_copy = &EVENT_MAGIC_GDK_EVENT (emacs_event);
462
+ − 1539 struct device *d = XDEVICE (FRAME_DEVICE (frame));
+ − 1540 gboolean ignore_p = FALSE;
+ − 1541
+ − 1542 set_last_server_timestamp (d, event);
+ − 1543
+ − 1544 #define FROB(event_member) gdk_event_copy->event_member = event->event_member
+ − 1545
+ − 1546 switch (event->type)
+ − 1547 {
+ − 1548 case GDK_SELECTION_REQUEST:
+ − 1549 case GDK_SELECTION_CLEAR:
+ − 1550 case GDK_SELECTION_NOTIFY: FROB(selection); break;
+ − 1551 case GDK_PROPERTY_NOTIFY: FROB(property); break;
+ − 1552 case GDK_CLIENT_EVENT: FROB(client); break;
+ − 1553 case GDK_MAP:
+ − 1554 case GDK_UNMAP: FROB(any); break;
+ − 1555 case GDK_CONFIGURE: FROB(configure); break;
+ − 1556 case GDK_ENTER_NOTIFY:
+ − 1557 case GDK_LEAVE_NOTIFY: FROB(crossing); break;
+ − 1558 case GDK_FOCUS_CHANGE: FROB(focus_change); break;
+ − 1559 case GDK_VISIBILITY_NOTIFY: FROB(visibility); break;
+ − 1560 default:
+ − 1561 ignore_p = TRUE;
+ − 1562 /* Hrmm... do we really want to swallow all the other events as magic? */
+ − 1563 *gdk_event_copy = *event;
+ − 1564 break;
+ − 1565 }
+ − 1566 #undef FROB
+ − 1567
+ − 1568 emacs_event->event_type = magic_event;
793
+ − 1569 emacs_event->channel = wrap_frame (frame);
462
+ − 1570
+ − 1571 if (ignore_p)
793
+ − 1572 {
462
+ − 1573 stderr_out ("Ignoring event... (%s)\n", event_name (event));
+ − 1574 Fdeallocate_event (lisp_event);
+ − 1575 return (FALSE);
793
+ − 1576 }
462
+ − 1577 else
793
+ − 1578 {
1204
+ − 1579 enqueue_dispatch_event (lisp_event);
462
+ − 1580 return (TRUE);
793
+ − 1581 }
462
+ − 1582 }
+ − 1583
+ − 1584
+ − 1585 /************************************************************************/
+ − 1586 /* input pending / C-g checking */
+ − 1587 /************************************************************************/
+ − 1588
+ − 1589 #include <gdk/gdkx.h>
+ − 1590
+ − 1591 static void
1204
+ − 1592 emacs_gtk_drain_queue (void)
462
+ − 1593
+ − 1594 {
+ − 1595 /* We can't just spin through here and wait for GTKs idea of the
+ − 1596 event queue to get empty, or the queue never gets drained. The
+ − 1597 situation is as follows. A process event gets signalled, we put
+ − 1598 it on the queue, then we go into Fnext_event(), which calls
1204
+ − 1599 emacs_gtk_drain_queue(). But gtk_events_pending() will always return
462
+ − 1600 TRUE if there are file-descriptor (aka our process) events
+ − 1601 pending. Using GDK_events_pending() only shows us windowing
+ − 1602 system events.
+ − 1603 */
+ − 1604 if (GDK_DISPLAY ())
+ − 1605 while (gdk_events_pending ())
+ − 1606 gtk_main_iteration ();
1204
+ − 1607
1268
+ − 1608 #ifdef HAVE_TTY
1204
+ − 1609 drain_tty_devices ();
462
+ − 1610 #endif
+ − 1611 }
+ − 1612
790
+ − 1613 static void
2286
+ − 1614 emacs_gtk_force_event_pending (struct frame* UNUSED (f))
790
+ − 1615 {
+ − 1616 #if 0
+ − 1617 stderr_out ("Force event pending called on frame %p!\n", f);
+ − 1618 #endif
+ − 1619 }
+ − 1620
462
+ − 1621
+ − 1622 /************************************************************************/
+ − 1623 /* initialization */
+ − 1624 /************************************************************************/
+ − 1625
+ − 1626 void
+ − 1627 syms_of_event_gtk (void)
+ − 1628 {
563
+ − 1629 DEFSYMBOL (Qsans_modifiers);
462
+ − 1630 }
+ − 1631
1416
+ − 1632 void
+ − 1633 reinit_vars_of_event_gtk (void)
462
+ − 1634 {
1204
+ − 1635 gtk_event_stream = xnew_and_zero (struct event_stream);
462
+ − 1636 gtk_event_stream->event_pending_p = emacs_gtk_event_pending_p;
+ − 1637 gtk_event_stream->next_event_cb = emacs_gtk_next_event;
+ − 1638 gtk_event_stream->handle_magic_event_cb= emacs_gtk_handle_magic_event;
788
+ − 1639 gtk_event_stream->format_magic_event_cb= emacs_gtk_format_magic_event;
+ − 1640 gtk_event_stream->compare_magic_event_cb= emacs_gtk_compare_magic_event;
+ − 1641 gtk_event_stream->hash_magic_event_cb = emacs_gtk_hash_magic_event;
462
+ − 1642 gtk_event_stream->add_timeout_cb = emacs_gtk_add_timeout;
+ − 1643 gtk_event_stream->remove_timeout_cb = emacs_gtk_remove_timeout;
+ − 1644 gtk_event_stream->select_console_cb = emacs_gtk_select_console;
+ − 1645 gtk_event_stream->unselect_console_cb = emacs_gtk_unselect_console;
+ − 1646 gtk_event_stream->select_process_cb = emacs_gtk_select_process;
+ − 1647 gtk_event_stream->unselect_process_cb = emacs_gtk_unselect_process;
1204
+ − 1648 gtk_event_stream->drain_queue_cb = emacs_gtk_drain_queue;
876
+ − 1649 gtk_event_stream->create_io_streams_cb= emacs_gtk_create_io_streams;
+ − 1650 gtk_event_stream->delete_io_streams_cb= emacs_gtk_delete_io_streams;
1204
+ − 1651 gtk_event_stream->force_event_pending_cb= emacs_gtk_force_event_pending;
462
+ − 1652
+ − 1653 the_GTK_timeout_blocktype = Blocktype_new (struct GTK_timeout_blocktype);
+ − 1654
+ − 1655 /* this function only makes safe calls */
+ − 1656 init_what_input_once ();
+ − 1657 }
+ − 1658
+ − 1659 void
+ − 1660 vars_of_event_gtk (void)
+ − 1661 {
+ − 1662 DEFVAR_BOOL ("gtk-allow-sendevents", >k_allow_sendevents /*
+ − 1663 *Non-nil means to allow synthetic events. Nil means they are ignored.
+ − 1664 Beware: allowing emacs to process SendEvents opens a big security hole.
+ − 1665 */ );
+ − 1666 gtk_allow_sendevents = 0;
+ − 1667
+ − 1668 last_quit_check_signal_tick_count = 0;
+ − 1669 }
+ − 1670
+ − 1671 void
+ − 1672 init_event_gtk_late (void) /* called when already initialized */
+ − 1673 {
+ − 1674 timeout_id_tick = 1;
+ − 1675 pending_timeouts = 0;
+ − 1676 completed_timeouts = 0;
+ − 1677
+ − 1678 event_stream = gtk_event_stream;
+ − 1679
+ − 1680 #if 0
+ − 1681 /* Shut GDK the hell up */
+ − 1682 gdk_error_trap_push ();
+ − 1683 #endif
+ − 1684
+ − 1685 gdk_input_add (signal_event_pipe[0], GDK_INPUT_READ,
+ − 1686 (GdkInputFunction) gtk_what_callback, NULL);
+ − 1687 }
+ − 1688
+ − 1689 /* Bogus utility routines */
1416
+ − 1690 static const char *
+ − 1691 event_name (GdkEvent *ev)
462
+ − 1692 {
+ − 1693 return (gtk_event_name (ev->any.type));
+ − 1694 }
+ − 1695
+ − 1696 /* This is down at the bottom of the file so I can avoid polluting the
+ − 1697 generic code with this X specific CRAP! */
+ − 1698
+ − 1699 #include <gdk/gdkx.h>
+ − 1700 #include <X11/keysym.h>
+ − 1701 /* #### BILL!!! Fix this please! */
+ − 1702
+ − 1703
+ − 1704 /************************************************************************/
+ − 1705 /* keymap handling */
+ − 1706 /************************************************************************/
+ − 1707
+ − 1708 /* X bogusly doesn't define the interpretations of any bits besides
+ − 1709 ModControl, ModShift, and ModLock; so the Interclient Communication
+ − 1710 Conventions Manual says that we have to bend over backwards to figure
+ − 1711 out what the other modifier bits mean. According to ICCCM:
+ − 1712
+ − 1713 - Any keycode which is assigned ModControl is a "control" key.
+ − 1714
+ − 1715 - Any modifier bit which is assigned to a keycode which generates Meta_L
+ − 1716 or Meta_R is the modifier bit meaning "meta". Likewise for Super, Hyper,
+ − 1717 etc.
+ − 1718
+ − 1719 - Any keypress event which contains ModControl in its state should be
+ − 1720 interpreted as a "control" character.
+ − 1721
+ − 1722 - Any keypress event which contains a modifier bit in its state which is
+ − 1723 generated by a keycode whose corresponding keysym is Meta_L or Meta_R
+ − 1724 should be interpreted as a "meta" character. Likewise for Super, Hyper,
+ − 1725 etc.
+ − 1726
+ − 1727 - It is illegal for a keysym to be associated with more than one modifier
+ − 1728 bit.
+ − 1729
+ − 1730 This means that the only thing that emacs can reasonably interpret as a
+ − 1731 "meta" key is a key whose keysym is Meta_L or Meta_R, and which generates
+ − 1732 one of the modifier bits Mod1-Mod5.
+ − 1733
+ − 1734 Unfortunately, many keyboards don't have Meta keys in their default
+ − 1735 configuration. So, if there are no Meta keys, but there are "Alt" keys,
+ − 1736 emacs will interpret Alt as Meta. If there are both Meta and Alt keys,
+ − 1737 then the Meta keys mean "Meta", and the Alt keys mean "Alt" (it used to
+ − 1738 mean "Symbol," but that just confused the hell out of way too many people).
+ − 1739
+ − 1740 This works with the default configurations of the 19 keyboard-types I've
+ − 1741 checked.
+ − 1742
+ − 1743 Emacs detects keyboard configurations which violate the above rules, and
+ − 1744 prints an error message on the standard-error-output. (Perhaps it should
+ − 1745 use a pop-up-window instead.)
+ − 1746 */
+ − 1747
+ − 1748 static void
+ − 1749 gtk_reset_key_mapping (struct device *d)
+ − 1750 {
+ − 1751 Display *display = GDK_DISPLAY ();
+ − 1752 struct gtk_device *xd = DEVICE_GTK_DATA (d);
+ − 1753 KeySym *keysym, *keysym_end;
+ − 1754 Lisp_Object hashtable;
+ − 1755 int key_code_count, keysyms_per_code;
+ − 1756
2054
+ − 1757 if (xd->x_keysym_map)
+ − 1758 XFree ((char *) xd->x_keysym_map);
462
+ − 1759 XDisplayKeycodes (display,
+ − 1760 &xd->x_keysym_map_min_code,
+ − 1761 &xd->x_keysym_map_max_code);
+ − 1762 key_code_count = xd->x_keysym_map_max_code - xd->x_keysym_map_min_code + 1;
2054
+ − 1763 xd->x_keysym_map =
462
+ − 1764 XGetKeyboardMapping (display, xd->x_keysym_map_min_code, key_code_count,
+ − 1765 &xd->x_keysym_map_keysyms_per_code);
+ − 1766
+ − 1767 hashtable = xd->x_keysym_map_hashtable;
+ − 1768 if (HASH_TABLEP (hashtable))
+ − 1769 {
+ − 1770 Fclrhash (hashtable);
+ − 1771 }
+ − 1772 else
+ − 1773 {
+ − 1774 xd->x_keysym_map_hashtable = hashtable =
+ − 1775 make_lisp_hash_table (128, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
+ − 1776 }
+ − 1777
2054
+ − 1778 for (keysym = xd->x_keysym_map,
462
+ − 1779 keysyms_per_code = xd->x_keysym_map_keysyms_per_code,
+ − 1780 keysym_end = keysym + (key_code_count * keysyms_per_code);
+ − 1781 keysym < keysym_end;
+ − 1782 keysym += keysyms_per_code)
+ − 1783 {
+ − 1784 int j;
+ − 1785
+ − 1786 if (keysym[0] == NoSymbol)
+ − 1787 continue;
+ − 1788
+ − 1789 {
771
+ − 1790 Extbyte *name = XKeysymToString (keysym[0]);
462
+ − 1791 Lisp_Object sym = gtk_keysym_to_emacs_keysym (keysym[0], 0);
+ − 1792 if (name)
+ − 1793 {
771
+ − 1794 Fputhash (build_ext_string (name, Qnative), Qsans_modifiers,
+ − 1795 hashtable);
462
+ − 1796 Fputhash (sym, Qsans_modifiers, hashtable);
+ − 1797 }
+ − 1798 }
+ − 1799
+ − 1800 for (j = 1; j < keysyms_per_code; j++)
+ − 1801 {
+ − 1802 if (keysym[j] != keysym[0] &&
+ − 1803 keysym[j] != NoSymbol)
+ − 1804 {
771
+ − 1805 Extbyte *name = XKeysymToString (keysym[j]);
462
+ − 1806 Lisp_Object sym = gtk_keysym_to_emacs_keysym (keysym[j], 0);
+ − 1807 if (name && NILP (Fgethash (sym, hashtable, Qnil)))
+ − 1808 {
771
+ − 1809 Fputhash (build_ext_string (name, Qnative), Qt, hashtable);
462
+ − 1810 Fputhash (sym, Qt, hashtable);
+ − 1811 }
+ − 1812 }
+ − 1813 }
+ − 1814 }
+ − 1815 }
+ − 1816
+ − 1817 static const char *
+ − 1818 index_to_name (int indice)
+ − 1819 {
+ − 1820 switch (indice)
+ − 1821 {
+ − 1822 case ShiftMapIndex: return "ModShift";
+ − 1823 case LockMapIndex: return "ModLock";
+ − 1824 case ControlMapIndex: return "ModControl";
+ − 1825 case Mod1MapIndex: return "Mod1";
+ − 1826 case Mod2MapIndex: return "Mod2";
+ − 1827 case Mod3MapIndex: return "Mod3";
+ − 1828 case Mod4MapIndex: return "Mod4";
+ − 1829 case Mod5MapIndex: return "Mod5";
+ − 1830 default: return "???";
+ − 1831 }
+ − 1832 }
+ − 1833
+ − 1834 /* Boy, I really wish C had local functions... */
+ − 1835 struct c_doesnt_have_closures /* #### not yet used */
+ − 1836 {
+ − 1837 int warned_about_overlapping_modifiers;
+ − 1838 int warned_about_predefined_modifiers;
+ − 1839 int warned_about_duplicate_modifiers;
+ − 1840 int meta_bit;
+ − 1841 int hyper_bit;
+ − 1842 int super_bit;
+ − 1843 int alt_bit;
+ − 1844 int mode_bit;
+ − 1845 };
+ − 1846
+ − 1847 static void
+ − 1848 gtk_reset_modifier_mapping (struct device *d)
+ − 1849 {
+ − 1850 Display *display = GDK_DISPLAY ();
+ − 1851 struct gtk_device *xd = DEVICE_GTK_DATA (d);
+ − 1852 int modifier_index, modifier_key, column, mkpm;
+ − 1853 int warned_about_overlapping_modifiers = 0;
+ − 1854 /* int warned_about_predefined_modifiers = 0; */
+ − 1855 /* int warned_about_duplicate_modifiers = 0; */
+ − 1856 int meta_bit = 0;
+ − 1857 int hyper_bit = 0;
+ − 1858 int super_bit = 0;
+ − 1859 int alt_bit = 0;
+ − 1860 int mode_bit = 0;
+ − 1861 XModifierKeymap *map = (XModifierKeymap *) xd->x_modifier_keymap;
+ − 1862
+ − 1863 xd->lock_interpretation = 0;
+ − 1864
+ − 1865 if (map)
+ − 1866 XFreeModifiermap (map);
+ − 1867
+ − 1868 gtk_reset_key_mapping (d);
+ − 1869
+ − 1870 xd->x_modifier_keymap = map = XGetModifierMapping (display);
+ − 1871
+ − 1872 /* Boy, I really wish C had local functions...
+ − 1873 */
+ − 1874
+ − 1875 /* The call to warn_when_safe must be on the same line as the string or
+ − 1876 make-msgfile won't pick it up properly (the newline doesn't confuse
+ − 1877 it, but the backslash does). */
+ − 1878
+ − 1879 #define store_modifier(name,old) \
+ − 1880 old = modifier_index;
+ − 1881
+ − 1882 mkpm = map->max_keypermod;
+ − 1883 for (modifier_index = 0; modifier_index < 8; modifier_index++)
+ − 1884 for (modifier_key = 0; modifier_key < mkpm; modifier_key++) {
+ − 1885 KeySym last_sym = 0;
+ − 1886 for (column = 0; column < 4; column += 2) {
+ − 1887 KeyCode code = map->modifiermap[modifier_index * mkpm
+ − 1888 + modifier_key];
+ − 1889 KeySym sym = (code ? XKeycodeToKeysym (display, code, column) : 0);
+ − 1890 if (sym == last_sym) continue;
+ − 1891 last_sym = sym;
+ − 1892 switch (sym) {
+ − 1893 case XK_Mode_switch:store_modifier ("Mode_switch", mode_bit); break;
+ − 1894 case XK_Meta_L: store_modifier ("Meta_L", meta_bit); break;
+ − 1895 case XK_Meta_R: store_modifier ("Meta_R", meta_bit); break;
+ − 1896 case XK_Super_L: store_modifier ("Super_L", super_bit); break;
+ − 1897 case XK_Super_R: store_modifier ("Super_R", super_bit); break;
+ − 1898 case XK_Hyper_L: store_modifier ("Hyper_L", hyper_bit); break;
+ − 1899 case XK_Hyper_R: store_modifier ("Hyper_R", hyper_bit); break;
+ − 1900 case XK_Alt_L: store_modifier ("Alt_L", alt_bit); break;
+ − 1901 case XK_Alt_R: store_modifier ("Alt_R", alt_bit); break;
+ − 1902 #if 0
+ − 1903 case XK_Control_L: check_modifier ("Control_L", ControlMask); break;
+ − 1904 case XK_Control_R: check_modifier ("Control_R", ControlMask); break;
+ − 1905 case XK_Shift_L: check_modifier ("Shift_L", ShiftMask); break;
+ − 1906 case XK_Shift_R: check_modifier ("Shift_R", ShiftMask); break;
+ − 1907 #endif
+ − 1908 case XK_Shift_Lock: /* check_modifier ("Shift_Lock", LockMask); */
+ − 1909 xd->lock_interpretation = XK_Shift_Lock; break;
+ − 1910 case XK_Caps_Lock: /* check_modifier ("Caps_Lock", LockMask); */
+ − 1911 xd->lock_interpretation = XK_Caps_Lock; break;
+ − 1912
+ − 1913 /* It probably doesn't make any sense for a modifier bit to be
+ − 1914 assigned to a key that is not one of the above, but OpenWindows
+ − 1915 assigns modifier bits to a couple of random function keys for
+ − 1916 no reason that I can discern, so printing a warning here would
+ − 1917 be annoying. */
+ − 1918 }
+ − 1919 }
+ − 1920 }
+ − 1921 #undef store_modifier
+ − 1922 #undef check_modifier
+ − 1923 #undef modwarn
+ − 1924 #undef modbarf
+ − 1925
+ − 1926 /* If there was no Meta key, then try using the Alt key instead.
+ − 1927 If there is both a Meta key and an Alt key, then the Alt key
+ − 1928 is not disturbed and remains an Alt key. */
+ − 1929 if (! meta_bit && alt_bit)
+ − 1930 meta_bit = alt_bit, alt_bit = 0;
+ − 1931
+ − 1932 /* mode_bit overrides everything, since it's processed down inside of
+ − 1933 XLookupString() instead of by us. If Meta and Mode_switch both
+ − 1934 generate the same modifier bit (which is an error), then we don't
+ − 1935 interpret that bit as Meta, because we can't make XLookupString()
+ − 1936 not interpret it as Mode_switch; and interpreting it as both would
+ − 1937 be totally wrong. */
+ − 1938 if (mode_bit)
+ − 1939 {
+ − 1940 const char *warn = 0;
+ − 1941 if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0;
+ − 1942 else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0;
+ − 1943 else if (mode_bit == super_bit) warn = "Super", super_bit = 0;
+ − 1944 else if (mode_bit == alt_bit) warn = "Alt", alt_bit = 0;
+ − 1945 if (warn)
+ − 1946 {
+ − 1947 warn_when_safe
+ − 1948 (Qkey_mapping, Qwarning,
+ − 1949 "XEmacs: %s is being used for both Mode_switch and %s.",
+ − 1950 index_to_name (mode_bit), warn),
+ − 1951 warned_about_overlapping_modifiers = 1;
+ − 1952 }
+ − 1953 }
+ − 1954 #undef index_to_name
+ − 1955
+ − 1956 xd->MetaMask = (meta_bit ? (1 << meta_bit) : 0);
+ − 1957 xd->HyperMask = (hyper_bit ? (1 << hyper_bit) : 0);
+ − 1958 xd->SuperMask = (super_bit ? (1 << super_bit) : 0);
+ − 1959 xd->AltMask = (alt_bit ? (1 << alt_bit) : 0);
+ − 1960 xd->ModeMask = (mode_bit ? (1 << mode_bit) : 0); /* unused */
+ − 1961
+ − 1962 }
+ − 1963
+ − 1964 void
+ − 1965 gtk_init_modifier_mapping (struct device *d)
+ − 1966 {
+ − 1967 struct gtk_device *gd = DEVICE_GTK_DATA (d);
+ − 1968 gd->x_keysym_map_hashtable = Qnil;
+ − 1969 gd->x_keysym_map = NULL;
+ − 1970 gd->x_modifier_keymap = NULL;
+ − 1971 gtk_reset_modifier_mapping (d);
+ − 1972 }
+ − 1973
+ − 1974 #if 0
+ − 1975 static int
+ − 1976 gtk_key_is_modifier_p (KeyCode keycode, struct device *d)
+ − 1977 {
+ − 1978 struct gtk_device *xd = DEVICE_GTK_DATA (d);
+ − 1979 KeySym *syms;
+ − 1980 KeySym *map = (KeySym *) xd->x_keysym_map;
+ − 1981 int i;
+ − 1982
+ − 1983 if (keycode < xd->x_keysym_map_min_code ||
+ − 1984 keycode > xd->x_keysym_map_max_code)
+ − 1985 return 0;
+ − 1986
+ − 1987 syms = &map [(keycode - xd->x_keysym_map_min_code) *
+ − 1988 xd->x_keysym_map_keysyms_per_code];
+ − 1989 for (i = 0; i < xd->x_keysym_map_keysyms_per_code; i++)
+ − 1990 if (IsModifierKey (syms [i]) ||
+ − 1991 syms [i] == XK_Mode_switch) /* why doesn't IsModifierKey count this? */
+ − 1992 return 1;
+ − 1993 return 0;
+ − 1994 }
+ − 1995 #endif