Havoc Pennington's implementation of convenient character set conversion
[glib.git] / giowin32.c
blob4acdb160abea89f0c0ed9ae99a1609930a00fdf9
1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * giowin32.c: IO Channels for Win32.
5 * Copyright 1998 Owen Taylor and Tor Lillqvist
6 * Copyright 1999-2000 Tor Lillqvist and Craig Setera
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
25 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
26 * file for a list of people on the GLib Team. See the ChangeLog
27 * files for a list of changes. These files are distributed with
28 * GLib at ftp://ftp.gtk.org/pub/gtk/.
31 /* Define this to get (very) verbose logging of all channels */
32 /* #define G_IO_WIN32_DEBUG */
34 #include "glib.h"
36 #include <stdlib.h>
37 #include <windows.h>
38 #include <winsock.h> /* Not everybody has winsock2 */
39 #include <fcntl.h>
40 #include <io.h>
41 #include <process.h>
42 #include <errno.h>
43 #include <sys/stat.h>
45 typedef struct _GIOWin32Channel GIOWin32Channel;
46 typedef struct _GIOWin32Watch GIOWin32Watch;
48 #define BUFFER_SIZE 4096
50 typedef enum {
51 G_IO_WINDOWS_MESSAGES, /* Windows messages */
52 G_IO_FILE_DESC, /* Unix-like file descriptors from
53 * _open() or _pipe(). Read with read().
54 * Have to create separate thread to read.
56 G_IO_STREAM_SOCKET /* Stream sockets. Similar as fds, but
57 * read with recv().
59 } GIOWin32ChannelType;
61 struct _GIOWin32Channel {
62 GIOChannel channel;
63 gint fd; /* Either a Unix-like file handle as provided
64 * by the Microsoft C runtime, or a SOCKET
65 * as provided by WinSock.
67 GIOWin32ChannelType type;
69 gboolean debug;
71 /* This is used by G_IO_WINDOWS_MESSAGES channels */
72 HWND hwnd; /* handle of window, or NULL */
74 /* Following fields used by fd and socket channels for input */
76 /* Data is kept in a circular buffer. To be able to distinguish between
77 * empty and full buffer, we cannot fill it completely, but have to
78 * leave a one character gap.
80 * Data available is between indexes rdp and wrp-1 (modulo BUFFER_SIZE).
82 * Empty: wrp == rdp
83 * Full: (wrp + 1) % BUFFER_SIZE == rdp
84 * Partial: otherwise
86 guchar *buffer; /* (Circular) buffer */
87 gint wrp, rdp; /* Buffer indices for writing and reading */
88 gboolean running; /* Is reader thread running. FALSE if
89 * EOF has been reached.
91 guint thread_id; /* If non-NULL has a reader thread, or has
92 * had.*/
93 HANDLE data_avail_event;
94 HANDLE space_avail_event;
95 CRITICAL_SECTION mutex;
97 /* Function that actually reads from fd */
98 int (*reader) (int fd, guchar *buf, int len);
101 #define LOCK(mutex) EnterCriticalSection (&mutex)
102 #define UNLOCK(mutex) LeaveCriticalSection (&mutex)
104 struct _GIOWin32Watch {
105 GPollFD pollfd;
106 GIOChannel *channel;
107 GIOCondition condition;
108 GIOFunc callback;
111 static void
112 g_io_channel_win32_init (GIOWin32Channel *channel)
114 #ifdef G_IO_WIN32_DEBUG
115 channel->debug = TRUE;
116 #else
117 if (getenv ("G_IO_WIN32_DEBUG") != NULL)
118 channel->debug = TRUE;
119 else
120 channel->debug = FALSE;
121 #endif
122 channel->buffer = NULL;
123 channel->running = FALSE;
124 channel->thread_id = 0;
125 channel->data_avail_event = NULL;
126 channel->space_avail_event = NULL;
129 static void
130 create_events (GIOWin32Channel *channel)
132 SECURITY_ATTRIBUTES sec_attrs;
134 sec_attrs.nLength = sizeof(SECURITY_ATTRIBUTES);
135 sec_attrs.lpSecurityDescriptor = NULL;
136 sec_attrs.bInheritHandle = FALSE;
138 /* The data available event is manual reset, the space available event
139 * is automatic reset.
141 if (!(channel->data_avail_event = CreateEvent (&sec_attrs, TRUE, FALSE, NULL))
142 || !(channel->space_avail_event = CreateEvent (&sec_attrs, FALSE, FALSE, NULL)))
144 gchar *msg = g_win32_error_message (GetLastError ());
145 g_error ("Error creating event: %s", msg);
147 InitializeCriticalSection (&channel->mutex);
150 static unsigned __stdcall
151 reader_thread (void *parameter)
153 GIOWin32Channel *channel = parameter;
154 guchar *buffer;
155 guint nbytes;
157 g_io_channel_ref ((GIOChannel *) channel);
159 if (channel->debug)
160 g_print ("thread %#x: starting. pid:%#x, fd:%d, data_avail:%#x, space_avail:%#x\n",
161 channel->thread_id,
162 (guint) GetCurrentProcessId (),
163 channel->fd,
164 (guint) channel->data_avail_event,
165 (guint) channel->space_avail_event);
167 channel->buffer = g_malloc (BUFFER_SIZE);
168 channel->rdp = channel->wrp = 0;
169 channel->running = TRUE;
171 SetEvent (channel->space_avail_event);
173 while (channel->running)
175 LOCK (channel->mutex);
176 if (channel->debug)
177 g_print ("thread %#x: rdp=%d, wrp=%d\n",
178 channel->thread_id, channel->rdp, channel->wrp);
179 if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
181 /* Buffer is full */
182 if (channel->debug)
183 g_print ("thread %#x: resetting space_available\n",
184 channel->thread_id);
185 ResetEvent (channel->space_avail_event);
186 if (channel->debug)
187 g_print ("thread %#x: waiting for space\n", channel->thread_id);
188 UNLOCK (channel->mutex);
189 WaitForSingleObject (channel->space_avail_event, INFINITE);
190 LOCK (channel->mutex);
191 if (channel->debug)
192 g_print ("thread %#x: rdp=%d, wrp=%d\n",
193 channel->thread_id, channel->rdp, channel->wrp);
196 buffer = channel->buffer + channel->wrp;
198 /* Always leave at least one byte unused gap to be able to
199 * distinguish between the full and empty condition...
201 nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE,
202 BUFFER_SIZE - channel->wrp);
204 UNLOCK (channel->mutex);
206 nbytes = (*channel->reader) (channel->fd, buffer, nbytes);
208 if (nbytes <= 0)
209 break;
211 LOCK (channel->mutex);
212 if (channel->debug)
213 g_print ("thread %#x: got %d bytes, rdp=%d, wrp=%d\n",
214 channel->thread_id, nbytes, channel->rdp, channel->wrp);
215 channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
216 if (channel->debug)
217 g_print ("thread %#x: rdp=%d, wrp=%d, setting data available\n",
218 channel->thread_id, channel->rdp, channel->wrp);
219 SetEvent (channel->data_avail_event);
220 UNLOCK (channel->mutex);
223 LOCK (channel->mutex);
224 channel->running = FALSE;
225 if (channel->debug)
226 g_print ("thread %#x: got EOF, rdp=%d, wrp=%d, setting data available\n",
227 channel->thread_id, channel->rdp, channel->wrp);
228 SetEvent (channel->data_avail_event);
229 UNLOCK (channel->mutex);
231 g_io_channel_unref((GIOChannel *) channel);
233 /* All of the Microsoft docs say we should explicitly
234 * end the thread...
236 _endthreadex(1);
238 return 0;
241 static void
242 create_reader_thread (GIOWin32Channel *channel,
243 gpointer reader)
245 channel->reader = reader;
247 if (_beginthreadex (NULL, 0, reader_thread, channel, 0,
248 &channel->thread_id) == 0)
249 g_warning ("Error creating reader thread: %s", strerror (errno));
250 WaitForSingleObject (channel->space_avail_event, INFINITE);
253 static int
254 buffer_read (GIOWin32Channel *channel,
255 guchar *dest,
256 guint count,
257 GIOError *error)
259 guint nbytes;
260 guint left = count;
262 LOCK (channel->mutex);
263 if (channel->debug)
264 g_print ("reading from thread %#x %d bytes, rdp=%d, wrp=%d\n",
265 channel->thread_id, count, channel->rdp, channel->wrp);
267 if (channel->rdp == channel->wrp)
269 UNLOCK (channel->mutex);
270 if (channel->debug)
271 g_print ("waiting for data from thread %#x\n", channel->thread_id);
272 WaitForSingleObject (channel->data_avail_event, INFINITE);
273 LOCK (channel->mutex);
274 if (channel->rdp == channel->wrp && !channel->running)
276 UNLOCK (channel->mutex);
277 return 0;
281 if (channel->rdp < channel->wrp)
282 nbytes = channel->wrp - channel->rdp;
283 else
284 nbytes = BUFFER_SIZE - channel->rdp;
285 UNLOCK (channel->mutex);
286 nbytes = MIN (left, nbytes);
287 if (channel->debug)
288 g_print ("moving %d bytes from thread %#x\n",
289 nbytes, channel->thread_id);
290 memcpy (dest, channel->buffer + channel->rdp, nbytes);
291 dest += nbytes;
292 left -= nbytes;
293 LOCK (channel->mutex);
294 channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE;
295 if (channel->debug)
296 g_print ("setting space available for thread %#x\n", channel->thread_id);
297 SetEvent (channel->space_avail_event);
298 if (channel->debug)
299 g_print ("for thread %#x: rdp=%d, wrp=%d\n",
300 channel->thread_id, channel->rdp, channel->wrp);
301 if (channel->running && channel->rdp == channel->wrp)
303 if (channel->debug)
304 g_print ("resetting data_available of thread %#x\n",
305 channel->thread_id);
306 ResetEvent (channel->data_avail_event);
308 UNLOCK (channel->mutex);
310 /* We have no way to indicate any errors form the actual
311 * read() or recv() call in the reader thread. Should we have?
313 *error = G_IO_ERROR_NONE;
314 return count - left;
317 static gboolean
318 g_io_win32_prepare (gpointer source_data,
319 GTimeVal *current_time,
320 gint *timeout,
321 gpointer user_data)
323 *timeout = -1;
325 return FALSE;
328 static gboolean
329 g_io_win32_check (gpointer source_data,
330 GTimeVal *current_time,
331 gpointer user_data)
333 GIOWin32Watch *data = source_data;
334 GIOWin32Channel *channel = (GIOWin32Channel *) data->channel;
336 /* If the thread has died, we have encountered EOF. If the buffer
337 * also is emtpty set the HUP bit.
339 if (!channel->running && channel->rdp == channel->wrp)
341 if (channel->debug)
342 g_print ("g_io_win32_check: setting G_IO_HUP thread %#x rdp=%d wrp=%d\n",
343 channel->thread_id, channel->rdp, channel->wrp);
344 data->pollfd.revents |= G_IO_HUP;
345 return TRUE;
348 return (data->pollfd.revents & data->condition);
351 static gboolean
352 g_io_win32_dispatch (gpointer source_data,
353 GTimeVal *current_time,
354 gpointer user_data)
357 GIOWin32Watch *data = source_data;
359 return (*data->callback) (data->channel,
360 data->pollfd.revents & data->condition,
361 user_data);
364 static void
365 g_io_win32_destroy (gpointer source_data)
367 GIOWin32Watch *data = source_data;
369 g_main_remove_poll (&data->pollfd);
370 g_io_channel_unref (data->channel);
371 g_free (data);
374 static GSourceFuncs win32_watch_funcs = {
375 g_io_win32_prepare,
376 g_io_win32_check,
377 g_io_win32_dispatch,
378 g_io_win32_destroy
381 static guint
382 g_io_win32_add_watch (GIOChannel *channel,
383 gint priority,
384 GIOCondition condition,
385 GIOFunc func,
386 gpointer user_data,
387 GDestroyNotify notify,
388 int (*reader) (int, guchar *, int))
390 GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
391 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
393 watch->channel = channel;
394 g_io_channel_ref (channel);
396 watch->callback = func;
397 watch->condition = condition;
399 if (win32_channel->data_avail_event == NULL)
400 create_events (win32_channel);
402 watch->pollfd.fd = (gint) win32_channel->data_avail_event;
403 watch->pollfd.events = condition;
405 if (win32_channel->debug)
406 g_print ("g_io_win32_add_watch: fd:%d handle:%#x\n",
407 win32_channel->fd, watch->pollfd.fd);
409 if (win32_channel->thread_id == 0)
410 create_reader_thread (win32_channel, reader);
412 g_main_add_poll (&watch->pollfd, priority);
414 return g_source_add (priority, TRUE, &win32_watch_funcs, watch,
415 user_data, notify);
418 static GIOError
419 g_io_win32_msg_read (GIOChannel *channel,
420 gchar *buf,
421 guint count,
422 guint *bytes_read)
424 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
425 MSG msg; /* In case of alignment problems */
427 if (count < sizeof (MSG))
428 return G_IO_ERROR_INVAL;
430 if (!PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_REMOVE))
431 return G_IO_ERROR_AGAIN;
433 memmove (buf, &msg, sizeof (MSG));
434 *bytes_read = sizeof (MSG);
435 return G_IO_ERROR_NONE;
438 static GIOError
439 g_io_win32_msg_write (GIOChannel *channel,
440 gchar *buf,
441 guint count,
442 guint *bytes_written)
444 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
445 MSG msg;
447 if (count != sizeof (MSG))
448 return G_IO_ERROR_INVAL;
450 /* In case of alignment problems */
451 memmove (&msg, buf, sizeof (MSG));
452 if (!PostMessage (win32_channel->hwnd, msg.message, msg.wParam, msg.lParam))
453 return G_IO_ERROR_UNKNOWN;
455 *bytes_written = sizeof (MSG);
456 return G_IO_ERROR_NONE;
459 static GIOError
460 g_io_win32_no_seek (GIOChannel *channel,
461 gint offset,
462 GSeekType type)
464 return G_IO_ERROR_UNKNOWN;
467 static void
468 g_io_win32_msg_close (GIOChannel *channel)
470 /* Nothing to be done. Or should we set hwnd to some invalid value? */
473 static void
474 g_io_win32_free (GIOChannel *channel)
476 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
478 if (win32_channel->buffer)
480 CloseHandle (win32_channel->data_avail_event);
481 CloseHandle (win32_channel->space_avail_event);
482 DeleteCriticalSection (&win32_channel->mutex);
485 g_free (win32_channel->buffer);
486 g_free (win32_channel);
489 static guint
490 g_io_win32_msg_add_watch (GIOChannel *channel,
491 gint priority,
492 GIOCondition condition,
493 GIOFunc func,
494 gpointer user_data,
495 GDestroyNotify notify)
497 GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
499 watch->channel = channel;
500 g_io_channel_ref (channel);
502 watch->callback = func;
503 watch->condition = condition;
505 watch->pollfd.fd = G_WIN32_MSG_HANDLE;
506 watch->pollfd.events = condition;
508 g_main_add_poll (&watch->pollfd, priority);
510 return g_source_add (priority, TRUE, &win32_watch_funcs,
511 watch, user_data, notify);
514 static GIOError
515 g_io_win32_fd_read (GIOChannel *channel,
516 gchar *buf,
517 guint count,
518 guint *bytes_read)
520 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
521 gint result;
522 GIOError error;
524 if (win32_channel->debug)
525 g_print ("g_io_win32_fd_read: fd:%d count:%d\n",
526 win32_channel->fd, count);
528 if (win32_channel->thread_id)
530 result = buffer_read (win32_channel, buf, count, &error);
531 if (result < 0)
533 *bytes_read = 0;
534 return error;
536 else
538 *bytes_read = result;
539 return G_IO_ERROR_NONE;
543 result = read (win32_channel->fd, buf, count);
545 if (result < 0)
547 *bytes_read = 0;
548 if (errno == EINVAL)
549 return G_IO_ERROR_INVAL;
550 else
551 return G_IO_ERROR_UNKNOWN;
553 else
555 *bytes_read = result;
556 return G_IO_ERROR_NONE;
560 static GIOError
561 g_io_win32_fd_write (GIOChannel *channel,
562 gchar *buf,
563 guint count,
564 guint *bytes_written)
566 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
567 gint result;
569 result = write (win32_channel->fd, buf, count);
570 if (win32_channel->debug)
571 g_print ("g_io_win32_fd_write: fd:%d count:%d = %d\n",
572 win32_channel->fd, count, result);
574 if (result < 0)
576 *bytes_written = 0;
577 switch (errno)
579 case EINVAL:
580 return G_IO_ERROR_INVAL;
581 case EAGAIN:
582 return G_IO_ERROR_AGAIN;
583 default:
584 return G_IO_ERROR_UNKNOWN;
587 else
589 *bytes_written = result;
590 return G_IO_ERROR_NONE;
594 static GIOError
595 g_io_win32_fd_seek (GIOChannel *channel,
596 gint offset,
597 GSeekType type)
599 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
600 int whence;
601 off_t result;
603 switch (type)
605 case G_SEEK_SET:
606 whence = SEEK_SET;
607 break;
608 case G_SEEK_CUR:
609 whence = SEEK_CUR;
610 break;
611 case G_SEEK_END:
612 whence = SEEK_END;
613 break;
614 default:
615 g_warning ("g_io_win32_fd_seek: unknown seek type");
616 return G_IO_ERROR_UNKNOWN;
619 result = lseek (win32_channel->fd, offset, whence);
621 if (result < 0)
623 switch (errno)
625 case EINVAL:
626 return G_IO_ERROR_INVAL;
627 default:
628 return G_IO_ERROR_UNKNOWN;
631 else
632 return G_IO_ERROR_NONE;
635 static void
636 g_io_win32_fd_close (GIOChannel *channel)
638 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
640 close (win32_channel->fd);
641 return;
644 static int
645 fd_reader (int fd,
646 guchar *buf,
647 int len)
649 return read (fd, buf, len);
652 static guint
653 g_io_win32_fd_add_watch (GIOChannel *channel,
654 gint priority,
655 GIOCondition condition,
656 GIOFunc func,
657 gpointer user_data,
658 GDestroyNotify notify)
660 return g_io_win32_add_watch (channel, priority, condition,
661 func, user_data, notify, fd_reader);
664 static GIOError
665 g_io_win32_sock_read (GIOChannel *channel,
666 gchar *buf,
667 guint count,
668 guint *bytes_read)
670 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
671 gint result;
672 GIOError error;
674 if (win32_channel->thread_id)
676 result = buffer_read (win32_channel, buf, count, &error);
677 if (result < 0)
679 *bytes_read = 0;
680 return error;
682 else
684 *bytes_read = result;
685 return G_IO_ERROR_NONE;
689 result = recv (win32_channel->fd, buf, count, 0);
691 if (result < 0)
693 *bytes_read = 0;
694 return G_IO_ERROR_UNKNOWN;
696 else
698 *bytes_read = result;
699 return G_IO_ERROR_NONE;
703 static GIOError
704 g_io_win32_sock_write (GIOChannel *channel,
705 gchar *buf,
706 guint count,
707 guint *bytes_written)
709 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
710 gint result;
712 result = send (win32_channel->fd, buf, count, 0);
714 if (result == SOCKET_ERROR)
716 *bytes_written = 0;
717 switch (WSAGetLastError ())
719 case WSAEINVAL:
720 return G_IO_ERROR_INVAL;
721 case WSAEWOULDBLOCK:
722 case WSAEINTR:
723 return G_IO_ERROR_AGAIN;
724 default:
725 return G_IO_ERROR_UNKNOWN;
728 else
730 *bytes_written = result;
731 return G_IO_ERROR_NONE;
735 static void
736 g_io_win32_sock_close (GIOChannel *channel)
738 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
740 closesocket (win32_channel->fd);
743 static int
744 sock_reader (int fd,
745 guchar *buf,
746 int len)
748 return recv (fd, buf, len, 0);
751 static guint
752 g_io_win32_sock_add_watch (GIOChannel *channel,
753 gint priority,
754 GIOCondition condition,
755 GIOFunc func,
756 gpointer user_data,
757 GDestroyNotify notify)
759 return g_io_win32_add_watch (channel, priority, condition,
760 func, user_data, notify, sock_reader);
763 static GIOFuncs win32_channel_msg_funcs = {
764 g_io_win32_msg_read,
765 g_io_win32_msg_write,
766 g_io_win32_no_seek,
767 g_io_win32_msg_close,
768 g_io_win32_msg_add_watch,
769 g_io_win32_free
772 static GIOFuncs win32_channel_fd_funcs = {
773 g_io_win32_fd_read,
774 g_io_win32_fd_write,
775 g_io_win32_fd_seek,
776 g_io_win32_fd_close,
777 g_io_win32_fd_add_watch,
778 g_io_win32_free
781 static GIOFuncs win32_channel_sock_funcs = {
782 g_io_win32_sock_read,
783 g_io_win32_sock_write,
784 g_io_win32_no_seek,
785 g_io_win32_sock_close,
786 g_io_win32_sock_add_watch,
787 g_io_win32_free
790 GIOChannel *
791 g_io_channel_win32_new_messages (guint hwnd)
793 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
794 GIOChannel *channel = (GIOChannel *) win32_channel;
796 g_io_channel_init (channel);
797 g_io_channel_win32_init (win32_channel);
798 channel->funcs = &win32_channel_msg_funcs;
799 win32_channel->type = G_IO_WINDOWS_MESSAGES;
800 win32_channel->hwnd = (HWND) hwnd;
802 return channel;
805 GIOChannel *
806 g_io_channel_win32_new_fd (gint fd)
808 GIOWin32Channel *win32_channel;
809 GIOChannel *channel;
810 struct stat st;
812 if (fstat (fd, &st) == -1)
814 g_warning ("%d isn't a (emulated) file descriptor", fd);
815 return NULL;
818 win32_channel = g_new (GIOWin32Channel, 1);
819 channel = (GIOChannel *) win32_channel;
821 g_io_channel_init (channel);
822 g_io_channel_win32_init (win32_channel);
823 channel->funcs = &win32_channel_fd_funcs;
824 win32_channel->type = G_IO_FILE_DESC;
825 win32_channel->fd = fd;
827 return channel;
830 gint
831 g_io_channel_win32_get_fd (GIOChannel *channel)
833 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
835 return win32_channel->fd;
838 GIOChannel *
839 g_io_channel_win32_new_stream_socket (int socket)
841 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
842 GIOChannel *channel = (GIOChannel *) win32_channel;
844 g_io_channel_init (channel);
845 g_io_channel_win32_init (win32_channel);
846 channel->funcs = &win32_channel_sock_funcs;
847 win32_channel->type = G_IO_STREAM_SOCKET;
848 win32_channel->fd = socket;
850 return channel;
853 GIOChannel *
854 g_io_channel_unix_new (gint fd)
856 return g_io_channel_win32_new_fd (fd);
859 gint
860 g_io_channel_unix_get_fd (GIOChannel *channel)
862 return g_io_channel_win32_get_fd (channel);
865 void
866 g_io_channel_win32_set_debug (GIOChannel *channel,
867 gboolean flag)
869 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
871 win32_channel->debug = flag;
874 gint
875 g_io_channel_win32_poll (GPollFD *fds,
876 gint n_fds,
877 gint timeout)
879 int i;
880 int result;
881 gboolean debug = FALSE;
883 g_return_val_if_fail (n_fds >= 0, 0);
885 result = (*g_main_win32_get_poll_func ()) (fds, n_fds, timeout);
887 return result;
890 void
891 g_io_channel_win32_make_pollfd (GIOChannel *channel,
892 GIOCondition condition,
893 GPollFD *fd)
895 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
897 if (win32_channel->data_avail_event == NULL)
898 create_events (win32_channel);
900 fd->fd = win32_channel->data_avail_event;
901 fd->events = condition;
903 if (win32_channel->thread_id == 0)
904 if (win32_channel->type == G_IO_FILE_DESC)
905 create_reader_thread (win32_channel, fd_reader);
906 else if (win32_channel->type == G_IO_STREAM_SOCKET)
907 create_reader_thread (win32_channel, sock_reader);
910 gint
911 g_io_channel_win32_wait_for_condition (GIOChannel *channel,
912 GIOCondition condition,
913 gint timeout)
915 GPollFD pollfd;
916 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
918 g_io_channel_win32_make_pollfd (channel, condition, &pollfd);
920 return g_io_channel_win32_poll (&pollfd, 1, timeout);
923 /* This variable and the functions below are present just to be
924 * binary compatible with old clients... But note that in GIMP, the
925 * libgimp/gimp.c:gimp_extension_process() function will have to be modified
926 * anyhow for this new approach.
928 * These will be removed after some weeks.
930 guint g_pipe_readable_msg = 0;
932 GIOChannel *
933 g_io_channel_win32_new_pipe (int fd)
935 return g_io_channel_win32_new_fd (fd);
938 GIOChannel *
939 g_io_channel_win32_new_pipe_with_wakeups (int fd,
940 guint peer,
941 int peer_fd)
943 return g_io_channel_win32_new_fd (fd);
946 void
947 g_io_channel_win32_pipe_request_wakeups (GIOChannel *channel,
948 guint peer,
949 int peer_fd)
951 /* Nothing needed now */
954 void
955 g_io_channel_win32_pipe_readable (gint fd,
956 guint offset)
958 /* Nothing needed now */