summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Lillqvist <tml@src.gnome.org>1999-01-16 23:46:42 +0000
committerTor Lillqvist <tml@src.gnome.org>1999-01-16 23:46:42 +0000
commitf477518c3af60dccfdd172abee0c7368e8f44189 (patch)
treea49e3518958eb7d6525068b2489b3e87f724d145
parent883776f0353e0cf3bf60f854bb1795e921748dcd (diff)
downloadglib-f477518c3af60dccfdd172abee0c7368e8f44189.tar.gz
Merge in current Win32 version. Almost no Unix code touched.
* README.win32: More text. * config.h.win32 glibconfig.h.win32: Update to match the corresponding generated files on Unix. * makefile.msc: Update with new source files, and gthread library. Use the compiler flag -MD instead of using -D_DLL and "/nodefaultlib:libc msvcrt.lib" in the link phase. * glib.def: Include new functions, drop removed ones. * glib.h: Add comments about main loop and polling on Win32. (In general, it's only for the GIMP's use.) Add Win32 IO Channel functions. Remove the obsoleted old IO Channel stuff (which was in #if 0 already). * giowin32.c: New file. * gmain.c: Include config.h, conditionalize <sys/time.h> inclusion. Add g_poll implementation for Win32 (only for the GIMP's needs for now, it's hard or even impossible to be as clean and generic as on Unix). Implement g_get_current_time on Win32. If threads aren't supported, don't try to wake up main thread's loop. On Win32, use a semaphore and not a pipe to wake up the main loop. * gmessages.c: On Win32, allocate a console window if the standard output handle is invalid before writing to stdout, and reopen stdout to that console window. * giochannel.c: Conditionalize unistd.h inclusion. Some indentation cleanup. * gstrfuncs.c: Include <signal.h>. * gutils.c: On Win32, also check the HOMEDRIVE and HOMEPATH environment variables. * gmodule-dl.c gmodule-dld.c: In _g_module_build_path, don't add the "lib" prefix and ".so" or ".sl" suffix if already there. * gmodule-win32.c: Likewise for the ".dll" suffix. * gthread-posix.c: Conditionalize <sys/time.h> inclusion.
-rw-r--r--ChangeLog42
-rw-r--r--ChangeLog.pre-2-042
-rw-r--r--ChangeLog.pre-2-1042
-rw-r--r--ChangeLog.pre-2-1242
-rw-r--r--ChangeLog.pre-2-242
-rw-r--r--ChangeLog.pre-2-442
-rw-r--r--ChangeLog.pre-2-642
-rw-r--r--ChangeLog.pre-2-842
-rw-r--r--README.win3221
-rw-r--r--config.h.win329
-rw-r--r--giochannel.c8
-rw-r--r--giowin32.c1027
-rw-r--r--glib.def99
-rw-r--r--glib.h117
-rw-r--r--glib/giochannel.c8
-rw-r--r--glib/giowin32.c1027
-rw-r--r--glib/glib.def99
-rw-r--r--glib/glib.h117
-rw-r--r--glib/gmain.c219
-rw-r--r--glib/gmessages.c21
-rw-r--r--glib/gstrfuncs.c1
-rw-r--r--glib/gutils.c23
-rw-r--r--glibconfig.h.win3265
-rw-r--r--gmain.c219
-rw-r--r--gmessages.c21
-rw-r--r--gmodule/ChangeLog8
-rw-r--r--gmodule/gmodule-dl.c9
-rw-r--r--gmodule/gmodule-dld.c11
-rw-r--r--gmodule/gmodule-win32.c12
-rw-r--r--gstrfuncs.c1
-rw-r--r--gthread/ChangeLog4
-rw-r--r--gthread/gthread-posix.c2
-rw-r--r--gutils.c23
-rw-r--r--makefile.msc72
34 files changed, 3435 insertions, 144 deletions
diff --git a/ChangeLog b/ChangeLog
index df7dc128f..88295e56c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+1999-01-16 Tor Lillqvist <tml@iki.fi>
+
+ * Merge in current Win32 version:
+
+ * README.win32: More text.
+
+ * config.h.win32 glibconfig.h.win32: Update to match the
+ corresponding generated files on Unix.
+
+ * makefile.msc: Update with new source files, and gthread
+ library. Use the compiler flag -MD instead of using -D_DLL and
+ /nodefaultlib:libc msvcrt.lib in the link phase.
+
+ * glib.def: Update to include new functions, drop removed ones.
+
+ * glib.h: Add comments about main loop and polling on Win32. (In
+ general, it's only for the GIMP's use.) Add Win32 IO Channel
+ functions. Remove the obsoleted old IO Channel stuff (which was
+ in #if 0 already).
+
+ * giowin32.c: New file.
+
+ * gmain.c: Include config.h, conditionalize <sys/time.h>
+ inclusion. Add g_poll implementation for Win32 (only for the
+ GIMP's needs for now, it's hard or even impossible to be as clean
+ and generic as on Unix). Implement g_get_current_time on Win32. If
+ threads aren't supported, don't try to wake up main thread's
+ loop. On Win32, use a semaphore and not a pipe to wake up the main
+ loop.
+
+ * gmessages.c: On Win32, allocate a console window if the standard
+ output handle is invalid before writing to stdout, and reopen stdout
+ to that console window.
+
+ * giochannel.c: Conditionalize unistd.h inclusion. Some indentation
+ cleanup.
+
+ * gstrfuncs.c: Include <signal.h>.
+
+ * gutils.c: On Win32, also check the HOMEDRIVE and HOMEPATH
+ environment variables.
+
Sun Jan 17 01:06:38 1999 Timur Bakeyev <mc@bat.ru>
* configure.in: Add support for FreeBSD 2.2.x macro _THREAD_SAFE.
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index df7dc128f..88295e56c 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,45 @@
+1999-01-16 Tor Lillqvist <tml@iki.fi>
+
+ * Merge in current Win32 version:
+
+ * README.win32: More text.
+
+ * config.h.win32 glibconfig.h.win32: Update to match the
+ corresponding generated files on Unix.
+
+ * makefile.msc: Update with new source files, and gthread
+ library. Use the compiler flag -MD instead of using -D_DLL and
+ /nodefaultlib:libc msvcrt.lib in the link phase.
+
+ * glib.def: Update to include new functions, drop removed ones.
+
+ * glib.h: Add comments about main loop and polling on Win32. (In
+ general, it's only for the GIMP's use.) Add Win32 IO Channel
+ functions. Remove the obsoleted old IO Channel stuff (which was
+ in #if 0 already).
+
+ * giowin32.c: New file.
+
+ * gmain.c: Include config.h, conditionalize <sys/time.h>
+ inclusion. Add g_poll implementation for Win32 (only for the
+ GIMP's needs for now, it's hard or even impossible to be as clean
+ and generic as on Unix). Implement g_get_current_time on Win32. If
+ threads aren't supported, don't try to wake up main thread's
+ loop. On Win32, use a semaphore and not a pipe to wake up the main
+ loop.
+
+ * gmessages.c: On Win32, allocate a console window if the standard
+ output handle is invalid before writing to stdout, and reopen stdout
+ to that console window.
+
+ * giochannel.c: Conditionalize unistd.h inclusion. Some indentation
+ cleanup.
+
+ * gstrfuncs.c: Include <signal.h>.
+
+ * gutils.c: On Win32, also check the HOMEDRIVE and HOMEPATH
+ environment variables.
+
Sun Jan 17 01:06:38 1999 Timur Bakeyev <mc@bat.ru>
* configure.in: Add support for FreeBSD 2.2.x macro _THREAD_SAFE.
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index df7dc128f..88295e56c 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,45 @@
+1999-01-16 Tor Lillqvist <tml@iki.fi>
+
+ * Merge in current Win32 version:
+
+ * README.win32: More text.
+
+ * config.h.win32 glibconfig.h.win32: Update to match the
+ corresponding generated files on Unix.
+
+ * makefile.msc: Update with new source files, and gthread
+ library. Use the compiler flag -MD instead of using -D_DLL and
+ /nodefaultlib:libc msvcrt.lib in the link phase.
+
+ * glib.def: Update to include new functions, drop removed ones.
+
+ * glib.h: Add comments about main loop and polling on Win32. (In
+ general, it's only for the GIMP's use.) Add Win32 IO Channel
+ functions. Remove the obsoleted old IO Channel stuff (which was
+ in #if 0 already).
+
+ * giowin32.c: New file.
+
+ * gmain.c: Include config.h, conditionalize <sys/time.h>
+ inclusion. Add g_poll implementation for Win32 (only for the
+ GIMP's needs for now, it's hard or even impossible to be as clean
+ and generic as on Unix). Implement g_get_current_time on Win32. If
+ threads aren't supported, don't try to wake up main thread's
+ loop. On Win32, use a semaphore and not a pipe to wake up the main
+ loop.
+
+ * gmessages.c: On Win32, allocate a console window if the standard
+ output handle is invalid before writing to stdout, and reopen stdout
+ to that console window.
+
+ * giochannel.c: Conditionalize unistd.h inclusion. Some indentation
+ cleanup.
+
+ * gstrfuncs.c: Include <signal.h>.
+
+ * gutils.c: On Win32, also check the HOMEDRIVE and HOMEPATH
+ environment variables.
+
Sun Jan 17 01:06:38 1999 Timur Bakeyev <mc@bat.ru>
* configure.in: Add support for FreeBSD 2.2.x macro _THREAD_SAFE.
diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12
index df7dc128f..88295e56c 100644
--- a/ChangeLog.pre-2-12
+++ b/ChangeLog.pre-2-12
@@ -1,3 +1,45 @@
+1999-01-16 Tor Lillqvist <tml@iki.fi>
+
+ * Merge in current Win32 version:
+
+ * README.win32: More text.
+
+ * config.h.win32 glibconfig.h.win32: Update to match the
+ corresponding generated files on Unix.
+
+ * makefile.msc: Update with new source files, and gthread
+ library. Use the compiler flag -MD instead of using -D_DLL and
+ /nodefaultlib:libc msvcrt.lib in the link phase.
+
+ * glib.def: Update to include new functions, drop removed ones.
+
+ * glib.h: Add comments about main loop and polling on Win32. (In
+ general, it's only for the GIMP's use.) Add Win32 IO Channel
+ functions. Remove the obsoleted old IO Channel stuff (which was
+ in #if 0 already).
+
+ * giowin32.c: New file.
+
+ * gmain.c: Include config.h, conditionalize <sys/time.h>
+ inclusion. Add g_poll implementation for Win32 (only for the
+ GIMP's needs for now, it's hard or even impossible to be as clean
+ and generic as on Unix). Implement g_get_current_time on Win32. If
+ threads aren't supported, don't try to wake up main thread's
+ loop. On Win32, use a semaphore and not a pipe to wake up the main
+ loop.
+
+ * gmessages.c: On Win32, allocate a console window if the standard
+ output handle is invalid before writing to stdout, and reopen stdout
+ to that console window.
+
+ * giochannel.c: Conditionalize unistd.h inclusion. Some indentation
+ cleanup.
+
+ * gstrfuncs.c: Include <signal.h>.
+
+ * gutils.c: On Win32, also check the HOMEDRIVE and HOMEPATH
+ environment variables.
+
Sun Jan 17 01:06:38 1999 Timur Bakeyev <mc@bat.ru>
* configure.in: Add support for FreeBSD 2.2.x macro _THREAD_SAFE.
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index df7dc128f..88295e56c 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,45 @@
+1999-01-16 Tor Lillqvist <tml@iki.fi>
+
+ * Merge in current Win32 version:
+
+ * README.win32: More text.
+
+ * config.h.win32 glibconfig.h.win32: Update to match the
+ corresponding generated files on Unix.
+
+ * makefile.msc: Update with new source files, and gthread
+ library. Use the compiler flag -MD instead of using -D_DLL and
+ /nodefaultlib:libc msvcrt.lib in the link phase.
+
+ * glib.def: Update to include new functions, drop removed ones.
+
+ * glib.h: Add comments about main loop and polling on Win32. (In
+ general, it's only for the GIMP's use.) Add Win32 IO Channel
+ functions. Remove the obsoleted old IO Channel stuff (which was
+ in #if 0 already).
+
+ * giowin32.c: New file.
+
+ * gmain.c: Include config.h, conditionalize <sys/time.h>
+ inclusion. Add g_poll implementation for Win32 (only for the
+ GIMP's needs for now, it's hard or even impossible to be as clean
+ and generic as on Unix). Implement g_get_current_time on Win32. If
+ threads aren't supported, don't try to wake up main thread's
+ loop. On Win32, use a semaphore and not a pipe to wake up the main
+ loop.
+
+ * gmessages.c: On Win32, allocate a console window if the standard
+ output handle is invalid before writing to stdout, and reopen stdout
+ to that console window.
+
+ * giochannel.c: Conditionalize unistd.h inclusion. Some indentation
+ cleanup.
+
+ * gstrfuncs.c: Include <signal.h>.
+
+ * gutils.c: On Win32, also check the HOMEDRIVE and HOMEPATH
+ environment variables.
+
Sun Jan 17 01:06:38 1999 Timur Bakeyev <mc@bat.ru>
* configure.in: Add support for FreeBSD 2.2.x macro _THREAD_SAFE.
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index df7dc128f..88295e56c 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,45 @@
+1999-01-16 Tor Lillqvist <tml@iki.fi>
+
+ * Merge in current Win32 version:
+
+ * README.win32: More text.
+
+ * config.h.win32 glibconfig.h.win32: Update to match the
+ corresponding generated files on Unix.
+
+ * makefile.msc: Update with new source files, and gthread
+ library. Use the compiler flag -MD instead of using -D_DLL and
+ /nodefaultlib:libc msvcrt.lib in the link phase.
+
+ * glib.def: Update to include new functions, drop removed ones.
+
+ * glib.h: Add comments about main loop and polling on Win32. (In
+ general, it's only for the GIMP's use.) Add Win32 IO Channel
+ functions. Remove the obsoleted old IO Channel stuff (which was
+ in #if 0 already).
+
+ * giowin32.c: New file.
+
+ * gmain.c: Include config.h, conditionalize <sys/time.h>
+ inclusion. Add g_poll implementation for Win32 (only for the
+ GIMP's needs for now, it's hard or even impossible to be as clean
+ and generic as on Unix). Implement g_get_current_time on Win32. If
+ threads aren't supported, don't try to wake up main thread's
+ loop. On Win32, use a semaphore and not a pipe to wake up the main
+ loop.
+
+ * gmessages.c: On Win32, allocate a console window if the standard
+ output handle is invalid before writing to stdout, and reopen stdout
+ to that console window.
+
+ * giochannel.c: Conditionalize unistd.h inclusion. Some indentation
+ cleanup.
+
+ * gstrfuncs.c: Include <signal.h>.
+
+ * gutils.c: On Win32, also check the HOMEDRIVE and HOMEPATH
+ environment variables.
+
Sun Jan 17 01:06:38 1999 Timur Bakeyev <mc@bat.ru>
* configure.in: Add support for FreeBSD 2.2.x macro _THREAD_SAFE.
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index df7dc128f..88295e56c 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,45 @@
+1999-01-16 Tor Lillqvist <tml@iki.fi>
+
+ * Merge in current Win32 version:
+
+ * README.win32: More text.
+
+ * config.h.win32 glibconfig.h.win32: Update to match the
+ corresponding generated files on Unix.
+
+ * makefile.msc: Update with new source files, and gthread
+ library. Use the compiler flag -MD instead of using -D_DLL and
+ /nodefaultlib:libc msvcrt.lib in the link phase.
+
+ * glib.def: Update to include new functions, drop removed ones.
+
+ * glib.h: Add comments about main loop and polling on Win32. (In
+ general, it's only for the GIMP's use.) Add Win32 IO Channel
+ functions. Remove the obsoleted old IO Channel stuff (which was
+ in #if 0 already).
+
+ * giowin32.c: New file.
+
+ * gmain.c: Include config.h, conditionalize <sys/time.h>
+ inclusion. Add g_poll implementation for Win32 (only for the
+ GIMP's needs for now, it's hard or even impossible to be as clean
+ and generic as on Unix). Implement g_get_current_time on Win32. If
+ threads aren't supported, don't try to wake up main thread's
+ loop. On Win32, use a semaphore and not a pipe to wake up the main
+ loop.
+
+ * gmessages.c: On Win32, allocate a console window if the standard
+ output handle is invalid before writing to stdout, and reopen stdout
+ to that console window.
+
+ * giochannel.c: Conditionalize unistd.h inclusion. Some indentation
+ cleanup.
+
+ * gstrfuncs.c: Include <signal.h>.
+
+ * gutils.c: On Win32, also check the HOMEDRIVE and HOMEPATH
+ environment variables.
+
Sun Jan 17 01:06:38 1999 Timur Bakeyev <mc@bat.ru>
* configure.in: Add support for FreeBSD 2.2.x macro _THREAD_SAFE.
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index df7dc128f..88295e56c 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,45 @@
+1999-01-16 Tor Lillqvist <tml@iki.fi>
+
+ * Merge in current Win32 version:
+
+ * README.win32: More text.
+
+ * config.h.win32 glibconfig.h.win32: Update to match the
+ corresponding generated files on Unix.
+
+ * makefile.msc: Update with new source files, and gthread
+ library. Use the compiler flag -MD instead of using -D_DLL and
+ /nodefaultlib:libc msvcrt.lib in the link phase.
+
+ * glib.def: Update to include new functions, drop removed ones.
+
+ * glib.h: Add comments about main loop and polling on Win32. (In
+ general, it's only for the GIMP's use.) Add Win32 IO Channel
+ functions. Remove the obsoleted old IO Channel stuff (which was
+ in #if 0 already).
+
+ * giowin32.c: New file.
+
+ * gmain.c: Include config.h, conditionalize <sys/time.h>
+ inclusion. Add g_poll implementation for Win32 (only for the
+ GIMP's needs for now, it's hard or even impossible to be as clean
+ and generic as on Unix). Implement g_get_current_time on Win32. If
+ threads aren't supported, don't try to wake up main thread's
+ loop. On Win32, use a semaphore and not a pipe to wake up the main
+ loop.
+
+ * gmessages.c: On Win32, allocate a console window if the standard
+ output handle is invalid before writing to stdout, and reopen stdout
+ to that console window.
+
+ * giochannel.c: Conditionalize unistd.h inclusion. Some indentation
+ cleanup.
+
+ * gstrfuncs.c: Include <signal.h>.
+
+ * gutils.c: On Win32, also check the HOMEDRIVE and HOMEPATH
+ environment variables.
+
Sun Jan 17 01:06:38 1999 Timur Bakeyev <mc@bat.ru>
* configure.in: Add support for FreeBSD 2.2.x macro _THREAD_SAFE.
diff --git a/README.win32 b/README.win32
index e819d9364..e2f179a52 100644
--- a/README.win32
+++ b/README.win32
@@ -1,7 +1,16 @@
-For more information about the Windows port, see
-http://www.iki.fi/tml/gimp/win32/ .
+For more information about the port or GLib, GTk+ and the GIMP to
+native Windows, see http://www.iki.fi/tml/gimp/win32/ . ("Native"
+means that we use the Win32 API only, and not any POSIX emulation
+layer except that provided by the Microsoft runtime C library, and the
+pthreads emulation library from Cygnus.)
-As for now, only Microsoft C is really supported. Before compiling,
-check the BIN definition in makefile.msc. Compile with `nmake -f
-makefile.msc`. Install with `nmake -f makefile.msc install`. Gnu-Win32
-with egcs and maybe LCC-Win32 support will be added later.
+As for now, only the Microsoft compiler and tools are really
+supported. Before compiling, check the BIN definition in
+makefile.msc. Compile with `nmake -f makefile.msc`. Install with
+`nmake -f makefile.msc install`. Cygwin (without cygwin runtime,
+i.e. "mingw32") and maybe LCC-Win32 support will be added later. Note
+that when using the cygwin compiler and other tools *with* the cygwin
+runtime the normal Unix configuration method should work.
+
+The thread support uses the pthreads package from Cygnus, which isn't
+ready yet, and thus really should not be relied upon.
diff --git a/config.h.win32 b/config.h.win32
index 159a2d195..6fc30a5e3 100644
--- a/config.h.win32
+++ b/config.h.win32
@@ -23,13 +23,17 @@
/* #undef ENABLE_MEM_PROFILE */
#define G_COMPILED_WITH_DEBUGGING "minimum"
+
/* #undef HAVE_BROKEN_WCTYPE */
/* #undef HAVE_DOPRNT */
#define HAVE_FLOAT_H 1
#define HAVE_LIMITS_H 1
+/* #undef HAVE_LOCALTIME_R */
/* #undef HAVE_LONG_DOUBLE */
+/* #undef HAVE_POLL */
/* #undef HAVE_PWD_H */
/* #undef HAVE_SYS_PARAM_H */
+/* #undef HAVE_SYS_POLL_H */
/* #undef HAVE_SYS_SELECT_H */
/* #undef HAVE_SYS_TIME_H */
/* #undef HAVE_SYS_TIMES_H */
@@ -52,10 +56,13 @@
#define GLIB_MAJOR_VERSION 1
#define GLIB_MINOR_VERSION 1
-#define GLIB_MICRO_VERSION 4
+#define GLIB_MICRO_VERSION 12
#define GLIB_INTERFACE_AGE 0
#define GLIB_BINARY_AGE 0
+#define G_THREAD_SOURCE "gthread-posix.c"
+#define G_THREADS_IMPL_POSIX
+
/* The number of bytes in a char. */
#define SIZEOF_CHAR 1
diff --git a/giochannel.c b/giochannel.c
index a9bf10a8a..7c05e3c81 100644
--- a/giochannel.c
+++ b/giochannel.c
@@ -24,8 +24,12 @@
* MT safe
*/
+#include "config.h"
+
#include "glib.h"
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
void
g_io_channel_init (GIOChannel *channel)
@@ -94,7 +98,7 @@ g_io_channel_close (GIOChannel *channel)
}
guint
-g_io_add_watch_full (GIOChannel *channel,
+g_io_add_watch_full (GIOChannel *channel,
gint priority,
GIOCondition condition,
GIOFunc func,
@@ -108,7 +112,7 @@ g_io_add_watch_full (GIOChannel *channel,
}
guint
-g_io_add_watch (GIOChannel *channel,
+g_io_add_watch (GIOChannel *channel,
GIOCondition condition,
GIOFunc func,
gpointer user_data)
diff --git a/giowin32.c b/giowin32.c
new file mode 100644
index 000000000..16387d43b
--- /dev/null
+++ b/giowin32.c
@@ -0,0 +1,1027 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * giowin32.c: IO Channels for Win32.
+ * Copyright 1998 Owen Taylor and Tor Lillqvist
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "glib.h"
+#include <windows.h>
+#include <winsock.h> /* Not everybody has winsock2 */
+#include <fcntl.h>
+#include <io.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include <stdio.h>
+
+typedef struct _GIOWin32Channel GIOWin32Channel;
+typedef struct _GIOWin32Watch GIOWin32Watch;
+
+guint g_pipe_readable_msg;
+
+typedef enum {
+ G_IO_WINDOWS_MESSAGES, /* Windows messages */
+ G_IO_FILE_DESC, /* Unix-like file descriptors from _open*/
+ G_IO_PIPE, /* pipe, with windows messages for signalling */
+ G_IO_STREAM_SOCKET /* Stream sockets */
+} GIOWin32ChannelType;
+
+struct _GIOWin32Channel {
+ GIOChannel channel;
+ gint fd; /* Either a Unix-like file handle as provided
+ * by the Microsoft C runtime, or a SOCKET
+ * as provided by WinSock.
+ */
+ GIOWin32ChannelType type;
+
+ /* This is used by G_IO_WINDOWS_MESSAGES channels */
+ HWND hwnd; /* handle of window, or NULL */
+
+ /* This is used by G_IO_PIPE channels */
+ guint peer; /* thread id of reader */
+ guint peer_fd; /* fd in the reader */
+ guint offset; /* counter of accumulated bytes */
+ guint need_wakeups; /* in output channels whether the
+ * reader needs wakeups
+ */
+};
+
+struct _GIOWin32Watch {
+ GPollFD pollfd;
+ GIOChannel *channel;
+ GIOCondition condition;
+ GIOFunc callback;
+};
+
+static gboolean g_io_win32_msg_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout);
+static gboolean g_io_win32_msg_check (gpointer source_data,
+ GTimeVal *current_time);
+static gboolean g_io_win32_msg_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data);
+
+static gboolean g_io_win32_fd_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout);
+static gboolean g_io_win32_fd_check (gpointer source_data,
+ GTimeVal *current_time);
+static gboolean g_io_win32_fd_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data);
+
+static gboolean g_io_win32_pipe_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout);
+static gboolean g_io_win32_pipe_check (gpointer source_data,
+ GTimeVal *current_time);
+static gboolean g_io_win32_pipe_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data);
+static void g_io_win32_pipe_destroy (gpointer source_data);
+
+static gboolean g_io_win32_sock_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout);
+static gboolean g_io_win32_sock_check (gpointer source_data,
+ GTimeVal *current_time);
+static gboolean g_io_win32_sock_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data);
+
+static void g_io_win32_destroy (gpointer source_data);
+
+static GIOError g_io_win32_msg_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+
+static GIOError g_io_win32_msg_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static GIOError g_io_win32_msg_seek (GIOChannel *channel,
+ gint offset,
+ GSeekType type);
+static void g_io_win32_msg_close (GIOChannel *channel);
+static guint g_io_win32_msg_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify);
+
+static GIOError g_io_win32_fd_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static GIOError g_io_win32_fd_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static GIOError g_io_win32_fd_seek (GIOChannel *channel,
+ gint offset,
+ GSeekType type);
+static void g_io_win32_fd_close (GIOChannel *channel);
+
+static void g_io_win32_free (GIOChannel *channel);
+
+static guint g_io_win32_fd_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify);
+
+static GIOError g_io_win32_no_seek (GIOChannel *channel,
+ gint offset,
+ GSeekType type);
+
+static GIOError g_io_win32_pipe_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static GIOError g_io_win32_pipe_write (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static void g_io_win32_pipe_close (GIOChannel *channel);
+static guint g_io_win32_pipe_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify);
+static void g_io_win32_pipe_free (GIOChannel *channel);
+
+static GIOError g_io_win32_sock_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static GIOError g_io_win32_sock_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static void g_io_win32_sock_close (GIOChannel *channel);
+static guint g_io_win32_sock_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify);
+
+GSourceFuncs win32_watch_msg_funcs = {
+ g_io_win32_msg_prepare,
+ g_io_win32_msg_check,
+ g_io_win32_msg_dispatch,
+ g_io_win32_destroy
+};
+
+GSourceFuncs win32_watch_fd_funcs = {
+ g_io_win32_fd_prepare,
+ g_io_win32_fd_check,
+ g_io_win32_fd_dispatch,
+ g_io_win32_destroy
+};
+
+GSourceFuncs win32_watch_pipe_funcs = {
+ g_io_win32_pipe_prepare,
+ g_io_win32_pipe_check,
+ g_io_win32_pipe_dispatch,
+ g_io_win32_pipe_destroy
+};
+
+GSourceFuncs win32_watch_sock_funcs = {
+ g_io_win32_sock_prepare,
+ g_io_win32_sock_check,
+ g_io_win32_sock_dispatch,
+ g_io_win32_destroy
+};
+
+GIOFuncs win32_channel_msg_funcs = {
+ g_io_win32_msg_read,
+ g_io_win32_msg_write,
+ g_io_win32_no_seek,
+ g_io_win32_msg_close,
+ g_io_win32_msg_add_watch,
+ g_io_win32_free
+};
+
+GIOFuncs win32_channel_fd_funcs = {
+ g_io_win32_fd_read,
+ g_io_win32_fd_write,
+ g_io_win32_fd_seek,
+ g_io_win32_fd_close,
+ g_io_win32_fd_add_watch,
+ g_io_win32_free
+};
+
+GIOFuncs win32_channel_pipe_funcs = {
+ g_io_win32_pipe_read,
+ g_io_win32_pipe_write,
+ g_io_win32_no_seek,
+ g_io_win32_pipe_close,
+ g_io_win32_pipe_add_watch,
+ g_io_win32_pipe_free
+};
+
+GIOFuncs win32_channel_sock_funcs = {
+ g_io_win32_sock_read,
+ g_io_win32_sock_write,
+ g_io_win32_no_seek,
+ g_io_win32_sock_close,
+ g_io_win32_sock_add_watch,
+ g_io_win32_free
+};
+
+#define N_WATCHED_PIPES 4
+
+static struct {
+ gint fd;
+ GIOWin32Watch *watch;
+ GIOWin32Channel *channel;
+ gpointer user_data;
+} watched_pipes[N_WATCHED_PIPES];
+
+static gint n_watched_pipes = 0;
+
+static gboolean
+g_io_win32_msg_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout)
+{
+ GIOWin32Watch *data = source_data;
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) data->channel;
+ MSG msg;
+
+ *timeout = -1;
+
+ return PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_NOREMOVE) == TRUE;
+}
+
+static gboolean
+g_io_win32_msg_check (gpointer source_data,
+ GTimeVal *current_time)
+{
+ GIOWin32Watch *data = source_data;
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) data->channel;
+ MSG msg;
+
+ return PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_NOREMOVE) == TRUE;
+}
+
+static gboolean
+g_io_win32_msg_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data)
+
+{
+ GIOWin32Watch *data = source_data;
+
+ return (*data->callback)(data->channel,
+ data->pollfd.revents & data->condition,
+ user_data);
+}
+
+static void
+g_io_win32_destroy (gpointer source_data)
+{
+ GIOWin32Watch *data = source_data;
+
+ g_main_remove_poll (&data->pollfd);
+ g_io_channel_unref (data->channel);
+ g_free (data);
+}
+
+static gboolean
+g_io_win32_fd_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout)
+{
+ *timeout = -1;
+
+ return FALSE;
+}
+
+static gboolean
+g_io_win32_fd_check (gpointer source_data,
+ GTimeVal *current_time)
+{
+ GIOWin32Watch *data = source_data;
+
+ return (data->pollfd.revents & data->condition);
+}
+
+static gboolean
+g_io_win32_fd_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data)
+
+{
+ GIOWin32Watch *data = source_data;
+
+ return (*data->callback)(data->channel,
+ data->pollfd.revents & data->condition,
+ user_data);
+}
+
+static GIOError
+g_io_win32_msg_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_read)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ MSG msg; /* In case of alignment problems */
+
+ if (count < sizeof (MSG))
+ return G_IO_ERROR_INVAL;
+
+ if (!PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_REMOVE))
+ return G_IO_ERROR_AGAIN;
+
+ memmove (buf, &msg, sizeof (MSG));
+ *bytes_read = sizeof (MSG);
+ return G_IO_ERROR_NONE;
+}
+
+static GIOError
+g_io_win32_msg_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ MSG msg;
+ gint result;
+
+ if (count != sizeof (MSG))
+ return G_IO_ERROR_INVAL;
+
+ /* In case of alignment problems */
+ memmove (&msg, buf, sizeof (MSG));
+ if (!PostMessage (win32_channel->hwnd, msg.message, msg.wParam, msg.lParam))
+ return G_IO_ERROR_UNKNOWN;
+
+ *bytes_written = sizeof (MSG);
+ return G_IO_ERROR_NONE;
+}
+
+static GIOError
+g_io_win32_no_seek (GIOChannel *channel,
+ gint offset,
+ GSeekType type)
+{
+ g_warning ("g_io_win32_no_seek: unseekable IO channel type");
+ return G_IO_ERROR_UNKNOWN;
+}
+
+
+static void
+g_io_win32_msg_close (GIOChannel *channel)
+{
+ /* Nothing to be done. Or should we set hwnd to some invalid value? */
+}
+
+static void
+g_io_win32_free (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ g_free (win32_channel);
+}
+
+static guint
+g_io_win32_msg_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->callback = func;
+ watch->condition = condition;
+
+ watch->pollfd.fd = G_WIN32_MSG_HANDLE;
+ watch->pollfd.events = condition;
+
+ g_main_add_poll (&watch->pollfd, priority);
+
+ return g_source_add (priority, TRUE, &win32_watch_msg_funcs,
+ watch, user_data, notify);
+}
+
+static gboolean
+g_io_win32_pipe_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout)
+{
+ *timeout = -1;
+
+ return FALSE;
+}
+
+static gboolean
+g_io_win32_pipe_check (gpointer source_data,
+ GTimeVal *current_time)
+{
+ GIOWin32Watch *data = source_data;
+ return FALSE;
+}
+
+static gboolean
+g_io_win32_pipe_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data)
+
+{
+ GIOWin32Watch *data = source_data;
+
+ return (*data->callback)(data->channel,
+ data->pollfd.revents & data->condition,
+ user_data);
+}
+
+static void
+g_io_win32_pipe_destroy (gpointer source_data)
+{
+ GIOWin32Watch *data = source_data;
+
+ g_io_channel_unref (data->channel);
+ g_free (data);
+}
+
+static gboolean
+g_io_win32_sock_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout)
+{
+ *timeout = -1;
+
+ return FALSE;
+}
+
+static gboolean
+g_io_win32_sock_check (gpointer source_data,
+ GTimeVal *current_time)
+{
+ GIOWin32Watch *data = source_data;
+
+ return (data->pollfd.revents & data->condition);
+}
+
+static gboolean
+g_io_win32_sock_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data)
+
+{
+ GIOWin32Watch *data = source_data;
+
+ return (*data->callback)(data->channel,
+ data->pollfd.revents & data->condition,
+ user_data);
+}
+
+static GIOError
+g_io_win32_fd_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_read)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gint result;
+
+ result = read (win32_channel->fd, buf, count);
+ if (result < 0)
+ {
+ *bytes_read = 0;
+ switch (errno)
+ {
+ case EINVAL:
+ return G_IO_ERROR_INVAL;
+ case EAGAIN:
+ return G_IO_ERROR_AGAIN;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ {
+ *bytes_read = result;
+ return G_IO_ERROR_NONE;
+ }
+}
+
+static GIOError
+g_io_win32_fd_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gint result;
+
+ result = write (win32_channel->fd, buf, count);
+
+ if (result < 0)
+ {
+ *bytes_written = 0;
+ switch (errno)
+ {
+ case EINVAL:
+ return G_IO_ERROR_INVAL;
+ case EAGAIN:
+ return G_IO_ERROR_AGAIN;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ {
+ *bytes_written = result;
+ return G_IO_ERROR_NONE;
+ }
+}
+
+static GIOError
+g_io_win32_fd_seek (GIOChannel *channel,
+ gint offset,
+ GSeekType type)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ int whence;
+ off_t result;
+
+ switch (type)
+ {
+ case G_SEEK_SET:
+ whence = SEEK_SET;
+ break;
+ case G_SEEK_CUR:
+ whence = SEEK_CUR;
+ break;
+ case G_SEEK_END:
+ whence = SEEK_END;
+ break;
+ default:
+ g_warning ("g_io_win32_fd_seek: unknown seek type");
+ return G_IO_ERROR_UNKNOWN;
+ }
+
+ result = lseek (win32_channel->fd, offset, whence);
+
+ if (result < 0)
+ {
+ switch (errno)
+ {
+ case EINVAL:
+ return G_IO_ERROR_INVAL;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ return G_IO_ERROR_NONE;
+}
+
+static void
+g_io_win32_fd_close (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ close (win32_channel->fd);
+ return;
+}
+
+static guint
+g_io_win32_fd_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->callback = func;
+ watch->condition = condition;
+
+ /* This probably does not work, except for CONIN$. */
+ watch->pollfd.fd = _get_osfhandle (win32_channel->fd);
+ watch->pollfd.events = condition;
+
+ g_main_add_poll (&watch->pollfd, priority);
+
+ return g_source_add (priority, TRUE, &win32_watch_fd_funcs,
+ watch, user_data, notify);
+}
+
+static GIOError
+g_io_win32_pipe_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_read)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ HANDLE handle;
+ DWORD avail;
+ gint result;
+
+ handle = (HANDLE) _get_osfhandle (win32_channel->fd);
+ if (!PeekNamedPipe (handle, NULL, 0, NULL, &avail, NULL))
+ {
+ return G_IO_ERROR_UNKNOWN;
+ }
+
+ count = MIN (count, avail);
+
+ count = MAX (count, 1); /* Must read at least one byte, or
+ * caller will think it's EOF.
+ */
+ /* g_print ("g_io_win32_pipe_read: %d %d\n", win32_channel->fd, count); */
+ if (count == 0)
+ result = 0;
+ else
+ result = read (win32_channel->fd, buf, count);
+ if (result < 0)
+ {
+ *bytes_read = 0;
+ switch (errno)
+ {
+ case EINVAL:
+ return G_IO_ERROR_INVAL;
+ case EAGAIN:
+ return G_IO_ERROR_AGAIN;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ {
+ *bytes_read = result;
+ win32_channel->offset += result;
+ /* g_print ("=%d (%d)\n", result, win32_channel->offset); */
+ return G_IO_ERROR_NONE;
+ }
+}
+
+static GIOError
+g_io_win32_pipe_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ LONG prevcnt;
+ gint result;
+
+ /* g_print ("g_io_win32_pipe_write: %d %d\n", win32_channel->fd, count); */
+ result = write (win32_channel->fd, buf, count);
+ if (result < 0)
+ {
+ *bytes_written = 0;
+ switch (errno)
+ {
+ case EINVAL:
+ return G_IO_ERROR_INVAL;
+ case EAGAIN:
+ return G_IO_ERROR_AGAIN;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ {
+ if (g_pipe_readable_msg == 0)
+ g_pipe_readable_msg = RegisterWindowMessage ("g-pipe-readable");
+
+ win32_channel->offset += result;
+ /* g_print ("=%d (%d)\n", result, win32_channel->offset); */
+ if (win32_channel->need_wakeups)
+ {
+ PostThreadMessage (win32_channel->peer,
+ g_pipe_readable_msg,
+ win32_channel->peer_fd,
+ win32_channel->offset);
+ }
+ *bytes_written = result;
+ return G_IO_ERROR_NONE;
+ }
+}
+
+static void
+g_io_win32_pipe_close (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ /* g_print ("g_io_win32_pipe_close: %#x %d\n", channel, win32_channel->fd); */
+
+ close (win32_channel->fd);
+ return;
+}
+
+static guint
+g_io_win32_pipe_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gint i;
+
+ /* g_print ("g_io_win32_pipe_add_watch: %d\n", win32_channel->fd); */
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->callback = func;
+ watch->condition = condition;
+
+ watch->pollfd.fd = win32_channel->fd;
+ watch->pollfd.events = condition;
+
+ for (i = 0; i < n_watched_pipes; i++)
+ if (watched_pipes[i].fd == -1)
+ break;
+ if (i == N_WATCHED_PIPES)
+ g_error ("Too many watched pipes");
+ else
+ {
+ watched_pipes[i].fd = win32_channel->fd;
+ watched_pipes[i].watch = watch;
+ watched_pipes[i].channel = win32_channel;
+ watched_pipes[i].user_data = user_data;
+ n_watched_pipes = MAX (i + 1, n_watched_pipes);
+ }
+ return g_source_add (priority, FALSE, &win32_watch_pipe_funcs, watch, user_data, notify);
+}
+
+static void
+g_io_win32_pipe_free (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gint i;
+
+ /* g_print ("g_io_win32_pipe_free: %#x %#x\n", channel, channel->channel_data); */
+
+ for (i = 0; i < n_watched_pipes; i++)
+ if (watched_pipes[i].fd == win32_channel->fd)
+ {
+ watched_pipes[i].fd = -1;
+ break;
+ }
+ g_io_win32_free (channel);
+}
+
+static GIOError
+g_io_win32_sock_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_read)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gint result;
+
+ result = recv (win32_channel->fd, buf, count, 0);
+ if (result == SOCKET_ERROR)
+ {
+ *bytes_read = 0;
+ switch (WSAGetLastError ())
+ {
+ case WSAEINVAL:
+ return G_IO_ERROR_INVAL;
+ case WSAEWOULDBLOCK:
+ case WSAEINTR:
+ return G_IO_ERROR_AGAIN;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ {
+ *bytes_read = result;
+ return G_IO_ERROR_NONE;
+ }
+}
+
+static GIOError
+g_io_win32_sock_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gint result;
+
+ result = send (win32_channel->fd, buf, count, 0);
+
+ if (result == SOCKET_ERROR)
+ {
+ *bytes_written = 0;
+ switch (WSAGetLastError ())
+ {
+ case WSAEINVAL:
+ return G_IO_ERROR_INVAL;
+ case WSAEWOULDBLOCK:
+ case WSAEINTR:
+ return G_IO_ERROR_AGAIN;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ {
+ *bytes_written = result;
+ return G_IO_ERROR_NONE;
+ }
+}
+
+static void
+g_io_win32_sock_close (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ closesocket (win32_channel->fd);
+ return;
+}
+
+static guint
+g_io_win32_sock_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->callback = func;
+ watch->condition = condition;
+
+ watch->pollfd.fd = win32_channel->fd;
+ watch->pollfd.events = condition;
+
+ g_main_add_poll (&watch->pollfd, priority);
+
+ return g_source_add (priority, TRUE, &win32_watch_sock_funcs, watch, user_data, notify);
+}
+
+GIOChannel *
+g_io_channel_win32_new_messages (guint hwnd)
+{
+ GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+ GIOChannel *channel = (GIOChannel *) win32_channel;
+
+ g_io_channel_init (channel);
+ channel->funcs = &win32_channel_msg_funcs;
+ win32_channel->fd = -1;
+ win32_channel->type = G_IO_WINDOWS_MESSAGES;
+ win32_channel->hwnd = (HWND) hwnd;
+
+ return channel;
+}
+
+GIOChannel *
+g_io_channel_unix_new (gint fd)
+{
+ GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+ GIOChannel *channel = (GIOChannel *) win32_channel;
+
+ g_io_channel_init (channel);
+ channel->funcs = &win32_channel_fd_funcs;
+ win32_channel->fd = fd;
+ win32_channel->type = G_IO_FILE_DESC;
+
+ return channel;
+}
+
+gint
+g_io_channel_unix_get_fd (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ return win32_channel->fd;
+}
+
+GIOChannel *
+g_io_channel_win32_new_pipe_with_wakeups (int fd,
+ guint peer,
+ int peer_fd)
+{
+ GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+ GIOChannel *channel = (GIOChannel *) win32_channel;
+
+ /* g_print ("g_io_channel_win32_new_pipe_with_wakeups %d %#x %d\n", fd, peer, peer_fd); */
+
+ g_io_channel_init (channel);
+ channel->funcs = &win32_channel_pipe_funcs;
+ win32_channel->fd = fd;
+ win32_channel->type = G_IO_PIPE;
+ win32_channel->peer = peer;
+ win32_channel->peer_fd = peer_fd;
+ win32_channel->offset = 0;
+ win32_channel->need_wakeups = TRUE;
+
+ return channel;
+}
+
+GIOChannel *
+g_io_channel_win32_new_pipe (int fd)
+{
+ GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+ GIOChannel *channel = (GIOChannel *) win32_channel;
+
+ g_io_channel_init (channel);
+ channel->funcs = &win32_channel_pipe_funcs;
+ win32_channel->fd = fd;
+ win32_channel->type = G_IO_PIPE;
+ win32_channel->offset = 0;
+ win32_channel->need_wakeups = FALSE;
+
+ return channel;
+}
+
+GIOChannel *
+g_io_channel_win32_new_stream_socket (int socket)
+{
+ GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+ GIOChannel *channel = (GIOChannel *) win32_channel;
+
+ g_io_channel_init (channel);
+ channel->funcs = &win32_channel_sock_funcs;
+ win32_channel->fd = socket;
+ win32_channel->type = G_IO_STREAM_SOCKET;
+
+ return channel;
+}
+
+gint
+g_io_channel_win32_get_fd (GIOChannel *channel)
+{
+ return g_io_channel_unix_get_fd (channel);
+}
+
+void
+g_io_channel_win32_pipe_request_wakeups (GIOChannel *channel,
+ guint peer,
+ int peer_fd)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ win32_channel->peer = peer;
+ win32_channel->peer_fd = peer_fd;
+ win32_channel->need_wakeups = TRUE;
+}
+
+void
+g_io_channel_win32_pipe_readable (gint fd,
+ guint offset)
+{
+ gint i;
+
+ for (i = 0; i < n_watched_pipes; i++)
+ if (watched_pipes[i].fd == fd)
+ {
+ if (watched_pipes[i].channel->offset < offset)
+ (*watched_pipes[i].watch->callback) (watched_pipes[i].watch->channel,
+ G_IO_IN,
+ watched_pipes[i].user_data);
+ break;
+ }
+}
diff --git a/glib.def b/glib.def
index 4858d6cb9..15177bc8b 100644
--- a/glib.def
+++ b/glib.def
@@ -1,6 +1,7 @@
EXPORTS
g_array_append_vals
g_array_free
+ g_array_insert_vals
g_array_new
g_array_prepend_vals
g_array_remove_index
@@ -42,11 +43,55 @@ EXPORTS
g_dataset_id_get_data
g_dataset_id_remove_no_notify
g_dataset_id_set_data_full
+ g_date_add_days
+ g_date_add_months
+ g_date_add_years
+ g_date_clear
+ g_date_compare
+ g_date_day
+ g_date_day_of_year
+ g_date_days_in_month
+ g_date_free
+ g_date_is_first_of_month
+ g_date_is_last_of_month
+ g_date_is_leap_year
+ g_date_julian
+ g_date_julian
+ g_date_monday_week_of_year
+ g_date_monday_weeks_in_year
+ g_date_new
+ g_date_new_dmy
+ g_date_new_julian
+ g_date_month
+ g_date_set_day
+ g_date_set_dmy
+ g_date_set_julian
+ g_date_set_month
+ g_date_set_parse
+ g_date_set_time
+ g_date_set_year
+ g_date_strftime
+ g_date_subtract_days
+ g_date_subtract_months
+ g_date_subtract_years
+ g_date_sunday_week_of_year
+ g_date_sunday_weeks_in_year
+ g_date_to_struct_tm
+ g_date_valid
+ g_date_valid_day
+ g_date_valid_dmy
+ g_date_valid_julian
+ g_date_valid_month
+ g_date_valid_weekday
+ g_date_valid_year
+ g_date_weekday
+ g_date_year
g_direct_equal
g_direct_hash
g_dirname
g_free
g_get_current_dir
+ g_get_current_time
g_get_home_dir
g_get_prgname
g_get_real_name
@@ -81,22 +126,38 @@ EXPORTS
g_hook_list_invoke
g_hook_list_invoke_check
g_hook_list_marshal
+ g_hook_list_marshal_check
g_hook_list_clear
g_hook_next_valid
g_hook_prepend
g_hook_ref
g_hook_unref
+ g_idle_add
+ g_idle_add_full
g_int_equal
g_int_hash
- g_iochannel_new
- g_iochannel_free
- g_iochannel_close_and_free
- g_iochannel_wakeup_peer
+ g_io_add_watch
+ g_io_add_watch_full
+ g_io_channel_close
+ g_io_channel_init
+ g_io_channel_read
+ g_io_channel_ref
+ g_io_channel_seek
+ g_io_channel_unix_get_fd
+ g_io_channel_unix_new
+ g_io_channel_unref
+ g_io_channel_win32_get_fd
+ g_io_channel_win32_new_messages
+ g_io_channel_win32_new_pipe
+ g_io_channel_win32_new_pipe_with_wakeups
+ g_io_channel_win32_new_stream_socket
+ g_io_channel_win32_pipe_readable
+ g_io_channel_win32_pipe_request_wakeups
+ g_io_channel_write
g_list_alloc
- g_list_allocator_free
- g_list_allocator_new
g_list_append
g_list_concat
+ g_list_copy
g_list_find
g_list_find_custom
g_list_first
@@ -115,7 +176,6 @@ EXPORTS
g_list_remove
g_list_remove_link
g_list_reverse
- g_list_set_allocator
g_list_sort
g_log
g_log_default_handler
@@ -124,6 +184,16 @@ EXPORTS
g_log_set_fatal_mask
g_log_set_handler
g_logv
+ g_main_add_poll
+ g_main_destroy
+ g_main_is_running
+ g_main_iteration
+ g_main_new
+ g_main_pending
+ g_main_remove_poll
+ g_main_quit
+ g_main_run
+ g_main_set_poll_func
g_malloc
g_malloc0
g_mem_check
@@ -136,8 +206,11 @@ EXPORTS
g_mem_chunk_new
g_mem_chunk_print
g_mem_chunk_reset
+ g_mem_init
g_mem_profile
g_memdup
+ g_messages_init
+ g_mutex_init
g_node_child_index
g_node_child_position
g_node_children_foreach
@@ -166,6 +239,7 @@ EXPORTS
g_parse_debug_string
g_path_is_absolute
g_path_skip_root
+ g_pipe_readable_msg
g_print
g_printerr
g_printf_string_upper_bound
@@ -224,6 +298,7 @@ EXPORTS
g_slist_alloc
g_slist_append
g_slist_concat
+ g_slist_copy
g_slist_find
g_slist_find_custom
g_slist_foreach
@@ -241,9 +316,15 @@ EXPORTS
g_slist_remove
g_slist_remove_link
g_slist_reverse
- g_slist_set_allocator
g_slist_sort
g_snprintf
+ g_source_add
+ g_source_remove
+ g_source_remove_by_source_data
+ g_source_remove_by_user_data
+ g_static_mutex_get_mutex_impl
+ g_static_private_get
+ g_static_private_set
g_str_equal
g_str_hash
g_strcasecmp
@@ -284,6 +365,8 @@ EXPORTS
g_strsplit
g_strtod
g_strup
+ g_timeout_add
+ g_timeout_add_full
g_timer_destroy
g_timer_elapsed
g_timer_new
diff --git a/glib.h b/glib.h
index cd4ff5cfc..0bbafe119 100644
--- a/glib.h
+++ b/glib.h
@@ -2447,7 +2447,26 @@ guint g_idle_add_full (gint priority,
/* GPollFD
*
- * Unix-specific IO and main loop calls
+ * System-specific IO and main loop calls
+ *
+ * On Win32, the fd in a GPollFD should be Win32 HANDLE (*not* a file
+ * descriptor as provided by the C runtime) that can be used by
+ * MsgWaitForMultipleObjects. This does *not* include file handles
+ * from CreateFile, SOCKETs, nor pipe handles. (But you can use
+ * WSAEventSelect to signal events when a SOCKET is readable).
+ *
+ * On Win32, fd can also be the special value G_WIN32_MSG_HANDLE to
+ * indicate polling for messages. These message queue GPollFDs should
+ * be added with the g_main_poll_win32_msg_add function.
+ *
+ * But note that G_WIN32_MSG_HANDLE GPollFDs should not be used by GDK
+ * (GTK) programs, as GDK itself wants to read messages and convert them
+ * to GDK events.
+ *
+ * So, unless you really know what you are doing, it's best not to try
+ * to use the main loop polling stuff for your own needs on
+ * Win32. It's really only written for the GIMP's needs so
+ * far.
*/
typedef struct _GPollFD GPollFD;
@@ -2466,45 +2485,77 @@ void g_main_add_poll (GPollFD *fd,
void g_main_remove_poll (GPollFD *fd);
void g_main_set_poll_func (GPollFunc func);
+/* On Unix, IO channels created with this function for any file
+ * descriptor or socket.
+ *
+ * On Win32, use this only for plain files opened with the MSVCRT (the
+ * Microsoft run-time C library) _open(), including file descriptors
+ * 0, 1 and 2 (corresponding to stdin, stdout and stderr).
+ * Actually, don't do even that, this code isn't done yet.
+ *
+ * The term file descriptor as used in the context of Win32 refers to
+ * the emulated Unix-like file descriptors MSVCRT provides.
+ */
GIOChannel* g_io_channel_unix_new (int fd);
gint g_io_channel_unix_get_fd (GIOChannel *channel);
+#ifdef NATIVE_WIN32
+
+GUTILS_C_VAR guint g_pipe_readable_msg;
-/* old IO Channels */
-#if 0
-/* IO Channels.
- * These are used for plug-in communication in the GIMP, for instance.
- * On Unix, it's simply an encapsulated file descriptor (a pipe).
- * On Windows, it's a handle to an anonymouos pipe, *and* (in the case
- * of the writable end) a thread id to post a message to when you have written
- * stuff.
+#define G_WIN32_MSG_HANDLE 19981206
+
+/* This is used to add polling for Windows messages. GDK (GTk+) programs
+ * should *not* use this. (In fact, I can't think of any program that
+ * would want to use this, but it's here just for completeness's sake.
*/
-struct _GIOChannel
-{
- gint fd; /* file handle (pseudo such in Win32) */
-#ifdef NATIVE_WIN32
- guint peer; /* thread to post message to */
- guint peer_fd; /* read handle (in the other process) */
- guint offset; /* counter of accumulated bytes, to
- * be included in the message posted
- * so we keep in sync.
- */
- guint need_wakeups; /* in output channels whether the reader
- * needs wakeups
- */
-#endif
-};
-GIOChannel *g_iochannel_new (gint fd);
-void g_iochannel_free (GIOChannel *channel);
-void g_iochannel_close_and_free (GIOChannel *channel);
-void g_iochannel_wakeup_peer (GIOChannel *channel);
-#ifndef NATIVE_WIN32
-# define g_iochannel_wakeup_peer(channel) G_STMT_START { } G_STMT_END
-#endif
-#endif /* old IO Channels */
+void g_main_poll_win32_msg_add(gint priority,
+ GPollFD *fd,
+ guint hwnd);
+
+/* An IO channel for Windows messages for window handle hwnd. */
+GIOChannel *g_io_channel_win32_new_messages (guint hwnd);
+
+/* An IO channel for an anonymous pipe as returned from the MSVCRT
+ * _pipe(), with no mechanism for the writer to tell the reader when
+ * there is data in the pipe.
+ *
+ * This is not really implemented yet.
+ */
+GIOChannel *g_io_channel_win32_new_pipe (int fd);
+/* An IO channel for a pipe as returned from the MSVCRT _pipe(), with
+ * Windows user messages used to signal data in the pipe for the
+ * reader.
+ *
+ * fd is the file descriptor. For the write end, peer is the thread id
+ * of the reader, and peer_fd is his file descriptor for the read end
+ * of the pipe.
+ *
+ * This is used by the GIMP, and works.
+ */
+GIOChannel *g_io_channel_win32_new_pipe_with_wakeups (int fd,
+ guint peer,
+ int peer_fd);
+
+void g_io_channel_win32_pipe_request_wakeups (GIOChannel *channel,
+ guint peer,
+ int peer_fd);
+
+void g_io_channel_win32_pipe_readable (int fd,
+ guint offset);
+
+/* Get the C runtime file descriptor of a channel. */
+gint g_io_channel_win32_get_fd (GIOChannel *channel);
+
+/* An IO channel for a SOCK_STREAM winsock socket. The parameter is
+ * actually a SOCKET.
+ */
+GIOChannel *g_io_channel_win32_new_stream_socket (int socket);
+
+#endif
-/* Windows emulation stubs for common unix functions
+/* Windows emulation stubs for common Unix functions
*/
#ifdef NATIVE_WIN32
# define MAXPATHLEN 1024
diff --git a/glib/giochannel.c b/glib/giochannel.c
index a9bf10a8a..7c05e3c81 100644
--- a/glib/giochannel.c
+++ b/glib/giochannel.c
@@ -24,8 +24,12 @@
* MT safe
*/
+#include "config.h"
+
#include "glib.h"
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
void
g_io_channel_init (GIOChannel *channel)
@@ -94,7 +98,7 @@ g_io_channel_close (GIOChannel *channel)
}
guint
-g_io_add_watch_full (GIOChannel *channel,
+g_io_add_watch_full (GIOChannel *channel,
gint priority,
GIOCondition condition,
GIOFunc func,
@@ -108,7 +112,7 @@ g_io_add_watch_full (GIOChannel *channel,
}
guint
-g_io_add_watch (GIOChannel *channel,
+g_io_add_watch (GIOChannel *channel,
GIOCondition condition,
GIOFunc func,
gpointer user_data)
diff --git a/glib/giowin32.c b/glib/giowin32.c
new file mode 100644
index 000000000..16387d43b
--- /dev/null
+++ b/glib/giowin32.c
@@ -0,0 +1,1027 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * giowin32.c: IO Channels for Win32.
+ * Copyright 1998 Owen Taylor and Tor Lillqvist
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "glib.h"
+#include <windows.h>
+#include <winsock.h> /* Not everybody has winsock2 */
+#include <fcntl.h>
+#include <io.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include <stdio.h>
+
+typedef struct _GIOWin32Channel GIOWin32Channel;
+typedef struct _GIOWin32Watch GIOWin32Watch;
+
+guint g_pipe_readable_msg;
+
+typedef enum {
+ G_IO_WINDOWS_MESSAGES, /* Windows messages */
+ G_IO_FILE_DESC, /* Unix-like file descriptors from _open*/
+ G_IO_PIPE, /* pipe, with windows messages for signalling */
+ G_IO_STREAM_SOCKET /* Stream sockets */
+} GIOWin32ChannelType;
+
+struct _GIOWin32Channel {
+ GIOChannel channel;
+ gint fd; /* Either a Unix-like file handle as provided
+ * by the Microsoft C runtime, or a SOCKET
+ * as provided by WinSock.
+ */
+ GIOWin32ChannelType type;
+
+ /* This is used by G_IO_WINDOWS_MESSAGES channels */
+ HWND hwnd; /* handle of window, or NULL */
+
+ /* This is used by G_IO_PIPE channels */
+ guint peer; /* thread id of reader */
+ guint peer_fd; /* fd in the reader */
+ guint offset; /* counter of accumulated bytes */
+ guint need_wakeups; /* in output channels whether the
+ * reader needs wakeups
+ */
+};
+
+struct _GIOWin32Watch {
+ GPollFD pollfd;
+ GIOChannel *channel;
+ GIOCondition condition;
+ GIOFunc callback;
+};
+
+static gboolean g_io_win32_msg_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout);
+static gboolean g_io_win32_msg_check (gpointer source_data,
+ GTimeVal *current_time);
+static gboolean g_io_win32_msg_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data);
+
+static gboolean g_io_win32_fd_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout);
+static gboolean g_io_win32_fd_check (gpointer source_data,
+ GTimeVal *current_time);
+static gboolean g_io_win32_fd_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data);
+
+static gboolean g_io_win32_pipe_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout);
+static gboolean g_io_win32_pipe_check (gpointer source_data,
+ GTimeVal *current_time);
+static gboolean g_io_win32_pipe_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data);
+static void g_io_win32_pipe_destroy (gpointer source_data);
+
+static gboolean g_io_win32_sock_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout);
+static gboolean g_io_win32_sock_check (gpointer source_data,
+ GTimeVal *current_time);
+static gboolean g_io_win32_sock_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data);
+
+static void g_io_win32_destroy (gpointer source_data);
+
+static GIOError g_io_win32_msg_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+
+static GIOError g_io_win32_msg_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static GIOError g_io_win32_msg_seek (GIOChannel *channel,
+ gint offset,
+ GSeekType type);
+static void g_io_win32_msg_close (GIOChannel *channel);
+static guint g_io_win32_msg_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify);
+
+static GIOError g_io_win32_fd_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static GIOError g_io_win32_fd_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static GIOError g_io_win32_fd_seek (GIOChannel *channel,
+ gint offset,
+ GSeekType type);
+static void g_io_win32_fd_close (GIOChannel *channel);
+
+static void g_io_win32_free (GIOChannel *channel);
+
+static guint g_io_win32_fd_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify);
+
+static GIOError g_io_win32_no_seek (GIOChannel *channel,
+ gint offset,
+ GSeekType type);
+
+static GIOError g_io_win32_pipe_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static GIOError g_io_win32_pipe_write (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static void g_io_win32_pipe_close (GIOChannel *channel);
+static guint g_io_win32_pipe_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify);
+static void g_io_win32_pipe_free (GIOChannel *channel);
+
+static GIOError g_io_win32_sock_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static GIOError g_io_win32_sock_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+static void g_io_win32_sock_close (GIOChannel *channel);
+static guint g_io_win32_sock_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify);
+
+GSourceFuncs win32_watch_msg_funcs = {
+ g_io_win32_msg_prepare,
+ g_io_win32_msg_check,
+ g_io_win32_msg_dispatch,
+ g_io_win32_destroy
+};
+
+GSourceFuncs win32_watch_fd_funcs = {
+ g_io_win32_fd_prepare,
+ g_io_win32_fd_check,
+ g_io_win32_fd_dispatch,
+ g_io_win32_destroy
+};
+
+GSourceFuncs win32_watch_pipe_funcs = {
+ g_io_win32_pipe_prepare,
+ g_io_win32_pipe_check,
+ g_io_win32_pipe_dispatch,
+ g_io_win32_pipe_destroy
+};
+
+GSourceFuncs win32_watch_sock_funcs = {
+ g_io_win32_sock_prepare,
+ g_io_win32_sock_check,
+ g_io_win32_sock_dispatch,
+ g_io_win32_destroy
+};
+
+GIOFuncs win32_channel_msg_funcs = {
+ g_io_win32_msg_read,
+ g_io_win32_msg_write,
+ g_io_win32_no_seek,
+ g_io_win32_msg_close,
+ g_io_win32_msg_add_watch,
+ g_io_win32_free
+};
+
+GIOFuncs win32_channel_fd_funcs = {
+ g_io_win32_fd_read,
+ g_io_win32_fd_write,
+ g_io_win32_fd_seek,
+ g_io_win32_fd_close,
+ g_io_win32_fd_add_watch,
+ g_io_win32_free
+};
+
+GIOFuncs win32_channel_pipe_funcs = {
+ g_io_win32_pipe_read,
+ g_io_win32_pipe_write,
+ g_io_win32_no_seek,
+ g_io_win32_pipe_close,
+ g_io_win32_pipe_add_watch,
+ g_io_win32_pipe_free
+};
+
+GIOFuncs win32_channel_sock_funcs = {
+ g_io_win32_sock_read,
+ g_io_win32_sock_write,
+ g_io_win32_no_seek,
+ g_io_win32_sock_close,
+ g_io_win32_sock_add_watch,
+ g_io_win32_free
+};
+
+#define N_WATCHED_PIPES 4
+
+static struct {
+ gint fd;
+ GIOWin32Watch *watch;
+ GIOWin32Channel *channel;
+ gpointer user_data;
+} watched_pipes[N_WATCHED_PIPES];
+
+static gint n_watched_pipes = 0;
+
+static gboolean
+g_io_win32_msg_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout)
+{
+ GIOWin32Watch *data = source_data;
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) data->channel;
+ MSG msg;
+
+ *timeout = -1;
+
+ return PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_NOREMOVE) == TRUE;
+}
+
+static gboolean
+g_io_win32_msg_check (gpointer source_data,
+ GTimeVal *current_time)
+{
+ GIOWin32Watch *data = source_data;
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) data->channel;
+ MSG msg;
+
+ return PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_NOREMOVE) == TRUE;
+}
+
+static gboolean
+g_io_win32_msg_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data)
+
+{
+ GIOWin32Watch *data = source_data;
+
+ return (*data->callback)(data->channel,
+ data->pollfd.revents & data->condition,
+ user_data);
+}
+
+static void
+g_io_win32_destroy (gpointer source_data)
+{
+ GIOWin32Watch *data = source_data;
+
+ g_main_remove_poll (&data->pollfd);
+ g_io_channel_unref (data->channel);
+ g_free (data);
+}
+
+static gboolean
+g_io_win32_fd_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout)
+{
+ *timeout = -1;
+
+ return FALSE;
+}
+
+static gboolean
+g_io_win32_fd_check (gpointer source_data,
+ GTimeVal *current_time)
+{
+ GIOWin32Watch *data = source_data;
+
+ return (data->pollfd.revents & data->condition);
+}
+
+static gboolean
+g_io_win32_fd_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data)
+
+{
+ GIOWin32Watch *data = source_data;
+
+ return (*data->callback)(data->channel,
+ data->pollfd.revents & data->condition,
+ user_data);
+}
+
+static GIOError
+g_io_win32_msg_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_read)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ MSG msg; /* In case of alignment problems */
+
+ if (count < sizeof (MSG))
+ return G_IO_ERROR_INVAL;
+
+ if (!PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_REMOVE))
+ return G_IO_ERROR_AGAIN;
+
+ memmove (buf, &msg, sizeof (MSG));
+ *bytes_read = sizeof (MSG);
+ return G_IO_ERROR_NONE;
+}
+
+static GIOError
+g_io_win32_msg_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ MSG msg;
+ gint result;
+
+ if (count != sizeof (MSG))
+ return G_IO_ERROR_INVAL;
+
+ /* In case of alignment problems */
+ memmove (&msg, buf, sizeof (MSG));
+ if (!PostMessage (win32_channel->hwnd, msg.message, msg.wParam, msg.lParam))
+ return G_IO_ERROR_UNKNOWN;
+
+ *bytes_written = sizeof (MSG);
+ return G_IO_ERROR_NONE;
+}
+
+static GIOError
+g_io_win32_no_seek (GIOChannel *channel,
+ gint offset,
+ GSeekType type)
+{
+ g_warning ("g_io_win32_no_seek: unseekable IO channel type");
+ return G_IO_ERROR_UNKNOWN;
+}
+
+
+static void
+g_io_win32_msg_close (GIOChannel *channel)
+{
+ /* Nothing to be done. Or should we set hwnd to some invalid value? */
+}
+
+static void
+g_io_win32_free (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ g_free (win32_channel);
+}
+
+static guint
+g_io_win32_msg_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->callback = func;
+ watch->condition = condition;
+
+ watch->pollfd.fd = G_WIN32_MSG_HANDLE;
+ watch->pollfd.events = condition;
+
+ g_main_add_poll (&watch->pollfd, priority);
+
+ return g_source_add (priority, TRUE, &win32_watch_msg_funcs,
+ watch, user_data, notify);
+}
+
+static gboolean
+g_io_win32_pipe_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout)
+{
+ *timeout = -1;
+
+ return FALSE;
+}
+
+static gboolean
+g_io_win32_pipe_check (gpointer source_data,
+ GTimeVal *current_time)
+{
+ GIOWin32Watch *data = source_data;
+ return FALSE;
+}
+
+static gboolean
+g_io_win32_pipe_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data)
+
+{
+ GIOWin32Watch *data = source_data;
+
+ return (*data->callback)(data->channel,
+ data->pollfd.revents & data->condition,
+ user_data);
+}
+
+static void
+g_io_win32_pipe_destroy (gpointer source_data)
+{
+ GIOWin32Watch *data = source_data;
+
+ g_io_channel_unref (data->channel);
+ g_free (data);
+}
+
+static gboolean
+g_io_win32_sock_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout)
+{
+ *timeout = -1;
+
+ return FALSE;
+}
+
+static gboolean
+g_io_win32_sock_check (gpointer source_data,
+ GTimeVal *current_time)
+{
+ GIOWin32Watch *data = source_data;
+
+ return (data->pollfd.revents & data->condition);
+}
+
+static gboolean
+g_io_win32_sock_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data)
+
+{
+ GIOWin32Watch *data = source_data;
+
+ return (*data->callback)(data->channel,
+ data->pollfd.revents & data->condition,
+ user_data);
+}
+
+static GIOError
+g_io_win32_fd_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_read)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gint result;
+
+ result = read (win32_channel->fd, buf, count);
+ if (result < 0)
+ {
+ *bytes_read = 0;
+ switch (errno)
+ {
+ case EINVAL:
+ return G_IO_ERROR_INVAL;
+ case EAGAIN:
+ return G_IO_ERROR_AGAIN;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ {
+ *bytes_read = result;
+ return G_IO_ERROR_NONE;
+ }
+}
+
+static GIOError
+g_io_win32_fd_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gint result;
+
+ result = write (win32_channel->fd, buf, count);
+
+ if (result < 0)
+ {
+ *bytes_written = 0;
+ switch (errno)
+ {
+ case EINVAL:
+ return G_IO_ERROR_INVAL;
+ case EAGAIN:
+ return G_IO_ERROR_AGAIN;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ {
+ *bytes_written = result;
+ return G_IO_ERROR_NONE;
+ }
+}
+
+static GIOError
+g_io_win32_fd_seek (GIOChannel *channel,
+ gint offset,
+ GSeekType type)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ int whence;
+ off_t result;
+
+ switch (type)
+ {
+ case G_SEEK_SET:
+ whence = SEEK_SET;
+ break;
+ case G_SEEK_CUR:
+ whence = SEEK_CUR;
+ break;
+ case G_SEEK_END:
+ whence = SEEK_END;
+ break;
+ default:
+ g_warning ("g_io_win32_fd_seek: unknown seek type");
+ return G_IO_ERROR_UNKNOWN;
+ }
+
+ result = lseek (win32_channel->fd, offset, whence);
+
+ if (result < 0)
+ {
+ switch (errno)
+ {
+ case EINVAL:
+ return G_IO_ERROR_INVAL;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ return G_IO_ERROR_NONE;
+}
+
+static void
+g_io_win32_fd_close (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ close (win32_channel->fd);
+ return;
+}
+
+static guint
+g_io_win32_fd_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->callback = func;
+ watch->condition = condition;
+
+ /* This probably does not work, except for CONIN$. */
+ watch->pollfd.fd = _get_osfhandle (win32_channel->fd);
+ watch->pollfd.events = condition;
+
+ g_main_add_poll (&watch->pollfd, priority);
+
+ return g_source_add (priority, TRUE, &win32_watch_fd_funcs,
+ watch, user_data, notify);
+}
+
+static GIOError
+g_io_win32_pipe_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_read)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ HANDLE handle;
+ DWORD avail;
+ gint result;
+
+ handle = (HANDLE) _get_osfhandle (win32_channel->fd);
+ if (!PeekNamedPipe (handle, NULL, 0, NULL, &avail, NULL))
+ {
+ return G_IO_ERROR_UNKNOWN;
+ }
+
+ count = MIN (count, avail);
+
+ count = MAX (count, 1); /* Must read at least one byte, or
+ * caller will think it's EOF.
+ */
+ /* g_print ("g_io_win32_pipe_read: %d %d\n", win32_channel->fd, count); */
+ if (count == 0)
+ result = 0;
+ else
+ result = read (win32_channel->fd, buf, count);
+ if (result < 0)
+ {
+ *bytes_read = 0;
+ switch (errno)
+ {
+ case EINVAL:
+ return G_IO_ERROR_INVAL;
+ case EAGAIN:
+ return G_IO_ERROR_AGAIN;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ {
+ *bytes_read = result;
+ win32_channel->offset += result;
+ /* g_print ("=%d (%d)\n", result, win32_channel->offset); */
+ return G_IO_ERROR_NONE;
+ }
+}
+
+static GIOError
+g_io_win32_pipe_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ LONG prevcnt;
+ gint result;
+
+ /* g_print ("g_io_win32_pipe_write: %d %d\n", win32_channel->fd, count); */
+ result = write (win32_channel->fd, buf, count);
+ if (result < 0)
+ {
+ *bytes_written = 0;
+ switch (errno)
+ {
+ case EINVAL:
+ return G_IO_ERROR_INVAL;
+ case EAGAIN:
+ return G_IO_ERROR_AGAIN;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ {
+ if (g_pipe_readable_msg == 0)
+ g_pipe_readable_msg = RegisterWindowMessage ("g-pipe-readable");
+
+ win32_channel->offset += result;
+ /* g_print ("=%d (%d)\n", result, win32_channel->offset); */
+ if (win32_channel->need_wakeups)
+ {
+ PostThreadMessage (win32_channel->peer,
+ g_pipe_readable_msg,
+ win32_channel->peer_fd,
+ win32_channel->offset);
+ }
+ *bytes_written = result;
+ return G_IO_ERROR_NONE;
+ }
+}
+
+static void
+g_io_win32_pipe_close (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ /* g_print ("g_io_win32_pipe_close: %#x %d\n", channel, win32_channel->fd); */
+
+ close (win32_channel->fd);
+ return;
+}
+
+static guint
+g_io_win32_pipe_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gint i;
+
+ /* g_print ("g_io_win32_pipe_add_watch: %d\n", win32_channel->fd); */
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->callback = func;
+ watch->condition = condition;
+
+ watch->pollfd.fd = win32_channel->fd;
+ watch->pollfd.events = condition;
+
+ for (i = 0; i < n_watched_pipes; i++)
+ if (watched_pipes[i].fd == -1)
+ break;
+ if (i == N_WATCHED_PIPES)
+ g_error ("Too many watched pipes");
+ else
+ {
+ watched_pipes[i].fd = win32_channel->fd;
+ watched_pipes[i].watch = watch;
+ watched_pipes[i].channel = win32_channel;
+ watched_pipes[i].user_data = user_data;
+ n_watched_pipes = MAX (i + 1, n_watched_pipes);
+ }
+ return g_source_add (priority, FALSE, &win32_watch_pipe_funcs, watch, user_data, notify);
+}
+
+static void
+g_io_win32_pipe_free (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gint i;
+
+ /* g_print ("g_io_win32_pipe_free: %#x %#x\n", channel, channel->channel_data); */
+
+ for (i = 0; i < n_watched_pipes; i++)
+ if (watched_pipes[i].fd == win32_channel->fd)
+ {
+ watched_pipes[i].fd = -1;
+ break;
+ }
+ g_io_win32_free (channel);
+}
+
+static GIOError
+g_io_win32_sock_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_read)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gint result;
+
+ result = recv (win32_channel->fd, buf, count, 0);
+ if (result == SOCKET_ERROR)
+ {
+ *bytes_read = 0;
+ switch (WSAGetLastError ())
+ {
+ case WSAEINVAL:
+ return G_IO_ERROR_INVAL;
+ case WSAEWOULDBLOCK:
+ case WSAEINTR:
+ return G_IO_ERROR_AGAIN;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ {
+ *bytes_read = result;
+ return G_IO_ERROR_NONE;
+ }
+}
+
+static GIOError
+g_io_win32_sock_write(GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gint result;
+
+ result = send (win32_channel->fd, buf, count, 0);
+
+ if (result == SOCKET_ERROR)
+ {
+ *bytes_written = 0;
+ switch (WSAGetLastError ())
+ {
+ case WSAEINVAL:
+ return G_IO_ERROR_INVAL;
+ case WSAEWOULDBLOCK:
+ case WSAEINTR:
+ return G_IO_ERROR_AGAIN;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ }
+ else
+ {
+ *bytes_written = result;
+ return G_IO_ERROR_NONE;
+ }
+}
+
+static void
+g_io_win32_sock_close (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ closesocket (win32_channel->fd);
+ return;
+}
+
+static guint
+g_io_win32_sock_add_watch (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->callback = func;
+ watch->condition = condition;
+
+ watch->pollfd.fd = win32_channel->fd;
+ watch->pollfd.events = condition;
+
+ g_main_add_poll (&watch->pollfd, priority);
+
+ return g_source_add (priority, TRUE, &win32_watch_sock_funcs, watch, user_data, notify);
+}
+
+GIOChannel *
+g_io_channel_win32_new_messages (guint hwnd)
+{
+ GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+ GIOChannel *channel = (GIOChannel *) win32_channel;
+
+ g_io_channel_init (channel);
+ channel->funcs = &win32_channel_msg_funcs;
+ win32_channel->fd = -1;
+ win32_channel->type = G_IO_WINDOWS_MESSAGES;
+ win32_channel->hwnd = (HWND) hwnd;
+
+ return channel;
+}
+
+GIOChannel *
+g_io_channel_unix_new (gint fd)
+{
+ GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+ GIOChannel *channel = (GIOChannel *) win32_channel;
+
+ g_io_channel_init (channel);
+ channel->funcs = &win32_channel_fd_funcs;
+ win32_channel->fd = fd;
+ win32_channel->type = G_IO_FILE_DESC;
+
+ return channel;
+}
+
+gint
+g_io_channel_unix_get_fd (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ return win32_channel->fd;
+}
+
+GIOChannel *
+g_io_channel_win32_new_pipe_with_wakeups (int fd,
+ guint peer,
+ int peer_fd)
+{
+ GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+ GIOChannel *channel = (GIOChannel *) win32_channel;
+
+ /* g_print ("g_io_channel_win32_new_pipe_with_wakeups %d %#x %d\n", fd, peer, peer_fd); */
+
+ g_io_channel_init (channel);
+ channel->funcs = &win32_channel_pipe_funcs;
+ win32_channel->fd = fd;
+ win32_channel->type = G_IO_PIPE;
+ win32_channel->peer = peer;
+ win32_channel->peer_fd = peer_fd;
+ win32_channel->offset = 0;
+ win32_channel->need_wakeups = TRUE;
+
+ return channel;
+}
+
+GIOChannel *
+g_io_channel_win32_new_pipe (int fd)
+{
+ GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+ GIOChannel *channel = (GIOChannel *) win32_channel;
+
+ g_io_channel_init (channel);
+ channel->funcs = &win32_channel_pipe_funcs;
+ win32_channel->fd = fd;
+ win32_channel->type = G_IO_PIPE;
+ win32_channel->offset = 0;
+ win32_channel->need_wakeups = FALSE;
+
+ return channel;
+}
+
+GIOChannel *
+g_io_channel_win32_new_stream_socket (int socket)
+{
+ GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+ GIOChannel *channel = (GIOChannel *) win32_channel;
+
+ g_io_channel_init (channel);
+ channel->funcs = &win32_channel_sock_funcs;
+ win32_channel->fd = socket;
+ win32_channel->type = G_IO_STREAM_SOCKET;
+
+ return channel;
+}
+
+gint
+g_io_channel_win32_get_fd (GIOChannel *channel)
+{
+ return g_io_channel_unix_get_fd (channel);
+}
+
+void
+g_io_channel_win32_pipe_request_wakeups (GIOChannel *channel,
+ guint peer,
+ int peer_fd)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+
+ win32_channel->peer = peer;
+ win32_channel->peer_fd = peer_fd;
+ win32_channel->need_wakeups = TRUE;
+}
+
+void
+g_io_channel_win32_pipe_readable (gint fd,
+ guint offset)
+{
+ gint i;
+
+ for (i = 0; i < n_watched_pipes; i++)
+ if (watched_pipes[i].fd == fd)
+ {
+ if (watched_pipes[i].channel->offset < offset)
+ (*watched_pipes[i].watch->callback) (watched_pipes[i].watch->channel,
+ G_IO_IN,
+ watched_pipes[i].user_data);
+ break;
+ }
+}
diff --git a/glib/glib.def b/glib/glib.def
index 4858d6cb9..15177bc8b 100644
--- a/glib/glib.def
+++ b/glib/glib.def
@@ -1,6 +1,7 @@
EXPORTS
g_array_append_vals
g_array_free
+ g_array_insert_vals
g_array_new
g_array_prepend_vals
g_array_remove_index
@@ -42,11 +43,55 @@ EXPORTS
g_dataset_id_get_data
g_dataset_id_remove_no_notify
g_dataset_id_set_data_full
+ g_date_add_days
+ g_date_add_months
+ g_date_add_years
+ g_date_clear
+ g_date_compare
+ g_date_day
+ g_date_day_of_year
+ g_date_days_in_month
+ g_date_free
+ g_date_is_first_of_month
+ g_date_is_last_of_month
+ g_date_is_leap_year
+ g_date_julian
+ g_date_julian
+ g_date_monday_week_of_year
+ g_date_monday_weeks_in_year
+ g_date_new
+ g_date_new_dmy
+ g_date_new_julian
+ g_date_month
+ g_date_set_day
+ g_date_set_dmy
+ g_date_set_julian
+ g_date_set_month
+ g_date_set_parse
+ g_date_set_time
+ g_date_set_year
+ g_date_strftime
+ g_date_subtract_days
+ g_date_subtract_months
+ g_date_subtract_years
+ g_date_sunday_week_of_year
+ g_date_sunday_weeks_in_year
+ g_date_to_struct_tm
+ g_date_valid
+ g_date_valid_day
+ g_date_valid_dmy
+ g_date_valid_julian
+ g_date_valid_month
+ g_date_valid_weekday
+ g_date_valid_year
+ g_date_weekday
+ g_date_year
g_direct_equal
g_direct_hash
g_dirname
g_free
g_get_current_dir
+ g_get_current_time
g_get_home_dir
g_get_prgname
g_get_real_name
@@ -81,22 +126,38 @@ EXPORTS
g_hook_list_invoke
g_hook_list_invoke_check
g_hook_list_marshal
+ g_hook_list_marshal_check
g_hook_list_clear
g_hook_next_valid
g_hook_prepend
g_hook_ref
g_hook_unref
+ g_idle_add
+ g_idle_add_full
g_int_equal
g_int_hash
- g_iochannel_new
- g_iochannel_free
- g_iochannel_close_and_free
- g_iochannel_wakeup_peer
+ g_io_add_watch
+ g_io_add_watch_full
+ g_io_channel_close
+ g_io_channel_init
+ g_io_channel_read
+ g_io_channel_ref
+ g_io_channel_seek
+ g_io_channel_unix_get_fd
+ g_io_channel_unix_new
+ g_io_channel_unref
+ g_io_channel_win32_get_fd
+ g_io_channel_win32_new_messages
+ g_io_channel_win32_new_pipe
+ g_io_channel_win32_new_pipe_with_wakeups
+ g_io_channel_win32_new_stream_socket
+ g_io_channel_win32_pipe_readable
+ g_io_channel_win32_pipe_request_wakeups
+ g_io_channel_write
g_list_alloc
- g_list_allocator_free
- g_list_allocator_new
g_list_append
g_list_concat
+ g_list_copy
g_list_find
g_list_find_custom
g_list_first
@@ -115,7 +176,6 @@ EXPORTS
g_list_remove
g_list_remove_link
g_list_reverse
- g_list_set_allocator
g_list_sort
g_log
g_log_default_handler
@@ -124,6 +184,16 @@ EXPORTS
g_log_set_fatal_mask
g_log_set_handler
g_logv
+ g_main_add_poll
+ g_main_destroy
+ g_main_is_running
+ g_main_iteration
+ g_main_new
+ g_main_pending
+ g_main_remove_poll
+ g_main_quit
+ g_main_run
+ g_main_set_poll_func
g_malloc
g_malloc0
g_mem_check
@@ -136,8 +206,11 @@ EXPORTS
g_mem_chunk_new
g_mem_chunk_print
g_mem_chunk_reset
+ g_mem_init
g_mem_profile
g_memdup
+ g_messages_init
+ g_mutex_init
g_node_child_index
g_node_child_position
g_node_children_foreach
@@ -166,6 +239,7 @@ EXPORTS
g_parse_debug_string
g_path_is_absolute
g_path_skip_root
+ g_pipe_readable_msg
g_print
g_printerr
g_printf_string_upper_bound
@@ -224,6 +298,7 @@ EXPORTS
g_slist_alloc
g_slist_append
g_slist_concat
+ g_slist_copy
g_slist_find
g_slist_find_custom
g_slist_foreach
@@ -241,9 +316,15 @@ EXPORTS
g_slist_remove
g_slist_remove_link
g_slist_reverse
- g_slist_set_allocator
g_slist_sort
g_snprintf
+ g_source_add
+ g_source_remove
+ g_source_remove_by_source_data
+ g_source_remove_by_user_data
+ g_static_mutex_get_mutex_impl
+ g_static_private_get
+ g_static_private_set
g_str_equal
g_str_hash
g_strcasecmp
@@ -284,6 +365,8 @@ EXPORTS
g_strsplit
g_strtod
g_strup
+ g_timeout_add
+ g_timeout_add_full
g_timer_destroy
g_timer_elapsed
g_timer_new
diff --git a/glib/glib.h b/glib/glib.h
index cd4ff5cfc..0bbafe119 100644
--- a/glib/glib.h
+++ b/glib/glib.h
@@ -2447,7 +2447,26 @@ guint g_idle_add_full (gint priority,
/* GPollFD
*
- * Unix-specific IO and main loop calls
+ * System-specific IO and main loop calls
+ *
+ * On Win32, the fd in a GPollFD should be Win32 HANDLE (*not* a file
+ * descriptor as provided by the C runtime) that can be used by
+ * MsgWaitForMultipleObjects. This does *not* include file handles
+ * from CreateFile, SOCKETs, nor pipe handles. (But you can use
+ * WSAEventSelect to signal events when a SOCKET is readable).
+ *
+ * On Win32, fd can also be the special value G_WIN32_MSG_HANDLE to
+ * indicate polling for messages. These message queue GPollFDs should
+ * be added with the g_main_poll_win32_msg_add function.
+ *
+ * But note that G_WIN32_MSG_HANDLE GPollFDs should not be used by GDK
+ * (GTK) programs, as GDK itself wants to read messages and convert them
+ * to GDK events.
+ *
+ * So, unless you really know what you are doing, it's best not to try
+ * to use the main loop polling stuff for your own needs on
+ * Win32. It's really only written for the GIMP's needs so
+ * far.
*/
typedef struct _GPollFD GPollFD;
@@ -2466,45 +2485,77 @@ void g_main_add_poll (GPollFD *fd,
void g_main_remove_poll (GPollFD *fd);
void g_main_set_poll_func (GPollFunc func);
+/* On Unix, IO channels created with this function for any file
+ * descriptor or socket.
+ *
+ * On Win32, use this only for plain files opened with the MSVCRT (the
+ * Microsoft run-time C library) _open(), including file descriptors
+ * 0, 1 and 2 (corresponding to stdin, stdout and stderr).
+ * Actually, don't do even that, this code isn't done yet.
+ *
+ * The term file descriptor as used in the context of Win32 refers to
+ * the emulated Unix-like file descriptors MSVCRT provides.
+ */
GIOChannel* g_io_channel_unix_new (int fd);
gint g_io_channel_unix_get_fd (GIOChannel *channel);
+#ifdef NATIVE_WIN32
+
+GUTILS_C_VAR guint g_pipe_readable_msg;
-/* old IO Channels */
-#if 0
-/* IO Channels.
- * These are used for plug-in communication in the GIMP, for instance.
- * On Unix, it's simply an encapsulated file descriptor (a pipe).
- * On Windows, it's a handle to an anonymouos pipe, *and* (in the case
- * of the writable end) a thread id to post a message to when you have written
- * stuff.
+#define G_WIN32_MSG_HANDLE 19981206
+
+/* This is used to add polling for Windows messages. GDK (GTk+) programs
+ * should *not* use this. (In fact, I can't think of any program that
+ * would want to use this, but it's here just for completeness's sake.
*/
-struct _GIOChannel
-{
- gint fd; /* file handle (pseudo such in Win32) */
-#ifdef NATIVE_WIN32
- guint peer; /* thread to post message to */
- guint peer_fd; /* read handle (in the other process) */
- guint offset; /* counter of accumulated bytes, to
- * be included in the message posted
- * so we keep in sync.
- */
- guint need_wakeups; /* in output channels whether the reader
- * needs wakeups
- */
-#endif
-};
-GIOChannel *g_iochannel_new (gint fd);
-void g_iochannel_free (GIOChannel *channel);
-void g_iochannel_close_and_free (GIOChannel *channel);
-void g_iochannel_wakeup_peer (GIOChannel *channel);
-#ifndef NATIVE_WIN32
-# define g_iochannel_wakeup_peer(channel) G_STMT_START { } G_STMT_END
-#endif
-#endif /* old IO Channels */
+void g_main_poll_win32_msg_add(gint priority,
+ GPollFD *fd,
+ guint hwnd);
+
+/* An IO channel for Windows messages for window handle hwnd. */
+GIOChannel *g_io_channel_win32_new_messages (guint hwnd);
+
+/* An IO channel for an anonymous pipe as returned from the MSVCRT
+ * _pipe(), with no mechanism for the writer to tell the reader when
+ * there is data in the pipe.
+ *
+ * This is not really implemented yet.
+ */
+GIOChannel *g_io_channel_win32_new_pipe (int fd);
+/* An IO channel for a pipe as returned from the MSVCRT _pipe(), with
+ * Windows user messages used to signal data in the pipe for the
+ * reader.
+ *
+ * fd is the file descriptor. For the write end, peer is the thread id
+ * of the reader, and peer_fd is his file descriptor for the read end
+ * of the pipe.
+ *
+ * This is used by the GIMP, and works.
+ */
+GIOChannel *g_io_channel_win32_new_pipe_with_wakeups (int fd,
+ guint peer,
+ int peer_fd);
+
+void g_io_channel_win32_pipe_request_wakeups (GIOChannel *channel,
+ guint peer,
+ int peer_fd);
+
+void g_io_channel_win32_pipe_readable (int fd,
+ guint offset);
+
+/* Get the C runtime file descriptor of a channel. */
+gint g_io_channel_win32_get_fd (GIOChannel *channel);
+
+/* An IO channel for a SOCK_STREAM winsock socket. The parameter is
+ * actually a SOCKET.
+ */
+GIOChannel *g_io_channel_win32_new_stream_socket (int socket);
+
+#endif
-/* Windows emulation stubs for common unix functions
+/* Windows emulation stubs for common Unix functions
*/
#ifdef NATIVE_WIN32
# define MAXPATHLEN 1024
diff --git a/glib/gmain.c b/glib/gmain.c
index ff4c20513..7e3571b4c 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -24,17 +24,33 @@
* MT safe
*/
+#include "config.h"
+
#include "glib.h"
#include <sys/types.h>
+#include <time.h>
+#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
+#endif
#ifdef GLIB_HAVE_SYS_POLL_H
# include <sys/poll.h>
# undef events /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */
# undef revents /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */
#endif /* GLIB_HAVE_SYS_POLL_H */
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <errno.h>
-#include "config.h"
+
+#ifdef NATIVE_WIN32
+#define STRICT
+#include <windows.h>
+#endif
+
+#ifdef _MSC_VER
+#include <fcntl.h>
+#include <io.h>
+#endif
/* Types */
@@ -138,15 +154,160 @@ static GPollRec *poll_free_list = NULL;
static GMemChunk *poll_chunk;
static guint n_poll_records = 0;
+#ifdef G_THREADS_ENABLED
+#ifndef NATIVE_WIN32
/* this pipe is used to wake up the main loop when a source is added.
*/
static gint wake_up_pipe[2] = { -1, -1 };
+#else
+static HANDLE wake_up_semaphore = NULL;
+#endif
static GPollFD wake_up_rec;
static gboolean poll_waiting = FALSE;
+#endif
#ifdef HAVE_POLL
static GPollFunc poll_func = (GPollFunc) poll;
#else /* !HAVE_POLL */
+#ifdef NATIVE_WIN32
+
+static gint
+g_poll (GPollFD *fds, guint nfds, gint timeout)
+{
+ HANDLE handles[MAXIMUM_WAIT_OBJECTS];
+ GPollFD *f;
+ DWORD ready;
+ MSG msg;
+ UINT timer;
+ LONG prevcnt;
+ gint poll_msgs = -1;
+ gint nhandles = 0;
+
+ for (f = fds; f < &fds[nfds]; ++f)
+ if (f->fd >= 0)
+ {
+ if (f->events & G_IO_IN)
+ if (f->fd == G_WIN32_MSG_HANDLE)
+ poll_msgs = f - fds;
+ else
+ {
+ /* g_print ("g_poll: waiting for handle %#x\n", f->fd); */
+ handles[nhandles++] = (HANDLE) f->fd;
+ }
+ }
+
+ if (timeout == -1)
+ timeout = INFINITE;
+
+ if (poll_msgs >= 0)
+ {
+ /* Waiting for messages, and maybe events */
+ if (nhandles == 0)
+ {
+ if (timeout == INFINITE)
+ {
+ /* Waiting just for messages, infinite timeout
+ * -> Use PeekMessage, then WaitMessage
+ */
+ /* g_print ("WaitMessage, PeekMessage\n"); */
+ if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
+ ready = WAIT_OBJECT_0;
+ else if (!WaitMessage ())
+ g_warning ("g_poll: WaitMessage failed");
+ ready = WAIT_OBJECT_0;
+ }
+ else if (timeout == 0)
+ {
+ /* Waiting just for messages, zero timeout
+ * -> Use PeekMessage
+ */
+ /* g_print ("PeekMessage\n"); */
+ if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
+ ready = WAIT_OBJECT_0;
+ else
+ ready = WAIT_TIMEOUT;
+ }
+ else
+ {
+ /* Waiting just for messages, some timeout
+ * -> First try PeekMessage, then set a timer, wait for message,
+ * kill timer, use PeekMessage
+ */
+ /* g_print ("PeekMessage\n"); */
+ if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
+ ready = WAIT_OBJECT_0;
+ else if ((timer = SetTimer (NULL, 0, timeout, NULL)) == 0)
+ g_warning ("g_poll: SetTimer failed");
+ else
+ {
+ /* g_print ("WaitMessage\n"); */
+ WaitMessage ();
+ KillTimer (NULL, timer);
+ if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
+ ready = WAIT_OBJECT_0;
+ else
+ ready = WAIT_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* Wait for either message or event
+ * -> Use MsgWaitForMultipleObjects
+ */
+ /* g_print ("MsgWaitForMultipleObjects(%d, %d)\n", nhandles, timeout); */
+ ready = MsgWaitForMultipleObjects (nhandles, handles, FALSE,
+ timeout, QS_ALLINPUT);
+ /* g_print("=%d\n", ready); */
+ if (ready == WAIT_FAILED)
+ g_warning ("g_poll: MsgWaitForMultipleObjects failed");
+ }
+ }
+ else if (nhandles == 0)
+ {
+ /* Wait for nothing (huh?) */
+ return 0;
+ }
+ else
+ {
+ /* Wait for just events
+ * -> Use WaitForMultipleObjects
+ */
+ /* g_print ("WaitForMultipleObjects(%d, %d)\n", nhandles, timeout); */
+ ready = WaitForMultipleObjects (nhandles, handles, FALSE, timeout);
+ /* g_print("=%d\n", ready); */
+ if (ready == WAIT_FAILED)
+ g_warning ("g_poll: WaitForMultipleObjects failed");
+ }
+
+ for (f = fds; f < &fds[nfds]; ++f)
+ f->revents = 0;
+
+ if (ready == WAIT_FAILED)
+ return -1;
+ else if (poll_msgs >= 0 && ready == WAIT_OBJECT_0 + nhandles)
+ {
+ fds[poll_msgs].revents |= G_IO_IN;
+ }
+ else if (ready >= WAIT_OBJECT_0 && ready < WAIT_OBJECT_0 + nhandles)
+ for (f = fds; f < &fds[nfds]; ++f)
+ {
+ if ((f->events & G_IO_IN)
+ && f->fd == (gint) handles[ready - WAIT_OBJECT_0])
+ {
+ f->revents |= G_IO_IN;
+ /* g_print ("event %#x\n", f->fd); */
+ ResetEvent ((HANDLE) f->fd);
+ }
+ }
+
+ if (ready == WAIT_TIMEOUT)
+ return 0;
+ else
+ return 1;
+}
+
+#else /* !NATIVE_WIN32 */
/* The following implementation of poll() comes from the GNU C Library.
* Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
@@ -219,6 +380,8 @@ g_poll (GPollFD *fds, guint nfds, gint timeout)
return ready;
}
+#endif /* !NATIVE_WIN32 */
+
static GPollFunc poll_func = g_poll;
#endif /* !HAVE_POLL */
@@ -280,14 +443,19 @@ g_source_add (gint priority,
return_val = source->hook.hook_id;
+#ifdef G_THREADS_ENABLED
/* Now wake up the main loop if it is waiting in the poll() */
if (poll_waiting)
{
poll_waiting = FALSE;
+#ifndef NATIVE_WIN32
write (wake_up_pipe[1], "A", 1);
+#else
+ ReleaseSemaphore (wake_up_semaphore, 1, NULL);
+#endif
}
-
+#endif
G_UNLOCK (main_loop);
return return_val;
@@ -348,6 +516,7 @@ g_source_remove_by_source_data (gpointer source_data)
void
g_get_current_time (GTimeVal *result)
{
+#ifndef _MSC_VER
struct timeval r;
g_return_if_fail (result != NULL);
@@ -356,6 +525,29 @@ g_get_current_time (GTimeVal *result)
gettimeofday (&r, NULL);
result->tv_sec = r.tv_sec;
result->tv_usec = r.tv_usec;
+#else
+ /* Avoid calling time() except for the first time.
+ * GetTickCount() should be pretty fast and low-level?
+ * I could also use ftime() but it seems unnecessarily overheady.
+ */
+ static DWORD start_tick = 0;
+ static time_t start_time;
+ DWORD tick;
+ time_t t;
+
+ g_return_if_fail (result != NULL);
+
+ if (start_tick == 0)
+ {
+ start_tick = GetTickCount ();
+ time (&start_time);
+ }
+
+ tick = GetTickCount ();
+
+ result->tv_sec = (tick - start_tick) / 1000 + start_time;
+ result->tv_usec = ((tick - start_tick) % 1000) * 1000;
+#endif
}
/* Running the main loop */
@@ -652,7 +844,8 @@ g_main_poll (gint timeout,
gint i;
gint npoll;
-
+#ifdef G_THREADS_ENABLED
+#ifndef NATIVE_WIN32
if (wake_up_pipe[0] < 0)
{
if (pipe (wake_up_pipe) < 0)
@@ -663,7 +856,17 @@ g_main_poll (gint timeout,
wake_up_rec.events = G_IO_IN;
g_main_add_poll_unlocked (0, &wake_up_rec);
}
-
+#else
+ if (wake_up_semaphore == NULL)
+ {
+ if ((wake_up_semaphore = CreateSemaphore (NULL, 0, 100, NULL)) == NULL)
+ g_error ("Cannot create wake-up semaphore: %d", GetLastError ());
+ wake_up_rec.fd = (gint) wake_up_semaphore;
+ wake_up_rec.events = G_IO_IN;
+ g_main_add_poll_unlocked (0, &wake_up_rec);
+ }
+#endif
+#endif
fd_array = g_new (GPollFD, n_poll_records);
pollrec = poll_records;
@@ -677,21 +880,25 @@ g_main_poll (gint timeout,
pollrec = pollrec->next;
i++;
}
-
+#ifdef G_THREADS_ENABLED
poll_waiting = TRUE;
-
+#endif
G_UNLOCK (main_loop);
npoll = i;
(*poll_func) (fd_array, npoll, timeout);
G_LOCK (main_loop);
+#ifdef G_THREADS_ENABLED
if (!poll_waiting)
{
+#ifndef NATIVE_WIN32
gchar c;
read (wake_up_pipe[0], &c, 1);
+#endif
}
else
poll_waiting = FALSE;
+#endif
pollrec = poll_records;
i = 0;
diff --git a/glib/gmessages.c b/glib/gmessages.c
index eb8aed7a8..1ef33445d 100644
--- a/glib/gmessages.c
+++ b/glib/gmessages.c
@@ -35,6 +35,9 @@
#endif
#ifdef NATIVE_WIN32
+#define STRICT
+#include <windows.h>
+
/* Just use stdio. If we're out of memory, we're hosed anyway. */
#undef write
@@ -49,6 +52,22 @@ write (FILE *fd,
}
#endif /* NATIVE_WIN32 */
+static void
+ensure_stdout_valid (void)
+{
+#ifdef NATIVE_WIN32
+ HANDLE handle;
+
+ handle = GetStdHandle (STD_OUTPUT_HANDLE);
+
+ if (handle == INVALID_HANDLE_VALUE)
+ {
+ AllocConsole ();
+ freopen ("CONOUT$", "w", stdout);
+ }
+#endif
+}
+
/* --- structures --- */
typedef struct _GLogDomain GLogDomain;
@@ -410,6 +429,7 @@ g_log_default_handler (const gchar *log_domain,
* DOS prompt.
*/
fd = stdout;
+ ensure_stdout_valid ();
#else
fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
#endif
@@ -623,6 +643,7 @@ g_print (const gchar *format,
local_glib_print_func (string);
else
{
+ ensure_stdout_valid ();
fputs (string, stdout);
fflush (stdout);
}
diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c
index e154c56dc..268d2831c 100644
--- a/glib/gstrfuncs.c
+++ b/glib/gstrfuncs.c
@@ -31,6 +31,7 @@
#include <string.h>
#include <locale.h>
#include <ctype.h> /* For tolower() */
+#include <signal.h>
#include "glib.h"
/* do not include <unistd.h> in this place since it
* inteferes with g_strsignal() on some OSes
diff --git a/glib/gutils.c b/glib/gutils.c
index e235d295f..5bcaa492a 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -413,7 +413,30 @@ g_get_any_init (void)
#endif /* NATIVE_WIN32 */
}
+#ifdef NATIVE_WIN32
+ /* The official way to specify a home directory on NT is
+ * the HOMEDRIVE and HOMEPATH environment variables.
+ *
+ * This is inside #ifdef NATIVE_WIN32 because with the cygwin dll,
+ * HOME should be a POSIX style pathname.
+ */
+
+ if (getenv ("HOMEDRIVE") != NULL && getenv ("HOMEPATH") != NULL)
+ {
+ gchar *homedrive, *homepath;
+
+ homedrive = g_strdup (g_getenv ("HOMEDRIVE"));
+ homepath = g_strdup (g_getenv ("HOMEPATH"));
+
+ g_home_dir = g_strconcat (homedrive, homepath, NULL);
+ g_free (homedrive);
+ g_free (homepath);
+ }
+ if (!g_home_dir)
+ g_home_dir = g_strdup (g_getenv ("HOME"));
+#else
g_home_dir = g_strdup (g_getenv ("HOME"));
+#endif
#ifdef HAVE_PWD_H
/* FIXME: we must actually use the getpwuid_r function here, as
diff --git a/glibconfig.h.win32 b/glibconfig.h.win32
index 9dde2c23c..5ecf82fb4 100644
--- a/glibconfig.h.win32
+++ b/glibconfig.h.win32
@@ -31,22 +31,23 @@ extern "C" {
#pragma warning(disable:4101)
#pragma warning(error:4150)
-#pragma warning(disable:4244) /* No possible loss of data warnings, please */
+#pragma warning(disable:4244) /* No possible loss of data warnings */
+#pragma warning(disable:4305) /* No truncation from int to char warnings */
#endif /* _MSC_VER */
#include <limits.h>
#include <float.h>
-#define G_MINFLOAT FLT_MIN
-#define G_MAXFLOAT FLT_MAX
-#define G_MINDOUBLE DBL_MIN
-#define G_MAXDOUBLE DBL_MAX
-#define G_MINSHORT SHRT_MIN
-#define G_MAXSHORT SHRT_MAX
-#define G_MININT INT_MIN
-#define G_MAXINT INT_MAX
-#define G_MINLONG LONG_MIN
-#define G_MAXLONG LONG_MAX
+#define G_MINFLOAT FLT_MIN
+#define G_MAXFLOAT FLT_MAX
+#define G_MINDOUBLE DBL_MIN
+#define G_MAXDOUBLE DBL_MAX
+#define G_MINSHORT SHRT_MIN
+#define G_MAXSHORT SHRT_MAX
+#define G_MININT INT_MIN
+#define G_MAXINT INT_MAX
+#define G_MINLONG LONG_MIN
+#define G_MAXLONG LONG_MAX
typedef signed char gint8;
typedef unsigned char guint8;
@@ -54,12 +55,13 @@ typedef signed short gint16;
typedef unsigned short guint16;
typedef signed int gint32;
typedef unsigned int guint32;
+
#define G_HAVE_GINT64 1
typedef __int64 gint64;
typedef unsigned __int64 guint64;
-#define G_GINT64_CONSTANT(val) (val)
+#define G_GINT64_CONSTANT(val) (val##i64)
#define GPOINTER_TO_INT(p) ((gint)(p))
#define GPOINTER_TO_UINT(p) ((guint)(p))
@@ -71,13 +73,35 @@ typedef unsigned __int64 guint64;
#define g_memmove(d,s,n) G_STMT_START { memmove ((d), (s), (n)); } G_STMT_END
+#define G_HAVE_ALLOCA 1
+#define alloca _alloca
+
#define GLIB_MAJOR_VERSION 1
#define GLIB_MINOR_VERSION 1
-#define GLIB_MICRO_VERSION 4
-
-#define G_COMPILED_WITH_DEBUGGING "minimum"
+#define GLIB_MICRO_VERSION 12
+#ifdef __cplusplus
+#define G_HAVE_INLINE 1
+#else /* !__cplusplus */
#define G_HAVE___INLINE 1
+#endif
+
+#define G_THREADS_ENABLED
+typedef struct _GStaticMutex GStaticMutex;
+struct _GStaticMutex
+{
+ struct _GMutex *runtime_mutex;
+ union {
+ char pad[24];
+ double dummy_double;
+ void *dummy_pointer;
+ long dummy_long;
+ } aligned_pad_u;
+};
+#define G_STATIC_MUTEX_INIT { NULL, { { 0, 0, 0, 0, 0 } } }
+#define g_static_mutex_get_mutex(mutex) \
+ (g_thread_use_default_impl ? ((GMutex*) &(mutex).aligned_pad_u) : \
+ g_static_mutex_get_mutex_impl (&(mutex).runtime_mutex))
#define G_BYTE_ORDER G_LITTLE_ENDIAN
@@ -106,13 +130,20 @@ typedef unsigned __int64 guint64;
#define GINT_TO_BE(val) ((gint) GINT32_TO_BE (val))
#define GUINT_TO_BE(val) ((guint) GUINT32_TO_BE (val))
+#define GLIB_SYSDEF_POLLIN = 1
+#define GLIB_SYSDEF_POLLOUT = 4
+#define GLIB_SYSDEF_POLLPRI = 2
+#define GLIB_SYSDEF_POLLERR = 8
+#define GLIB_SYSDEF_POLLHUP = 16
+#define GLIB_SYSDEF_POLLNVAL = 32
+
#define G_HAVE_WCHAR_H 1
#define G_HAVE_WCTYPE_H 1
-/* Define if this is Win32, possibly using the GNU-Win32 emulation layer. */
+/* Define if this is Win32, possibly using the Cygwin emulation layer. */
#define WIN32 1
-/* Define if this is Win32 without GNU-Win32. */
+/* Define if this is Win32 without Cygwin. */
#define NATIVE_WIN32 1
#ifdef __cplusplus
diff --git a/gmain.c b/gmain.c
index ff4c20513..7e3571b4c 100644
--- a/gmain.c
+++ b/gmain.c
@@ -24,17 +24,33 @@
* MT safe
*/
+#include "config.h"
+
#include "glib.h"
#include <sys/types.h>
+#include <time.h>
+#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
+#endif
#ifdef GLIB_HAVE_SYS_POLL_H
# include <sys/poll.h>
# undef events /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */
# undef revents /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */
#endif /* GLIB_HAVE_SYS_POLL_H */
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <errno.h>
-#include "config.h"
+
+#ifdef NATIVE_WIN32
+#define STRICT
+#include <windows.h>
+#endif
+
+#ifdef _MSC_VER
+#include <fcntl.h>
+#include <io.h>
+#endif
/* Types */
@@ -138,15 +154,160 @@ static GPollRec *poll_free_list = NULL;
static GMemChunk *poll_chunk;
static guint n_poll_records = 0;
+#ifdef G_THREADS_ENABLED
+#ifndef NATIVE_WIN32
/* this pipe is used to wake up the main loop when a source is added.
*/
static gint wake_up_pipe[2] = { -1, -1 };
+#else
+static HANDLE wake_up_semaphore = NULL;
+#endif
static GPollFD wake_up_rec;
static gboolean poll_waiting = FALSE;
+#endif
#ifdef HAVE_POLL
static GPollFunc poll_func = (GPollFunc) poll;
#else /* !HAVE_POLL */
+#ifdef NATIVE_WIN32
+
+static gint
+g_poll (GPollFD *fds, guint nfds, gint timeout)
+{
+ HANDLE handles[MAXIMUM_WAIT_OBJECTS];
+ GPollFD *f;
+ DWORD ready;
+ MSG msg;
+ UINT timer;
+ LONG prevcnt;
+ gint poll_msgs = -1;
+ gint nhandles = 0;
+
+ for (f = fds; f < &fds[nfds]; ++f)
+ if (f->fd >= 0)
+ {
+ if (f->events & G_IO_IN)
+ if (f->fd == G_WIN32_MSG_HANDLE)
+ poll_msgs = f - fds;
+ else
+ {
+ /* g_print ("g_poll: waiting for handle %#x\n", f->fd); */
+ handles[nhandles++] = (HANDLE) f->fd;
+ }
+ }
+
+ if (timeout == -1)
+ timeout = INFINITE;
+
+ if (poll_msgs >= 0)
+ {
+ /* Waiting for messages, and maybe events */
+ if (nhandles == 0)
+ {
+ if (timeout == INFINITE)
+ {
+ /* Waiting just for messages, infinite timeout
+ * -> Use PeekMessage, then WaitMessage
+ */
+ /* g_print ("WaitMessage, PeekMessage\n"); */
+ if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
+ ready = WAIT_OBJECT_0;
+ else if (!WaitMessage ())
+ g_warning ("g_poll: WaitMessage failed");
+ ready = WAIT_OBJECT_0;
+ }
+ else if (timeout == 0)
+ {
+ /* Waiting just for messages, zero timeout
+ * -> Use PeekMessage
+ */
+ /* g_print ("PeekMessage\n"); */
+ if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
+ ready = WAIT_OBJECT_0;
+ else
+ ready = WAIT_TIMEOUT;
+ }
+ else
+ {
+ /* Waiting just for messages, some timeout
+ * -> First try PeekMessage, then set a timer, wait for message,
+ * kill timer, use PeekMessage
+ */
+ /* g_print ("PeekMessage\n"); */
+ if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
+ ready = WAIT_OBJECT_0;
+ else if ((timer = SetTimer (NULL, 0, timeout, NULL)) == 0)
+ g_warning ("g_poll: SetTimer failed");
+ else
+ {
+ /* g_print ("WaitMessage\n"); */
+ WaitMessage ();
+ KillTimer (NULL, timer);
+ if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
+ ready = WAIT_OBJECT_0;
+ else
+ ready = WAIT_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* Wait for either message or event
+ * -> Use MsgWaitForMultipleObjects
+ */
+ /* g_print ("MsgWaitForMultipleObjects(%d, %d)\n", nhandles, timeout); */
+ ready = MsgWaitForMultipleObjects (nhandles, handles, FALSE,
+ timeout, QS_ALLINPUT);
+ /* g_print("=%d\n", ready); */
+ if (ready == WAIT_FAILED)
+ g_warning ("g_poll: MsgWaitForMultipleObjects failed");
+ }
+ }
+ else if (nhandles == 0)
+ {
+ /* Wait for nothing (huh?) */
+ return 0;
+ }
+ else
+ {
+ /* Wait for just events
+ * -> Use WaitForMultipleObjects
+ */
+ /* g_print ("WaitForMultipleObjects(%d, %d)\n", nhandles, timeout); */
+ ready = WaitForMultipleObjects (nhandles, handles, FALSE, timeout);
+ /* g_print("=%d\n", ready); */
+ if (ready == WAIT_FAILED)
+ g_warning ("g_poll: WaitForMultipleObjects failed");
+ }
+
+ for (f = fds; f < &fds[nfds]; ++f)
+ f->revents = 0;
+
+ if (ready == WAIT_FAILED)
+ return -1;
+ else if (poll_msgs >= 0 && ready == WAIT_OBJECT_0 + nhandles)
+ {
+ fds[poll_msgs].revents |= G_IO_IN;
+ }
+ else if (ready >= WAIT_OBJECT_0 && ready < WAIT_OBJECT_0 + nhandles)
+ for (f = fds; f < &fds[nfds]; ++f)
+ {
+ if ((f->events & G_IO_IN)
+ && f->fd == (gint) handles[ready - WAIT_OBJECT_0])
+ {
+ f->revents |= G_IO_IN;
+ /* g_print ("event %#x\n", f->fd); */
+ ResetEvent ((HANDLE) f->fd);
+ }
+ }
+
+ if (ready == WAIT_TIMEOUT)
+ return 0;
+ else
+ return 1;
+}
+
+#else /* !NATIVE_WIN32 */
/* The following implementation of poll() comes from the GNU C Library.
* Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
@@ -219,6 +380,8 @@ g_poll (GPollFD *fds, guint nfds, gint timeout)
return ready;
}
+#endif /* !NATIVE_WIN32 */
+
static GPollFunc poll_func = g_poll;
#endif /* !HAVE_POLL */
@@ -280,14 +443,19 @@ g_source_add (gint priority,
return_val = source->hook.hook_id;
+#ifdef G_THREADS_ENABLED
/* Now wake up the main loop if it is waiting in the poll() */
if (poll_waiting)
{
poll_waiting = FALSE;
+#ifndef NATIVE_WIN32
write (wake_up_pipe[1], "A", 1);
+#else
+ ReleaseSemaphore (wake_up_semaphore, 1, NULL);
+#endif
}
-
+#endif
G_UNLOCK (main_loop);
return return_val;
@@ -348,6 +516,7 @@ g_source_remove_by_source_data (gpointer source_data)
void
g_get_current_time (GTimeVal *result)
{
+#ifndef _MSC_VER
struct timeval r;
g_return_if_fail (result != NULL);
@@ -356,6 +525,29 @@ g_get_current_time (GTimeVal *result)
gettimeofday (&r, NULL);
result->tv_sec = r.tv_sec;
result->tv_usec = r.tv_usec;
+#else
+ /* Avoid calling time() except for the first time.
+ * GetTickCount() should be pretty fast and low-level?
+ * I could also use ftime() but it seems unnecessarily overheady.
+ */
+ static DWORD start_tick = 0;
+ static time_t start_time;
+ DWORD tick;
+ time_t t;
+
+ g_return_if_fail (result != NULL);
+
+ if (start_tick == 0)
+ {
+ start_tick = GetTickCount ();
+ time (&start_time);
+ }
+
+ tick = GetTickCount ();
+
+ result->tv_sec = (tick - start_tick) / 1000 + start_time;
+ result->tv_usec = ((tick - start_tick) % 1000) * 1000;
+#endif
}
/* Running the main loop */
@@ -652,7 +844,8 @@ g_main_poll (gint timeout,
gint i;
gint npoll;
-
+#ifdef G_THREADS_ENABLED
+#ifndef NATIVE_WIN32
if (wake_up_pipe[0] < 0)
{
if (pipe (wake_up_pipe) < 0)
@@ -663,7 +856,17 @@ g_main_poll (gint timeout,
wake_up_rec.events = G_IO_IN;
g_main_add_poll_unlocked (0, &wake_up_rec);
}
-
+#else
+ if (wake_up_semaphore == NULL)
+ {
+ if ((wake_up_semaphore = CreateSemaphore (NULL, 0, 100, NULL)) == NULL)
+ g_error ("Cannot create wake-up semaphore: %d", GetLastError ());
+ wake_up_rec.fd = (gint) wake_up_semaphore;
+ wake_up_rec.events = G_IO_IN;
+ g_main_add_poll_unlocked (0, &wake_up_rec);
+ }
+#endif
+#endif
fd_array = g_new (GPollFD, n_poll_records);
pollrec = poll_records;
@@ -677,21 +880,25 @@ g_main_poll (gint timeout,
pollrec = pollrec->next;
i++;
}
-
+#ifdef G_THREADS_ENABLED
poll_waiting = TRUE;
-
+#endif
G_UNLOCK (main_loop);
npoll = i;
(*poll_func) (fd_array, npoll, timeout);
G_LOCK (main_loop);
+#ifdef G_THREADS_ENABLED
if (!poll_waiting)
{
+#ifndef NATIVE_WIN32
gchar c;
read (wake_up_pipe[0], &c, 1);
+#endif
}
else
poll_waiting = FALSE;
+#endif
pollrec = poll_records;
i = 0;
diff --git a/gmessages.c b/gmessages.c
index eb8aed7a8..1ef33445d 100644
--- a/gmessages.c
+++ b/gmessages.c
@@ -35,6 +35,9 @@
#endif
#ifdef NATIVE_WIN32
+#define STRICT
+#include <windows.h>
+
/* Just use stdio. If we're out of memory, we're hosed anyway. */
#undef write
@@ -49,6 +52,22 @@ write (FILE *fd,
}
#endif /* NATIVE_WIN32 */
+static void
+ensure_stdout_valid (void)
+{
+#ifdef NATIVE_WIN32
+ HANDLE handle;
+
+ handle = GetStdHandle (STD_OUTPUT_HANDLE);
+
+ if (handle == INVALID_HANDLE_VALUE)
+ {
+ AllocConsole ();
+ freopen ("CONOUT$", "w", stdout);
+ }
+#endif
+}
+
/* --- structures --- */
typedef struct _GLogDomain GLogDomain;
@@ -410,6 +429,7 @@ g_log_default_handler (const gchar *log_domain,
* DOS prompt.
*/
fd = stdout;
+ ensure_stdout_valid ();
#else
fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
#endif
@@ -623,6 +643,7 @@ g_print (const gchar *format,
local_glib_print_func (string);
else
{
+ ensure_stdout_valid ();
fputs (string, stdout);
fflush (stdout);
}
diff --git a/gmodule/ChangeLog b/gmodule/ChangeLog
index 86dd222ae..e90408a33 100644
--- a/gmodule/ChangeLog
+++ b/gmodule/ChangeLog
@@ -1,3 +1,11 @@
+1999-01-16 Tor Lillqvist <tml@iki.fi>
+
+ * gmodule-dl.c gmodule-dld.c: In
+ _g_module_build_path, don't add the "lib" prefix and
+ ".so" or ".sl" suffix if already there.
+
+ * gmodule-win32.c: Likewise for the ".dll" suffix.
+
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gmodule.c: Made it MT safe, the g_module_error() is now thread
diff --git a/gmodule/gmodule-dl.c b/gmodule/gmodule-dl.c
index 4a5686616..e8c986fc7 100644
--- a/gmodule/gmodule-dl.c
+++ b/gmodule/gmodule-dl.c
@@ -125,8 +125,13 @@ static gchar*
_g_module_build_path (const gchar *directory,
const gchar *module_name)
{
- if (directory)
- return g_strconcat (directory, "/lib", module_name, ".so", NULL);
+ if (directory && *directory)
+ if (strncmp (module_name, "lib", 3) == 0)
+ return g_strconcat (directory, "/", module_name, NULL);
+ else
+ return g_strconcat (directory, "/lib", module_name, ".so", NULL);
+ else if (strncmp (module_name, "lib", 3) == 0)
+ return g_strdup (module_name);
else
return g_strconcat ("lib", module_name, ".so", NULL);
}
diff --git a/gmodule/gmodule-dld.c b/gmodule/gmodule-dld.c
index 53b269b48..17d6e010e 100644
--- a/gmodule/gmodule-dld.c
+++ b/gmodule/gmodule-dld.c
@@ -122,8 +122,13 @@ static gchar*
_g_module_build_path (const gchar *directory,
const gchar *module_name)
{
- if (directory)
- return g_strconcat (directory, "/", module_name, ".sl", NULL);
+ if (directory && *directory)
+ if (strncmp (module_name, "lib", 3) == 0)
+ return g_strconcat (directory, "/", module_name, NULL);
+ else
+ return g_strconcat (directory, "/lib", module_name, ".sl", NULL);
+ else if (strncmp (module_name, "lib", 3) == 0)
+ return g_strdup (module_name);
else
- return g_strconcat (module_name, ".sl", NULL);
+ return g_strconcat ("lib", module_name, ".sl", NULL);
}
diff --git a/gmodule/gmodule-win32.c b/gmodule/gmodule-win32.c
index 98643ad23..c3fc9a90d 100644
--- a/gmodule/gmodule-win32.c
+++ b/gmodule/gmodule-win32.c
@@ -91,8 +91,16 @@ static gchar*
_g_module_build_path (const gchar *directory,
const gchar *module_name)
{
- if (directory)
- return g_strconcat (directory, "\\", module_name, ".dll", NULL);
+ gint k;
+
+ k = strlen (module_name);
+ if (directory && *directory)
+ if (k > 4 && g_strcasecmp (module_name + k - 4, ".dll") == 0)
+ return g_strconcat (directory, "\\", module_name, NULL);
+ else
+ return g_strconcat (directory, "\\", module_name, ".dll", NULL);
+ else if (k > 4 && g_strcasecmp (module_name + k - 4, ".dll") == 0)
+ return g_strdup (module_name);
else
return g_strconcat (module_name, ".dll", NULL);
}
diff --git a/gstrfuncs.c b/gstrfuncs.c
index e154c56dc..268d2831c 100644
--- a/gstrfuncs.c
+++ b/gstrfuncs.c
@@ -31,6 +31,7 @@
#include <string.h>
#include <locale.h>
#include <ctype.h> /* For tolower() */
+#include <signal.h>
#include "glib.h"
/* do not include <unistd.h> in this place since it
* inteferes with g_strsignal() on some OSes
diff --git a/gthread/ChangeLog b/gthread/ChangeLog
index 939ae56c5..13b767410 100644
--- a/gthread/ChangeLog
+++ b/gthread/ChangeLog
@@ -1,3 +1,7 @@
+1999-01-16 1999 Tor Lillqvist <tml@iki.fi>
+
+ * gthread-posix.c: Conditionalize <sys/time.h> inclusion.
+
1999-01-07 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* testgthread.c: conditionally compile according to the
diff --git a/gthread/gthread-posix.c b/gthread/gthread-posix.c
index b2c293cbf..e35acbdd5 100644
--- a/gthread/gthread-posix.c
+++ b/gthread/gthread-posix.c
@@ -27,7 +27,9 @@
#include <pthread.h>
#include <errno.h>
#include <stdlib.h>
+#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
+#endif
#define posix_print_error( name, num ) \
g_error( "file %s: line %d (%s): error %s during %s", \
diff --git a/gutils.c b/gutils.c
index e235d295f..5bcaa492a 100644
--- a/gutils.c
+++ b/gutils.c
@@ -413,7 +413,30 @@ g_get_any_init (void)
#endif /* NATIVE_WIN32 */
}
+#ifdef NATIVE_WIN32
+ /* The official way to specify a home directory on NT is
+ * the HOMEDRIVE and HOMEPATH environment variables.
+ *
+ * This is inside #ifdef NATIVE_WIN32 because with the cygwin dll,
+ * HOME should be a POSIX style pathname.
+ */
+
+ if (getenv ("HOMEDRIVE") != NULL && getenv ("HOMEPATH") != NULL)
+ {
+ gchar *homedrive, *homepath;
+
+ homedrive = g_strdup (g_getenv ("HOMEDRIVE"));
+ homepath = g_strdup (g_getenv ("HOMEPATH"));
+
+ g_home_dir = g_strconcat (homedrive, homepath, NULL);
+ g_free (homedrive);
+ g_free (homepath);
+ }
+ if (!g_home_dir)
+ g_home_dir = g_strdup (g_getenv ("HOME"));
+#else
g_home_dir = g_strdup (g_getenv ("HOME"));
+#endif
#ifdef HAVE_PWD_H
/* FIXME: we must actually use the getpwuid_r function here, as
diff --git a/makefile.msc b/makefile.msc
index 6a7f9b6e2..3b2b77fb5 100644
--- a/makefile.msc
+++ b/makefile.msc
@@ -1,24 +1,29 @@
-## Makefile for building the GLib and gmodule dll with Microsoft C
+## Makefile for building the GLib, gmodule and gthread dlls with Microsoft C
## Use: nmake -f makefile.msc install
# Change this to wherever you want to install the DLLs. This directory
# should be in your PATH.
BIN = C:\bin
+# This is the Cygnus pthread-win32,
+# see http://sourceware.cygnus.com/pthreads-win32/
+PTHREAD_LIB = ..\lib\pthread.lib
+PTHREAD_INC = ..\include
+
################################################################
# Nothing much configurable below
# cl -? described the options
-CC = cl -G5 -GF -Ox -W3 -D_DLL -nologo
+CC = cl -G5 -GF -Ox -W3 -MD -nologo
-LDFLAGS = /link /nodefaultlib:libc msvcrt.lib # /debug:full /debugtype:cv
+# No general LDFLAGS needes
+LDFLAGS = /link
INSTALL = copy
-TOUCH = copy makefile.msc+nul
GLIB_VER = 1.1
-CFLAGS = -I.
+CFLAGS = -I. -DHAVE_CONFIG_H
all : \
glibconfig.h \
@@ -26,24 +31,34 @@ all : \
glib-$(GLIB_VER).dll \
gmodule\gmoduleconf.h \
gmodule-$(GLIB_VER).dll \
+ gthread-$(GLIB_VER).dll \
testglib.exe \
- testgmodule.exe
+ testgmodule.exe \
+ testgdate.exe \
+ testgdateparser.exe \
+ testgthread.exe
install : all
$(INSTALL) glib-$(GLIB_VER).dll $(BIN)
$(INSTALL) gmodule-$(GLIB_VER).dll $(BIN)
+ $(INSTALL) gthread-$(GLIB_VER).dll $(BIN)
glib_OBJECTS = \
garray.obj \
gcache.obj \
gcompletion.obj \
gdataset.obj \
+ gdate.obj \
gerror.obj \
ghook.obj \
ghash.obj \
+ giochannel.obj \
+ giowin32.obj \
glist.obj \
+ gmain.obj \
gmem.obj \
gmessages.obj \
+ gmutex.obj \
gnode.obj \
gprimes.obj \
gslist.obj \
@@ -55,8 +70,8 @@ glib_OBJECTS = \
gscanner.obj \
gutils.obj
-glib-$(GLIB_VER).dll : $(glib_OBJECTS)
- $(CC) $(CFLAGS) -MD -LD -Feglib-$(GLIB_VER).dll $(glib_OBJECTS) user32.lib advapi32.lib $(LDFLAGS) /def:glib.def
+glib-$(GLIB_VER).dll : $(glib_OBJECTS) glib.def
+ $(CC) $(CFLAGS) -LD -Feglib-$(GLIB_VER).dll $(glib_OBJECTS) user32.lib advapi32.lib wsock32.lib $(LDFLAGS) /def:glib.def
glibconfig.h: glibconfig.h.win32
copy glibconfig.h.win32 glibconfig.h
@@ -65,44 +80,71 @@ config.h: config.h.win32
copy config.h.win32 config.h
.c.obj :
- $(CC) $(CFLAGS) -GD -c -DHAVE_CONFIG_H -DGLIB_COMPILATION -DG_LOG_DOMAIN=g_log_domain_glib $<
+ $(CC) $(CFLAGS) -GD -c -DGLIB_COMPILATION -DG_LOG_DOMAIN=g_log_domain_glib $<
gmodule_OBJECTS = \
gmodule.obj
gmodule-$(GLIB_VER).dll : $(gmodule_OBJECTS)
- $(CC) $(CFLAGS) -MD -LD -Fegmodule-$(GLIB_VER).dll $(gmodule_OBJECTS) glib-$(GLIB_VER).lib $(LDFLAGS) /def:gmodule\gmodule.def
+ $(CC) $(CFLAGS) -LD -Fegmodule-$(GLIB_VER).dll $(gmodule_OBJECTS) glib-$(GLIB_VER).lib $(LDFLAGS) /def:gmodule\gmodule.def
gmodule.obj : gmodule\gmodule.c gmodule\gmodule-win32.c
- $(CC) $(CFLAGS) -Igmodule -c -DG_LIB_DOMAIN=g_log_domain_gmodule gmodule\gmodule.c
+ $(CC) $(CFLAGS) -GD -Igmodule -c -DG_LOG_DOMAIN=g_log_domain_gmodule gmodule\gmodule.c
gmodule\gmoduleconf.h: gmodule\gmoduleconf.h.win32
copy gmodule\gmoduleconf.h.win32 gmodule\gmoduleconf.h
+gthread_OBJECTS = \
+ gthread.obj
+
+gthread-$(GLIB_VER).dll : $(gthread_OBJECTS)
+ $(CC) $(CFLAGS) -LD -Fegthread-$(GLIB_VER).dll $(gthread_OBJECTS) glib-$(GLIB_VER).lib $(PTHREAD_LIB) glib-$(GLIB_VER).lib $(LDFLAGS) /def:gthread\gthread.def
+
+gthread.obj : gthread\gthread.c gthread\gthread-posix.c
+ $(CC) $(CFLAGS) -GD -I$(PTHREAD_INC) -DG_LOG_DOMAIN=\"GThread\" -c gthread\gthread.c
+
testglib.exe : glib-$(GLIB_VER).dll testglib.obj
- $(CC) $(CFLAGS) -MD -Fetestglib.exe testglib.obj glib-$(GLIB_VER).lib $(LDFLAGS) /map
+ $(CC) $(CFLAGS) -Fetestglib.exe testglib.obj glib-$(GLIB_VER).lib $(LDFLAGS) /subsystem:console
testglib.obj : testglib.c
$(CC) -c $(CFLAGS) testglib.c
+testgdate.exe : glib-$(GLIB_VER).dll testgdate.obj
+ $(CC) $(CFLAGS) -Fetestgdate.exe testgdate.obj glib-$(GLIB_VER).lib $(LDFLAGS) /subsystem:console
+
+testgdate.obj : testgdate.c
+ $(CC) -c $(CFLAGS) testgdate.c
+
+testgdateparser.exe : glib-$(GLIB_VER).dll testgdateparser.obj
+ $(CC) $(CFLAGS) -Fetestgdateparser.exe testgdateparser.obj glib-$(GLIB_VER).lib $(LDFLAGS) /subsystem:console
+
+testgdateparser.obj : testgdateparser.c
+ $(CC) -c $(CFLAGS) testgdateparser.c
+
testgmodule.exe : glib-$(GLIB_VER).dll gmodule-$(GLIB_VER).dll testgmodule.obj libgplugin_a.dll libgplugin_b.dll
- $(CC) $(CFLAGS) -MD testgmodule.obj glib-$(GLIB_VER).lib gmodule-$(GLIB_VER).lib $(LDFLAGS)
+ $(CC) $(CFLAGS) testgmodule.obj glib-$(GLIB_VER).lib gmodule-$(GLIB_VER).lib $(LDFLAGS) /subsystem:console
testgmodule.obj : gmodule\testgmodule.c
$(CC) $(CFLAGS) -Igmodule -c gmodule\testgmodule.c
libgplugin_a.dll : libgplugin_a.obj
- $(CC) $(CFLAGS) -MD -LD libgplugin_a.obj glib-$(GLIB_VER).lib gmodule-$(GLIB_VER).lib $(LDFLAGS)
+ $(CC) $(CFLAGS) -LD libgplugin_a.obj glib-$(GLIB_VER).lib gmodule-$(GLIB_VER).lib $(LDFLAGS)
libgplugin_a.obj : gmodule\libgplugin_a.c
$(CC) $(CFLAGS) -Igmodule -c gmodule\libgplugin_a.c
libgplugin_b.dll : libgplugin_b.obj
- $(CC) $(CFLAGS) -MD -LD libgplugin_b.obj glib-$(GLIB_VER).lib gmodule-$(GLIB_VER).lib $(LDFLAGS)
+ $(CC) $(CFLAGS) -LD libgplugin_b.obj glib-$(GLIB_VER).lib gmodule-$(GLIB_VER).lib $(LDFLAGS)
libgplugin_b.obj : gmodule\libgplugin_b.c
$(CC) $(CFLAGS) -Igmodule -c gmodule\libgplugin_b.c
+testgthread.exe : glib-$(GLIB_VER).dll gthread-$(GLIB_VER).dll testgthread.obj
+ $(CC) $(CFLAGS) testgthread.obj glib-$(GLIB_VER).lib gthread-$(GLIB_VER).lib $(PTHREAD_LIB) $(LDFLAGS) /subsystem:console
+
+testgthread.obj : gthread\testgthread.c
+ $(CC) $(CFLAGS) -I$(PTHREAD_INC) -c gthread\testgthread.c
+
clean:
del config.h
del glibconfig.h