comparison src/event-msw.c @ 380:8626e4521993 r21-2-5

Import from CVS: tag r21-2-5
author cvs
date Mon, 13 Aug 2007 11:07:10 +0200
parents 6240c7796c7a
children 064ab7fed2e0
comparison
equal deleted inserted replaced
379:76b7d63099ad 380:8626e4521993
153 LSTREAM_TYPE_DATA (stream, ntpipe_slurp) 153 LSTREAM_TYPE_DATA (stream, ntpipe_slurp)
154 154
155 /* This structure is allocated by the main thread, and is deallocated 155 /* This structure is allocated by the main thread, and is deallocated
156 in the thread upon exit. There are situations when a thread 156 in the thread upon exit. There are situations when a thread
157 remains blocked for a long time, much longer than the lstream 157 remains blocked for a long time, much longer than the lstream
158 exists. For exmaple, "start notepad" command is issued from the 158 exists. For example, "start notepad" command is issued from the
159 shell, then the shell is closed by C-c C-d. Although the shell 159 shell, then the shell is closed by C-c C-d. Although the shell
160 process exits, its output pipe will not get closed until the 160 process exits, its output pipe will not get closed until the
161 notepad process exits also, because it inherits the pipe form the 161 notepad process exits also, because it inherits the pipe form the
162 shell. In this case, we abandon the thread, and let it live until 162 shell. In this case, we abandon the thread, and let it live until
163 all such processes exit. While struct ntpipe_slurp_stream is 163 all such processes exit. While struct ntpipe_slurp_stream is
192 192
193 DEFINE_LSTREAM_IMPLEMENTATION ("ntpipe-input", lstream_ntpipe_slurp, 193 DEFINE_LSTREAM_IMPLEMENTATION ("ntpipe-input", lstream_ntpipe_slurp,
194 sizeof (struct ntpipe_slurp_stream)); 194 sizeof (struct ntpipe_slurp_stream));
195 195
196 /* This function is thread-safe, and is called from either thread 196 /* This function is thread-safe, and is called from either thread
197 context. It serializes freeing shared dtata structure */ 197 context. It serializes freeing shared data structure */
198 static void 198 static void
199 slurper_free_shared_data_maybe (struct ntpipe_slurp_stream_shared_data* s) 199 slurper_free_shared_data_maybe (struct ntpipe_slurp_stream_shared_data* s)
200 { 200 {
201 if (InterlockedDecrement (&s->lock_count) == 0) 201 if (InterlockedDecrement (&s->lock_count) == 0)
202 { 202 {
266 266
267 /* Cleanup and exit if we're shot off */ 267 /* Cleanup and exit if we're shot off */
268 if (s->die_p) 268 if (s->die_p)
269 break; 269 break;
270 270
271 /* Block until the client finishes with retireving the rest of 271 /* Block until the client finishes with retrieving the rest of
272 pipe data */ 272 pipe data */
273 WaitForSingleObject (s->hev_thread, INFINITE); 273 WaitForSingleObject (s->hev_thread, INFINITE);
274 } 274 }
275 275
276 slurper_free_shared_data_maybe (s); 276 slurper_free_shared_data_maybe (s);
617 LPARAM user_data; /* Any user data stored in the stream object */ 617 LPARAM user_data; /* Any user data stored in the stream object */
618 SOCKET s; /* Socket handle (which is a Win32 handle) */ 618 SOCKET s; /* Socket handle (which is a Win32 handle) */
619 OVERLAPPED ov; /* Overlapped I/O structure */ 619 OVERLAPPED ov; /* Overlapped I/O structure */
620 void* buffer; /* Buffer. Allocated for input stream only */ 620 void* buffer; /* Buffer. Allocated for input stream only */
621 unsigned int bufsize; /* Number of bytes last read */ 621 unsigned int bufsize; /* Number of bytes last read */
622 unsigned int bufpos; /* Psition in buffer for next fetch */ 622 unsigned int bufpos; /* Position in buffer for next fetch */
623 unsigned int error_p :1; /* I/O Error seen */ 623 unsigned int error_p :1; /* I/O Error seen */
624 unsigned int eof_p :1; /* EOF Error seen */ 624 unsigned int eof_p :1; /* EOF Error seen */
625 unsigned int pending_p :1; /* There is a pending I/O operation */ 625 unsigned int pending_p :1; /* There is a pending I/O operation */
626 unsigned int blocking_p :1; /* Last write attempt would block */ 626 unsigned int blocking_p :1; /* Last write attempt would block */
627 }; 627 };
1166 * 1166 *
1167 * Windows message queue is not looked into during the call, 1167 * Windows message queue is not looked into during the call,
1168 * neither are waitable handles checked. The function pumps 1168 * neither are waitable handles checked. The function pumps
1169 * thus only dispatch events already queued, as well as those 1169 * thus only dispatch events already queued, as well as those
1170 * resulted in dispatching thereof. This is done by setting 1170 * resulted in dispatching thereof. This is done by setting
1171 * module local variable mswidows_in_modal_loop to nonzero. 1171 * module local variable mswindows_in_modal_loop to nonzero.
1172 * 1172 *
1173 * Return value is Qt if no errors was trapped, or Qunbound if 1173 * Return value is Qt if no errors was trapped, or Qunbound if
1174 * there was an error. 1174 * there was an error.
1175 * 1175 *
1176 * In case of error, a cons representing the error, in the 1176 * In case of error, a cons representing the error, in the
1184 * assigned Qnil. 1184 * assigned Qnil.
1185 * 1185 *
1186 * If the value of mswindows_error_caught_in_modal_loop is not 1186 * If the value of mswindows_error_caught_in_modal_loop is not
1187 * nil already upon entry, the function just returns non-nil. 1187 * nil already upon entry, the function just returns non-nil.
1188 * This situation means that a new event has been queued while 1188 * This situation means that a new event has been queued while
1189 * cancleng mode. The event will be dequeued on the next regular 1189 * in cancel mode. The event will be dequeued on the next regular
1190 * call of next-event; the pump is off since error is caught. 1190 * call of next-event; the pump is off since error is caught.
1191 * The caller must *unconditionally* cancel modal loop if the 1191 * The caller must *unconditionally* cancel modal loop if the
1192 * value returned by this function is nil. Otherwise, everything 1192 * value returned by this function is nil. Otherwise, everything
1193 * will become frozen until the modal loop exits under normal 1193 * will become frozen until the modal loop exits under normal
1194 * condition (scrollbar drag is released, menu closed etc.) 1194 * condition (scrollbar drag is released, menu closed etc.)
1218 mswindows_unmodalize_signal_maybe (); 1218 mswindows_unmodalize_signal_maybe ();
1219 } 1219 }
1220 } 1220 }
1221 1221
1222 /* 1222 /*
1223 * This is a special flavour of the mswindows_need_event function, 1223 * This is a special flavor of the mswindows_need_event function,
1224 * used while in event pump. Actually, there is only kind of events 1224 * used while in event pump. Actually, there is only kind of events
1225 * allowed while in event pump: a timer. An attempt to fetch any 1225 * allowed while in event pump: a timer. An attempt to fetch any
1226 * other event leads to a dealock, as there's no source of user input 1226 * other event leads to a deadlock, as there's no source of user input
1227 * ('cause event pump mirrors windows modal loop, which is a sole 1227 * ('cause event pump mirrors windows modal loop, which is a sole
1228 * owner of thread message queue). 1228 * owner of thread message queue).
1229 * 1229 *
1230 * To detect this, we use a counter of active timers, and allow 1230 * To detect this, we use a counter of active timers, and allow
1231 * fetching WM_TIMER messages. Instead of trying to fetch a WM_TIMER 1231 * fetching WM_TIMER messages. Instead of trying to fetch a WM_TIMER
1365 } 1365 }
1366 else if (active==-1) 1366 else if (active==-1)
1367 { 1367 {
1368 if (errno != EINTR) 1368 if (errno != EINTR)
1369 { 1369 {
1370 /* something bad happended */ 1370 /* something bad happened */
1371 assert(0); 1371 assert(0);
1372 } 1372 }
1373 } 1373 }
1374 else 1374 else
1375 { 1375 {
1399 mswindows_drain_windows_queue (); 1399 mswindows_drain_windows_queue ();
1400 } 1400 }
1401 else 1401 else
1402 { 1402 {
1403 int ix = active - WAIT_OBJECT_0; 1403 int ix = active - WAIT_OBJECT_0;
1404 /* First, try to find which process' ouptut has signaled */ 1404 /* First, try to find which process' output has signaled */
1405 struct Lisp_Process *p = 1405 struct Lisp_Process *p =
1406 get_process_from_usid (HANDLE_TO_USID (mswindows_waitable_handles[ix])); 1406 get_process_from_usid (HANDLE_TO_USID (mswindows_waitable_handles[ix]));
1407 if (p != NULL) 1407 if (p != NULL)
1408 { 1408 {
1409 /* Found a signaled process input handle */ 1409 /* Found a signaled process input handle */
1410 mswindows_enqueue_process_event (p); 1410 mswindows_enqueue_process_event (p);
1411 } 1411 }
1412 else 1412 else
1413 { 1413 {
1414 /* None. This means that the process handle itself has signaled. 1414 /* None. This means that the process handle itself has signaled.
1415 Remove the handle from the wait vector, and make status_ntoify 1415 Remove the handle from the wait vector, and make status_notify
1416 note the exited process */ 1416 note the exited process */
1417 mswindows_waitable_handles [ix] = 1417 mswindows_waitable_handles [ix] =
1418 mswindows_waitable_handles [--mswindows_waitable_count]; 1418 mswindows_waitable_handles [--mswindows_waitable_count];
1419 kick_status_notify (); 1419 kick_status_notify ();
1420 /* Have to return something: there may be no accompanying 1420 /* Have to return something: there may be no accompanying
1574 * The windows procedure for the window class XEMACS_CLASS 1574 * The windows procedure for the window class XEMACS_CLASS
1575 */ 1575 */
1576 LRESULT WINAPI 1576 LRESULT WINAPI
1577 mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 1577 mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1578 { 1578 {
1579 /* Note: Remember to initialise emacs_event and event before use. 1579 /* Note: Remember to initialize emacs_event and event before use.
1580 This code calls code that can GC. You must GCPRO before calling such code. */ 1580 This code calls code that can GC. You must GCPRO before calling such code. */
1581 Lisp_Object emacs_event = Qnil; 1581 Lisp_Object emacs_event = Qnil;
1582 Lisp_Object fobj = Qnil; 1582 Lisp_Object fobj = Qnil;
1583 1583
1584 struct Lisp_Event *event; 1584 struct Lisp_Event *event;
1858 else 1858 else
1859 assert ("Spurious timer fired" == 0); 1859 assert ("Spurious timer fired" == 0);
1860 break; 1860 break;
1861 1861
1862 case WM_MOUSEMOVE: 1862 case WM_MOUSEMOVE:
1863 /* Optimization: don't report mouse movement while size is changind */ 1863 /* Optimization: don't report mouse movement while size is changing */
1864 msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); 1864 msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
1865 if (!msframe->sizing) 1865 if (!msframe->sizing)
1866 { 1866 {
1867 /* When waiting for the second mouse button to finish 1867 /* When waiting for the second mouse button to finish
1868 button2 emulation, and have moved too far, just pretend 1868 button2 emulation, and have moved too far, just pretend
1869 as if timer has expired. This impoves drag-select feedback */ 1869 as if timer has expired. This improves drag-select feedback */
1870 if ((msframe->button2_need_lbutton || msframe->button2_need_rbutton) 1870 if ((msframe->button2_need_lbutton || msframe->button2_need_rbutton)
1871 && !mswindows_button2_near_enough (msframe->last_click_point, 1871 && !mswindows_button2_near_enough (msframe->last_click_point,
1872 MAKEPOINTS (lParam))) 1872 MAKEPOINTS (lParam)))
1873 { 1873 {
1874 KillTimer (hwnd, BUTTON_2_TIMER_ID); 1874 KillTimer (hwnd, BUTTON_2_TIMER_ID);
2800 Number of physical mouse buttons. 2800 Number of physical mouse buttons.
2801 */ ); 2801 */ );
2802 2802
2803 DEFVAR_INT ("mswindows-mouse-button-max-skew-x", &mswindows_mouse_button_max_skew_x /* 2803 DEFVAR_INT ("mswindows-mouse-button-max-skew-x", &mswindows_mouse_button_max_skew_x /*
2804 *Maximum horizontal distance in pixels between points in which left and 2804 *Maximum horizontal distance in pixels between points in which left and
2805 right button clicks occured for them to be translated into single 2805 right button clicks occurred for them to be translated into single
2806 middle button event. Clicks must occur in time not longer than defined 2806 middle button event. Clicks must occur in time not longer than defined
2807 by the variable `mswindows-mouse-button-tolerance'. 2807 by the variable `mswindows-mouse-button-tolerance'.
2808 If negative or zero, currently set system default is used instead. 2808 If negative or zero, currently set system default is used instead.
2809 */ ); 2809 */ );
2810 2810
2811 DEFVAR_INT ("mswindows-mouse-button-max-skew-y", &mswindows_mouse_button_max_skew_y /* 2811 DEFVAR_INT ("mswindows-mouse-button-max-skew-y", &mswindows_mouse_button_max_skew_y /*
2812 *Maximum vertical distance in pixels between points in which left and 2812 *Maximum vertical distance in pixels between points in which left and
2813 right button clicks occured for them to be translated into single 2813 right button clicks occurred for them to be translated into single
2814 middle button event. Clicks must occur in time not longer than defined 2814 middle button event. Clicks must occur in time not longer than defined
2815 by the variable `mswindows-mouse-button-tolerance'. 2815 by the variable `mswindows-mouse-button-tolerance'.
2816 If negative or zero, currently set system default is used instead. 2816 If negative or zero, currently set system default is used instead.
2817 */ ); 2817 */ );
2818 2818