comparison src/event-msw.c @ 282:c42ec1d1cded r21-0b39

Import from CVS: tag r21-0b39
author cvs
date Mon, 13 Aug 2007 10:33:18 +0200
parents 7df0dd720c89
children 558f606b08ae
comparison
equal deleted inserted replaced
281:090b52736db2 282:c42ec1d1cded
42 #ifdef HAVE_MENUBARS 42 #ifdef HAVE_MENUBARS
43 # include "menubar-msw.h" 43 # include "menubar-msw.h"
44 #endif 44 #endif
45 45
46 #include "device.h" 46 #include "device.h"
47 #include "dragdrop.h"
47 #include "events.h" 48 #include "events.h"
48 #include "frame.h" 49 #include "frame.h"
49 #include "lstream.h" 50 #include "lstream.h"
50 #include "process.h" 51 #include "process.h"
51 #include "redisplay.h" 52 #include "redisplay.h"
71 Removed upon dequeueing an event */ 72 Removed upon dequeueing an event */
72 #define FAKE_MOD_QUIT 0x80 73 #define FAKE_MOD_QUIT 0x80
73 74
74 /* Timer ID used for button2 emulation */ 75 /* Timer ID used for button2 emulation */
75 #define BUTTON_2_TIMER_ID 1 76 #define BUTTON_2_TIMER_ID 1
76
77 /* Drag and drop event data types (subset of types in offix-types.h) */
78 #define DndFile 2
79 #define DndFiles 3
80 #define DndText 4
81 77
82 extern Lisp_Object 78 extern Lisp_Object
83 mswindows_get_toolbar_button_text (struct frame* f, int command_id); 79 mswindows_get_toolbar_button_text (struct frame* f, int command_id);
84 extern Lisp_Object 80 extern Lisp_Object
85 mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id); 81 mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id);
443 439
444 /************************************************************************/ 440 /************************************************************************/
445 /* Pipe outstream - writes process input */ 441 /* Pipe outstream - writes process input */
446 /************************************************************************/ 442 /************************************************************************/
447 443
448 #define MAX_FLUSH_TIME 500
449
450 #define NTPIPE_SHOVE_STREAM_DATA(stream) \ 444 #define NTPIPE_SHOVE_STREAM_DATA(stream) \
451 LSTREAM_TYPE_DATA (stream, ntpipe_shove) 445 LSTREAM_TYPE_DATA (stream, ntpipe_shove)
452 446
453 #define MAX_SHOVE_BUFFER_SIZE 128 447 #define MAX_SHOVE_BUFFER_SIZE 128
454 448
604 LSTREAM_HAS_METHOD (ntpipe_shove, was_blocked_p); 598 LSTREAM_HAS_METHOD (ntpipe_shove, was_blocked_p);
605 LSTREAM_HAS_METHOD (ntpipe_shove, closer); 599 LSTREAM_HAS_METHOD (ntpipe_shove, closer);
606 } 600 }
607 601
608 /************************************************************************/ 602 /************************************************************************/
603 /* Winsock I/O stream */
604 /************************************************************************/
605 #if defined (HAVE_SOCKETS) && !defined(HAVE_MSG_SELECT)
606
607 #define WINSOCK_READ_BUFFER_SIZE 1024
608
609 struct winsock_stream
610 {
611 LPARAM user_data; /* Any user data stored in the stream object */
612 SOCKET s; /* Socket handle (which is a Win32 handle) */
613 OVERLAPPED ov; /* Overlapped I/O structure */
614 void* buffer; /* Buffer. Allocated for input stream only */
615 unsigned int bufsize; /* Number of bytes last read */
616 unsigned int bufpos; /* Psition in buffer for next fetch */
617 unsigned int error_p :1; /* I/O Error seen */
618 unsigned int eof_p :1; /* EOF Error seen */
619 unsigned int pending_p :1; /* There is a pending I/O operation */
620 unsigned int blocking_p :1; /* Last write attempt would block */
621 };
622
623 #define WINSOCK_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, winsock)
624
625 DEFINE_LSTREAM_IMPLEMENTATION ("winsock", lstream_winsock,
626 sizeof (struct winsock_stream));
627
628 static void
629 winsock_initiate_read (struct winsock_stream *str)
630 {
631 ResetEvent (str->ov.hEvent);
632 str->bufpos = 0;
633
634 if (!ReadFile ((HANDLE)str->s, str->buffer, WINSOCK_READ_BUFFER_SIZE,
635 &str->bufsize, &str->ov))
636 {
637 if (GetLastError () == ERROR_IO_PENDING)
638 str->pending_p = 1;
639 else if (GetLastError () == ERROR_HANDLE_EOF)
640 str->eof_p = 1;
641 else
642 str->error_p = 1;
643 }
644 else if (str->bufsize == 0)
645 str->eof_p = 1;
646 }
647
648 static int
649 winsock_reader (Lstream *stream, unsigned char *data, size_t size)
650 {
651 struct winsock_stream *str = WINSOCK_STREAM_DATA (stream);
652
653 /* If the current operation is not yet complete, there's nothing to
654 give back */
655 if (str->pending_p)
656 {
657 if (WaitForSingleObject (str->ov.hEvent, 0) == WAIT_TIMEOUT)
658 {
659 errno = EAGAIN;
660 return -1;
661 }
662 else
663 {
664 if (!GetOverlappedResult ((HANDLE)str->s, &str->ov, &str->bufsize, TRUE))
665 {
666 if (GetLastError() == ERROR_HANDLE_EOF)
667 str->bufsize = 0;
668 else
669 str->error_p = 1;
670 }
671 if (str->bufsize == 0)
672 str->eof_p = 1;
673 str->pending_p = 0;
674 }
675 }
676
677 if (str->eof_p)
678 return 0;
679 if (str->error_p)
680 return -1;
681
682 /* Return as much of buffer as we have */
683 size = min (size, (size_t) (str->bufsize - str->bufpos));
684 memcpy (data, (void*)((BYTE*)str->buffer + str->bufpos), size);
685 str->bufpos += size;
686
687 /* Read more if buffer is exhausted */
688 if (str->bufsize == str->bufpos)
689 winsock_initiate_read (str);
690
691 return size;
692 }
693
694 static int
695 winsock_writer (Lstream *stream, CONST unsigned char *data, size_t size)
696 {
697 struct winsock_stream *str = WINSOCK_STREAM_DATA (stream);
698
699 if (str->pending_p)
700 {
701 if (WaitForSingleObject (str->ov.hEvent, 0) == WAIT_TIMEOUT)
702 {
703 str->blocking_p = 1;
704 return -1;
705 }
706 else
707 {
708 DWORD dw_unused;
709 if (!GetOverlappedResult ((HANDLE)str->s, &str->ov, &dw_unused, TRUE))
710 str->error_p = 1;
711 str->pending_p = 0;
712 }
713 }
714
715 str->blocking_p = 0;
716
717 if (str->error_p)
718 return -1;
719
720 if (size == 0)
721 return 0;
722
723 {
724 ResetEvent (str->ov.hEvent);
725
726 if (WriteFile ((HANDLE)str->s, data, size, NULL, &str->ov)
727 || GetLastError() == ERROR_IO_PENDING)
728 str->pending_p = 1;
729 else
730 str->error_p = 1;
731 }
732
733 return str->error_p ? -1 : size;
734 }
735
736 static int
737 winsock_closer (Lstream *lstr)
738 {
739 struct winsock_stream *str = WINSOCK_STREAM_DATA (lstr);
740
741 if (lstr->flags & LSTREAM_FL_READ)
742 shutdown (str->s, 0);
743 else
744 shutdown (str->s, 1);
745
746 CloseHandle ((HANDLE)str->s);
747 if (str->pending_p)
748 WaitForSingleObject (str->ov.hEvent, INFINITE);
749
750 if (lstr->flags & LSTREAM_FL_READ)
751 xfree (str->buffer);
752
753 CloseHandle (str->ov.hEvent);
754 return 0;
755 }
756
757 static int
758 winsock_was_blocked_p (Lstream *stream)
759 {
760 struct winsock_stream *str = WINSOCK_STREAM_DATA (stream);
761 return str->blocking_p;
762 }
763
764 static Lisp_Object
765 make_winsock_stream_1 (SOCKET s, LPARAM param, CONST char *mode)
766 {
767 Lisp_Object obj;
768 Lstream *lstr = Lstream_new (lstream_winsock, mode);
769 struct winsock_stream *str = WINSOCK_STREAM_DATA (lstr);
770
771 str->s = s;
772 str->blocking_p = 0;
773 str->error_p = 0;
774 str->eof_p = 0;
775 str->pending_p = 0;
776 str->user_data = param;
777
778 xzero (str->ov);
779 str->ov.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
780
781 if (lstr->flags & LSTREAM_FL_READ)
782 {
783 str->buffer = xmalloc (WINSOCK_READ_BUFFER_SIZE);
784 winsock_initiate_read (str);
785 }
786
787 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
788 XSETLSTREAM (obj, lstr);
789 return obj;
790 }
791
792 static Lisp_Object
793 make_winsock_input_stream (SOCKET s, LPARAM param)
794 {
795 return make_winsock_stream_1 (s, param, "r");
796 }
797
798 static Lisp_Object
799 make_winsock_output_stream (SOCKET s, LPARAM param)
800 {
801 return make_winsock_stream_1 (s, param, "w");
802 }
803
804 static HANDLE
805 get_winsock_stream_waitable (Lstream *lstr)
806 {
807 struct winsock_stream *str = WINSOCK_STREAM_DATA (lstr);
808 return str->ov.hEvent;
809 }
810
811 static LPARAM
812 get_winsock_stream_param (Lstream *lstr)
813 {
814 struct winsock_stream *str = WINSOCK_STREAM_DATA (lstr);
815 return str->user_data;
816 }
817
818 static void
819 init_winsock_stream (void)
820 {
821 LSTREAM_HAS_METHOD (winsock, reader);
822 LSTREAM_HAS_METHOD (winsock, writer);
823 LSTREAM_HAS_METHOD (winsock, closer);
824 LSTREAM_HAS_METHOD (winsock, was_blocked_p);
825 }
826 #endif /* defined (HAVE_SOCKETS) */
827
828 /************************************************************************/
609 /* Dispatch queue management */ 829 /* Dispatch queue management */
610 /************************************************************************/ 830 /************************************************************************/
611 831
612 static int 832 static int
613 mswindows_user_event_p (struct Lisp_Event* sevt) 833 mswindows_user_event_p (struct Lisp_Event* sevt)
614 { 834 {
615 return (sevt->event_type == key_press_event 835 return (sevt->event_type == key_press_event
616 || sevt->event_type == button_press_event 836 || sevt->event_type == button_press_event
617 || sevt->event_type == button_release_event 837 || sevt->event_type == button_release_event);
618 || sevt->event_type == dnd_drop_event);
619 } 838 }
620 839
621 /* 840 /*
622 * Add an emacs event to the proper dispatch queue 841 * Add an emacs event to the proper dispatch queue
623 */ 842 */
1220 case XTYP_EXECUTE: 1439 case XTYP_EXECUTE:
1221 if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system)) 1440 if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system))
1222 { 1441 {
1223 DWORD len = DdeGetData (hdata, NULL, 0, 0); 1442 DWORD len = DdeGetData (hdata, NULL, 0, 0);
1224 char *cmd = alloca (len+1); 1443 char *cmd = alloca (len+1);
1225 #ifdef __CYGWIN32__
1226 char *cmd_1;
1227 #endif
1228 char *end; 1444 char *end;
1229 Lisp_Object l_dndlist; 1445 char *filename;
1446 struct gcpro gcpro1, gcpro2;
1447 Lisp_Object l_dndlist = Qnil;
1230 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); 1448 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
1231 struct Lisp_Event *event = XEVENT (emacs_event); 1449 struct Lisp_Event *event = XEVENT (emacs_event);
1232 1450
1233 DdeGetData (hdata, cmd, len, 0); 1451 DdeGetData (hdata, cmd, len, 0);
1234 cmd[len] = '\0'; 1452 cmd[len] = '\0';
1235 DdeFreeDataHandle (hdata); 1453 DdeFreeDataHandle (hdata);
1236 1454
1237 /* Check syntax & that it's an [Open("foo")] command */ 1455 /* Check syntax & that it's an [Open("foo")] command, which we
1456 * treat like a file drop */
1238 /* #### Ought to be generalised and accept some other commands */ 1457 /* #### Ought to be generalised and accept some other commands */
1239 if (*cmd == '[') 1458 if (*cmd == '[')
1240 cmd++; 1459 cmd++;
1241 if (strnicmp (cmd, MSWINDOWS_DDE_ITEM_OPEN, 1460 if (strnicmp (cmd, MSWINDOWS_DDE_ITEM_OPEN,
1242 strlen (MSWINDOWS_DDE_ITEM_OPEN))) 1461 strlen (MSWINDOWS_DDE_ITEM_OPEN)))
1256 return DDE_FNOTPROCESSED; 1475 return DDE_FNOTPROCESSED;
1257 if (*(++end)==']') 1476 if (*(++end)==']')
1258 end++; 1477 end++;
1259 if (*end) 1478 if (*end)
1260 return DDE_FNOTPROCESSED; 1479 return DDE_FNOTPROCESSED;
1480
1261 #ifdef __CYGWIN32__ 1481 #ifdef __CYGWIN32__
1262 CYGWIN_CONV_PATH(cmd,cmd_1); 1482 filename = alloca (cygwin32_win32_to_posix_path_list_buf_size (cmd) + 5);
1263 cmd = cmd_1; 1483 strcpy (filename, "file:");
1264 #endif 1484 cygwin32_win32_to_posix_path_list (cmd, filename+5);
1265 l_dndlist = make_ext_string (cmd, strlen(cmd), FORMAT_FILENAME); 1485 #else
1486 dostounix_filename (cmd);
1487 filename = alloca (strlen (cmd)+6);
1488 strcpy (filename, "file:");
1489 strcat (filename, cmd);
1490 #endif
1491 GCPRO2 (emacs_event, l_dndlist);
1492 l_dndlist = make_string (filename, strlen (filename));
1266 1493
1267 event->channel = Qnil; 1494 event->channel = Qnil;
1268 event->timestamp = GetTickCount(); 1495 event->timestamp = GetTickCount();
1269 event->event_type = dnd_drop_event; 1496 event->event_type = misc_user_event;
1270 event->event.dnd_drop.button = 0; 1497 event->event.misc.button = 1;
1271 event->event.dnd_drop.modifiers = 0; 1498 event->event.misc.modifiers = 0;
1272 event->event.dnd_drop.x = -1; 1499 event->event.misc.x = -1;
1273 event->event.dnd_drop.y = -1; 1500 event->event.misc.y = -1;
1274 event->event.dnd_drop.data = Fcons (make_int (DndFile), 1501 event->event.misc.function = Qdragdrop_drop_dispatch;
1275 Fcons (l_dndlist, Qnil)); 1502 event->event.misc.object = Fcons (Qdragdrop_URL,
1503 Fcons (l_dndlist, Qnil));
1276 mswindows_enqueue_dispatch_event (emacs_event); 1504 mswindows_enqueue_dispatch_event (emacs_event);
1277 1505 UNGCPRO;
1278 return (HDDEDATA) DDE_FACK; 1506 return (HDDEDATA) DDE_FACK;
1279 } 1507 }
1280 DdeFreeDataHandle (hdata); 1508 DdeFreeDataHandle (hdata);
1281 return (HDDEDATA) DDE_FNOTPROCESSED; 1509 return (HDDEDATA) DDE_FNOTPROCESSED;
1510
1282 default: 1511 default:
1283 return (HDDEDATA) NULL; 1512 return (HDDEDATA) NULL;
1284 } 1513 }
1285 1514
1286 } 1515 }
1832 2061
1833 case WM_DROPFILES: /* implementation ripped-off from event-Xt.c */ 2062 case WM_DROPFILES: /* implementation ripped-off from event-Xt.c */
1834 { 2063 {
1835 UINT filecount, i, len; 2064 UINT filecount, i, len;
1836 POINT point; 2065 POINT point;
1837 char filename[MAX_PATH]; 2066 char* filename;
1838 #ifdef __CYGWIN32__ 2067 #ifdef __CYGWIN32__
1839 char* fname; 2068 char* fname;
1840 #endif 2069 #endif
1841 Lisp_Object l_type, l_dndlist = Qnil, l_item; 2070 Lisp_Object l_dndlist = Qnil, l_item = Qnil;
2071 struct gcpro gcpro1, gcpro2, gcpro3;
1842 2072
1843 emacs_event = Fmake_event (Qnil, Qnil); 2073 emacs_event = Fmake_event (Qnil, Qnil);
1844 event = XEVENT(emacs_event); 2074 event = XEVENT(emacs_event);
1845 2075
2076 GCPRO3 (emacs_event, l_dndlist, l_item);
2077
1846 if (!DragQueryPoint ((HANDLE) wParam, &point)) 2078 if (!DragQueryPoint ((HANDLE) wParam, &point))
1847 point.x = point.y = -1; /* outside client area */ 2079 point.x = point.y = -1; /* outside client area */
1848 2080
1849 filecount = DragQueryFile ((HANDLE) wParam, -1, NULL, 0); 2081 event->event_type = misc_user_event;
1850 if (filecount == 1) 2082 event->channel = mswindows_find_frame(hwnd);
2083 event->timestamp = GetMessageTime();
2084 event->event.misc.button = 1; /* #### Should try harder */
2085 event->event.misc.modifiers = mswindows_modifier_state (NULL, 0);
2086 event->event.misc.x = point.x;
2087 event->event.misc.y = point.y;
2088 event->event.misc.function = Qdragdrop_drop_dispatch;
2089
2090 filecount = DragQueryFile ((HANDLE) wParam, 0xffffffff, NULL, 0);
2091 for (i=0; i<filecount; i++)
1851 { 2092 {
1852 l_type = make_int (DndFile); 2093 len = DragQueryFile ((HANDLE) wParam, i, NULL, 0);
1853 len = DragQueryFile ((HANDLE) wParam, 0, filename, MAX_PATH); 2094 /* The URLs that we make here aren't correct according to section
2095 * 3.10 of rfc1738 because they're missing the //<host>/ part and
2096 * because they may contain reserved characters. But that's OK. */
1854 #ifdef __CYGWIN32__ 2097 #ifdef __CYGWIN32__
1855 CYGWIN_CONV_PATH(filename, fname); 2098 fname = (char *)xmalloc (len+1);
1856 len=strlen(fname); 2099 DragQueryFile ((HANDLE) wParam, i, fname, len+1);
1857 l_dndlist = make_ext_string (fname, len, FORMAT_FILENAME); 2100 filename = xmalloc (cygwin32_win32_to_posix_path_list_buf_size (fname) + 5);
2101 strcpy (filename, "file:");
2102 cygwin32_win32_to_posix_path_list (fname, filename+5);
2103 xfree (fname);
1858 #else 2104 #else
1859 l_dndlist = make_ext_string (filename, len, FORMAT_FILENAME); 2105 filename = (char *)xmalloc (len+6);
1860 #endif 2106 strcpy (filename, "file:");
1861 } 2107 DragQueryFile ((HANDLE) wParam, i, filename+5, len+1);
1862 else 2108 dostounix_filename (filename+5);
1863 { 2109 #endif
1864 l_type = make_int (DndFiles); 2110 l_item = make_string (filename, strlen (filename));
1865 for (i=0; i<filecount; i++) 2111 l_dndlist = Fcons (l_item, l_dndlist);
1866 { 2112 xfree (filename);
1867 len = DragQueryFile ((HANDLE) wParam, i, filename, MAX_PATH);
1868 #ifdef __CYGWIN32__
1869 CYGWIN_CONV_PATH(filename, fname);
1870 len=strlen(fname);
1871 l_item = make_ext_string (fname, len, FORMAT_FILENAME);
1872 #else
1873 l_item = make_ext_string (filename, len, FORMAT_FILENAME);
1874 #endif
1875 l_dndlist = Fcons (l_item, l_dndlist); /* reverse order */
1876 }
1877 } 2113 }
1878 DragFinish ((HANDLE) wParam); 2114 DragFinish ((HANDLE) wParam);
1879 2115
1880 event->channel = mswindows_find_frame(hwnd); 2116 event->event.misc.object = Fcons (Qdragdrop_URL, l_dndlist);
1881 event->timestamp = GetMessageTime();
1882 event->event_type = dnd_drop_event;
1883 event->event.dnd_drop.button = 1; /* #### Should try harder */
1884 event->event.dnd_drop.modifiers = mswindows_modifier_state (NULL, 0);
1885 event->event.dnd_drop.x = point.x;
1886 event->event.dnd_drop.y = point.y;
1887 event->event.dnd_drop.data = Fcons (l_type, Fcons (l_dndlist, Qnil));
1888
1889 mswindows_enqueue_dispatch_event (emacs_event); 2117 mswindows_enqueue_dispatch_event (emacs_event);
2118 UNGCPRO;
1890 } 2119 }
1891 break; 2120 break;
2121
1892 2122
1893 defproc: 2123 defproc:
1894 default: 2124 default:
1895 return DefWindowProc (hwnd, message, wParam, lParam); 2125 return DefWindowProc (hwnd, message, wParam, lParam);
1896 } 2126 }
2211 } 2441 }
2212 2442
2213 static HANDLE 2443 static HANDLE
2214 get_process_input_waitable (struct Lisp_Process *process) 2444 get_process_input_waitable (struct Lisp_Process *process)
2215 { 2445 {
2216 Lisp_Object instr, outstr; 2446 Lisp_Object instr, outstr, p;
2447 XSETPROCESS (p, process);
2217 get_process_streams (process, &instr, &outstr); 2448 get_process_streams (process, &instr, &outstr);
2218 assert (!NILP (instr)); 2449 assert (!NILP (instr));
2219 return get_ntpipe_input_stream_waitable (XLSTREAM (instr)); 2450 #if defined (HAVE_SOCKETS) && !defined(HAVE_MSG_SELECT)
2451 return (network_connection_p (p)
2452 ? get_winsock_stream_waitable (XLSTREAM (instr))
2453 : get_ntpipe_input_stream_waitable (XLSTREAM (instr)));
2454 #else
2455 return get_ntpipe_input_stream_waitable (XLSTREAM (instr));
2456 #endif
2220 } 2457 }
2221 2458
2222 static void 2459 static void
2223 emacs_mswindows_select_process (struct Lisp_Process *process) 2460 emacs_mswindows_select_process (struct Lisp_Process *process)
2224 { 2461 {
2227 if (!add_waitable_handle (hev)) 2464 if (!add_waitable_handle (hev))
2228 error ("Too many active processes"); 2465 error ("Too many active processes");
2229 2466
2230 #ifdef HAVE_WIN32_PROCESSES 2467 #ifdef HAVE_WIN32_PROCESSES
2231 { 2468 {
2232 HANDLE hprocess = get_nt_process_handle (process); 2469 Lisp_Object p;
2233 if (!add_waitable_handle (hprocess)) 2470 XSETPROCESS (p, process);
2471 if (!network_connection_p (p))
2234 { 2472 {
2235 remove_waitable_handle (hev); 2473 HANDLE hprocess = get_nt_process_handle (process);
2236 error ("Too many active processes"); 2474 if (!add_waitable_handle (hprocess))
2475 {
2476 remove_waitable_handle (hev);
2477 error ("Too many active processes");
2478 }
2237 } 2479 }
2238 } 2480 }
2239 #endif 2481 #endif
2240 } 2482 }
2241 2483
2319 fdo=(int)outhandle; 2561 fdo=(int)outhandle;
2320 #else 2562 #else
2321 #error "So, WHICH kind of processes do you want?" 2563 #error "So, WHICH kind of processes do you want?"
2322 #endif 2564 #endif
2323 2565
2324 *instream = (hin != INVALID_HANDLE_VALUE 2566 *instream = (hin == INVALID_HANDLE_VALUE
2325 ? make_ntpipe_input_stream (hin, fdi) 2567 ? Qnil
2326 : Qnil); 2568 #if defined (HAVE_SOCKETS) && !defined (HAVE_MSG_SELECT)
2569 : flags & STREAM_NETWORK_CONNECTION
2570 ? make_winsock_input_stream ((SOCKET)hin, fdi)
2571 #endif
2572 : make_ntpipe_input_stream (hin, fdi));
2327 2573
2328 #ifdef HAVE_WIN32_PROCESSES 2574 #ifdef HAVE_WIN32_PROCESSES
2329 *outstream = (hout != INVALID_HANDLE_VALUE 2575 *outstream = (hout == INVALID_HANDLE_VALUE
2330 ? make_ntpipe_output_stream (hout, fdo) 2576 ? Qnil
2331 : Qnil); 2577 #if defined (HAVE_SOCKETS) && !defined (HAVE_MSG_SELECT)
2578 : flags & STREAM_NETWORK_CONNECTION
2579 ? make_winsock_output_stream ((SOCKET)hout, fdo)
2580 #endif
2581 : make_ntpipe_output_stream (hout, fdo));
2332 #elif defined (HAVE_UNIX_PROCESSES) 2582 #elif defined (HAVE_UNIX_PROCESSES)
2333 *outstream = (fdo >= 0 2583 *outstream = (fdo >= 0
2334 ? make_filedesc_output_stream (fdo, 0, -1, LSTR_BLOCKED_OK) 2584 ? make_filedesc_output_stream (fdo, 0, -1, LSTR_BLOCKED_OK)
2335 : Qnil); 2585 : Qnil);
2336 2586
2337 #if defined(HAVE_UNIX_PROCESSES) && defined(HAVE_PTYS) 2587 #if defined(HAVE_UNIX_PROCESSES) && defined(HAVE_PTYS)
2338 /* FLAGS is process->pty_flag for UNIX_PROCESSES */ 2588 /* FLAGS is process->pty_flag for UNIX_PROCESSES */
2339 if (flags && fdo >= 0) 2589 if ((flags & STREAM_PTY_FLUSHING) && fdo >= 0)
2340 { 2590 {
2341 Bufbyte eof_char = get_eof_char (fdo); 2591 Bufbyte eof_char = get_eof_char (fdo);
2342 int pty_max_bytes = get_pty_max_bytes (fdo); 2592 int pty_max_bytes = get_pty_max_bytes (fdo);
2343 filedesc_stream_set_pty_flushing (XLSTREAM(*outstream), pty_max_bytes, eof_char); 2593 filedesc_stream_set_pty_flushing (XLSTREAM(*outstream), pty_max_bytes, eof_char);
2344 } 2594 }
2345 #endif 2595 #endif
2346 #endif 2596 #endif
2347 2597
2348 return (NILP (*instream) ? USID_ERROR 2598 return (NILP (*instream)
2599 ? USID_ERROR
2600 #if defined(HAVE_SOCKETS) && !defined(HAVE_MSG_SELECT)
2601 : flags & STREAM_NETWORK_CONNECTION
2602 ? HANDLE_TO_USID (get_winsock_stream_waitable (XLSTREAM (*instream)))
2603 #endif
2349 : HANDLE_TO_USID (get_ntpipe_input_stream_waitable (XLSTREAM (*instream)))); 2604 : HANDLE_TO_USID (get_ntpipe_input_stream_waitable (XLSTREAM (*instream))));
2350 } 2605 }
2351 2606
2352 USID 2607 USID
2353 emacs_mswindows_delete_stream_pair (Lisp_Object instream, 2608 emacs_mswindows_delete_stream_pair (Lisp_Object instream,
2354 Lisp_Object outstream) 2609 Lisp_Object outstream)
2355 { 2610 {
2356 /* Oh nothing special here for Win32 at all */ 2611 /* Oh nothing special here for Win32 at all */
2357 #if defined (HAVE_UNIX_PROCESSES) 2612 #if defined (HAVE_UNIX_PROCESSES)
2358 int in = (NILP(instream) ? -1 2613 int in = (NILP(instream)
2614 ? -1
2615 #if defined(HAVE_SOCKETS) && !defined(HAVE_MSG_SELECT)
2616 : LSTREAM_TYPE_P (XLSTREAM (instream), winsock)
2617 ? get_winsock_stream_param (XLSTREAM (instream))
2618 #endif
2359 : get_ntpipe_input_stream_param (XLSTREAM (instream))); 2619 : get_ntpipe_input_stream_param (XLSTREAM (instream)));
2360 int out = (NILP(outstream) ? -1 2620 int out = (NILP(outstream) ? -1
2361 : filedesc_stream_fd (XLSTREAM (outstream))); 2621 : filedesc_stream_fd (XLSTREAM (outstream)));
2362 2622
2363 if (in >= 0) 2623 if (in >= 0)
2364 close (in); 2624 close (in);
2365 if (out != in && out >= 0) 2625 if (out != in && out >= 0)
2366 close (out); 2626 close (out);
2367 #endif 2627 #endif
2368 2628
2369 return (NILP (instream) ? USID_DONTHASH 2629 return (NILP (instream)
2630 ? USID_DONTHASH
2631 #if defined(HAVE_SOCKETS) && !defined(HAVE_MSG_SELECT)
2632 : LSTREAM_TYPE_P (XLSTREAM (instream), winsock)
2633 ? HANDLE_TO_USID (get_winsock_stream_waitable (XLSTREAM (instream)))
2634 #endif
2370 : HANDLE_TO_USID (get_ntpipe_input_stream_waitable (XLSTREAM (instream)))); 2635 : HANDLE_TO_USID (get_ntpipe_input_stream_waitable (XLSTREAM (instream))));
2371 } 2636 }
2372
2373 2637
2374 #ifndef HAVE_X_WINDOWS 2638 #ifndef HAVE_X_WINDOWS
2375 /* This is called from GC when a process object is about to be freed. 2639 /* This is called from GC when a process object is about to be freed.
2376 If we've still got pointers to it in this file, we're gonna lose hard. 2640 If we've still got pointers to it in this file, we're gonna lose hard.
2377 */ 2641 */
2489 void 2753 void
2490 lstream_type_create_mswindows_selectable (void) 2754 lstream_type_create_mswindows_selectable (void)
2491 { 2755 {
2492 init_slurp_stream (); 2756 init_slurp_stream ();
2493 init_shove_stream (); 2757 init_shove_stream ();
2758 #if defined (HAVE_SOCKETS) && !defined(HAVE_MSG_SELECT)
2759 init_winsock_stream ();
2760 #endif
2494 } 2761 }
2495 2762
2496 void 2763 void
2497 init_event_mswindows_late (void) 2764 init_event_mswindows_late (void)
2498 { 2765 {