Mercurial > hg > xemacs-beta
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 { |