Mercurial > hg > xemacs-beta
comparison src/event-msw.c @ 398:74fd4e045ea6 r21-2-29
Import from CVS: tag r21-2-29
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:13:30 +0200 |
parents | 1f50e6fe4f3f |
children | a86b2b5e0111 |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
54 #include "buffer.h" | 54 #include "buffer.h" |
55 #include "faces.h" | 55 #include "faces.h" |
56 #include "lstream.h" | 56 #include "lstream.h" |
57 #include "process.h" | 57 #include "process.h" |
58 #include "redisplay.h" | 58 #include "redisplay.h" |
59 #include "select.h" | |
59 #include "sysproc.h" | 60 #include "sysproc.h" |
60 #include "syswait.h" | 61 #include "syswait.h" |
61 #include "systime.h" | 62 #include "systime.h" |
62 #include "sysdep.h" | 63 #include "sysdep.h" |
63 #include "objects-msw.h" | 64 #include "objects-msw.h" |
70 typedef unsigned int SOCKET; | 71 typedef unsigned int SOCKET; |
71 #endif | 72 #endif |
72 #include <io.h> | 73 #include <io.h> |
73 #include <errno.h> | 74 #include <errno.h> |
74 | 75 |
76 #if defined (__CYGWIN32__) && (CYGWIN_VERSION_DLL_MAJOR < 20) | |
77 typedef NMHDR *LPNMHDR; | |
78 #endif | |
79 | |
75 #ifdef HAVE_MENUBARS | 80 #ifdef HAVE_MENUBARS |
76 #define ADJR_MENUFLAG TRUE | 81 #define ADJR_MENUFLAG TRUE |
77 #else | 82 #else |
78 #define ADJR_MENUFLAG FALSE | 83 #define ADJR_MENUFLAG FALSE |
79 #endif | 84 #endif |
83 #define FAKE_MOD_QUIT 0x80 | 88 #define FAKE_MOD_QUIT 0x80 |
84 | 89 |
85 /* Timer ID used for button2 emulation */ | 90 /* Timer ID used for button2 emulation */ |
86 #define BUTTON_2_TIMER_ID 1 | 91 #define BUTTON_2_TIMER_ID 1 |
87 | 92 |
88 extern Lisp_Object | |
89 mswindows_get_toolbar_button_text (struct frame* f, int command_id); | |
90 extern Lisp_Object | |
91 mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id); | |
92 extern Lisp_Object | |
93 mswindows_handle_gui_wm_command (struct frame* f, HWND ctrl, WORD id); | |
94 | |
95 static Lisp_Object mswindows_find_frame (HWND hwnd); | 93 static Lisp_Object mswindows_find_frame (HWND hwnd); |
96 static Lisp_Object mswindows_find_console (HWND hwnd); | 94 static Lisp_Object mswindows_find_console (HWND hwnd); |
97 static Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods); | 95 static Lisp_Object mswindows_key_to_emacs_keysym (int mswindows_key, int mods, |
96 int extendedp); | |
98 static int mswindows_modifier_state (BYTE* keymap, int has_AltGr); | 97 static int mswindows_modifier_state (BYTE* keymap, int has_AltGr); |
99 static void mswindows_set_chord_timer (HWND hwnd); | 98 static void mswindows_set_chord_timer (HWND hwnd); |
100 static int mswindows_button2_near_enough (POINTS p1, POINTS p2); | 99 static int mswindows_button2_near_enough (POINTS p1, POINTS p2); |
101 static int mswindows_current_layout_has_AltGr (void); | 100 static int mswindows_current_layout_has_AltGr (void); |
102 | 101 |
117 * one. | 116 * one. |
118 */ | 117 */ |
119 static Lisp_Object mswindows_u_dispatch_event_queue, mswindows_u_dispatch_event_queue_tail; | 118 static Lisp_Object mswindows_u_dispatch_event_queue, mswindows_u_dispatch_event_queue_tail; |
120 static Lisp_Object mswindows_s_dispatch_event_queue, mswindows_s_dispatch_event_queue_tail; | 119 static Lisp_Object mswindows_s_dispatch_event_queue, mswindows_s_dispatch_event_queue_tail; |
121 | 120 |
121 /* For speed: whether there is a WM_PAINT magic message in the system queue */ | |
122 static int mswindows_paint_pending = 0; | |
123 | |
122 /* The number of things we can wait on */ | 124 /* The number of things we can wait on */ |
123 #define MAX_WAITABLE (MAXIMUM_WAIT_OBJECTS - 1) | 125 #define MAX_WAITABLE (MAXIMUM_WAIT_OBJECTS - 1) |
124 | 126 |
125 #ifndef HAVE_MSG_SELECT | 127 #ifndef HAVE_MSG_SELECT |
126 /* List of mswindows waitable handles. */ | 128 /* List of mswindows waitable handles. */ |
127 static HANDLE mswindows_waitable_handles[MAX_WAITABLE]; | 129 static HANDLE mswindows_waitable_handles[MAX_WAITABLE]; |
128 | 130 |
129 /* Number of wait handles */ | 131 /* Number of wait handles */ |
130 static int mswindows_waitable_count=0; | 132 static int mswindows_waitable_count=0; |
131 #endif /* HAVE_MSG_SELECT */ | 133 #endif /* HAVE_MSG_SELECT */ |
134 | |
132 /* Brush for painting widgets */ | 135 /* Brush for painting widgets */ |
133 static HBRUSH widget_brush = 0; | 136 static HBRUSH widget_brush = 0; |
134 static LONG last_widget_brushed = 0; | 137 static LONG last_widget_brushed = 0; |
135 | 138 |
136 /* Count of quit chars currently in the queue */ | 139 /* Count of quit chars currently in the queue */ |
138 Decremented in mswindows_dequeue_dispatch_event() */ | 141 Decremented in mswindows_dequeue_dispatch_event() */ |
139 int mswindows_quit_chars_count = 0; | 142 int mswindows_quit_chars_count = 0; |
140 | 143 |
141 /* These are Lisp integers; see DEFVARS in this file for description. */ | 144 /* These are Lisp integers; see DEFVARS in this file for description. */ |
142 int mswindows_dynamic_frame_resize; | 145 int mswindows_dynamic_frame_resize; |
146 int mswindows_meta_activates_menu; | |
143 int mswindows_num_mouse_buttons; | 147 int mswindows_num_mouse_buttons; |
144 int mswindows_mouse_button_max_skew_x; | 148 int mswindows_mouse_button_max_skew_x; |
145 int mswindows_mouse_button_max_skew_y; | 149 int mswindows_mouse_button_max_skew_y; |
146 int mswindows_mouse_button_tolerance; | 150 int mswindows_mouse_button_tolerance; |
147 | 151 |
191 LONG lock_count; /* Client count of this struct, 0=safe to free */ | 195 LONG lock_count; /* Client count of this struct, 0=safe to free */ |
192 BYTE onebyte; /* One byte buffer read by thread */ | 196 BYTE onebyte; /* One byte buffer read by thread */ |
193 }; | 197 }; |
194 | 198 |
195 #define MAX_SLURP_STREAMS 32 | 199 #define MAX_SLURP_STREAMS 32 |
196 struct ntpipe_slurp_stream_shared_data | 200 struct ntpipe_slurp_stream_shared_data |
197 shared_data_block[MAX_SLURP_STREAMS]={{0}}; | 201 shared_data_block[MAX_SLURP_STREAMS]={{0}}; |
198 | 202 |
199 struct ntpipe_slurp_stream | 203 struct ntpipe_slurp_stream |
200 { | 204 { |
201 LPARAM user_data; /* Any user data stored in the stream object */ | 205 LPARAM user_data; /* Any user data stored in the stream object */ |
263 /* Before we notify caller, we unsignal our event. */ | 267 /* Before we notify caller, we unsignal our event. */ |
264 ResetEvent (s->hev_thread); | 268 ResetEvent (s->hev_thread); |
265 | 269 |
266 /* Now we got something to notify caller, either a byte or an | 270 /* Now we got something to notify caller, either a byte or an |
267 error/eof indication. Before we do, allow internal pipe | 271 error/eof indication. Before we do, allow internal pipe |
268 buffer to accumulate little bit more data. | 272 buffer to accumulate little bit more data. |
269 Reader function pulses this event before waiting for | 273 Reader function pulses this event before waiting for |
270 a character, to avoid pipe delay, and to get the byte | 274 a character, to avoid pipe delay, and to get the byte |
271 immediately. */ | 275 immediately. */ |
272 if (!s->die_p) | 276 if (!s->die_p) |
273 WaitForSingleObject (s->hev_unsleep, PIPE_READ_DELAY); | 277 WaitForSingleObject (s->hev_unsleep, PIPE_READ_DELAY); |
352 { | 356 { |
353 struct ntpipe_slurp_stream* s = NTPIPE_SLURP_STREAM_DATA(stream); | 357 struct ntpipe_slurp_stream* s = NTPIPE_SLURP_STREAM_DATA(stream); |
354 return s->thread_data->hev_caller; | 358 return s->thread_data->hev_caller; |
355 } | 359 } |
356 | 360 |
357 static int | 361 static ssize_t |
358 ntpipe_slurp_reader (Lstream *stream, unsigned char *data, size_t size) | 362 ntpipe_slurp_reader (Lstream *stream, unsigned char *data, size_t size) |
359 { | 363 { |
360 /* This function must be called from the main thread only */ | 364 /* This function must be called from the main thread only */ |
361 struct ntpipe_slurp_stream_shared_data* s = | 365 struct ntpipe_slurp_stream_shared_data* s = |
362 NTPIPE_SLURP_STREAM_DATA(stream)->thread_data; | 366 NTPIPE_SLURP_STREAM_DATA(stream)->thread_data; |
363 | 367 |
364 if (!s->die_p) | 368 if (!s->die_p) |
365 { | 369 { |
366 DWORD wait_result; | 370 DWORD wait_result; |
367 /* Disallow pipe read delay for the thread: we need a character | 371 /* Disallow pipe read delay for the thread: we need a character |
368 ASAP */ | 372 ASAP */ |
369 SetEvent (s->hev_unsleep); | 373 SetEvent (s->hev_unsleep); |
370 | 374 |
371 /* Check if we have a character ready. Give it a short delay, | 375 /* Check if we have a character ready. Give it a short delay, |
372 for the thread to awake from pipe delay, just ion case*/ | 376 for the thread to awake from pipe delay, just ion case*/ |
373 wait_result = WaitForSingleObject (s->hev_caller, 2); | 377 wait_result = WaitForSingleObject (s->hev_caller, 2); |
374 | 378 |
375 /* Revert to the normal sleep behavior. */ | 379 /* Revert to the normal sleep behavior. */ |
416 fail if the next call fails. */ | 420 fail if the next call fails. */ |
417 if (bytes_available) | 421 if (bytes_available) |
418 ReadFile (s->hpipe, data, min (bytes_available, size), | 422 ReadFile (s->hpipe, data, min (bytes_available, size), |
419 &bytes_read, NULL); | 423 &bytes_read, NULL); |
420 } | 424 } |
421 | 425 |
422 /* Now we can unblock thread, so it attempts to read more */ | 426 /* Now we can unblock thread, so it attempts to read more */ |
423 SetEvent (s->hev_thread); | 427 SetEvent (s->hev_thread); |
424 return bytes_read + 1; | 428 return bytes_read + 1; |
425 } | 429 } |
426 } | 430 } |
427 return 0; | 431 return 0; |
428 } | 432 } |
429 | 433 |
430 static int | 434 static int |
431 ntpipe_slurp_closer (Lstream *stream) | 435 ntpipe_slurp_closer (Lstream *stream) |
432 { | 436 { |
433 /* This function must be called from the main thread only */ | 437 /* This function must be called from the main thread only */ |
434 struct ntpipe_slurp_stream_shared_data* s = | 438 struct ntpipe_slurp_stream_shared_data* s = |
435 NTPIPE_SLURP_STREAM_DATA(stream)->thread_data; | 439 NTPIPE_SLURP_STREAM_DATA(stream)->thread_data; |
436 | 440 |
437 /* Force thread to stop */ | 441 /* Force thread to stop */ |
438 InterlockedIncrement (&s->die_p); | 442 InterlockedIncrement (&s->die_p); |
439 | 443 |
461 | 465 |
462 #define NTPIPE_SHOVE_STREAM_DATA(stream) \ | 466 #define NTPIPE_SHOVE_STREAM_DATA(stream) \ |
463 LSTREAM_TYPE_DATA (stream, ntpipe_shove) | 467 LSTREAM_TYPE_DATA (stream, ntpipe_shove) |
464 | 468 |
465 #define MAX_SHOVE_BUFFER_SIZE 128 | 469 #define MAX_SHOVE_BUFFER_SIZE 128 |
466 | 470 |
467 struct ntpipe_shove_stream | 471 struct ntpipe_shove_stream |
468 { | 472 { |
469 LPARAM user_data; /* Any user data stored in the stream object */ | 473 LPARAM user_data; /* Any user data stored in the stream object */ |
470 HANDLE hev_thread; /* Our thread blocks on this, signaled by caller */ | 474 HANDLE hev_thread; /* Our thread blocks on this, signaled by caller */ |
471 /* This is an auto-reset object. */ | 475 /* This is an auto-reset object. */ |
488 { | 492 { |
489 struct ntpipe_shove_stream *s = (struct ntpipe_shove_stream*) vparam; | 493 struct ntpipe_shove_stream *s = (struct ntpipe_shove_stream*) vparam; |
490 | 494 |
491 for (;;) | 495 for (;;) |
492 { | 496 { |
493 DWORD bytes_written; | 497 DWORD bytes_written; |
494 | 498 |
495 /* Block on event and wait for a job */ | 499 /* Block on event and wait for a job */ |
496 InterlockedIncrement (&s->idle_p); | 500 InterlockedIncrement (&s->idle_p); |
497 WaitForSingleObject (s->hev_thread, INFINITE); | 501 WaitForSingleObject (s->hev_thread, INFINITE); |
498 | 502 |
525 s->die_p = 0; | 529 s->die_p = 0; |
526 s->error_p = FALSE; | 530 s->error_p = FALSE; |
527 s->hpipe = hpipe; | 531 s->hpipe = hpipe; |
528 s->user_data = param; | 532 s->user_data = param; |
529 | 533 |
530 /* Create reader thread. This could fail, so do not | 534 /* Create reader thread. This could fail, so do not |
531 create the event until thread is created */ | 535 create the event until thread is created */ |
532 s->hthread = CreateThread (NULL, 0, shove_thread, (LPVOID)s, | 536 s->hthread = CreateThread (NULL, 0, shove_thread, (LPVOID)s, |
533 CREATE_SUSPENDED, &thread_id_unused); | 537 CREATE_SUSPENDED, &thread_id_unused); |
534 if (s->hthread == NULL) | 538 if (s->hthread == NULL) |
535 { | 539 { |
554 struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream); | 558 struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream); |
555 return s->user_data; | 559 return s->user_data; |
556 } | 560 } |
557 #endif | 561 #endif |
558 | 562 |
559 static int | 563 static ssize_t |
560 ntpipe_shove_writer (Lstream *stream, const unsigned char *data, size_t size) | 564 ntpipe_shove_writer (Lstream *stream, const unsigned char *data, size_t size) |
561 { | 565 { |
562 struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream); | 566 struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream); |
563 | 567 |
564 if (s->error_p) | 568 if (s->error_p) |
663 } | 667 } |
664 else if (str->bufsize == 0) | 668 else if (str->bufsize == 0) |
665 str->eof_p = 1; | 669 str->eof_p = 1; |
666 } | 670 } |
667 | 671 |
668 static int | 672 static ssize_t |
669 winsock_reader (Lstream *stream, unsigned char *data, size_t size) | 673 winsock_reader (Lstream *stream, unsigned char *data, size_t size) |
670 { | 674 { |
671 struct winsock_stream *str = WINSOCK_STREAM_DATA (stream); | 675 struct winsock_stream *str = WINSOCK_STREAM_DATA (stream); |
672 | 676 |
673 /* If the current operation is not yet complete, there's nothing to | 677 /* If the current operation is not yet complete, there's nothing to |
696 | 700 |
697 if (str->eof_p) | 701 if (str->eof_p) |
698 return 0; | 702 return 0; |
699 if (str->error_p) | 703 if (str->error_p) |
700 return -1; | 704 return -1; |
701 | 705 |
702 /* Return as much of buffer as we have */ | 706 /* Return as much of buffer as we have */ |
703 size = min (size, (size_t) (str->bufsize - str->bufpos)); | 707 size = min (size, (size_t) (str->bufsize - str->bufpos)); |
704 memcpy (data, (void*)((BYTE*)str->buffer + str->bufpos), size); | 708 memcpy (data, (void*)((BYTE*)str->buffer + str->bufpos), size); |
705 str->bufpos += size; | 709 str->bufpos += size; |
706 | 710 |
709 winsock_initiate_read (str); | 713 winsock_initiate_read (str); |
710 | 714 |
711 return size; | 715 return size; |
712 } | 716 } |
713 | 717 |
714 static int | 718 static ssize_t |
715 winsock_writer (Lstream *stream, CONST unsigned char *data, size_t size) | 719 winsock_writer (Lstream *stream, const unsigned char *data, size_t size) |
716 { | 720 { |
717 struct winsock_stream *str = WINSOCK_STREAM_DATA (stream); | 721 struct winsock_stream *str = WINSOCK_STREAM_DATA (stream); |
718 | 722 |
719 if (str->pending_p) | 723 if (str->pending_p) |
720 { | 724 { |
737 if (str->error_p) | 741 if (str->error_p) |
738 return -1; | 742 return -1; |
739 | 743 |
740 if (size == 0) | 744 if (size == 0) |
741 return 0; | 745 return 0; |
742 | 746 |
743 { | 747 { |
744 ResetEvent (str->ov.hEvent); | 748 ResetEvent (str->ov.hEvent); |
745 | 749 |
746 /* Docs indicate that 4th parameter to WriteFile can be NULL since this is | 750 /* Docs indicate that 4th parameter to WriteFile can be NULL since this is |
747 * an overlapped operation. This fails on Win95 with winsock 1.x so we | 751 * an overlapped operation. This fails on Win95 with winsock 1.x so we |
783 struct winsock_stream *str = WINSOCK_STREAM_DATA (stream); | 787 struct winsock_stream *str = WINSOCK_STREAM_DATA (stream); |
784 return str->blocking_p; | 788 return str->blocking_p; |
785 } | 789 } |
786 | 790 |
787 static Lisp_Object | 791 static Lisp_Object |
788 make_winsock_stream_1 (SOCKET s, LPARAM param, CONST char *mode) | 792 make_winsock_stream_1 (SOCKET s, LPARAM param, const char *mode) |
789 { | 793 { |
790 Lisp_Object obj; | 794 Lisp_Object obj; |
791 Lstream *lstr = Lstream_new (lstream_winsock, mode); | 795 Lstream *lstr = Lstream_new (lstream_winsock, mode); |
792 struct winsock_stream *str = WINSOCK_STREAM_DATA (lstr); | 796 struct winsock_stream *str = WINSOCK_STREAM_DATA (lstr); |
793 | 797 |
851 /************************************************************************/ | 855 /************************************************************************/ |
852 /* Dispatch queue management */ | 856 /* Dispatch queue management */ |
853 /************************************************************************/ | 857 /************************************************************************/ |
854 | 858 |
855 static int | 859 static int |
856 mswindows_user_event_p (struct Lisp_Event* sevt) | 860 mswindows_user_event_p (Lisp_Event* sevt) |
857 { | 861 { |
858 return (sevt->event_type == key_press_event | 862 return (sevt->event_type == key_press_event |
859 || sevt->event_type == button_press_event | 863 || sevt->event_type == button_press_event |
860 || sevt->event_type == button_release_event | 864 || sevt->event_type == button_release_event |
861 || sevt->event_type == misc_user_event); | 865 || sevt->event_type == misc_user_event); |
862 } | 866 } |
863 | 867 |
864 /* | 868 /* |
865 * Add an emacs event to the proper dispatch queue | 869 * Add an emacs event to the proper dispatch queue |
866 */ | 870 */ |
867 static void | 871 static void |
868 mswindows_enqueue_dispatch_event (Lisp_Object event) | 872 mswindows_enqueue_dispatch_event (Lisp_Object event) |
869 { | 873 { |
870 int user_p = mswindows_user_event_p (XEVENT(event)); | 874 int user_p = mswindows_user_event_p (XEVENT(event)); |
871 enqueue_event (event, | 875 enqueue_event (event, |
872 user_p ? &mswindows_u_dispatch_event_queue : | 876 user_p ? &mswindows_u_dispatch_event_queue : |
873 &mswindows_s_dispatch_event_queue, | 877 &mswindows_s_dispatch_event_queue, |
874 user_p ? &mswindows_u_dispatch_event_queue_tail : | 878 user_p ? &mswindows_u_dispatch_event_queue_tail : |
875 &mswindows_s_dispatch_event_queue_tail); | 879 &mswindows_s_dispatch_event_queue_tail); |
876 | 880 |
877 /* Avoid blocking on WaitMessage */ | 881 /* Avoid blocking on WaitMessage */ |
887 void | 891 void |
888 mswindows_enqueue_misc_user_event (Lisp_Object channel, Lisp_Object function, | 892 mswindows_enqueue_misc_user_event (Lisp_Object channel, Lisp_Object function, |
889 Lisp_Object object) | 893 Lisp_Object object) |
890 { | 894 { |
891 Lisp_Object event = Fmake_event (Qnil, Qnil); | 895 Lisp_Object event = Fmake_event (Qnil, Qnil); |
892 struct Lisp_Event* e = XEVENT (event); | 896 Lisp_Event* e = XEVENT (event); |
893 | 897 |
894 e->event_type = misc_user_event; | 898 e->event_type = misc_user_event; |
895 e->channel = channel; | 899 e->channel = channel; |
900 e->timestamp = GetTickCount (); | |
896 e->event.misc.function = function; | 901 e->event.misc.function = function; |
897 e->event.misc.object = object; | 902 e->event.misc.object = object; |
898 | 903 |
899 mswindows_enqueue_dispatch_event (event); | 904 mswindows_enqueue_dispatch_event (event); |
900 } | 905 } |
901 | 906 |
902 void | 907 void |
903 mswindows_enqueue_magic_event (HWND hwnd, UINT message) | 908 mswindows_enqueue_magic_event (HWND hwnd, UINT msg) |
904 { | 909 { |
905 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 910 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
906 struct Lisp_Event* event = XEVENT (emacs_event); | 911 Lisp_Event* event = XEVENT (emacs_event); |
907 | 912 |
908 event->channel = hwnd ? mswindows_find_frame (hwnd) : Qnil; | 913 event->channel = hwnd ? mswindows_find_frame (hwnd) : Qnil; |
909 event->timestamp = GetMessageTime(); | 914 event->timestamp = GetMessageTime(); |
910 event->event_type = magic_event; | 915 event->event_type = magic_event; |
911 EVENT_MSWINDOWS_MAGIC_TYPE (event) = message; | 916 EVENT_MSWINDOWS_MAGIC_TYPE (event) = msg; |
912 | 917 |
913 mswindows_enqueue_dispatch_event (emacs_event); | 918 mswindows_enqueue_dispatch_event (emacs_event); |
914 } | 919 } |
915 | 920 |
916 static void | 921 static void |
917 mswindows_enqueue_process_event (struct Lisp_Process* p) | 922 mswindows_enqueue_process_event (Lisp_Process* p) |
918 { | 923 { |
919 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 924 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
920 struct Lisp_Event* event = XEVENT (emacs_event); | 925 Lisp_Event* event = XEVENT (emacs_event); |
921 Lisp_Object process; | 926 Lisp_Object process; |
922 XSETPROCESS (process, p); | 927 XSETPROCESS (process, p); |
923 | 928 |
924 event->event_type = process_event; | 929 event->event_type = process_event; |
925 event->timestamp = GetTickCount (); | 930 event->timestamp = GetTickCount (); |
927 | 932 |
928 mswindows_enqueue_dispatch_event (emacs_event); | 933 mswindows_enqueue_dispatch_event (emacs_event); |
929 } | 934 } |
930 | 935 |
931 static void | 936 static void |
932 mswindows_enqueue_mouse_button_event (HWND hwnd, UINT message, POINTS where, DWORD when) | 937 mswindows_enqueue_mouse_button_event (HWND hwnd, UINT msg, POINTS where, DWORD when) |
933 { | 938 { |
934 | 939 |
935 /* We always use last message time, because mouse button | 940 /* We always use last message time, because mouse button |
936 events may get delayed, and XEmacs double click | 941 events may get delayed, and XEmacs double click |
937 recognition will fail */ | 942 recognition will fail */ |
938 | 943 |
939 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 944 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
940 struct Lisp_Event* event = XEVENT(emacs_event); | 945 Lisp_Event* event = XEVENT(emacs_event); |
941 | 946 |
942 event->channel = mswindows_find_frame(hwnd); | 947 event->channel = mswindows_find_frame(hwnd); |
943 event->timestamp = when; | 948 event->timestamp = when; |
944 event->event.button.button = | 949 event->event.button.button = |
945 (message==WM_LBUTTONDOWN || message==WM_LBUTTONUP) ? 1 : | 950 (msg==WM_LBUTTONDOWN || msg==WM_LBUTTONUP) ? 1 : |
946 ((message==WM_RBUTTONDOWN || message==WM_RBUTTONUP) ? 3 : 2); | 951 ((msg==WM_RBUTTONDOWN || msg==WM_RBUTTONUP) ? 3 : 2); |
947 event->event.button.x = where.x; | 952 event->event.button.x = where.x; |
948 event->event.button.y = where.y; | 953 event->event.button.y = where.y; |
949 event->event.button.modifiers = mswindows_modifier_state (NULL, 0); | 954 event->event.button.modifiers = mswindows_modifier_state (NULL, 0); |
950 | 955 |
951 if (message==WM_LBUTTONDOWN || message==WM_MBUTTONDOWN || | 956 if (msg==WM_LBUTTONDOWN || msg==WM_MBUTTONDOWN || |
952 message==WM_RBUTTONDOWN) | 957 msg==WM_RBUTTONDOWN) |
953 { | 958 { |
954 event->event_type = button_press_event; | 959 event->event_type = button_press_event; |
955 SetCapture (hwnd); | 960 SetCapture (hwnd); |
956 /* we need this to make sure the main window regains the focus | 961 /* we need this to make sure the main window regains the focus |
957 from control subwindows */ | 962 from control subwindows */ |
964 else | 969 else |
965 { | 970 { |
966 event->event_type = button_release_event; | 971 event->event_type = button_release_event; |
967 ReleaseCapture (); | 972 ReleaseCapture (); |
968 } | 973 } |
969 | 974 |
970 mswindows_enqueue_dispatch_event (emacs_event); | 975 mswindows_enqueue_dispatch_event (emacs_event); |
971 } | 976 } |
972 | 977 |
973 static void | 978 static void |
974 mswindows_enqueue_keypress_event (HWND hwnd, Lisp_Object keysym, int mods) | 979 mswindows_enqueue_keypress_event (HWND hwnd, Lisp_Object keysym, int mods) |
975 { | 980 { |
976 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 981 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
977 struct Lisp_Event* event = XEVENT(emacs_event); | 982 Lisp_Event* event = XEVENT(emacs_event); |
978 | 983 |
979 event->channel = mswindows_find_console(hwnd); | 984 event->channel = mswindows_find_console(hwnd); |
980 event->timestamp = GetMessageTime(); | 985 event->timestamp = GetMessageTime(); |
981 event->event_type = key_press_event; | 986 event->event_type = key_press_event; |
982 event->event.key.keysym = keysym; | 987 event->event.key.keysym = keysym; |
990 */ | 995 */ |
991 static Lisp_Object | 996 static Lisp_Object |
992 mswindows_dequeue_dispatch_event () | 997 mswindows_dequeue_dispatch_event () |
993 { | 998 { |
994 Lisp_Object event; | 999 Lisp_Object event; |
995 struct Lisp_Event* sevt; | 1000 Lisp_Event* sevt; |
996 | 1001 |
997 assert (!NILP(mswindows_u_dispatch_event_queue) || | 1002 assert (!NILP(mswindows_u_dispatch_event_queue) || |
998 !NILP(mswindows_s_dispatch_event_queue)); | 1003 !NILP(mswindows_s_dispatch_event_queue)); |
999 | 1004 |
1000 event = dequeue_event ( | 1005 event = dequeue_event ( |
1001 NILP(mswindows_u_dispatch_event_queue) ? | 1006 NILP(mswindows_u_dispatch_event_queue) ? |
1002 &mswindows_s_dispatch_event_queue : | 1007 &mswindows_s_dispatch_event_queue : |
1003 &mswindows_u_dispatch_event_queue, | 1008 &mswindows_u_dispatch_event_queue, |
1004 NILP(mswindows_u_dispatch_event_queue) ? | 1009 NILP(mswindows_u_dispatch_event_queue) ? |
1005 &mswindows_s_dispatch_event_queue_tail : | 1010 &mswindows_s_dispatch_event_queue_tail : |
1006 &mswindows_u_dispatch_event_queue_tail); | 1011 &mswindows_u_dispatch_event_queue_tail); |
1007 | 1012 |
1008 sevt = XEVENT(event); | 1013 sevt = XEVENT(event); |
1009 if (sevt->event_type == key_press_event | 1014 if (sevt->event_type == key_press_event |
1024 * event in the queue and that of the given event is non-zero. | 1029 * event in the queue and that of the given event is non-zero. |
1025 * For all other event types, this function aborts. | 1030 * For all other event types, this function aborts. |
1026 */ | 1031 */ |
1027 | 1032 |
1028 Lisp_Object | 1033 Lisp_Object |
1029 mswindows_cancel_dispatch_event (struct Lisp_Event *match) | 1034 mswindows_cancel_dispatch_event (Lisp_Event *match) |
1030 { | 1035 { |
1031 Lisp_Object event; | 1036 Lisp_Object event; |
1032 Lisp_Object previous_event = Qnil; | 1037 Lisp_Object previous_event = Qnil; |
1033 int user_p = mswindows_user_event_p (match); | 1038 int user_p = mswindows_user_event_p (match); |
1034 Lisp_Object* head = user_p ? &mswindows_u_dispatch_event_queue : | 1039 Lisp_Object* head = user_p ? &mswindows_u_dispatch_event_queue : |
1035 &mswindows_s_dispatch_event_queue; | 1040 &mswindows_s_dispatch_event_queue; |
1036 Lisp_Object* tail = user_p ? &mswindows_u_dispatch_event_queue_tail : | 1041 Lisp_Object* tail = user_p ? &mswindows_u_dispatch_event_queue_tail : |
1037 &mswindows_s_dispatch_event_queue_tail; | 1042 &mswindows_s_dispatch_event_queue_tail; |
1038 | 1043 |
1039 assert (match->event_type == timeout_event | 1044 assert (match->event_type == timeout_event |
1040 || match->event_type == key_press_event); | 1045 || match->event_type == key_press_event); |
1041 | 1046 |
1042 EVENT_CHAIN_LOOP (event, *head) | 1047 EVENT_CHAIN_LOOP (event, *head) |
1043 { | 1048 { |
1044 struct Lisp_Event *e = XEVENT (event); | 1049 Lisp_Event *e = XEVENT (event); |
1045 if ((e->event_type == match->event_type) && | 1050 if ((e->event_type == match->event_type) && |
1046 ((e->event_type == timeout_event) ? | 1051 ((e->event_type == timeout_event) ? |
1047 (e->event.timeout.interval_id == match->event.timeout.interval_id) : | 1052 (e->event.timeout.interval_id == match->event.timeout.interval_id) : |
1048 /* Must be key_press_event */ | 1053 /* Must be key_press_event */ |
1049 ((e->event.key.modifiers & match->event.key.modifiers) != 0))) | 1054 ((e->event.key.modifiers & match->event.key.modifiers) != 0))) |
1054 { | 1059 { |
1055 XSET_EVENT_NEXT (previous_event, XEVENT_NEXT (event)); | 1060 XSET_EVENT_NEXT (previous_event, XEVENT_NEXT (event)); |
1056 if (EQ (*tail, event)) | 1061 if (EQ (*tail, event)) |
1057 *tail = previous_event; | 1062 *tail = previous_event; |
1058 } | 1063 } |
1059 | 1064 |
1060 return event; | 1065 return event; |
1061 } | 1066 } |
1062 previous_event = event; | 1067 previous_event = event; |
1063 } | 1068 } |
1064 return Qnil; | 1069 return Qnil; |
1095 { | 1100 { |
1096 int ix = find_waitable_handle (h); | 1101 int ix = find_waitable_handle (h); |
1097 if (ix < 0) | 1102 if (ix < 0) |
1098 return; | 1103 return; |
1099 | 1104 |
1100 mswindows_waitable_handles [ix] = | 1105 mswindows_waitable_handles [ix] = |
1101 mswindows_waitable_handles [--mswindows_waitable_count]; | 1106 mswindows_waitable_handles [--mswindows_waitable_count]; |
1102 } | 1107 } |
1103 #endif /* HAVE_MSG_SELECT */ | 1108 #endif /* HAVE_MSG_SELECT */ |
1104 | 1109 |
1105 | 1110 |
1119 mswindows_protect_modal_loop (Lisp_Object (*bfun) (Lisp_Object barg), | 1124 mswindows_protect_modal_loop (Lisp_Object (*bfun) (Lisp_Object barg), |
1120 Lisp_Object barg) | 1125 Lisp_Object barg) |
1121 { | 1126 { |
1122 Lisp_Object tmp; | 1127 Lisp_Object tmp; |
1123 | 1128 |
1124 ++mswindows_in_modal_loop; | 1129 ++mswindows_in_modal_loop; |
1125 tmp = condition_case_1 (Qt, | 1130 tmp = condition_case_1 (Qt, |
1126 bfun, barg, | 1131 bfun, barg, |
1127 mswindows_modal_loop_error_handler, Qnil); | 1132 mswindows_modal_loop_error_handler, Qnil); |
1128 --mswindows_in_modal_loop; | 1133 --mswindows_in_modal_loop; |
1129 | 1134 |
1143 Fsignal (sym, data); | 1148 Fsignal (sym, data); |
1144 } | 1149 } |
1145 } | 1150 } |
1146 | 1151 |
1147 /* | 1152 /* |
1148 * This is an unsafe part of event pump, guarded by | 1153 * This is an unsafe part of event pump, guarded by |
1149 * condition_case. See mswindows_pump_outstanding_events | 1154 * condition_case. See mswindows_pump_outstanding_events |
1150 */ | 1155 */ |
1151 static Lisp_Object | 1156 static Lisp_Object |
1152 mswindows_unsafe_pump_events (Lisp_Object u_n_u_s_e_d) | 1157 mswindows_unsafe_pump_events (Lisp_Object u_n_u_s_e_d) |
1153 { | 1158 { |
1167 if (do_redisplay) | 1172 if (do_redisplay) |
1168 redisplay (); | 1173 redisplay (); |
1169 | 1174 |
1170 Fdeallocate_event (event); | 1175 Fdeallocate_event (event); |
1171 UNGCPRO; | 1176 UNGCPRO; |
1172 | 1177 |
1173 /* Qt becomes return value of mswindows_pump_outstanding_events | 1178 /* Qt becomes return value of mswindows_pump_outstanding_events |
1174 once we get here */ | 1179 once we get here */ |
1175 return Qt; | 1180 return Qt; |
1176 } | 1181 } |
1177 | 1182 |
1215 /* This function can call lisp */ | 1220 /* This function can call lisp */ |
1216 | 1221 |
1217 Lisp_Object result = Qt; | 1222 Lisp_Object result = Qt; |
1218 struct gcpro gcpro1; | 1223 struct gcpro gcpro1; |
1219 GCPRO1 (result); | 1224 GCPRO1 (result); |
1220 | 1225 |
1221 if (NILP(mswindows_error_caught_in_modal_loop)) | 1226 if (NILP(mswindows_error_caught_in_modal_loop)) |
1222 result = mswindows_protect_modal_loop (mswindows_unsafe_pump_events, Qnil); | 1227 result = mswindows_protect_modal_loop (mswindows_unsafe_pump_events, Qnil); |
1223 UNGCPRO; | 1228 UNGCPRO; |
1224 return result; | 1229 return result; |
1225 } | 1230 } |
1226 | 1231 |
1227 static void | 1232 /* |
1233 * KEYBOARD_ONLY_P is set to non-zero when we are called from | |
1234 * QUITP, and are interesting in keyboard messages only. | |
1235 */ | |
1236 static void | |
1228 mswindows_drain_windows_queue () | 1237 mswindows_drain_windows_queue () |
1229 { | 1238 { |
1230 MSG msg; | 1239 MSG msg; |
1240 | |
1241 /* should call mswindows_need_event_in_modal_loop() if in modal loop */ | |
1242 assert (!mswindows_in_modal_loop); | |
1243 | |
1231 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) | 1244 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) |
1232 { | 1245 { |
1233 /* we have to translate messages that are not sent to the main | 1246 /* We have to translate messages that are not sent to the main |
1234 window. this is so that key presses work ok in things like | 1247 window. This is so that key presses work ok in things like |
1235 edit fields. however, we *musn't* translate message for the | 1248 edit fields. However, we *musn't* translate message for the |
1236 main window as this is handled in the wnd proc. */ | 1249 main window as this is handled in the wnd proc. */ |
1237 if ( GetWindowLong (msg.hwnd, GWL_STYLE) & WS_CHILD ) | 1250 if (GetWindowLong (msg.hwnd, GWL_STYLE) & WS_CHILD) |
1238 { | 1251 { |
1239 TranslateMessage (&msg); | 1252 TranslateMessage (&msg); |
1253 } | |
1254 else if (msg.message == WM_PAINT) | |
1255 { | |
1256 /* hdc will be NULL unless this is a subwindow - in which case we | |
1257 shouldn't have received a paint message for it here. */ | |
1258 assert (msg.wParam == 0); | |
1259 | |
1260 if (!mswindows_paint_pending) | |
1261 { | |
1262 /* Queue a magic event for handling when safe */ | |
1263 mswindows_enqueue_magic_event (msg.hwnd, WM_PAINT); | |
1264 mswindows_paint_pending = 1; | |
1265 } | |
1266 | |
1267 /* Don't dispatch. WM_PAINT is always the last message in the | |
1268 queue so it's OK to just return. */ | |
1269 return; | |
1240 } | 1270 } |
1241 DispatchMessage (&msg); | 1271 DispatchMessage (&msg); |
1242 mswindows_unmodalize_signal_maybe (); | 1272 mswindows_unmodalize_signal_maybe (); |
1243 } | 1273 } |
1244 } | 1274 } |
1245 | 1275 |
1246 /* | 1276 /* |
1247 * This is a special flavor of the mswindows_need_event function, | 1277 * This is a special flavor of the mswindows_need_event function, |
1248 * used while in event pump. Actually, there is only kind of events | 1278 * used while in event pump. Actually, there is only kind of events |
1249 * allowed while in event pump: a timer. An attempt to fetch any | 1279 * allowed while in event pump: a timer. An attempt to fetch any |
1250 * other event leads to a deadlock, as there's no source of user input | 1280 * other event leads to a deadlock, as there's no source of user input |
1251 * ('cause event pump mirrors windows modal loop, which is a sole | 1281 * ('cause event pump mirrors windows modal loop, which is a sole |
1274 while (NILP (mswindows_s_dispatch_event_queue)) | 1304 while (NILP (mswindows_s_dispatch_event_queue)) |
1275 { | 1305 { |
1276 /* We'll deadlock if go waiting */ | 1306 /* We'll deadlock if go waiting */ |
1277 if (mswindows_pending_timers_count == 0) | 1307 if (mswindows_pending_timers_count == 0) |
1278 error ("Deadlock due to an attempt to call next-event in a wrong context"); | 1308 error ("Deadlock due to an attempt to call next-event in a wrong context"); |
1279 | 1309 |
1280 /* Fetch and dispatch any pending timers */ | 1310 /* Fetch and dispatch any pending timers */ |
1281 GetMessage (&msg, NULL, WM_TIMER, WM_TIMER); | 1311 GetMessage (&msg, NULL, WM_TIMER, WM_TIMER); |
1282 DispatchMessage (&msg); | 1312 DispatchMessage (&msg); |
1283 } | 1313 } |
1284 } | 1314 } |
1299 { | 1329 { |
1300 mswindows_need_event_in_modal_loop (badly_p); | 1330 mswindows_need_event_in_modal_loop (badly_p); |
1301 return; | 1331 return; |
1302 } | 1332 } |
1303 | 1333 |
1304 /* Have to drain Windows message queue first, otherwise, we may miss | |
1305 quit char when called from quit_p */ | |
1306 mswindows_drain_windows_queue (); | |
1307 | |
1308 while (NILP (mswindows_u_dispatch_event_queue) | 1334 while (NILP (mswindows_u_dispatch_event_queue) |
1309 && NILP (mswindows_s_dispatch_event_queue)) | 1335 && NILP (mswindows_s_dispatch_event_queue)) |
1310 { | 1336 { |
1311 #ifdef HAVE_MSG_SELECT | 1337 #ifdef HAVE_MSG_SELECT |
1312 int i; | 1338 int i; |
1313 SELECT_TYPE temp_mask = input_wait_mask; | 1339 SELECT_TYPE temp_mask = input_wait_mask; |
1314 EMACS_TIME sometime; | 1340 EMACS_TIME sometime; |
1315 EMACS_SELECT_TIME select_time_to_block, *pointer_to_this; | 1341 EMACS_SELECT_TIME select_time_to_block, *pointer_to_this; |
1316 | 1342 |
1317 if (badly_p) | 1343 if (badly_p) |
1318 pointer_to_this = 0; | 1344 pointer_to_this = 0; |
1319 else | 1345 else |
1320 { | 1346 { |
1321 EMACS_SET_SECS_USECS (sometime, 0, 0); | 1347 EMACS_SET_SECS_USECS (sometime, 0, 0); |
1322 EMACS_TIME_TO_SELECT_TIME (sometime, select_time_to_block); | 1348 EMACS_TIME_TO_SELECT_TIME (sometime, select_time_to_block); |
1323 pointer_to_this = &select_time_to_block; | 1349 pointer_to_this = &select_time_to_block; |
1324 } | 1350 } |
1325 | 1351 |
1326 active = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this); | 1352 active = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this); |
1327 | 1353 |
1328 if (active == 0) | 1354 if (active == 0) |
1329 { | 1355 { |
1356 assert (!badly_p); | |
1330 return; /* timeout */ | 1357 return; /* timeout */ |
1331 } | 1358 } |
1332 else if (active > 0) | 1359 else if (active > 0) |
1333 { | 1360 { |
1334 if (FD_ISSET (windows_fd, &temp_mask)) | 1361 if (FD_ISSET (windows_fd, &temp_mask)) |
1335 { | 1362 { |
1336 mswindows_drain_windows_queue (); | 1363 mswindows_drain_windows_queue (); |
1337 } | 1364 } |
1338 #ifdef HAVE_TTY | 1365 #ifdef HAVE_TTY |
1339 /* Look for a TTY event */ | 1366 /* Look for a TTY event */ |
1340 for (i = 0; i < MAXDESC-1; i++) | 1367 for (i = 0; i < MAXDESC-1; i++) |
1341 { | 1368 { |
1342 /* To avoid race conditions (among other things, an infinite | 1369 /* To avoid race conditions (among other things, an infinite |
1343 loop when called from Fdiscard_input()), we must return | 1370 loop when called from Fdiscard_input()), we must return |
1344 user events ahead of process events. */ | 1371 user events ahead of process events. */ |
1345 if (FD_ISSET (i, &temp_mask) && FD_ISSET (i, &tty_only_mask)) | 1372 if (FD_ISSET (i, &temp_mask) && FD_ISSET (i, &tty_only_mask)) |
1346 { | 1373 { |
1347 struct console *c = tty_find_console_from_fd (i); | 1374 struct console *c = tty_find_console_from_fd (i); |
1348 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 1375 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
1349 struct Lisp_Event* event = XEVENT (emacs_event); | 1376 Lisp_Event* event = XEVENT (emacs_event); |
1350 | 1377 |
1351 assert (c); | 1378 assert (c); |
1352 if (read_event_from_tty_or_stream_desc (event, c, i)) | 1379 if (read_event_from_tty_or_stream_desc (event, c, i)) |
1353 { | 1380 { |
1354 mswindows_enqueue_dispatch_event (emacs_event); | 1381 mswindows_enqueue_dispatch_event (emacs_event); |
1355 return; | 1382 return; |
1362 { | 1389 { |
1363 if (FD_ISSET (i, &temp_mask)) | 1390 if (FD_ISSET (i, &temp_mask)) |
1364 { | 1391 { |
1365 if (FD_ISSET (i, &process_only_mask)) | 1392 if (FD_ISSET (i, &process_only_mask)) |
1366 { | 1393 { |
1367 struct Lisp_Process *p = | 1394 Lisp_Process *p = |
1368 get_process_from_usid (FD_TO_USID(i)); | 1395 get_process_from_usid (FD_TO_USID(i)); |
1369 | 1396 |
1370 mswindows_enqueue_process_event (p); | 1397 mswindows_enqueue_process_event (p); |
1371 } | 1398 } |
1372 else | 1399 else |
1373 { | 1400 { |
1374 /* We might get here when a fake event came | 1401 /* We might get here when a fake event came |
1403 /* This will assert if handle being waited for becomes abandoned. | 1430 /* This will assert if handle being waited for becomes abandoned. |
1404 Not the case currently tho */ | 1431 Not the case currently tho */ |
1405 assert ((!badly_p && active == WAIT_TIMEOUT) || | 1432 assert ((!badly_p && active == WAIT_TIMEOUT) || |
1406 (active >= WAIT_OBJECT_0 && | 1433 (active >= WAIT_OBJECT_0 && |
1407 active <= WAIT_OBJECT_0 + mswindows_waitable_count)); | 1434 active <= WAIT_OBJECT_0 + mswindows_waitable_count)); |
1408 | 1435 |
1409 if (active == WAIT_TIMEOUT) | 1436 if (active == WAIT_TIMEOUT) |
1410 { | 1437 { |
1411 /* No luck trying - just return what we've already got */ | 1438 /* No luck trying - just return what we've already got */ |
1412 return; | 1439 return; |
1413 } | 1440 } |
1418 } | 1445 } |
1419 else | 1446 else |
1420 { | 1447 { |
1421 int ix = active - WAIT_OBJECT_0; | 1448 int ix = active - WAIT_OBJECT_0; |
1422 /* First, try to find which process' output has signaled */ | 1449 /* First, try to find which process' output has signaled */ |
1423 struct Lisp_Process *p = | 1450 Lisp_Process *p = |
1424 get_process_from_usid (HANDLE_TO_USID (mswindows_waitable_handles[ix])); | 1451 get_process_from_usid (HANDLE_TO_USID (mswindows_waitable_handles[ix])); |
1425 if (p != NULL) | 1452 if (p != NULL) |
1426 { | 1453 { |
1427 /* Found a signaled process input handle */ | 1454 /* Found a signaled process input handle */ |
1428 mswindows_enqueue_process_event (p); | 1455 mswindows_enqueue_process_event (p); |
1446 | 1473 |
1447 /************************************************************************/ | 1474 /************************************************************************/ |
1448 /* Event generators */ | 1475 /* Event generators */ |
1449 /************************************************************************/ | 1476 /************************************************************************/ |
1450 | 1477 |
1451 /* | 1478 /* |
1452 * Callback procedure for synchronous timer messages | 1479 * Callback procedure for synchronous timer messages |
1453 */ | 1480 */ |
1454 static void CALLBACK | 1481 static void CALLBACK |
1455 mswindows_wm_timer_callback (HWND hwnd, UINT umsg, UINT id_timer, DWORD dwtime) | 1482 mswindows_wm_timer_callback (HWND hwnd, UINT umsg, UINT id_timer, DWORD dwtime) |
1456 { | 1483 { |
1457 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 1484 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
1458 struct Lisp_Event *event = XEVENT (emacs_event); | 1485 Lisp_Event *event = XEVENT (emacs_event); |
1459 | 1486 |
1460 if (KillTimer (NULL, id_timer)) | 1487 if (KillTimer (NULL, id_timer)) |
1461 --mswindows_pending_timers_count; | 1488 --mswindows_pending_timers_count; |
1462 | 1489 |
1463 event->channel = Qnil; | 1490 event->channel = Qnil; |
1468 event->event.timeout.object = Qnil; | 1495 event->event.timeout.object = Qnil; |
1469 | 1496 |
1470 mswindows_enqueue_dispatch_event (emacs_event); | 1497 mswindows_enqueue_dispatch_event (emacs_event); |
1471 } | 1498 } |
1472 | 1499 |
1473 /* | 1500 /* |
1474 * Callback procedure for dde messages | 1501 * Callback procedure for dde messages |
1475 * | 1502 * |
1476 * We execute a dde Open("file") by simulating a file drop, so dde support | 1503 * We execute a dde Open("file") by simulating a file drop, so dde support |
1477 * depends on dnd support. | 1504 * depends on dnd support. |
1478 */ | 1505 */ |
1479 #ifdef HAVE_DRAGNDROP | 1506 #ifdef HAVE_DRAGNDROP |
1480 HDDEDATA CALLBACK | 1507 HDDEDATA CALLBACK |
1481 mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv, | 1508 mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv, |
1482 HSZ hszTopic, HSZ hszItem, HDDEDATA hdata, | 1509 HSZ hszTopic, HSZ hszItem, HDDEDATA hdata, |
1483 DWORD dwData1, DWORD dwData2) | 1510 DWORD dwData1, DWORD dwData2) |
1484 { | 1511 { |
1485 switch (uType) | 1512 switch (uType) |
1486 { | 1513 { |
1487 case XTYP_CONNECT: | 1514 case XTYP_CONNECT: |
1488 if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system)) | 1515 if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system)) |
1489 return (HDDEDATA)TRUE; | 1516 return (HDDEDATA)TRUE; |
1490 return (HDDEDATA)FALSE; | 1517 return (HDDEDATA)FALSE; |
1491 | 1518 |
1498 if (!(hszItem || DdeCmpStringHandles (hszItem, mswindows_dde_service)) && | 1525 if (!(hszItem || DdeCmpStringHandles (hszItem, mswindows_dde_service)) && |
1499 !(hszTopic || DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system))); | 1526 !(hszTopic || DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system))); |
1500 return (DdeCreateDataHandle (mswindows_dde_mlid, (LPBYTE)pairs, | 1527 return (DdeCreateDataHandle (mswindows_dde_mlid, (LPBYTE)pairs, |
1501 sizeof (pairs), 0L, 0, uFmt, 0)); | 1528 sizeof (pairs), 0L, 0, uFmt, 0)); |
1502 } | 1529 } |
1503 return (HDDEDATA)NULL; | 1530 return (HDDEDATA)NULL; |
1504 | 1531 |
1505 case XTYP_EXECUTE: | 1532 case XTYP_EXECUTE: |
1506 if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system)) | 1533 if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system)) |
1507 { | 1534 { |
1508 DWORD len = DdeGetData (hdata, NULL, 0, 0); | 1535 DWORD len = DdeGetData (hdata, NULL, 0, 0); |
1511 char *filename; | 1538 char *filename; |
1512 struct gcpro gcpro1, gcpro2; | 1539 struct gcpro gcpro1, gcpro2; |
1513 Lisp_Object l_dndlist = Qnil; | 1540 Lisp_Object l_dndlist = Qnil; |
1514 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 1541 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
1515 Lisp_Object frmcons, devcons, concons; | 1542 Lisp_Object frmcons, devcons, concons; |
1516 struct Lisp_Event *event = XEVENT (emacs_event); | 1543 Lisp_Event *event = XEVENT (emacs_event); |
1517 | 1544 |
1518 DdeGetData (hdata, cmd, len, 0); | 1545 DdeGetData (hdata, cmd, len, 0); |
1519 cmd[len] = '\0'; | 1546 cmd[len] = '\0'; |
1520 DdeFreeDataHandle (hdata); | 1547 DdeFreeDataHandle (hdata); |
1521 | 1548 |
1579 Fcons (l_dndlist, Qnil)); | 1606 Fcons (l_dndlist, Qnil)); |
1580 mswindows_enqueue_dispatch_event (emacs_event); | 1607 mswindows_enqueue_dispatch_event (emacs_event); |
1581 UNGCPRO; | 1608 UNGCPRO; |
1582 return (HDDEDATA) DDE_FACK; | 1609 return (HDDEDATA) DDE_FACK; |
1583 } | 1610 } |
1584 DdeFreeDataHandle (hdata); | 1611 DdeFreeDataHandle (hdata); |
1585 return (HDDEDATA) DDE_FNOTPROCESSED; | 1612 return (HDDEDATA) DDE_FNOTPROCESSED; |
1586 | 1613 |
1587 default: | 1614 default: |
1588 return (HDDEDATA) NULL; | 1615 return (HDDEDATA) NULL; |
1589 } | 1616 } |
1590 } | 1617 } |
1591 #endif | 1618 #endif |
1619 | |
1620 /* | |
1621 * Helper to do repainting - repaints can happen both from the windows | |
1622 * procedure and from magic events | |
1623 */ | |
1624 void | |
1625 mswindows_handle_paint (struct frame *frame) | |
1626 { | |
1627 HWND hwnd = FRAME_MSWINDOWS_HANDLE (frame); | |
1628 | |
1629 /* According to the docs we need to check GetUpdateRect() before | |
1630 actually doing a WM_PAINT */ | |
1631 if (GetUpdateRect (hwnd, NULL, FALSE)) | |
1632 { | |
1633 PAINTSTRUCT paintStruct; | |
1634 int x, y, width, height; | |
1635 | |
1636 BeginPaint (hwnd, &paintStruct); | |
1637 x = paintStruct.rcPaint.left; | |
1638 y = paintStruct.rcPaint.top; | |
1639 width = paintStruct.rcPaint.right - paintStruct.rcPaint.left; | |
1640 height = paintStruct.rcPaint.bottom - paintStruct.rcPaint.top; | |
1641 /* Normally we want to ignore expose events when child | |
1642 windows are unmapped, however once we are in the guts of | |
1643 WM_PAINT we need to make sure that we don't register | |
1644 unmaps then because they will not actually occur. */ | |
1645 if (!check_for_ignored_expose (frame, x, y, width, height)) | |
1646 { | |
1647 hold_ignored_expose_registration = 1; | |
1648 mswindows_redraw_exposed_area (frame, x, y, width, height); | |
1649 hold_ignored_expose_registration = 0; | |
1650 } | |
1651 EndPaint (hwnd, &paintStruct); | |
1652 } | |
1653 } | |
1654 | |
1655 /* | |
1656 * Returns 1 if a key is a real modifier or special key, which | |
1657 * is better handled by DefWindowProc | |
1658 */ | |
1659 static int | |
1660 key_needs_default_processing_p (UINT vkey) | |
1661 { | |
1662 if (mswindows_meta_activates_menu && vkey == VK_MENU) | |
1663 return 1; | |
1664 | |
1665 return 0; | |
1666 } | |
1592 | 1667 |
1593 /* | 1668 /* |
1594 * The windows procedure for the window class XEMACS_CLASS | 1669 * The windows procedure for the window class XEMACS_CLASS |
1595 */ | 1670 */ |
1596 LRESULT WINAPI | 1671 LRESULT WINAPI |
1599 /* Note: Remember to initialize emacs_event and event before use. | 1674 /* Note: Remember to initialize emacs_event and event before use. |
1600 This code calls code that can GC. You must GCPRO before calling such code. */ | 1675 This code calls code that can GC. You must GCPRO before calling such code. */ |
1601 Lisp_Object emacs_event = Qnil; | 1676 Lisp_Object emacs_event = Qnil; |
1602 Lisp_Object fobj = Qnil; | 1677 Lisp_Object fobj = Qnil; |
1603 | 1678 |
1604 struct Lisp_Event *event; | 1679 Lisp_Event *event; |
1605 struct frame *frame; | 1680 struct frame *frame; |
1606 struct mswindows_frame* msframe; | 1681 struct mswindows_frame* msframe; |
1607 | 1682 |
1608 switch (message) | 1683 switch (message) |
1609 { | 1684 { |
1685 case WM_DESTROYCLIPBOARD: | |
1686 /* We own the clipboard and someone else wants it. Delete our | |
1687 cached copy of the clipboard contents so we'll ask for it from | |
1688 Windows again when someone does a paste. */ | |
1689 handle_selection_clear(QCLIPBOARD); | |
1690 break; | |
1691 | |
1610 case WM_ERASEBKGND: | 1692 case WM_ERASEBKGND: |
1611 /* Erase background only during non-dynamic sizing */ | 1693 /* Erase background only during non-dynamic sizing */ |
1612 msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); | 1694 msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); |
1613 if (msframe->sizing && !mswindows_dynamic_frame_resize) | 1695 if (msframe->sizing && !mswindows_dynamic_frame_resize) |
1614 goto defproc; | 1696 goto defproc; |
1636 GetKeyboardState (keymap); | 1718 GetKeyboardState (keymap); |
1637 keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] &= ~0x80; | 1719 keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] &= ~0x80; |
1638 SetKeyboardState (keymap); | 1720 SetKeyboardState (keymap); |
1639 } | 1721 } |
1640 }; | 1722 }; |
1641 goto defproc; | 1723 if (key_needs_default_processing_p (wParam)) |
1724 goto defproc; | |
1725 else | |
1726 break; | |
1642 | 1727 |
1643 case WM_KEYDOWN: | 1728 case WM_KEYDOWN: |
1644 case WM_SYSKEYDOWN: | 1729 case WM_SYSKEYDOWN: |
1645 /* In some locales the right-hand Alt key is labelled AltGr. This key | 1730 /* In some locales the right-hand Alt key is labelled AltGr. This key |
1646 * should produce alternative charcaters when combined with another key. | 1731 * should produce alternative charcaters when combined with another key. |
1652 * calling TranslateMessage() unless AltGr is *really* down. */ | 1737 * calling TranslateMessage() unless AltGr is *really* down. */ |
1653 { | 1738 { |
1654 BYTE keymap[256]; | 1739 BYTE keymap[256]; |
1655 int has_AltGr = mswindows_current_layout_has_AltGr (); | 1740 int has_AltGr = mswindows_current_layout_has_AltGr (); |
1656 int mods; | 1741 int mods; |
1742 int extendedp = lParam & 0x1000000; | |
1657 Lisp_Object keysym; | 1743 Lisp_Object keysym; |
1658 | 1744 |
1659 GetKeyboardState (keymap); | 1745 GetKeyboardState (keymap); |
1660 mods = mswindows_modifier_state (keymap, has_AltGr); | 1746 mods = mswindows_modifier_state (keymap, has_AltGr); |
1661 | 1747 |
1662 /* Handle those keys for which TranslateMessage won't generate a WM_CHAR */ | 1748 /* Handle non-printables */ |
1663 if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods))) | 1749 if (!NILP (keysym = mswindows_key_to_emacs_keysym (wParam, mods, |
1750 extendedp))) | |
1664 mswindows_enqueue_keypress_event (hwnd, keysym, mods); | 1751 mswindows_enqueue_keypress_event (hwnd, keysym, mods); |
1665 else | 1752 else /* Normal keys & modifiers */ |
1666 { | 1753 { |
1667 int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd))); | 1754 int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd))); |
1668 BYTE keymap_orig[256]; | 1755 BYTE keymap_orig[256]; |
1669 POINT pnt = { LOWORD (GetMessagePos()), HIWORD (GetMessagePos()) }; | 1756 POINT pnt = { LOWORD (GetMessagePos()), HIWORD (GetMessagePos()) }; |
1670 MSG msg; | 1757 MSG msg; |
1671 | 1758 |
1672 msg.hwnd = hwnd; | 1759 msg.hwnd = hwnd; |
1673 msg.message = message; | 1760 msg.message = message; |
1674 msg.wParam = wParam; | 1761 msg.wParam = wParam; |
1675 msg.lParam = lParam; | 1762 msg.lParam = lParam; |
1676 msg.time = GetMessageTime(); | 1763 msg.time = GetMessageTime(); |
1678 | 1765 |
1679 /* GetKeyboardState() does not work as documented on Win95. We have | 1766 /* GetKeyboardState() does not work as documented on Win95. We have |
1680 * to loosely track Left and Right modifiers on behalf of the OS, | 1767 * to loosely track Left and Right modifiers on behalf of the OS, |
1681 * without screwing up Windows NT which tracks them properly. */ | 1768 * without screwing up Windows NT which tracks them properly. */ |
1682 if (wParam == VK_CONTROL) | 1769 if (wParam == VK_CONTROL) |
1683 keymap [(lParam & 0x1000000) ? VK_RCONTROL : VK_LCONTROL] |= 0x80; | 1770 keymap [extendedp ? VK_RCONTROL : VK_LCONTROL] |= 0x80; |
1684 else if (wParam == VK_MENU) | 1771 else if (wParam == VK_MENU) |
1685 keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] |= 0x80; | 1772 keymap [extendedp ? VK_RMENU : VK_LMENU] |= 0x80; |
1686 | 1773 |
1687 memcpy (keymap_orig, keymap, 256); | 1774 memcpy (keymap_orig, keymap, 256); |
1688 | 1775 |
1689 /* Remove shift modifier from an ascii character */ | 1776 /* Remove shift modifier from an ascii character */ |
1690 mods &= ~MOD_SHIFT; | 1777 mods &= ~MOD_SHIFT; |
1691 | 1778 |
1692 /* Clear control and alt modifiers unless AltGr is pressed */ | 1779 /* Clear control and alt modifiers unless AltGr is pressed */ |
1693 keymap [VK_RCONTROL] = 0; | 1780 keymap [VK_RCONTROL] = 0; |
1694 keymap [VK_LMENU] = 0; | 1781 keymap [VK_LMENU] = 0; |
1695 if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80)) | 1782 if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) |
1783 || !(keymap [VK_RMENU] & 0x80)) | |
1696 { | 1784 { |
1697 keymap [VK_LCONTROL] = 0; | 1785 keymap [VK_LCONTROL] = 0; |
1698 keymap [VK_CONTROL] = 0; | 1786 keymap [VK_CONTROL] = 0; |
1699 keymap [VK_RMENU] = 0; | 1787 keymap [VK_RMENU] = 0; |
1700 keymap [VK_MENU] = 0; | 1788 keymap [VK_MENU] = 0; |
1726 mswindows_enqueue_keypress_event (hwnd, make_char(ch), mods1); | 1814 mswindows_enqueue_keypress_event (hwnd, make_char(ch), mods1); |
1727 } /* while */ | 1815 } /* while */ |
1728 SetKeyboardState (keymap_orig); | 1816 SetKeyboardState (keymap_orig); |
1729 } /* else */ | 1817 } /* else */ |
1730 } | 1818 } |
1731 /* F10 causes menu activation by default. We do not want this */ | 1819 if (key_needs_default_processing_p (wParam)) |
1732 if (wParam != VK_F10) | |
1733 goto defproc; | 1820 goto defproc; |
1734 break; | 1821 else |
1822 break; | |
1735 | 1823 |
1736 case WM_MBUTTONDOWN: | 1824 case WM_MBUTTONDOWN: |
1737 case WM_MBUTTONUP: | 1825 case WM_MBUTTONUP: |
1738 /* Real middle mouse button has nothing to do with emulated one: | 1826 /* Real middle mouse button has nothing to do with emulated one: |
1739 if one wants to exercise fingers playing chords on the mouse, | 1827 if one wants to exercise fingers playing chords on the mouse, |
1740 he is allowed to do that! */ | 1828 he is allowed to do that! */ |
1741 mswindows_enqueue_mouse_button_event (hwnd, message, | 1829 mswindows_enqueue_mouse_button_event (hwnd, message, |
1742 MAKEPOINTS (lParam), GetMessageTime()); | 1830 MAKEPOINTS (lParam), GetMessageTime()); |
1743 break; | 1831 break; |
1744 | 1832 |
1745 case WM_LBUTTONUP: | 1833 case WM_LBUTTONUP: |
1746 msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); | 1834 msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); |
1747 msframe->last_click_time = GetMessageTime(); | 1835 msframe->last_click_time = GetMessageTime(); |
1748 | 1836 |
1749 KillTimer (hwnd, BUTTON_2_TIMER_ID); | 1837 KillTimer (hwnd, BUTTON_2_TIMER_ID); |
1861 msframe->button2_need_lbutton = 1; | 1949 msframe->button2_need_lbutton = 1; |
1862 msframe->last_click_point = MAKEPOINTS (lParam); | 1950 msframe->last_click_point = MAKEPOINTS (lParam); |
1863 } | 1951 } |
1864 msframe->last_click_time = GetMessageTime(); | 1952 msframe->last_click_time = GetMessageTime(); |
1865 break; | 1953 break; |
1866 | 1954 |
1867 case WM_TIMER: | 1955 case WM_TIMER: |
1868 if (wParam == BUTTON_2_TIMER_ID) | 1956 if (wParam == BUTTON_2_TIMER_ID) |
1869 { | 1957 { |
1870 msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); | 1958 msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); |
1871 KillTimer (hwnd, BUTTON_2_TIMER_ID); | 1959 KillTimer (hwnd, BUTTON_2_TIMER_ID); |
1910 event->timestamp = GetMessageTime(); | 1998 event->timestamp = GetMessageTime(); |
1911 event->event_type = pointer_motion_event; | 1999 event->event_type = pointer_motion_event; |
1912 event->event.motion.x = MAKEPOINTS(lParam).x; | 2000 event->event.motion.x = MAKEPOINTS(lParam).x; |
1913 event->event.motion.y = MAKEPOINTS(lParam).y; | 2001 event->event.motion.y = MAKEPOINTS(lParam).y; |
1914 event->event.motion.modifiers = mswindows_modifier_state (NULL, 0); | 2002 event->event.motion.modifiers = mswindows_modifier_state (NULL, 0); |
1915 | 2003 |
1916 mswindows_enqueue_dispatch_event (emacs_event); | 2004 mswindows_enqueue_dispatch_event (emacs_event); |
1917 } | 2005 } |
1918 break; | 2006 break; |
1919 | 2007 |
1920 case WM_CANCELMODE: | 2008 case WM_CANCELMODE: |
1923 selection would be canceled if any */ | 2011 selection would be canceled if any */ |
1924 mswindows_enqueue_misc_user_event (mswindows_find_frame (hwnd), | 2012 mswindows_enqueue_misc_user_event (mswindows_find_frame (hwnd), |
1925 Qcancel_mode_internal, Qnil); | 2013 Qcancel_mode_internal, Qnil); |
1926 break; | 2014 break; |
1927 | 2015 |
2016 case WM_NOTIFY: | |
2017 { | |
2018 LPNMHDR nmhdr = (LPNMHDR)lParam; | |
2019 | |
2020 if (nmhdr->code == TTN_NEEDTEXT) | |
2021 { | |
1928 #ifdef HAVE_TOOLBARS | 2022 #ifdef HAVE_TOOLBARS |
1929 case WM_NOTIFY: | 2023 LPTOOLTIPTEXT tttext = (LPTOOLTIPTEXT)lParam; |
1930 { | 2024 Lisp_Object btext; |
1931 LPTOOLTIPTEXT tttext = (LPTOOLTIPTEXT)lParam; | 2025 |
1932 Lisp_Object btext; | |
1933 if (tttext->hdr.code == TTN_NEEDTEXT) | |
1934 { | |
1935 /* find out which toolbar */ | 2026 /* find out which toolbar */ |
1936 frame = XFRAME (mswindows_find_frame (hwnd)); | 2027 frame = XFRAME (mswindows_find_frame (hwnd)); |
1937 btext = mswindows_get_toolbar_button_text ( frame, | 2028 btext = mswindows_get_toolbar_button_text ( frame, |
1938 tttext->hdr.idFrom ); | 2029 nmhdr->idFrom ); |
1939 | 2030 |
1940 tttext->lpszText = NULL; | 2031 tttext->lpszText = NULL; |
1941 tttext->hinst = NULL; | 2032 tttext->hinst = NULL; |
1942 | 2033 |
1943 if (!NILP(btext)) | 2034 if (!NILP(btext)) |
1944 { | 2035 { |
1945 /* I think this is safe since the text will only go away | 2036 /* I think this is safe since the text will only go away |
1946 when the toolbar does...*/ | 2037 when the toolbar does...*/ |
1947 GET_C_STRING_EXT_DATA_ALLOCA (btext, FORMAT_OS, | 2038 TO_EXTERNAL_FORMAT (LISP_STRING, btext, |
1948 tttext->lpszText); | 2039 C_STRING_ALLOCA, tttext->lpszText, |
2040 Qnative); | |
1949 } | 2041 } |
1950 #if 0 | 2042 #endif |
1951 tttext->uFlags |= TTF_DI_SETITEM; | 2043 } |
1952 #endif | 2044 /* handle tree view callbacks */ |
1953 } | 2045 else if (nmhdr->code == TVN_SELCHANGED) |
2046 { | |
2047 NM_TREEVIEW* ptree = (NM_TREEVIEW*)lParam; | |
2048 frame = XFRAME (mswindows_find_frame (hwnd)); | |
2049 mswindows_handle_gui_wm_command (frame, 0, ptree->itemNew.lParam); | |
2050 } | |
2051 /* handle tab control callbacks */ | |
2052 else if (nmhdr->code == TCN_SELCHANGE) | |
2053 { | |
2054 TC_ITEM item; | |
2055 int idx = SendMessage (nmhdr->hwndFrom, TCM_GETCURSEL, 0, 0); | |
2056 frame = XFRAME (mswindows_find_frame (hwnd)); | |
2057 | |
2058 item.mask = TCIF_PARAM; | |
2059 SendMessage (nmhdr->hwndFrom, TCM_GETITEM, (WPARAM)idx, | |
2060 (LPARAM)&item); | |
2061 | |
2062 mswindows_handle_gui_wm_command (frame, 0, item.lParam); | |
2063 } | |
1954 } | 2064 } |
1955 break; | 2065 break; |
1956 #endif | 2066 |
1957 | |
1958 case WM_PAINT: | 2067 case WM_PAINT: |
1959 { | 2068 /* hdc will be NULL unless this is a subwindow - in which case we |
1960 PAINTSTRUCT paintStruct; | 2069 shouldn't have received a paint message for it here. */ |
1961 | 2070 assert (wParam == 0); |
1962 frame = XFRAME (mswindows_find_frame (hwnd)); | 2071 |
1963 | 2072 /* Can't queue a magic event because windows goes modal and sends paint |
1964 BeginPaint (hwnd, &paintStruct); | 2073 messages directly to the windows procedure when doing solid drags |
1965 mswindows_redraw_exposed_area (frame, | 2074 and the message queue doesn't get processed. */ |
1966 paintStruct.rcPaint.left, paintStruct.rcPaint.top, | 2075 mswindows_handle_paint (XFRAME (mswindows_find_frame (hwnd))); |
1967 paintStruct.rcPaint.right, paintStruct.rcPaint.bottom); | |
1968 EndPaint (hwnd, &paintStruct); | |
1969 } | |
1970 break; | 2076 break; |
1971 | 2077 |
1972 case WM_SIZE: | 2078 case WM_SIZE: |
1973 /* We only care about this message if our size has really changed */ | 2079 /* We only care about this message if our size has really changed */ |
1974 if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED || wParam==SIZE_MINIMIZED) | 2080 if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED || wParam==SIZE_MINIMIZED) |
2006 /* If we are inside frame creation, we have to apply geometric | 2112 /* If we are inside frame creation, we have to apply geometric |
2007 properties now. */ | 2113 properties now. */ |
2008 if (FRAME_MSWINDOWS_TARGET_RECT (frame)) | 2114 if (FRAME_MSWINDOWS_TARGET_RECT (frame)) |
2009 { | 2115 { |
2010 /* Yes, we have to size again */ | 2116 /* Yes, we have to size again */ |
2011 mswindows_size_frame_internal ( frame, | 2117 mswindows_size_frame_internal ( frame, |
2012 FRAME_MSWINDOWS_TARGET_RECT | 2118 FRAME_MSWINDOWS_TARGET_RECT |
2013 (frame)); | 2119 (frame)); |
2014 /* Reset so we do not get here again. The SetWindowPos call in | 2120 /* Reset so we do not get here again. The SetWindowPos call in |
2015 * mswindows_size_frame_internal can cause recursion here. */ | 2121 * mswindows_size_frame_internal can cause recursion here. */ |
2016 if (FRAME_MSWINDOWS_TARGET_RECT (frame)) | 2122 if (FRAME_MSWINDOWS_TARGET_RECT (frame)) |
2017 { | 2123 { |
2022 else | 2128 else |
2023 { | 2129 { |
2024 if (!msframe->sizing && !FRAME_VISIBLE_P (frame)) | 2130 if (!msframe->sizing && !FRAME_VISIBLE_P (frame)) |
2025 mswindows_enqueue_magic_event (hwnd, XM_MAPFRAME); | 2131 mswindows_enqueue_magic_event (hwnd, XM_MAPFRAME); |
2026 FRAME_VISIBLE_P (frame) = 1; | 2132 FRAME_VISIBLE_P (frame) = 1; |
2027 | 2133 |
2028 if (!msframe->sizing || mswindows_dynamic_frame_resize) | 2134 if (!msframe->sizing || mswindows_dynamic_frame_resize) |
2029 redisplay (); | 2135 redisplay (); |
2030 } | 2136 } |
2031 } | 2137 } |
2032 } | 2138 } |
2113 { | 2219 { |
2114 /* Error during event pumping - cancel scroll */ | 2220 /* Error during event pumping - cancel scroll */ |
2115 SendMessage (hwndScrollBar, WM_CANCELMODE, 0, 0); | 2221 SendMessage (hwndScrollBar, WM_CANCELMODE, 0, 0); |
2116 } | 2222 } |
2117 UNGCPRO; | 2223 UNGCPRO; |
2118 break; | 2224 break; |
2225 } | |
2226 | |
2227 case WM_MOUSEWHEEL: | |
2228 { | |
2229 int keys = LOWORD (wParam); /* Modifier key flags */ | |
2230 int delta = (short) HIWORD (wParam); /* Wheel rotation amount */ | |
2231 struct gcpro gcpro1, gcpro2; | |
2232 | |
2233 if (mswindows_handle_mousewheel_event (mswindows_find_frame (hwnd), keys, delta)) | |
2234 { | |
2235 GCPRO2 (emacs_event, fobj); | |
2236 mswindows_pump_outstanding_events (); /* Can GC */ | |
2237 UNGCPRO; | |
2238 } | |
2239 else | |
2240 goto defproc; | |
2241 break; | |
2119 } | 2242 } |
2120 #endif | 2243 #endif |
2121 | 2244 |
2122 #ifdef HAVE_MENUBARS | 2245 #ifdef HAVE_MENUBARS |
2123 case WM_INITMENU: | 2246 case WM_INITMENU: |
2187 if (ii) | 2310 if (ii) |
2188 { | 2311 { |
2189 Lisp_Object image_instance; | 2312 Lisp_Object image_instance; |
2190 VOID_TO_LISP (image_instance, ii); | 2313 VOID_TO_LISP (image_instance, ii); |
2191 if (IMAGE_INSTANCEP (image_instance) | 2314 if (IMAGE_INSTANCEP (image_instance) |
2192 && | |
2193 IMAGE_INSTANCE_TYPE_P (image_instance, IMAGE_WIDGET) | |
2194 && | 2315 && |
2195 !NILP (XIMAGE_INSTANCE_WIDGET_FACE (image_instance))) | 2316 IMAGE_INSTANCE_TYPE_P (image_instance, IMAGE_WIDGET)) |
2196 { | 2317 { |
2197 /* set colors for the buttons */ | 2318 /* set colors for the buttons */ |
2198 HDC hdc = (HDC)wParam; | 2319 HDC hdc = (HDC)wParam; |
2199 if (last_widget_brushed != ii) | 2320 if (last_widget_brushed != ii) |
2200 { | 2321 { |
2201 if (widget_brush) | 2322 if (widget_brush) |
2202 DeleteObject (widget_brush); | 2323 DeleteObject (widget_brush); |
2203 widget_brush = CreateSolidBrush | 2324 widget_brush = CreateSolidBrush |
2204 (COLOR_INSTANCE_MSWINDOWS_COLOR | 2325 (COLOR_INSTANCE_MSWINDOWS_COLOR |
2205 (XCOLOR_INSTANCE | 2326 (XCOLOR_INSTANCE |
2206 (FACE_BACKGROUND | 2327 (FACE_BACKGROUND |
2207 (XIMAGE_INSTANCE_WIDGET_FACE (image_instance), | 2328 (XIMAGE_INSTANCE_WIDGET_FACE (image_instance), |
2208 XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance))))); | 2329 XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance))))); |
2209 } | 2330 } |
2210 last_widget_brushed = ii; | 2331 last_widget_brushed = ii; |
2211 SetTextColor | 2332 SetTextColor |
2212 (hdc, | 2333 (hdc, |
2213 COLOR_INSTANCE_MSWINDOWS_COLOR | 2334 COLOR_INSTANCE_MSWINDOWS_COLOR |
2214 (XCOLOR_INSTANCE | 2335 (XCOLOR_INSTANCE |
2215 (FACE_FOREGROUND | 2336 (FACE_FOREGROUND |
2216 (XIMAGE_INSTANCE_WIDGET_FACE (image_instance), | 2337 (XIMAGE_INSTANCE_WIDGET_FACE (image_instance), |
2217 XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance))))); | 2338 XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance))))); |
2218 SetBkMode (hdc, OPAQUE); | 2339 SetBkMode (hdc, OPAQUE); |
2219 SetBkColor | 2340 SetBkColor |
2220 (hdc, | 2341 (hdc, |
2221 COLOR_INSTANCE_MSWINDOWS_COLOR | 2342 COLOR_INSTANCE_MSWINDOWS_COLOR |
2222 (XCOLOR_INSTANCE | 2343 (XCOLOR_INSTANCE |
2223 (FACE_BACKGROUND | 2344 (FACE_BACKGROUND |
2224 (XIMAGE_INSTANCE_WIDGET_FACE (image_instance), | 2345 (XIMAGE_INSTANCE_WIDGET_FACE (image_instance), |
2225 XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance))))); | 2346 XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance))))); |
2226 return (LRESULT)widget_brush; | 2347 return (LRESULT)widget_brush; |
2227 } | 2348 } |
2228 } | 2349 } |
2390 /* | 2511 /* |
2391 * Translate a mswindows virtual key to a keysym. | 2512 * Translate a mswindows virtual key to a keysym. |
2392 * Only returns non-Qnil for keys that don't generate WM_CHAR messages | 2513 * Only returns non-Qnil for keys that don't generate WM_CHAR messages |
2393 * or whose ASCII codes (like space) xemacs doesn't like. | 2514 * or whose ASCII codes (like space) xemacs doesn't like. |
2394 * Virtual key values are defined in winresrc.h | 2515 * Virtual key values are defined in winresrc.h |
2395 * XXX I'm not sure that KEYSYM("name") is the best thing to use here. | |
2396 */ | 2516 */ |
2397 Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods) | 2517 Lisp_Object mswindows_key_to_emacs_keysym (int mswindows_key, int mods, |
2398 { | 2518 int extendedp) |
2399 switch (mswindows_key) | 2519 { |
2400 { | 2520 if (extendedp) /* Keys not present on a 82 key keyboard */ |
2401 /* First the predefined ones */ | 2521 { |
2402 case VK_BACK: return QKbackspace; | 2522 switch (mswindows_key) |
2403 case VK_TAB: return QKtab; | 2523 { |
2404 case '\n': return QKlinefeed; /* No VK_LINEFEED in winresrc.h */ | 2524 case VK_RETURN: return KEYSYM ("kp-enter"); |
2405 case VK_RETURN: return QKreturn; | 2525 case VK_PRIOR: return KEYSYM ("prior"); |
2406 case VK_ESCAPE: return QKescape; | 2526 case VK_NEXT: return KEYSYM ("next"); |
2407 case VK_SPACE: return QKspace; | 2527 case VK_END: return KEYSYM ("end"); |
2408 case VK_DELETE: return QKdelete; | 2528 case VK_HOME: return KEYSYM ("home"); |
2409 | 2529 case VK_LEFT: return KEYSYM ("left"); |
2410 /* The rest */ | 2530 case VK_UP: return KEYSYM ("up"); |
2411 case VK_CLEAR: return KEYSYM ("clear"); /* Should do ^L ? */ | 2531 case VK_RIGHT: return KEYSYM ("right"); |
2412 case VK_PRIOR: return KEYSYM ("prior"); | 2532 case VK_DOWN: return KEYSYM ("down"); |
2413 case VK_NEXT: return KEYSYM ("next"); | 2533 case VK_INSERT: return KEYSYM ("insert"); |
2414 case VK_END: return KEYSYM ("end"); | 2534 case VK_DELETE: return QKdelete; |
2415 case VK_HOME: return KEYSYM ("home"); | 2535 } |
2416 case VK_LEFT: return KEYSYM ("left"); | 2536 } |
2417 case VK_UP: return KEYSYM ("up"); | 2537 else |
2418 case VK_RIGHT: return KEYSYM ("right"); | 2538 { |
2419 case VK_DOWN: return KEYSYM ("down"); | 2539 switch (mswindows_key) |
2420 case VK_SELECT: return KEYSYM ("select"); | 2540 { |
2421 case VK_PRINT: return KEYSYM ("print"); | 2541 case VK_BACK: return QKbackspace; |
2422 case VK_EXECUTE: return KEYSYM ("execute"); | 2542 case VK_TAB: return QKtab; |
2423 case VK_SNAPSHOT: return KEYSYM ("print"); | 2543 case '\n': return QKlinefeed; |
2424 case VK_INSERT: return KEYSYM ("insert"); | 2544 case VK_CLEAR: return KEYSYM ("clear"); |
2425 case VK_HELP: return KEYSYM ("help"); | 2545 case VK_RETURN: return QKreturn; |
2426 #if 0 /* XXX What are these supposed to do? */ | 2546 case VK_ESCAPE: return QKescape; |
2427 case VK_LWIN return KEYSYM (""); | 2547 case VK_SPACE: return QKspace; |
2428 case VK_RWIN return KEYSYM (""); | 2548 case VK_PRIOR: return KEYSYM ("kp-prior"); |
2429 #endif | 2549 case VK_NEXT: return KEYSYM ("kp-next"); |
2430 case VK_APPS: return KEYSYM ("menu"); | 2550 case VK_END: return KEYSYM ("kp-end"); |
2431 case VK_F1: return KEYSYM ("f1"); | 2551 case VK_HOME: return KEYSYM ("kp-home"); |
2432 case VK_F2: return KEYSYM ("f2"); | 2552 case VK_LEFT: return KEYSYM ("kp-left"); |
2433 case VK_F3: return KEYSYM ("f3"); | 2553 case VK_UP: return KEYSYM ("kp-up"); |
2434 case VK_F4: return KEYSYM ("f4"); | 2554 case VK_RIGHT: return KEYSYM ("kp-right"); |
2435 case VK_F5: return KEYSYM ("f5"); | 2555 case VK_DOWN: return KEYSYM ("kp-down"); |
2436 case VK_F6: return KEYSYM ("f6"); | 2556 case VK_SELECT: return KEYSYM ("select"); |
2437 case VK_F7: return KEYSYM ("f7"); | 2557 case VK_PRINT: return KEYSYM ("print"); |
2438 case VK_F8: return KEYSYM ("f8"); | 2558 case VK_EXECUTE: return KEYSYM ("execute"); |
2439 case VK_F9: return KEYSYM ("f9"); | 2559 case VK_SNAPSHOT: return KEYSYM ("print"); |
2440 case VK_F10: return KEYSYM ("f10"); | 2560 case VK_INSERT: return KEYSYM ("kp-insert"); |
2441 case VK_F11: return KEYSYM ("f11"); | 2561 case VK_DELETE: return KEYSYM ("kp-delete"); |
2442 case VK_F12: return KEYSYM ("f12"); | 2562 case VK_HELP: return KEYSYM ("help"); |
2443 case VK_F13: return KEYSYM ("f13"); | 2563 #if 0 /* FSF Emacs allows these to return configurable syms/mods */ |
2444 case VK_F14: return KEYSYM ("f14"); | 2564 case VK_LWIN return KEYSYM (""); |
2445 case VK_F15: return KEYSYM ("f15"); | 2565 case VK_RWIN return KEYSYM (""); |
2446 case VK_F16: return KEYSYM ("f16"); | 2566 #endif |
2447 case VK_F17: return KEYSYM ("f17"); | 2567 case VK_APPS: return KEYSYM ("menu"); |
2448 case VK_F18: return KEYSYM ("f18"); | 2568 case VK_NUMPAD0: return KEYSYM ("kp-0"); |
2449 case VK_F19: return KEYSYM ("f19"); | 2569 case VK_NUMPAD1: return KEYSYM ("kp-1"); |
2450 case VK_F20: return KEYSYM ("f20"); | 2570 case VK_NUMPAD2: return KEYSYM ("kp-2"); |
2451 case VK_F21: return KEYSYM ("f21"); | 2571 case VK_NUMPAD3: return KEYSYM ("kp-3"); |
2452 case VK_F22: return KEYSYM ("f22"); | 2572 case VK_NUMPAD4: return KEYSYM ("kp-4"); |
2453 case VK_F23: return KEYSYM ("f23"); | 2573 case VK_NUMPAD5: return KEYSYM ("kp-5"); |
2454 case VK_F24: return KEYSYM ("f24"); | 2574 case VK_NUMPAD6: return KEYSYM ("kp-6"); |
2455 } | 2575 case VK_NUMPAD7: return KEYSYM ("kp-7"); |
2576 case VK_NUMPAD8: return KEYSYM ("kp-8"); | |
2577 case VK_NUMPAD9: return KEYSYM ("kp-9"); | |
2578 case VK_MULTIPLY: return KEYSYM ("kp-multiply"); | |
2579 case VK_ADD: return KEYSYM ("kp-add"); | |
2580 case VK_SEPARATOR: return KEYSYM ("kp-separator"); | |
2581 case VK_SUBTRACT: return KEYSYM ("kp-subtract"); | |
2582 case VK_DECIMAL: return KEYSYM ("kp-decimal"); | |
2583 case VK_DIVIDE: return KEYSYM ("kp-divide"); | |
2584 case VK_F1: return KEYSYM ("f1"); | |
2585 case VK_F2: return KEYSYM ("f2"); | |
2586 case VK_F3: return KEYSYM ("f3"); | |
2587 case VK_F4: return KEYSYM ("f4"); | |
2588 case VK_F5: return KEYSYM ("f5"); | |
2589 case VK_F6: return KEYSYM ("f6"); | |
2590 case VK_F7: return KEYSYM ("f7"); | |
2591 case VK_F8: return KEYSYM ("f8"); | |
2592 case VK_F9: return KEYSYM ("f9"); | |
2593 case VK_F10: return KEYSYM ("f10"); | |
2594 case VK_F11: return KEYSYM ("f11"); | |
2595 case VK_F12: return KEYSYM ("f12"); | |
2596 case VK_F13: return KEYSYM ("f13"); | |
2597 case VK_F14: return KEYSYM ("f14"); | |
2598 case VK_F15: return KEYSYM ("f15"); | |
2599 case VK_F16: return KEYSYM ("f16"); | |
2600 case VK_F17: return KEYSYM ("f17"); | |
2601 case VK_F18: return KEYSYM ("f18"); | |
2602 case VK_F19: return KEYSYM ("f19"); | |
2603 case VK_F20: return KEYSYM ("f20"); | |
2604 case VK_F21: return KEYSYM ("f21"); | |
2605 case VK_F22: return KEYSYM ("f22"); | |
2606 case VK_F23: return KEYSYM ("f23"); | |
2607 case VK_F24: return KEYSYM ("f24"); | |
2608 } | |
2609 } | |
2456 return Qnil; | 2610 return Qnil; |
2457 } | 2611 } |
2458 | 2612 |
2459 /* | 2613 /* |
2460 * Find the console that matches the supplied mswindows window handle | 2614 * Find the console that matches the supplied mswindows window handle |
2508 } | 2662 } |
2509 | 2663 |
2510 static void | 2664 static void |
2511 emacs_mswindows_remove_timeout (int id) | 2665 emacs_mswindows_remove_timeout (int id) |
2512 { | 2666 { |
2513 struct Lisp_Event match_against; | 2667 Lisp_Event match_against; |
2514 Lisp_Object emacs_event; | 2668 Lisp_Object emacs_event; |
2515 | 2669 |
2516 if (KillTimer (NULL, id)) | 2670 if (KillTimer (NULL, id)) |
2517 --mswindows_pending_timers_count; | 2671 --mswindows_pending_timers_count; |
2518 | 2672 |
2544 | 2698 |
2545 /* | 2699 /* |
2546 * Return the next event | 2700 * Return the next event |
2547 */ | 2701 */ |
2548 static void | 2702 static void |
2549 emacs_mswindows_next_event (struct Lisp_Event *emacs_event) | 2703 emacs_mswindows_next_event (Lisp_Event *emacs_event) |
2550 { | 2704 { |
2551 Lisp_Object event, event2; | 2705 Lisp_Object event, event2; |
2552 | 2706 |
2553 mswindows_need_event (1); | 2707 mswindows_need_event (1); |
2554 | 2708 |
2555 event = mswindows_dequeue_dispatch_event (!NILP(mswindows_u_dispatch_event_queue)); | 2709 event = mswindows_dequeue_dispatch_event (); |
2556 XSETEVENT (event2, emacs_event); | 2710 XSETEVENT (event2, emacs_event); |
2557 Fcopy_event (event, event2); | 2711 Fcopy_event (event, event2); |
2558 Fdeallocate_event (event); | 2712 Fdeallocate_event (event); |
2559 } | 2713 } |
2560 | 2714 |
2561 /* | 2715 /* |
2562 * Handle a magic event off the dispatch queue. | 2716 * Handle a magic event off the dispatch queue. |
2563 */ | 2717 */ |
2564 static void | 2718 static void |
2565 emacs_mswindows_handle_magic_event (struct Lisp_Event *emacs_event) | 2719 emacs_mswindows_handle_magic_event (Lisp_Event *emacs_event) |
2566 { | 2720 { |
2567 switch (EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event)) | 2721 switch (EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event)) |
2568 { | 2722 { |
2569 case XM_BUMPQUEUE: | 2723 case XM_BUMPQUEUE: |
2570 break; | 2724 break; |
2571 | 2725 |
2726 case WM_PAINT: | |
2727 mswindows_handle_paint (XFRAME (EVENT_CHANNEL (emacs_event))); | |
2728 mswindows_paint_pending = 0; | |
2729 break; | |
2730 | |
2572 case WM_SETFOCUS: | 2731 case WM_SETFOCUS: |
2573 case WM_KILLFOCUS: | 2732 case WM_KILLFOCUS: |
2574 { | 2733 { |
2575 Lisp_Object frame = EVENT_CHANNEL (emacs_event); | 2734 Lisp_Object frame = EVENT_CHANNEL (emacs_event); |
2576 struct frame *f = XFRAME (frame); | 2735 struct frame *f = XFRAME (frame); |
2594 | 2753 |
2595 case XM_MAPFRAME: | 2754 case XM_MAPFRAME: |
2596 case XM_UNMAPFRAME: | 2755 case XM_UNMAPFRAME: |
2597 { | 2756 { |
2598 Lisp_Object frame = EVENT_CHANNEL (emacs_event); | 2757 Lisp_Object frame = EVENT_CHANNEL (emacs_event); |
2599 va_run_hook_with_args (EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event) | 2758 va_run_hook_with_args (EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event) |
2600 == XM_MAPFRAME ? | 2759 == XM_MAPFRAME ? |
2601 Qmap_frame_hook : Qunmap_frame_hook, | 2760 Qmap_frame_hook : Qunmap_frame_hook, |
2602 1, frame); | 2761 1, frame); |
2603 } | 2762 } |
2604 break; | 2763 break; |
2605 | 2764 |
2606 /* #### What about Enter & Leave */ | 2765 /* #### What about Enter & Leave */ |
2607 #if 0 | 2766 #if 0 |
2608 va_run_hook_with_args (in_p ? Qmouse_enter_frame_hook : | 2767 va_run_hook_with_args (in_p ? Qmouse_enter_frame_hook : |
2609 Qmouse_leave_frame_hook, 1, frame); | 2768 Qmouse_leave_frame_hook, 1, frame); |
2610 #endif | 2769 #endif |
2614 } | 2773 } |
2615 } | 2774 } |
2616 | 2775 |
2617 #ifndef HAVE_MSG_SELECT | 2776 #ifndef HAVE_MSG_SELECT |
2618 static HANDLE | 2777 static HANDLE |
2619 get_process_input_waitable (struct Lisp_Process *process) | 2778 get_process_input_waitable (Lisp_Process *process) |
2620 { | 2779 { |
2621 Lisp_Object instr, outstr, p; | 2780 Lisp_Object instr, outstr, p; |
2622 XSETPROCESS (p, process); | 2781 XSETPROCESS (p, process); |
2623 get_process_streams (process, &instr, &outstr); | 2782 get_process_streams (process, &instr, &outstr); |
2624 assert (!NILP (instr)); | 2783 assert (!NILP (instr)); |
2630 return get_ntpipe_input_stream_waitable (XLSTREAM (instr)); | 2789 return get_ntpipe_input_stream_waitable (XLSTREAM (instr)); |
2631 #endif | 2790 #endif |
2632 } | 2791 } |
2633 | 2792 |
2634 static void | 2793 static void |
2635 emacs_mswindows_select_process (struct Lisp_Process *process) | 2794 emacs_mswindows_select_process (Lisp_Process *process) |
2636 { | 2795 { |
2637 HANDLE hev = get_process_input_waitable (process); | 2796 HANDLE hev = get_process_input_waitable (process); |
2638 | 2797 |
2639 if (!add_waitable_handle (hev)) | 2798 if (!add_waitable_handle (hev)) |
2640 error ("Too many active processes"); | 2799 error ("Too many active processes"); |
2655 } | 2814 } |
2656 #endif | 2815 #endif |
2657 } | 2816 } |
2658 | 2817 |
2659 static void | 2818 static void |
2660 emacs_mswindows_unselect_process (struct Lisp_Process *process) | 2819 emacs_mswindows_unselect_process (Lisp_Process *process) |
2661 { | 2820 { |
2662 /* Process handle is removed in the event loop as soon | 2821 /* Process handle is removed in the event loop as soon |
2663 as it is signaled, so don't bother here about it */ | 2822 as it is signaled, so don't bother here about it */ |
2664 HANDLE hev = get_process_input_waitable (process); | 2823 HANDLE hev = get_process_input_waitable (process); |
2665 remove_waitable_handle (hev); | 2824 remove_waitable_handle (hev); |
2689 } | 2848 } |
2690 | 2849 |
2691 static void | 2850 static void |
2692 emacs_mswindows_quit_p (void) | 2851 emacs_mswindows_quit_p (void) |
2693 { | 2852 { |
2694 MSG msg; | |
2695 | |
2696 /* Quit cannot happen in modal loop: all program | 2853 /* Quit cannot happen in modal loop: all program |
2697 input is dedicated to Windows. */ | 2854 input is dedicated to Windows. */ |
2698 if (mswindows_in_modal_loop) | 2855 if (mswindows_in_modal_loop) |
2699 return; | 2856 return; |
2700 | 2857 |
2701 /* Drain windows queue. This sets up number of quit characters in the queue | 2858 /* Drain windows queue. This sets up number of quit characters in |
2702 * (and also processes wm focus change, move, resize, etc messages). | 2859 the queue */ |
2703 * We don't want to process WM_PAINT messages because this function can be | 2860 mswindows_drain_windows_queue (); |
2704 * called from almost anywhere and the windows' states may be changing. */ | |
2705 while (PeekMessage (&msg, NULL, 0, WM_PAINT-1, PM_REMOVE) || | |
2706 PeekMessage (&msg, NULL, WM_PAINT+1, WM_USER-1, PM_REMOVE)) | |
2707 DispatchMessage (&msg); | |
2708 | 2861 |
2709 if (mswindows_quit_chars_count > 0) | 2862 if (mswindows_quit_chars_count > 0) |
2710 { | 2863 { |
2711 /* Yes there's a hidden one... Throw it away */ | 2864 /* Yes there's a hidden one... Throw it away */ |
2712 struct Lisp_Event match_against; | 2865 Lisp_Event match_against; |
2713 Lisp_Object emacs_event; | 2866 Lisp_Object emacs_event; |
2867 int critical_p = 0; | |
2714 | 2868 |
2715 match_against.event_type = key_press_event; | 2869 match_against.event_type = key_press_event; |
2716 match_against.event.key.modifiers = FAKE_MOD_QUIT; | 2870 match_against.event.key.modifiers = FAKE_MOD_QUIT; |
2717 | 2871 |
2718 emacs_event = mswindows_cancel_dispatch_event (&match_against); | 2872 while (mswindows_quit_chars_count-- > 0) |
2719 assert (!NILP (emacs_event)); | 2873 { |
2720 | 2874 emacs_event = mswindows_cancel_dispatch_event (&match_against); |
2721 Vquit_flag = (XEVENT(emacs_event)->event.key.modifiers & MOD_SHIFT | 2875 assert (!NILP (emacs_event)); |
2722 ? Qcritical : Qt); | 2876 |
2723 | 2877 if (XEVENT(emacs_event)->event.key.modifiers & MOD_SHIFT) |
2724 Fdeallocate_event(emacs_event); | 2878 critical_p = 1; |
2725 --mswindows_quit_chars_count; | 2879 |
2880 Fdeallocate_event(emacs_event); | |
2881 } | |
2882 | |
2883 Vquit_flag = critical_p ? Qcritical : Qt; | |
2726 } | 2884 } |
2727 } | 2885 } |
2728 | 2886 |
2729 USID | 2887 USID |
2730 emacs_mswindows_create_stream_pair (void* inhandle, void* outhandle, | 2888 emacs_mswindows_create_stream_pair (void* inhandle, void* outhandle, |
2832 #ifndef HAVE_X_WINDOWS | 2990 #ifndef HAVE_X_WINDOWS |
2833 /* This is called from GC when a process object is about to be freed. | 2991 /* This is called from GC when a process object is about to be freed. |
2834 If we've still got pointers to it in this file, we're gonna lose hard. | 2992 If we've still got pointers to it in this file, we're gonna lose hard. |
2835 */ | 2993 */ |
2836 void | 2994 void |
2837 debug_process_finalization (struct Lisp_Process *p) | 2995 debug_process_finalization (Lisp_Process *p) |
2838 { | 2996 { |
2839 #if 0 /* #### */ | 2997 #if 0 /* #### */ |
2840 Lisp_Object instr, outstr; | 2998 Lisp_Object instr, outstr; |
2841 | 2999 |
2842 get_process_streams (p, &instr, &outstr); | 3000 get_process_streams (p, &instr, &outstr); |
2850 #endif | 3008 #endif |
2851 | 3009 |
2852 /************************************************************************/ | 3010 /************************************************************************/ |
2853 /* initialization */ | 3011 /* initialization */ |
2854 /************************************************************************/ | 3012 /************************************************************************/ |
2855 | 3013 |
2856 void | 3014 void |
2857 vars_of_event_mswindows (void) | 3015 reinit_vars_of_event_mswindows (void) |
2858 { | 3016 { |
2859 mswindows_u_dispatch_event_queue = Qnil; | |
2860 staticpro (&mswindows_u_dispatch_event_queue); | |
2861 mswindows_u_dispatch_event_queue_tail = Qnil; | |
2862 | |
2863 mswindows_s_dispatch_event_queue = Qnil; | |
2864 staticpro (&mswindows_s_dispatch_event_queue); | |
2865 mswindows_s_dispatch_event_queue_tail = Qnil; | |
2866 | |
2867 mswindows_error_caught_in_modal_loop = Qnil; | |
2868 staticpro (&mswindows_error_caught_in_modal_loop); | |
2869 mswindows_in_modal_loop = 0; | 3017 mswindows_in_modal_loop = 0; |
2870 mswindows_pending_timers_count = 0; | 3018 mswindows_pending_timers_count = 0; |
2871 | 3019 |
2872 mswindows_event_stream = xnew (struct event_stream); | 3020 mswindows_event_stream = xnew (struct event_stream); |
2873 | 3021 |
2878 mswindows_event_stream->remove_timeout_cb = emacs_mswindows_remove_timeout; | 3026 mswindows_event_stream->remove_timeout_cb = emacs_mswindows_remove_timeout; |
2879 mswindows_event_stream->quit_p_cb = emacs_mswindows_quit_p; | 3027 mswindows_event_stream->quit_p_cb = emacs_mswindows_quit_p; |
2880 mswindows_event_stream->select_console_cb = emacs_mswindows_select_console; | 3028 mswindows_event_stream->select_console_cb = emacs_mswindows_select_console; |
2881 mswindows_event_stream->unselect_console_cb = emacs_mswindows_unselect_console; | 3029 mswindows_event_stream->unselect_console_cb = emacs_mswindows_unselect_console; |
2882 #ifdef HAVE_MSG_SELECT | 3030 #ifdef HAVE_MSG_SELECT |
2883 mswindows_event_stream->select_process_cb = | 3031 mswindows_event_stream->select_process_cb = |
2884 (void (*)(struct Lisp_Process*))event_stream_unixoid_select_process; | 3032 (void (*)(Lisp_Process*))event_stream_unixoid_select_process; |
2885 mswindows_event_stream->unselect_process_cb = | 3033 mswindows_event_stream->unselect_process_cb = |
2886 (void (*)(struct Lisp_Process*))event_stream_unixoid_unselect_process; | 3034 (void (*)(Lisp_Process*))event_stream_unixoid_unselect_process; |
2887 mswindows_event_stream->create_stream_pair_cb = event_stream_unixoid_create_stream_pair; | 3035 mswindows_event_stream->create_stream_pair_cb = event_stream_unixoid_create_stream_pair; |
2888 mswindows_event_stream->delete_stream_pair_cb = event_stream_unixoid_delete_stream_pair; | 3036 mswindows_event_stream->delete_stream_pair_cb = event_stream_unixoid_delete_stream_pair; |
2889 #else | 3037 #else |
2890 mswindows_event_stream->select_process_cb = emacs_mswindows_select_process; | 3038 mswindows_event_stream->select_process_cb = emacs_mswindows_select_process; |
2891 mswindows_event_stream->unselect_process_cb = emacs_mswindows_unselect_process; | 3039 mswindows_event_stream->unselect_process_cb = emacs_mswindows_unselect_process; |
2892 mswindows_event_stream->create_stream_pair_cb = emacs_mswindows_create_stream_pair; | 3040 mswindows_event_stream->create_stream_pair_cb = emacs_mswindows_create_stream_pair; |
2893 mswindows_event_stream->delete_stream_pair_cb = emacs_mswindows_delete_stream_pair; | 3041 mswindows_event_stream->delete_stream_pair_cb = emacs_mswindows_delete_stream_pair; |
2894 #endif | 3042 #endif |
3043 } | |
3044 | |
3045 void | |
3046 vars_of_event_mswindows (void) | |
3047 { | |
3048 reinit_vars_of_event_mswindows (); | |
3049 | |
3050 mswindows_u_dispatch_event_queue = Qnil; | |
3051 staticpro (&mswindows_u_dispatch_event_queue); | |
3052 mswindows_u_dispatch_event_queue_tail = Qnil; | |
3053 pdump_wire (&mswindows_u_dispatch_event_queue_tail); | |
3054 | |
3055 mswindows_s_dispatch_event_queue = Qnil; | |
3056 staticpro (&mswindows_s_dispatch_event_queue); | |
3057 mswindows_s_dispatch_event_queue_tail = Qnil; | |
3058 pdump_wire (&mswindows_s_dispatch_event_queue_tail); | |
3059 | |
3060 mswindows_error_caught_in_modal_loop = Qnil; | |
3061 staticpro (&mswindows_error_caught_in_modal_loop); | |
3062 | |
3063 DEFVAR_BOOL ("mswindows-meta-activates-menu", &mswindows_meta_activates_menu /* | |
3064 *Controls whether pressing and releasing the Meta (Alt) key should | |
3065 activate the menubar. | |
3066 Default is t. | |
3067 */ ); | |
2895 | 3068 |
2896 DEFVAR_BOOL ("mswindows-dynamic-frame-resize", &mswindows_dynamic_frame_resize /* | 3069 DEFVAR_BOOL ("mswindows-dynamic-frame-resize", &mswindows_dynamic_frame_resize /* |
2897 *Controls redrawing frame contents during mouse-drag or keyboard resize | 3070 *Controls redrawing frame contents during mouse-drag or keyboard resize |
2898 operation. When non-nil, the frame is redrawn while being resized. When | 3071 operation. When non-nil, the frame is redrawn while being resized. When |
2899 nil, frame is not redrawn, and exposed areas are filled with default | 3072 nil, frame is not redrawn, and exposed areas are filled with default |
2935 */ ); | 3108 */ ); |
2936 | 3109 |
2937 mswindows_mouse_button_max_skew_x = 0; | 3110 mswindows_mouse_button_max_skew_x = 0; |
2938 mswindows_mouse_button_max_skew_y = 0; | 3111 mswindows_mouse_button_max_skew_y = 0; |
2939 mswindows_mouse_button_tolerance = 0; | 3112 mswindows_mouse_button_tolerance = 0; |
3113 mswindows_meta_activates_menu = 1; | |
2940 } | 3114 } |
2941 | 3115 |
2942 void | 3116 void |
2943 syms_of_event_mswindows (void) | 3117 syms_of_event_mswindows (void) |
2944 { | 3118 { |