00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "config.h"
00032 #include "glib.h"
00033 #include <windows.h>
00034 #include <winsock.h>
00035 #include <fcntl.h>
00036 #include <io.h>
00037 #include <errno.h>
00038 #include <sys/types.h>
00039
00040 #include <stdio.h>
00041
00042 typedef struct _GIOWin32Channel GIOWin32Channel;
00043 typedef struct _GIOWin32Watch GIOWin32Watch;
00044
00045 guint g_pipe_readable_msg;
00046
00047 typedef enum {
00048 G_IO_WINDOWS_MESSAGES,
00049 G_IO_FILE_DESC,
00050 G_IO_PIPE,
00051 G_IO_STREAM_SOCKET
00052 } GIOWin32ChannelType;
00053
00054 struct _GIOWin32Channel {
00055 GIOChannel channel;
00056 gint fd;
00057
00058
00059
00060 GIOWin32ChannelType type;
00061
00062
00063 HWND hwnd;
00064
00065
00066 guint peer;
00067 guint peer_fd;
00068 guint offset;
00069 guint need_wakeups;
00070
00071
00072 };
00073
00074 struct _GIOWin32Watch {
00075 GPollFD pollfd;
00076 GIOChannel *channel;
00077 GIOCondition condition;
00078 GIOFunc callback;
00079 };
00080
00081 static gboolean g_io_win32_msg_prepare (gpointer source_data,
00082 GTimeVal *current_time,
00083 gint *timeout);
00084 static gboolean g_io_win32_msg_check (gpointer source_data,
00085 GTimeVal *current_time);
00086 static gboolean g_io_win32_msg_dispatch (gpointer source_data,
00087 GTimeVal *current_time,
00088 gpointer user_data);
00089
00090 static gboolean g_io_win32_fd_prepare (gpointer source_data,
00091 GTimeVal *current_time,
00092 gint *timeout);
00093 static gboolean g_io_win32_fd_check (gpointer source_data,
00094 GTimeVal *current_time);
00095 static gboolean g_io_win32_fd_dispatch (gpointer source_data,
00096 GTimeVal *current_time,
00097 gpointer user_data);
00098
00099 static gboolean g_io_win32_pipe_prepare (gpointer source_data,
00100 GTimeVal *current_time,
00101 gint *timeout);
00102 static gboolean g_io_win32_pipe_check (gpointer source_data,
00103 GTimeVal *current_time);
00104 static gboolean g_io_win32_pipe_dispatch (gpointer source_data,
00105 GTimeVal *current_time,
00106 gpointer user_data);
00107 static void g_io_win32_pipe_destroy (gpointer source_data);
00108
00109 static gboolean g_io_win32_sock_prepare (gpointer source_data,
00110 GTimeVal *current_time,
00111 gint *timeout);
00112 static gboolean g_io_win32_sock_check (gpointer source_data,
00113 GTimeVal *current_time);
00114 static gboolean g_io_win32_sock_dispatch (gpointer source_data,
00115 GTimeVal *current_time,
00116 gpointer user_data);
00117
00118 static void g_io_win32_destroy (gpointer source_data);
00119
00120 static GIOError g_io_win32_msg_read (GIOChannel *channel,
00121 gchar *buf,
00122 guint count,
00123 guint *bytes_written);
00124
00125 static GIOError g_io_win32_msg_write(GIOChannel *channel,
00126 gchar *buf,
00127 guint count,
00128 guint *bytes_written);
00129 static GIOError g_io_win32_msg_seek (GIOChannel *channel,
00130 gint offset,
00131 GSeekType type);
00132 static void g_io_win32_msg_close (GIOChannel *channel);
00133 static guint g_io_win32_msg_add_watch (GIOChannel *channel,
00134 gint priority,
00135 GIOCondition condition,
00136 GIOFunc func,
00137 gpointer user_data,
00138 GDestroyNotify notify);
00139
00140 static GIOError g_io_win32_fd_read (GIOChannel *channel,
00141 gchar *buf,
00142 guint count,
00143 guint *bytes_written);
00144 static GIOError g_io_win32_fd_write(GIOChannel *channel,
00145 gchar *buf,
00146 guint count,
00147 guint *bytes_written);
00148 static GIOError g_io_win32_fd_seek (GIOChannel *channel,
00149 gint offset,
00150 GSeekType type);
00151 static void g_io_win32_fd_close (GIOChannel *channel);
00152
00153 static void g_io_win32_free (GIOChannel *channel);
00154
00155 static guint g_io_win32_fd_add_watch (GIOChannel *channel,
00156 gint priority,
00157 GIOCondition condition,
00158 GIOFunc func,
00159 gpointer user_data,
00160 GDestroyNotify notify);
00161
00162 static GIOError g_io_win32_no_seek (GIOChannel *channel,
00163 gint offset,
00164 GSeekType type);
00165
00166 static GIOError g_io_win32_pipe_read (GIOChannel *channel,
00167 gchar *buf,
00168 guint count,
00169 guint *bytes_written);
00170 static GIOError g_io_win32_pipe_write (GIOChannel *channel,
00171 gchar *buf,
00172 guint count,
00173 guint *bytes_written);
00174 static void g_io_win32_pipe_close (GIOChannel *channel);
00175 static guint g_io_win32_pipe_add_watch (GIOChannel *channel,
00176 gint priority,
00177 GIOCondition condition,
00178 GIOFunc func,
00179 gpointer user_data,
00180 GDestroyNotify notify);
00181 static void g_io_win32_pipe_free (GIOChannel *channel);
00182
00183 static GIOError g_io_win32_sock_read (GIOChannel *channel,
00184 gchar *buf,
00185 guint count,
00186 guint *bytes_written);
00187 static GIOError g_io_win32_sock_write(GIOChannel *channel,
00188 gchar *buf,
00189 guint count,
00190 guint *bytes_written);
00191 static void g_io_win32_sock_close (GIOChannel *channel);
00192 static guint g_io_win32_sock_add_watch (GIOChannel *channel,
00193 gint priority,
00194 GIOCondition condition,
00195 GIOFunc func,
00196 gpointer user_data,
00197 GDestroyNotify notify);
00198
00199 GSourceFuncs win32_watch_msg_funcs = {
00200 g_io_win32_msg_prepare,
00201 g_io_win32_msg_check,
00202 g_io_win32_msg_dispatch,
00203 g_io_win32_destroy
00204 };
00205
00206 GSourceFuncs win32_watch_fd_funcs = {
00207 g_io_win32_fd_prepare,
00208 g_io_win32_fd_check,
00209 g_io_win32_fd_dispatch,
00210 g_io_win32_destroy
00211 };
00212
00213 GSourceFuncs win32_watch_pipe_funcs = {
00214 g_io_win32_pipe_prepare,
00215 g_io_win32_pipe_check,
00216 g_io_win32_pipe_dispatch,
00217 g_io_win32_pipe_destroy
00218 };
00219
00220 GSourceFuncs win32_watch_sock_funcs = {
00221 g_io_win32_sock_prepare,
00222 g_io_win32_sock_check,
00223 g_io_win32_sock_dispatch,
00224 g_io_win32_destroy
00225 };
00226
00227 GIOFuncs win32_channel_msg_funcs = {
00228 g_io_win32_msg_read,
00229 g_io_win32_msg_write,
00230 g_io_win32_no_seek,
00231 g_io_win32_msg_close,
00232 g_io_win32_msg_add_watch,
00233 g_io_win32_free
00234 };
00235
00236 GIOFuncs win32_channel_fd_funcs = {
00237 g_io_win32_fd_read,
00238 g_io_win32_fd_write,
00239 g_io_win32_fd_seek,
00240 g_io_win32_fd_close,
00241 g_io_win32_fd_add_watch,
00242 g_io_win32_free
00243 };
00244
00245 GIOFuncs win32_channel_pipe_funcs = {
00246 g_io_win32_pipe_read,
00247 g_io_win32_pipe_write,
00248 g_io_win32_no_seek,
00249 g_io_win32_pipe_close,
00250 g_io_win32_pipe_add_watch,
00251 g_io_win32_pipe_free
00252 };
00253
00254 GIOFuncs win32_channel_sock_funcs = {
00255 g_io_win32_sock_read,
00256 g_io_win32_sock_write,
00257 g_io_win32_no_seek,
00258 g_io_win32_sock_close,
00259 g_io_win32_sock_add_watch,
00260 g_io_win32_free
00261 };
00262
00263 #define N_WATCHED_PIPES 4
00264
00265 static struct {
00266 gint fd;
00267 GIOWin32Watch *watch;
00268 GIOWin32Channel *channel;
00269 gpointer user_data;
00270 } watched_pipes[N_WATCHED_PIPES];
00271
00272 static gint n_watched_pipes = 0;
00273
00274 static gboolean
00275 g_io_win32_msg_prepare (gpointer source_data,
00276 GTimeVal *current_time,
00277 gint *timeout)
00278 {
00279 GIOWin32Watch *data = source_data;
00280 GIOWin32Channel *win32_channel = (GIOWin32Channel *) data->channel;
00281 MSG msg;
00282
00283 *timeout = -1;
00284
00285 return PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_NOREMOVE) == TRUE;
00286 }
00287
00288 static gboolean
00289 g_io_win32_msg_check (gpointer source_data,
00290 GTimeVal *current_time)
00291 {
00292 GIOWin32Watch *data = source_data;
00293 GIOWin32Channel *win32_channel = (GIOWin32Channel *) data->channel;
00294 MSG msg;
00295
00296 return PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_NOREMOVE) == TRUE;
00297 }
00298
00299 static gboolean
00300 g_io_win32_msg_dispatch (gpointer source_data,
00301 GTimeVal *current_time,
00302 gpointer user_data)
00303
00304 {
00305 GIOWin32Watch *data = source_data;
00306
00307 return (*data->callback)(data->channel,
00308 data->pollfd.revents & data->condition,
00309 user_data);
00310 }
00311
00312 static void
00313 g_io_win32_destroy (gpointer source_data)
00314 {
00315 GIOWin32Watch *data = source_data;
00316
00317 g_main_remove_poll (&data->pollfd);
00318 g_io_channel_unref (data->channel);
00319 g_free (data);
00320 }
00321
00322 static gboolean
00323 g_io_win32_fd_prepare (gpointer source_data,
00324 GTimeVal *current_time,
00325 gint *timeout)
00326 {
00327 *timeout = -1;
00328
00329 return FALSE;
00330 }
00331
00332 static gboolean
00333 g_io_win32_fd_check (gpointer source_data,
00334 GTimeVal *current_time)
00335 {
00336 GIOWin32Watch *data = source_data;
00337
00338 return (data->pollfd.revents & data->condition);
00339 }
00340
00341 static gboolean
00342 g_io_win32_fd_dispatch (gpointer source_data,
00343 GTimeVal *current_time,
00344 gpointer user_data)
00345
00346 {
00347 GIOWin32Watch *data = source_data;
00348
00349 return (*data->callback)(data->channel,
00350 data->pollfd.revents & data->condition,
00351 user_data);
00352 }
00353
00354 static GIOError
00355 g_io_win32_msg_read (GIOChannel *channel,
00356 gchar *buf,
00357 guint count,
00358 guint *bytes_read)
00359 {
00360 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00361 MSG msg;
00362
00363 if (count < sizeof (MSG))
00364 return G_IO_ERROR_INVAL;
00365
00366 if (!PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_REMOVE))
00367 return G_IO_ERROR_AGAIN;
00368
00369 memmove (buf, &msg, sizeof (MSG));
00370 *bytes_read = sizeof (MSG);
00371 return G_IO_ERROR_NONE;
00372 }
00373
00374 static GIOError
00375 g_io_win32_msg_write(GIOChannel *channel,
00376 gchar *buf,
00377 guint count,
00378 guint *bytes_written)
00379 {
00380 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00381 MSG msg;
00382 gint result;
00383
00384 if (count != sizeof (MSG))
00385 return G_IO_ERROR_INVAL;
00386
00387
00388 memmove (&msg, buf, sizeof (MSG));
00389 if (!PostMessage (win32_channel->hwnd, msg.message, msg.wParam, msg.lParam))
00390 return G_IO_ERROR_UNKNOWN;
00391
00392 *bytes_written = sizeof (MSG);
00393 return G_IO_ERROR_NONE;
00394 }
00395
00396 static GIOError
00397 g_io_win32_no_seek (GIOChannel *channel,
00398 gint offset,
00399 GSeekType type)
00400 {
00401 g_warning ("g_io_win32_no_seek: unseekable IO channel type");
00402 return G_IO_ERROR_UNKNOWN;
00403 }
00404
00405
00406 static void
00407 g_io_win32_msg_close (GIOChannel *channel)
00408 {
00409
00410 }
00411
00412 static void
00413 g_io_win32_free (GIOChannel *channel)
00414 {
00415 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00416
00417 g_free (win32_channel);
00418 }
00419
00420 static guint
00421 g_io_win32_msg_add_watch (GIOChannel *channel,
00422 gint priority,
00423 GIOCondition condition,
00424 GIOFunc func,
00425 gpointer user_data,
00426 GDestroyNotify notify)
00427 {
00428 GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
00429 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00430
00431 watch->channel = channel;
00432 g_io_channel_ref (channel);
00433
00434 watch->callback = func;
00435 watch->condition = condition;
00436
00437 watch->pollfd.fd = G_WIN32_MSG_HANDLE;
00438 watch->pollfd.events = condition;
00439
00440 g_main_add_poll (&watch->pollfd, priority);
00441
00442 return g_source_add (priority, TRUE, &win32_watch_msg_funcs,
00443 watch, user_data, notify);
00444 }
00445
00446 static gboolean
00447 g_io_win32_pipe_prepare (gpointer source_data,
00448 GTimeVal *current_time,
00449 gint *timeout)
00450 {
00451 *timeout = -1;
00452
00453 return FALSE;
00454 }
00455
00456 static gboolean
00457 g_io_win32_pipe_check (gpointer source_data,
00458 GTimeVal *current_time)
00459 {
00460 GIOWin32Watch *data = source_data;
00461 return FALSE;
00462 }
00463
00464 static gboolean
00465 g_io_win32_pipe_dispatch (gpointer source_data,
00466 GTimeVal *current_time,
00467 gpointer user_data)
00468
00469 {
00470 GIOWin32Watch *data = source_data;
00471
00472 return (*data->callback)(data->channel,
00473 data->pollfd.revents & data->condition,
00474 user_data);
00475 }
00476
00477 static void
00478 g_io_win32_pipe_destroy (gpointer source_data)
00479 {
00480 GIOWin32Watch *data = source_data;
00481
00482 g_io_channel_unref (data->channel);
00483 g_free (data);
00484 }
00485
00486 static gboolean
00487 g_io_win32_sock_prepare (gpointer source_data,
00488 GTimeVal *current_time,
00489 gint *timeout)
00490 {
00491 *timeout = -1;
00492
00493 return FALSE;
00494 }
00495
00496 static gboolean
00497 g_io_win32_sock_check (gpointer source_data,
00498 GTimeVal *current_time)
00499 {
00500 GIOWin32Watch *data = source_data;
00501
00502 return (data->pollfd.revents & data->condition);
00503 }
00504
00505 static gboolean
00506 g_io_win32_sock_dispatch (gpointer source_data,
00507 GTimeVal *current_time,
00508 gpointer user_data)
00509
00510 {
00511 GIOWin32Watch *data = source_data;
00512
00513 return (*data->callback)(data->channel,
00514 data->pollfd.revents & data->condition,
00515 user_data);
00516 }
00517
00518 static GIOError
00519 g_io_win32_fd_read (GIOChannel *channel,
00520 gchar *buf,
00521 guint count,
00522 guint *bytes_read)
00523 {
00524 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00525 gint result;
00526
00527 result = read (win32_channel->fd, buf, count);
00528 if (result < 0)
00529 {
00530 *bytes_read = 0;
00531 switch (errno)
00532 {
00533 case EINVAL:
00534 return G_IO_ERROR_INVAL;
00535 case EAGAIN:
00536 return G_IO_ERROR_AGAIN;
00537 default:
00538 return G_IO_ERROR_UNKNOWN;
00539 }
00540 }
00541 else
00542 {
00543 *bytes_read = result;
00544 return G_IO_ERROR_NONE;
00545 }
00546 }
00547
00548 static GIOError
00549 g_io_win32_fd_write(GIOChannel *channel,
00550 gchar *buf,
00551 guint count,
00552 guint *bytes_written)
00553 {
00554 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00555 gint result;
00556
00557 result = write (win32_channel->fd, buf, count);
00558
00559 if (result < 0)
00560 {
00561 *bytes_written = 0;
00562 switch (errno)
00563 {
00564 case EINVAL:
00565 return G_IO_ERROR_INVAL;
00566 case EAGAIN:
00567 return G_IO_ERROR_AGAIN;
00568 default:
00569 return G_IO_ERROR_UNKNOWN;
00570 }
00571 }
00572 else
00573 {
00574 *bytes_written = result;
00575 return G_IO_ERROR_NONE;
00576 }
00577 }
00578
00579 static GIOError
00580 g_io_win32_fd_seek (GIOChannel *channel,
00581 gint offset,
00582 GSeekType type)
00583 {
00584 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00585 int whence;
00586 off_t result;
00587
00588 switch (type)
00589 {
00590 case G_SEEK_SET:
00591 whence = SEEK_SET;
00592 break;
00593 case G_SEEK_CUR:
00594 whence = SEEK_CUR;
00595 break;
00596 case G_SEEK_END:
00597 whence = SEEK_END;
00598 break;
00599 default:
00600 g_warning ("g_io_win32_fd_seek: unknown seek type");
00601 return G_IO_ERROR_UNKNOWN;
00602 }
00603
00604 result = lseek (win32_channel->fd, offset, whence);
00605
00606 if (result < 0)
00607 {
00608 switch (errno)
00609 {
00610 case EINVAL:
00611 return G_IO_ERROR_INVAL;
00612 default:
00613 return G_IO_ERROR_UNKNOWN;
00614 }
00615 }
00616 else
00617 return G_IO_ERROR_NONE;
00618 }
00619
00620 static void
00621 g_io_win32_fd_close (GIOChannel *channel)
00622 {
00623 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00624
00625 close (win32_channel->fd);
00626 return;
00627 }
00628
00629 static guint
00630 g_io_win32_fd_add_watch (GIOChannel *channel,
00631 gint priority,
00632 GIOCondition condition,
00633 GIOFunc func,
00634 gpointer user_data,
00635 GDestroyNotify notify)
00636 {
00637 GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
00638 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00639
00640 watch->channel = channel;
00641 g_io_channel_ref (channel);
00642
00643 watch->callback = func;
00644 watch->condition = condition;
00645
00646
00647 watch->pollfd.fd = _get_osfhandle (win32_channel->fd);
00648 watch->pollfd.events = condition;
00649
00650 g_main_add_poll (&watch->pollfd, priority);
00651
00652 return g_source_add (priority, TRUE, &win32_watch_fd_funcs,
00653 watch, user_data, notify);
00654 }
00655
00656 static GIOError
00657 g_io_win32_pipe_read (GIOChannel *channel,
00658 gchar *buf,
00659 guint count,
00660 guint *bytes_read)
00661 {
00662 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00663 HANDLE handle;
00664 DWORD avail;
00665 gint result;
00666
00667 handle = (HANDLE) _get_osfhandle (win32_channel->fd);
00668 if (!PeekNamedPipe (handle, NULL, 0, NULL, &avail, NULL))
00669 {
00670 return G_IO_ERROR_UNKNOWN;
00671 }
00672
00673 count = MIN (count, avail);
00674
00675 count = MAX (count, 1);
00676
00677
00678
00679 if (count == 0)
00680 result = 0;
00681 else
00682 result = read (win32_channel->fd, buf, count);
00683 if (result < 0)
00684 {
00685 *bytes_read = 0;
00686 switch (errno)
00687 {
00688 case EINVAL:
00689 return G_IO_ERROR_INVAL;
00690 case EAGAIN:
00691 return G_IO_ERROR_AGAIN;
00692 default:
00693 return G_IO_ERROR_UNKNOWN;
00694 }
00695 }
00696 else
00697 {
00698 *bytes_read = result;
00699 win32_channel->offset += result;
00700
00701 return G_IO_ERROR_NONE;
00702 }
00703 }
00704
00705 static GIOError
00706 g_io_win32_pipe_write(GIOChannel *channel,
00707 gchar *buf,
00708 guint count,
00709 guint *bytes_written)
00710 {
00711 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00712 LONG prevcnt;
00713 gint result;
00714
00715
00716 result = write (win32_channel->fd, buf, count);
00717 if (result < 0)
00718 {
00719 *bytes_written = 0;
00720 switch (errno)
00721 {
00722 case EINVAL:
00723 return G_IO_ERROR_INVAL;
00724 case EAGAIN:
00725 return G_IO_ERROR_AGAIN;
00726 default:
00727 return G_IO_ERROR_UNKNOWN;
00728 }
00729 }
00730 else
00731 {
00732 if (g_pipe_readable_msg == 0)
00733 g_pipe_readable_msg = RegisterWindowMessage ("g-pipe-readable");
00734
00735 win32_channel->offset += result;
00736
00737 if (win32_channel->need_wakeups)
00738 {
00739 PostThreadMessage (win32_channel->peer,
00740 g_pipe_readable_msg,
00741 win32_channel->peer_fd,
00742 win32_channel->offset);
00743 }
00744 *bytes_written = result;
00745 return G_IO_ERROR_NONE;
00746 }
00747 }
00748
00749 static void
00750 g_io_win32_pipe_close (GIOChannel *channel)
00751 {
00752 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00753
00754
00755
00756 close (win32_channel->fd);
00757 return;
00758 }
00759
00760 static guint
00761 g_io_win32_pipe_add_watch (GIOChannel *channel,
00762 gint priority,
00763 GIOCondition condition,
00764 GIOFunc func,
00765 gpointer user_data,
00766 GDestroyNotify notify)
00767 {
00768 GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
00769 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00770 gint i;
00771
00772
00773
00774 watch->channel = channel;
00775 g_io_channel_ref (channel);
00776
00777 watch->callback = func;
00778 watch->condition = condition;
00779
00780 watch->pollfd.fd = win32_channel->fd;
00781 watch->pollfd.events = condition;
00782
00783 for (i = 0; i < n_watched_pipes; i++)
00784 if (watched_pipes[i].fd == -1)
00785 break;
00786 if (i == N_WATCHED_PIPES)
00787 g_error ("Too many watched pipes");
00788 else
00789 {
00790 watched_pipes[i].fd = win32_channel->fd;
00791 watched_pipes[i].watch = watch;
00792 watched_pipes[i].channel = win32_channel;
00793 watched_pipes[i].user_data = user_data;
00794 n_watched_pipes = MAX (i + 1, n_watched_pipes);
00795 }
00796 return g_source_add (priority, FALSE, &win32_watch_pipe_funcs, watch, user_data, notify);
00797 }
00798
00799 static void
00800 g_io_win32_pipe_free (GIOChannel *channel)
00801 {
00802 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00803 gint i;
00804
00805
00806
00807 for (i = 0; i < n_watched_pipes; i++)
00808 if (watched_pipes[i].fd == win32_channel->fd)
00809 {
00810 watched_pipes[i].fd = -1;
00811 break;
00812 }
00813 g_io_win32_free (channel);
00814 }
00815
00816 static GIOError
00817 g_io_win32_sock_read (GIOChannel *channel,
00818 gchar *buf,
00819 guint count,
00820 guint *bytes_read)
00821 {
00822 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00823 gint result;
00824
00825 result = recv (win32_channel->fd, buf, count, 0);
00826 if (result == SOCKET_ERROR)
00827 {
00828 *bytes_read = 0;
00829 switch (WSAGetLastError ())
00830 {
00831 case WSAEINVAL:
00832 return G_IO_ERROR_INVAL;
00833 case WSAEWOULDBLOCK:
00834 case WSAEINTR:
00835 return G_IO_ERROR_AGAIN;
00836 default:
00837 return G_IO_ERROR_UNKNOWN;
00838 }
00839 }
00840 else
00841 {
00842 *bytes_read = result;
00843 return G_IO_ERROR_NONE;
00844 }
00845 }
00846
00847 static GIOError
00848 g_io_win32_sock_write(GIOChannel *channel,
00849 gchar *buf,
00850 guint count,
00851 guint *bytes_written)
00852 {
00853 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00854 gint result;
00855
00856 result = send (win32_channel->fd, buf, count, 0);
00857
00858 if (result == SOCKET_ERROR)
00859 {
00860 *bytes_written = 0;
00861 switch (WSAGetLastError ())
00862 {
00863 case WSAEINVAL:
00864 return G_IO_ERROR_INVAL;
00865 case WSAEWOULDBLOCK:
00866 case WSAEINTR:
00867 return G_IO_ERROR_AGAIN;
00868 default:
00869 return G_IO_ERROR_UNKNOWN;
00870 }
00871 }
00872 else
00873 {
00874 *bytes_written = result;
00875 return G_IO_ERROR_NONE;
00876 }
00877 }
00878
00879 static void
00880 g_io_win32_sock_close (GIOChannel *channel)
00881 {
00882 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00883
00884 closesocket (win32_channel->fd);
00885 return;
00886 }
00887
00888 static guint
00889 g_io_win32_sock_add_watch (GIOChannel *channel,
00890 gint priority,
00891 GIOCondition condition,
00892 GIOFunc func,
00893 gpointer user_data,
00894 GDestroyNotify notify)
00895 {
00896 GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
00897 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00898
00899 watch->channel = channel;
00900 g_io_channel_ref (channel);
00901
00902 watch->callback = func;
00903 watch->condition = condition;
00904
00905 watch->pollfd.fd = win32_channel->fd;
00906 watch->pollfd.events = condition;
00907
00908 g_main_add_poll (&watch->pollfd, priority);
00909
00910 return g_source_add (priority, TRUE, &win32_watch_sock_funcs, watch, user_data, notify);
00911 }
00912
00913 GIOChannel *
00914 g_io_channel_win32_new_messages (guint hwnd)
00915 {
00916 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
00917 GIOChannel *channel = (GIOChannel *) win32_channel;
00918
00919 g_io_channel_init (channel);
00920 channel->funcs = &win32_channel_msg_funcs;
00921 win32_channel->fd = -1;
00922 win32_channel->type = G_IO_WINDOWS_MESSAGES;
00923 win32_channel->hwnd = (HWND) hwnd;
00924
00925 return channel;
00926 }
00927
00928 GIOChannel *
00929 g_io_channel_unix_new (gint fd)
00930 {
00931 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
00932 GIOChannel *channel = (GIOChannel *) win32_channel;
00933
00934 g_io_channel_init (channel);
00935 channel->funcs = &win32_channel_fd_funcs;
00936 win32_channel->fd = fd;
00937 win32_channel->type = G_IO_FILE_DESC;
00938
00939 return channel;
00940 }
00941
00942 gint
00943 g_io_channel_unix_get_fd (GIOChannel *channel)
00944 {
00945 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
00946
00947 return win32_channel->fd;
00948 }
00949
00950 GIOChannel *
00951 g_io_channel_win32_new_pipe_with_wakeups (int fd,
00952 guint peer,
00953 int peer_fd)
00954 {
00955 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
00956 GIOChannel *channel = (GIOChannel *) win32_channel;
00957
00958
00959
00960 g_io_channel_init (channel);
00961 channel->funcs = &win32_channel_pipe_funcs;
00962 win32_channel->fd = fd;
00963 win32_channel->type = G_IO_PIPE;
00964 win32_channel->peer = peer;
00965 win32_channel->peer_fd = peer_fd;
00966 win32_channel->offset = 0;
00967 win32_channel->need_wakeups = TRUE;
00968
00969 return channel;
00970 }
00971
00972 GIOChannel *
00973 g_io_channel_win32_new_pipe (int fd)
00974 {
00975 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
00976 GIOChannel *channel = (GIOChannel *) win32_channel;
00977
00978 g_io_channel_init (channel);
00979 channel->funcs = &win32_channel_pipe_funcs;
00980 win32_channel->fd = fd;
00981 win32_channel->type = G_IO_PIPE;
00982 win32_channel->offset = 0;
00983 win32_channel->need_wakeups = FALSE;
00984
00985 return channel;
00986 }
00987
00988 GIOChannel *
00989 g_io_channel_win32_new_stream_socket (int socket)
00990 {
00991 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
00992 GIOChannel *channel = (GIOChannel *) win32_channel;
00993
00994 g_io_channel_init (channel);
00995 channel->funcs = &win32_channel_sock_funcs;
00996 win32_channel->fd = socket;
00997 win32_channel->type = G_IO_STREAM_SOCKET;
00998
00999 return channel;
01000 }
01001
01002 gint
01003 g_io_channel_win32_get_fd (GIOChannel *channel)
01004 {
01005 return g_io_channel_unix_get_fd (channel);
01006 }
01007
01008 void
01009 g_io_channel_win32_pipe_request_wakeups (GIOChannel *channel,
01010 guint peer,
01011 int peer_fd)
01012 {
01013 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
01014
01015 win32_channel->peer = peer;
01016 win32_channel->peer_fd = peer_fd;
01017 win32_channel->need_wakeups = TRUE;
01018 }
01019
01020 void
01021 g_io_channel_win32_pipe_readable (gint fd,
01022 guint offset)
01023 {
01024 gint i;
01025
01026 for (i = 0; i < n_watched_pipes; i++)
01027 if (watched_pipes[i].fd == fd)
01028 {
01029 if (watched_pipes[i].channel->offset < offset)
01030 (*watched_pipes[i].watch->callback) (watched_pipes[i].watch->channel,
01031 G_IO_IN,
01032 watched_pipes[i].user_data);
01033 break;
01034 }
01035 }