comparison src/event-gtk.c @ 462:0784d089fdc9 r21-2-46

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