Test for localtime_r only after including the right MT enabling CFLAGS
[platform/upstream/glib.git] / glib / glib.h
index 1548a5f..682dbd4 100644 (file)
@@ -155,7 +155,7 @@ extern "C" {
  * we define G_CAN_INLINE, if the compiler seems to be actually
  * *capable* to do function inlining, in which case inline function bodys
  * do make sense. we also define G_INLINE_FUNC to properly export the
- * function prototypes if no inlinig can be performed.
+ * function prototypes if no inlining can be performed.
  * we special case most of the stuff, so inline functions can have a normal
  * implementation by defining G_INLINE_FUNC to extern and G_CAN_INLINE to 1.
  */
@@ -301,6 +301,16 @@ extern "C" {
       ((type *) g_realloc (mem, (unsigned) sizeof (type) * (count)))
 #endif /* __DMALLOC_H__ */
 
+/* alloca-based counterparts of the above routines */
+#if G_HAVE_ALLOCA
+#  define g_alloca alloca
+#  define g_new_a(type, count)   \
+      ((type *) alloca ((unsigned) sizeof (type) * (count)))
+#  define g_new0_a(type, count)          \
+      ((type *) memset (alloca ((unsigned) sizeof (type) * (count)), 0, \
+                       ((unsigned) sizeof (type) * (count))))
+#endif /* G_HAVE_ALLOCA */
+
 #define g_mem_chunk_create(type, pre_alloc, alloc_type)        ( \
   g_mem_chunk_new (#type " mem chunks (" #pre_alloc ")", \
                   sizeof (type), \
@@ -487,12 +497,15 @@ typedef gint32    GTime;
 
 
 /* Portable endian checks and conversions
+ *
+ * glibconfig.h defines G_BYTE_ORDER which expands to one of
+ * the below macros.
  */
-
 #define G_LITTLE_ENDIAN 1234
 #define G_BIG_ENDIAN    4321
 #define G_PDP_ENDIAN    3412           /* unused, need specific PDP check */   
 
+
 /* Basic bit swapping functions
  */
 #define GUINT16_SWAP_LE_BE_CONSTANT(val)       ((guint16) ( \
@@ -507,7 +520,6 @@ typedef gint32      GTime;
 /* Intel specific stuff for speed
  */
 #if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
-
 #  define GUINT16_SWAP_LE_BE_X86(val) \
      (__extension__                                    \
       ({ register guint16 __v;                         \
@@ -518,9 +530,7 @@ typedef gint32      GTime;
                              : "=r" (__v)              \
                              : "0" ((guint16) (val))); \
        __v; }))
-
 #  define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_X86 (val))
-
 #  if !defined(__i486__) && !defined(__i586__) \
       && !defined(__pentium__) && !defined(__i686__) && !defined(__pentiumpro__)
 #     define GUINT32_SWAP_LE_BE_X86(val) \
@@ -535,7 +545,6 @@ typedef gint32      GTime;
                               : "=r" (__v)                     \
                               : "0" ((guint32) (val)));        \
        __v; }))
-
 #  else /* 486 and higher has bswap */
 #     define GUINT32_SWAP_LE_BE_X86(val) \
         (__extension__                                         \
@@ -548,9 +557,7 @@ typedef gint32      GTime;
                               : "0" ((guint32) (val)));        \
        __v; }))
 #  endif /* processor specific 32-bit stuff */
-
 #  define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_X86 (val))
-
 #else /* !__i386__ */
 #  define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val))
 #  define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val))
@@ -574,7 +581,6 @@ typedef gint32      GTime;
        (guint64) G_GINT64_CONSTANT(0x00ff000000000000U)) >> 40) |      \
       (((guint64) (val) &                                              \
        (guint64) G_GINT64_CONSTANT(0xff00000000000000U)) >> 56)))
-
 #  if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
 #    define GUINT64_SWAP_LE_BE_X86(val) \
        (__extension__                                          \
@@ -591,9 +597,7 @@ typedef gint32      GTime;
                __r.__l[1] = GUINT32_SWAP_LE_BE (__w.__l[0]);   \
              }                                                 \
          __r.__ll; }))
-
 #    define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_X86 (val))
-
 #  else /* !__i386__ */
 #    define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_CONSTANT(val))
 #  endif
@@ -608,8 +612,8 @@ typedef gint32      GTime;
     (((guint32) (val) & (guint32) 0x00ff00ffU) << 8) | \
     (((guint32) (val) & (guint32) 0xff00ff00U) >> 8)))
 
-/* The TO_?E stuff is defined in glibconfig.h. The transformation is symmetric,
  so the FROM just maps to the TO.
+/* The G*_TO_?E() macros are defined in glibconfig.h.
* The transformation is symmetric, so the FROM just maps to the TO.
  */
 #define GINT16_FROM_LE(val)    (GINT16_TO_LE (val))
 #define GUINT16_FROM_LE(val)   (GUINT16_TO_LE (val))
@@ -621,10 +625,10 @@ typedef gint32    GTime;
 #define GUINT32_FROM_BE(val)   (GUINT32_TO_BE (val))
 
 #ifdef G_HAVE_GINT64
-#define GINT64_FROM_LE(val)    (GINT32_TO_LE (val))
-#define GUINT64_FROM_LE(val)   (GUINT32_TO_LE (val))
-#define GINT64_FROM_BE(val)    (GINT32_TO_BE (val))
-#define GUINT64_FROM_BE(val)   (GUINT32_TO_BE (val))
+#define GINT64_FROM_LE(val)    (GINT64_TO_LE (val))
+#define GUINT64_FROM_LE(val)   (GUINT64_TO_LE (val))
+#define GINT64_FROM_BE(val)    (GINT64_TO_BE (val))
+#define GUINT64_FROM_BE(val)   (GUINT64_TO_BE (val))
 #endif
 
 #define GLONG_FROM_LE(val)     (GLONG_TO_LE (val))
@@ -637,6 +641,7 @@ typedef gint32      GTime;
 #define GINT_FROM_BE(val)      (GINT_TO_BE (val))
 #define GUINT_FROM_BE(val)     (GUINT_TO_BE (val))
 
+
 /* Portable versions of host-network order stuff
  */
 #define g_ntohl(val) (GUINT32_FROM_BE (val))
@@ -665,9 +670,9 @@ GUTILS_C_VAR const guint glib_micro_version;
 GUTILS_C_VAR const guint glib_interface_age;
 GUTILS_C_VAR const guint glib_binary_age;
 
+
 /* Forward declarations of glib types.
  */
-
 typedef struct _GAllocator     GAllocator;
 typedef struct _GArray         GArray;
 typedef struct _GByteArray     GByteArray;
@@ -694,7 +699,6 @@ typedef struct _GTuples             GTuples;
 typedef union  _GTokenValue    GTokenValue;
 typedef struct _GIOChannel     GIOChannel;
 
-
 typedef enum
 {
   G_TRAVERSE_LEAFS     = 1 << 0,
@@ -1189,9 +1193,14 @@ GHook*    g_hook_find_func_data          (GHookList              *hook_list,
                                         gboolean                need_valids,
                                         gpointer                func,
                                         gpointer                data);
+/* return the first valid hook, and increment its reference count */
 GHook*  g_hook_first_valid             (GHookList              *hook_list,
                                         gboolean                may_be_in_call);
-GHook*  g_hook_next_valid              (GHook                  *hook,
+/* return the next valid hook with incremented reference count, and
+ * decrement the reference count of the original hook
+ */
+GHook*  g_hook_next_valid              (GHookList              *hook_list,
+                                        GHook                  *hook,
                                         gboolean                may_be_in_call);
 
 /* GHookCompareFunc implementation to insert hooks sorted by their id */
@@ -1456,6 +1465,71 @@ gchar*    g_strescape            (gchar        *string);
 gpointer g_memdup              (gconstpointer mem,
                                 guint         byte_size);
 
+/* Macros for dynamic strings via fast stack allocation
+ * All macros take a special first argument: the target gchar* string
+ */
+#if G_HAVE_ALLOCA
+#  define g_strdup_a(newstr,str) G_STMT_START { \
+         gchar *__new;                         \
+         const gchar *__old = (str);           \
+         if (__old)                            \
+         {                                     \
+           size_t __len = strlen (__old) + 1;  \
+           __new = alloca (__len);             \
+           memcpy (__new, __old, __len);       \
+         }                                     \
+          else                                 \
+            __new = NULL;                      \
+          (newstr) = __new;                    \
+   } G_STMT_END
+#  define g_strndup_a(newstr,str,n) G_STMT_START { \
+         gchar *__new;                         \
+         const gchar *__old = (str);           \
+         if (__old)                            \
+         {                                     \
+            guint __n = (n);                   \
+           size_t __len = strlen (__old);      \
+           if (__len > (__n))                  \
+              __len = (__n);                   \
+           __new = alloca (__len + 1);         \
+           memcpy (__new, __old, __len);       \
+           __new[__len] = 0;                   \
+         }                                     \
+          else                                  \
+            __new = NULL;                       \
+         (newstr) = __new;                     \
+   } G_STMT_END
+#  define g_strconcat3_a(newstr,str1,str2,str3) G_STMT_START { \
+          const gchar *__str1 = (str1);                                \
+          const gchar *__str2 = (str2);                                \
+          const gchar *__str3 = (str3);                                \
+         gchar *__new;                                         \
+          if (__str1) {                                                \
+           size_t __len1 = strlen (__str1);                    \
+           if (__str2) {                                       \
+             size_t __len2 = strlen (__str2);                  \
+             if (__str3) {                                     \
+               size_t __len3 = strlen (__str3);                \
+               __new = alloca (__len1 + __len2 + __len3 + 1);  \
+               __new[__len1 + __len2 + __len3] = 0;            \
+               memcpy (__new + __len1 + __len2, __str3, __len3); \
+             } else {                                          \
+               __new = alloca (__len1 + __len2 + 1);           \
+               __new[__len1 + __len2] = 0;                     \
+             }                                                 \
+             memcpy (__new + __len1, __str2, __len2);          \
+           } else {                                            \
+             __new = alloca (__len1 + 1);                      \
+             __new[__len1] = 0;                                \
+           }                                                   \
+           memcpy (__new, __str1, __len1);                     \
+         } else                                                \
+           __new = NULL;                                       \
+         (newstr) = __new;                                     \
+   } G_STMT_END
+#endif /* G_HAVE_ALLOCA */
+
+
 /* NULL terminated string arrays.
  * g_strsplit() splits up string into max_tokens tokens at delim and
  * returns a newly allocated string array.
@@ -1632,7 +1706,7 @@ void       g_string_sprintfa  (GString     *string,
 
 #define g_array_append_val(a,v) g_array_append_vals(a,&v,1)
 #define g_array_prepend_val(a,v) g_array_prepend_vals(a,&v,1)
-#define g_array_insert_val(a,i,v) g_array_prepend_vals(a,i,&v,1)
+#define g_array_insert_val(a,i,v) g_array_insert_vals(a,i,&v,1)
 #define g_array_index(a,t,i) (((t*)a->data)[i])
 
 GArray* g_array_new              (gboolean         zero_terminated,
@@ -1976,7 +2050,7 @@ gpointer  g_scanner_scope_lookup_symbol   (GScanner       *scanner,
 void           g_scanner_scope_foreach_symbol  (GScanner       *scanner,
                                                 guint           scope_id,
                                                 GHFunc          func,
-                                                gpointer        func_data);
+                                                gpointer        user_data);
 gpointer       g_scanner_lookup_symbol         (GScanner       *scanner,
                                                 const gchar    *symbol);
 void           g_scanner_freeze_symbol_table   (GScanner       *scanner);
@@ -2007,7 +2081,8 @@ gint              g_scanner_stat_mode             (const gchar    *filename);
 } G_STMT_END
 
 
-/* Completion */
+/* GCompletion
+ */
 
 struct _GCompletion
 {
@@ -2030,30 +2105,32 @@ GList*       g_completion_complete     (GCompletion*    cmp,
 void        g_completion_free         (GCompletion*    cmp);
 
 
-
-
-/* Date calculations (not time for now, to be resolved). These are a
+/* GDate
+ *
+ * Date calculations (not time for now, to be resolved). These are a
  * mutant combination of Steffen Beyer's DateCalc routines
  * (http://www.perl.com/CPAN/authors/id/STBEY/) and Jon Trowbridge's
  * date routines (written for in-house software).  Written by Havoc
  * Pennington <hp@pobox.com> 
  */
 
-#include <time.h>
-
-/* this enum is used to specify order of appearance in parsed date
- *  strings
- */
+typedef guint16 GDateYear;
+typedef guint8  GDateDay;   /* day of the month */
+typedef struct _GDate GDate;
+/* make struct tm known without having to include time.h */
+struct tm;
 
-typedef enum {
-  G_DATE_MONTH = 0,
-  G_DATE_DAY   = 1,
+/* enum used to specify order of appearance in parsed date strings */
+typedef enum
+{
+  G_DATE_DAY   = 0,
+  G_DATE_MONTH = 1,
   G_DATE_YEAR  = 2
-} GDateMDY;
+} GDateDMY;
 
-/* These other types specify the actual values. */
-
-typedef enum {
+/* actual week and month values */
+typedef enum
+{
   G_DATE_BAD_WEEKDAY  = 0,
   G_DATE_MONDAY       = 1,
   G_DATE_TUESDAY      = 2,
@@ -2063,8 +2140,8 @@ typedef enum {
   G_DATE_SATURDAY     = 6,
   G_DATE_SUNDAY       = 7
 } GDateWeekday;
-
-typedef enum {
+typedef enum
+{
   G_DATE_BAD_MONTH = 0,
   G_DATE_JANUARY   = 1,
   G_DATE_FEBRUARY  = 2,
@@ -2080,22 +2157,17 @@ typedef enum {
   G_DATE_DECEMBER  = 12
 } GDateMonth;
 
-typedef guint16 GDateYear;
-typedef guint8  GDateDay;   /* day of the month */
-
 #define G_DATE_BAD_JULIAN 0U
 #define G_DATE_BAD_DAY    0U
 #define G_DATE_BAD_YEAR   0U
 
-typedef struct _GDate GDate;
-
 /* Note: directly manipulating structs is generally a bad idea, but
  * in this case it's an *incredibly* bad idea, because all or part
  * of this struct can be invalid at any given time. Use the functions,
  * or you will get hosed, I promise.
  */
-
-struct _GDate 
+struct _GDate
+{ 
   guint julian_days : 32; /* julian days representation - we use a
                            *  bitfield hoping that 64 bit platforms
                            *  will pack this whole struct in one big
@@ -2103,113 +2175,103 @@ struct _GDate {
                            */
 
   guint julian : 1;    /* julian is valid */
-  guint mdy    : 1;    /* mdy is valid */
+  guint dmy    : 1;    /* dmy is valid */
 
-  /* MDY representation */
-  guint month  : 4; 
+  /* DMY representation */
   guint day    : 6;  
+  guint month  : 4; 
   guint year   : 16; 
 };
 
-/* _new with no args returns an invalid date, you then have to _set() stuff 
+/* g_date_new() returns an invalid date, you then have to _set() stuff 
  * to get a usable object. You can also allocate a GDate statically,
  * then call g_date_clear() to initialize.
  */
-
 GDate*       g_date_new                   (void);
-GDate*       g_date_new_mdy               (GDateMonth   m
-                                           GDateDay     d
-                                           GDateYear    y);
+GDate*       g_date_new_dmy               (GDateDay     day
+                                           GDateMonth   month
+                                           GDateYear    year);
 GDate*       g_date_new_julian            (guint32      julian_day);
-void         g_date_free                  (GDate       *d);
+void         g_date_free                  (GDate       *date);
 
 /* check g_date_valid() after doing an operation that might fail, like
  * _parse.  Almost all g_date operations are undefined on invalid
  * dates (the exceptions are the mutators, since you need those to
  * return to validity).  
  */
+gboolean     g_date_valid                 (GDate       *date);
+gboolean     g_date_valid_day             (GDateDay     day);
+gboolean     g_date_valid_month           (GDateMonth   month);
+gboolean     g_date_valid_year            (GDateYear    year);
+gboolean     g_date_valid_weekday         (GDateWeekday weekday);
+gboolean     g_date_valid_julian          (guint32      julian_date);
+gboolean     g_date_valid_dmy             (GDateDay     day,
+                                           GDateMonth   month,
+                                           GDateYear    year);
 
-gboolean     g_date_valid                 (GDate       *d);
-gboolean     g_date_valid_month           (GDateMonth   m);
-gboolean     g_date_valid_year            (GDateYear    y);
-gboolean     g_date_valid_day             (GDateDay     d);
-gboolean     g_date_valid_weekday         (GDateWeekday w);
-gboolean     g_date_valid_julian          (guint32      j);
-gboolean     g_date_valid_mdy             (GDateMonth   m,
-                                           GDateDay     d,
-                                           GDateYear    y);
-
-GDateWeekday g_date_weekday               (GDate       *d);
-GDateMonth   g_date_month                 (GDate       *d);
-GDateYear    g_date_year                  (GDate       *d);
-GDateDay     g_date_day                   (GDate       *d);
-guint32      g_date_julian                (GDate       *d);
-
-guint        g_date_day_of_year           (GDate       *d);
+GDateWeekday g_date_weekday               (GDate       *date);
+GDateMonth   g_date_month                 (GDate       *date);
+GDateYear    g_date_year                  (GDate       *date);
+GDateDay     g_date_day                   (GDate       *date);
+guint32      g_date_julian                (GDate       *date);
+guint        g_date_day_of_year           (GDate       *date);
 
 /* First monday/sunday is the start of week 1; if we haven't reached
- *  that day, return 0. These are not ISO weeks of the year; that
- *  routine should be added.
+ * that day, return 0. These are not ISO weeks of the year; that
+ * routine needs to be added.
+ * these functions return the number of weeks, starting on the
+ * corrsponding day
  */
-
-guint        g_date_monday_week_of_year   (GDate      *d); /* # weeks, starting on Monday */
-guint        g_date_sunday_week_of_year   (GDate      *d); /* # weeks, starting on Sunday */
+guint        g_date_monday_week_of_year   (GDate      *date);
+guint        g_date_sunday_week_of_year   (GDate      *date);
 
 /* If you create a static date struct you need to clear it to get it
  * in a sane state before use. You can clear a whole array at
  * once with the ndates argument.
  */
-
-void         g_date_clear                 (GDate       *d, 
-                                           guint        ndates);
+void         g_date_clear                 (GDate       *date, 
+                                           guint        n_dates);
 
 /* The parse routine is meant for dates typed in by a user, so it
  * permits many formats but tries to catch common typos. If your data
  * needs to be strictly validated, it is not an appropriate function.
  */
-
-void         g_date_set_parse             (GDate       *d,
+void         g_date_set_parse             (GDate       *date,
                                            const gchar *str);
-
-void         g_date_set_time              (GDate       *d, 
-                                           time_t       t);
-
-void         g_date_set_month             (GDate       *d, 
-                                           GDateMonth   m);
-void         g_date_set_day               (GDate       *d, 
+void         g_date_set_time              (GDate       *date, 
+                                           GTime        time);
+void         g_date_set_month             (GDate       *date, 
+                                           GDateMonth   month);
+void         g_date_set_day               (GDate       *date, 
                                            GDateDay     day);
-void         g_date_set_year              (GDate       *d,
-                                           GDateYear    y);
-void         g_date_set_mdy               (GDate       *d,
-                                           GDateMonth   m,
+void         g_date_set_year              (GDate       *date,
+                                           GDateYear    year);
+void         g_date_set_dmy               (GDate       *date,
                                            GDateDay     day,
+                                           GDateMonth   month,
                                            GDateYear    y);
-
-void         g_date_set_julian            (GDate       *d,
-                                           guint32      j);
-
-gboolean     g_date_is_first_of_month     (GDate       *d);
-gboolean     g_date_is_last_of_month      (GDate       *d);
-
+void         g_date_set_julian            (GDate       *date,
+                                           guint32      julian_date);
+gboolean     g_date_is_first_of_month     (GDate       *date);
+gboolean     g_date_is_last_of_month      (GDate       *date);
 
 /* To go forward by some number of weeks just go forward weeks*7 days */
-void         g_date_add_days              (GDate       *d, 
-                                           guint        ndays);
-void         g_date_subtract_days         (GDate       *d, 
-                                           guint        ndays);
+void         g_date_add_days              (GDate       *date
+                                           guint        n_days);
+void         g_date_subtract_days         (GDate       *date
+                                           guint        n_days);
 
 /* If you add/sub months while day > 28, the day might change */
-void         g_date_add_months            (GDate       *d,
-                                           guint        nmonths);
-void         g_date_subtract_months       (GDate       *d,
-                                           guint        nmonths);
+void         g_date_add_months            (GDate       *date,
+                                           guint        n_months);
+void         g_date_subtract_months       (GDate       *date,
+                                           guint        n_months);
 
 /* If it's feb 29, changing years can move you to the 28th */
-void         g_date_add_years             (GDate       *d,
-                                           guint        nyears);
-void         g_date_subtract_years        (GDate       *d,
-                                           guint        nyears);
-
+void         g_date_add_years             (GDate       *date,
+                                           guint        n_years);
+void         g_date_subtract_years        (GDate       *date,
+                                           guint        n_years);
 gboolean     g_date_is_leap_year          (GDateYear    year);
 guint8       g_date_days_in_month         (GDateMonth   month, 
                                            GDateYear    year);
@@ -2219,9 +2281,7 @@ guint8       g_date_sunday_weeks_in_year  (GDateYear    year);
 /* qsort-friendly (with a cast...) */
 gint         g_date_compare               (GDate       *lhs,
                                            GDate       *rhs);
-
-
-void         g_date_to_struct_tm          (GDate       *d,
+void         g_date_to_struct_tm          (GDate       *date,
                                            struct tm   *tm);
 
 /* Just like strftime() except you can only use date-related formats.
@@ -2230,12 +2290,12 @@ void         g_date_to_struct_tm          (GDate       *d,
 gsize        g_date_strftime              (gchar       *s,
                                            gsize        slen,
                                            const gchar *format,
-                                           GDate       *d);
-
+                                           GDate       *date);
 
 
-
-/* GRelation: Indexed Relations.  Imagine a really simple table in a
+/* GRelation
+ *
+ * Indexed Relations.  Imagine a really simple table in a
  * database.  Relations are not ordered.  This data type is meant for
  * maintaining a N-way mapping.
  *
@@ -2295,6 +2355,198 @@ gpointer   g_tuples_index     (GTuples     *tuples,
 guint     g_spaced_primes_closest (guint num);
 
 
+/* GIOChannel
+ */
+
+typedef struct _GIOFuncs GIOFuncs;
+typedef enum
+{
+  G_IO_ERROR_NONE,
+  G_IO_ERROR_AGAIN,
+  G_IO_ERROR_INVAL,
+  G_IO_ERROR_UNKNOWN
+} GIOError;
+typedef enum
+{
+  G_SEEK_CUR,
+  G_SEEK_SET,
+  G_SEEK_END
+} GSeekType;
+typedef enum
+{
+  G_IO_IN      GLIB_SYSDEF_POLLIN,
+  G_IO_OUT     GLIB_SYSDEF_POLLOUT,
+  G_IO_PRI     GLIB_SYSDEF_POLLPRI,
+  G_IO_ERR     GLIB_SYSDEF_POLLERR,
+  G_IO_HUP     GLIB_SYSDEF_POLLHUP,
+  G_IO_NVAL    GLIB_SYSDEF_POLLNVAL
+} GIOCondition;
+
+struct _GIOChannel
+{
+  guint channel_flags;
+  guint ref_count;
+  GIOFuncs *funcs;
+};
+
+typedef gboolean (*GIOFunc) (GIOChannel   *source,
+                            GIOCondition  condition,
+                            gpointer      data);
+struct _GIOFuncs
+{
+  GIOError (*io_read)   (GIOChannel    *channel, 
+                        gchar          *buf, 
+                        guint           count,
+                        guint          *bytes_read);
+  GIOError (*io_write)  (GIOChannel    *channel, 
+                        gchar          *buf, 
+                        guint           count,
+                        guint          *bytes_written);
+  GIOError (*io_seek)   (GIOChannel    *channel, 
+                        gint            offset, 
+                        GSeekType       type);
+  void (*io_close)      (GIOChannel    *channel);
+  guint (*io_add_watch) (GIOChannel     *channel,
+                        gint            priority,
+                        GIOCondition    condition,
+                        GIOFunc         func,
+                        gpointer        user_data,
+                        GDestroyNotify  notify);
+  void (*io_free)       (GIOChannel    *channel);
+};
+
+void        g_io_channel_init   (GIOChannel    *channel);
+void        g_io_channel_ref    (GIOChannel    *channel);
+void        g_io_channel_unref  (GIOChannel    *channel);
+GIOError    g_io_channel_read   (GIOChannel    *channel, 
+                                gchar         *buf, 
+                                guint          count,
+                                guint         *bytes_read);
+GIOError  g_io_channel_write    (GIOChannel    *channel, 
+                                gchar         *buf, 
+                                guint          count,
+                                guint         *bytes_written);
+GIOError  g_io_channel_seek     (GIOChannel    *channel,
+                                gint           offset, 
+                                GSeekType      type);
+void      g_io_channel_close    (GIOChannel    *channel);
+guint     g_io_add_watch_full   (GIOChannel    *channel,
+                                gint           priority,
+                                GIOCondition   condition,
+                                GIOFunc        func,
+                                gpointer       user_data,
+                                GDestroyNotify notify);
+guint    g_io_add_watch         (GIOChannel    *channel,
+                                GIOCondition   condition,
+                                GIOFunc        func,
+                                gpointer       user_data);
+
+
+/* Main loop
+ */
+typedef struct _GTimeVal       GTimeVal;
+typedef struct _GSourceFuncs   GSourceFuncs;
+typedef struct _GMainLoop      GMainLoop;      /* Opaque */
+
+struct _GTimeVal
+{
+  glong tv_sec;
+  glong tv_usec;
+};
+struct _GSourceFuncs
+{
+  gboolean (*prepare)  (gpointer  source_data, 
+                       GTimeVal *current_time,
+                       gint     *timeout);
+  gboolean (*check)    (gpointer  source_data,
+                       GTimeVal *current_time);
+  gboolean (*dispatch) (gpointer  source_data, 
+                       GTimeVal *current_time,
+                       gpointer  user_data);
+  GDestroyNotify destroy;
+};
+
+/* Standard priorities */
+
+#define G_PRIORITY_HIGH            -100
+#define G_PRIORITY_DEFAULT          0
+#define G_PRIORITY_HIGH_IDLE        100
+#define G_PRIORITY_DEFAULT_IDLE     200
+#define G_PRIORITY_LOW             300
+
+typedef gboolean (*GSourceFunc) (gpointer data);
+
+/* Hooks for adding to the main loop */
+guint g_source_add                  (gint           priority, 
+                                    gboolean       can_recurse,
+                                    GSourceFuncs  *funcs,
+                                    gpointer       source_data, 
+                                    gpointer       user_data,
+                                    GDestroyNotify notify);
+void g_source_remove                (guint          tag);
+void g_source_remove_by_user_data   (gpointer       user_data);
+void g_source_remove_by_source_data (gpointer       source_data);
+
+void g_get_current_time                    (GTimeVal      *result);
+
+/* Running the main loop */
+GMainLoop*     g_main_new              (gboolean        is_running);
+void           g_main_run              (GMainLoop      *loop);
+void           g_main_quit             (GMainLoop      *loop);
+void           g_main_destroy          (GMainLoop      *loop);
+gboolean       g_main_is_running       (GMainLoop      *loop);
+
+/* Run a single iteration of the mainloop. If block is FALSE,
+ * will never block
+ */
+gboolean       g_main_iteration        (gboolean       may_block);
+
+/* See if any events are pending */
+gboolean       g_main_pending          (void);
+
+/* Idles and timeouts */
+guint          g_timeout_add_full      (gint           priority,
+                                        guint          interval, 
+                                        GSourceFunc    function,
+                                        gpointer       data,
+                                        GDestroyNotify notify);
+guint          g_timeout_add           (guint          interval,
+                                        GSourceFunc    function,
+                                        gpointer       data);
+guint          g_idle_add              (GSourceFunc    function,
+                                        gpointer       data);
+guint          g_idle_add_full         (gint           priority,
+                                        GSourceFunc    function,
+                                        gpointer       data,
+                                        GDestroyNotify destroy);
+
+/* GPollFD
+ *
+ * Unix-specific IO and main loop calls
+ */
+
+typedef struct _GPollFD GPollFD;
+typedef gint   (*GPollFunc)    (GPollFD *ufds,
+                                guint    nfsd,
+                                gint     timeout);
+struct _GPollFD
+{
+  gint         fd;
+  gushort      events;
+  gushort      revents;
+};
+
+void        g_main_add_poll          (GPollFD    *fd,
+                                     gint        priority);
+void        g_main_remove_poll       (GPollFD    *fd);
+void        g_main_set_poll_func     (GPollFunc   func);
+
+GIOChannel* g_io_channel_unix_new    (int         fd);
+gint        g_io_channel_unix_get_fd (GIOChannel *channel);
+
+
+/* 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).
@@ -2317,7 +2569,6 @@ struct _GIOChannel
                                 */
 #endif
 };
-
 GIOChannel *g_iochannel_new            (gint        fd);
 void        g_iochannel_free           (GIOChannel *channel);
 void        g_iochannel_close_and_free (GIOChannel *channel);
@@ -2325,15 +2576,14 @@ 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 */
 
 
 /* Windows emulation stubs for common unix functions
  */
 #ifdef NATIVE_WIN32
-
-#define MAXPATHLEN 1024
-
-#ifdef _MSC_VER
+#  define MAXPATHLEN 1024
+#  ifdef _MSC_VER
 typedef int pid_t;
 
 /* These POSIXish functions are available in the Microsoft C library
@@ -2348,30 +2598,27 @@ typedef int pid_t;
  * For some functions, we provide emulators in glib, which are prefixed
  * with gwin_.
  */
-#define getcwd                 _getcwd
-#define getpid                 _getpid
-#define access                 _access
-#define open                   _open
-#define read                   _read
-#define write                  _write
-#define lseek                  _lseek
-#define close                  _close
-#define pipe(phandles)         _pipe (phandles, 4096, _O_BINARY)
-#define popen                  _popen
-#define pclose                 _pclose
-#define fdopen                 _fdopen
-#define ftruncate(fd, size)    gwin_ftruncate (fd, size)
-#define opendir                        gwin_opendir
-#define readdir                        gwin_readdir
-#define rewinddir              gwin_rewinddir
-#define closedir               gwin_closedir
-
-#define NAME_MAX 255
-
+#    define getcwd             _getcwd
+#    define getpid             _getpid
+#    define access             _access
+#    define open               _open
+#    define read               _read
+#    define write              _write
+#    define lseek              _lseek
+#    define close              _close
+#    define pipe(phandles)     _pipe (phandles, 4096, _O_BINARY)
+#    define popen              _popen
+#    define pclose             _pclose
+#    define fdopen             _fdopen
+#    define ftruncate(fd, size)        gwin_ftruncate (fd, size)
+#    define opendir            gwin_opendir
+#    define readdir            gwin_readdir
+#    define rewinddir          gwin_rewinddir
+#    define closedir           gwin_closedir
+#    define NAME_MAX 255
 struct DIR
 {
   gchar    *dir_name;
-
   gboolean  just_opened;
   guint     find_file_handle;
   gpointer  find_file_data;
@@ -2381,7 +2628,6 @@ struct dirent
 {
   gchar  d_name[NAME_MAX + 1];
 };
-
 /* emulation functions */
 extern int     gwin_ftruncate  (gint            f,
                                 guint           size);
@@ -2389,11 +2635,153 @@ DIR*           gwin_opendir    (const gchar    *dirname);
 struct dirent* gwin_readdir    (DIR            *dir);
 void           gwin_rewinddir  (DIR            *dir);
 gint           gwin_closedir   (DIR            *dir);
+#  endif /* _MSC_VER */
+#endif  /* NATIVE_WIN32 */
 
-#endif /* _MSC_VER */
 
-#endif /* NATIVE_WIN32 */
+/* GLib Thread support
+ */
+typedef struct _GMutex         GMutex;
+typedef struct _GCond          GCond;
+typedef struct _GPrivate       GPrivate;
+typedef struct _GStaticPrivate GStaticPrivate;
+typedef struct _GThreadFunctions GThreadFunctions;
+struct _GThreadFunctions
+{
+  GMutex*  (*mutex_new)       (void);
+  void     (*mutex_lock)      (GMutex          *mutex);
+  gboolean (*mutex_trylock)   (GMutex          *mutex);
+  void     (*mutex_unlock)    (GMutex          *mutex);
+  void     (*mutex_free)      (GMutex          *mutex);
+  GCond*   (*cond_new)        (void);
+  void     (*cond_signal)     (GCond           *cond);
+  void     (*cond_broadcast)  (GCond           *cond);
+  void     (*cond_wait)       (GCond           *cond,
+                              GMutex           *mutex);
+  gboolean (*cond_timed_wait) (GCond           *cond,
+                              GMutex           *mutex, 
+                              GTimeVal         *end_time);
+  void      (*cond_free)      (GCond           *cond);
+  GPrivate* (*private_new)    (GDestroyNotify   destructor);
+  gpointer  (*private_get)    (GPrivate                *private_key);
+  void      (*private_set)    (GPrivate                *private_key,
+                              gpointer          data);
+};
 
+GUTILS_C_VAR GThreadFunctions  g_thread_functions_for_glib_use;
+GUTILS_C_VAR gboolean          g_thread_use_default_impl;
+GUTILS_C_VAR gboolean          g_threads_got_initialized;
+
+/* initializes the mutex/cond/private implementation for glib, might
+ * only be called once, and must not be called directly or indirectly
+ * from another glib-function, e.g. as a callback.
+ */
+void   g_thread_init   (GThreadFunctions       *vtable);
+
+/* internal function for fallback static mutex implementation */
+GMutex*        g_static_mutex_get_mutex_impl   (GMutex **mutex);
+
+/* shorthands for conditional and unconditional function calls */
+#define G_THREAD_UF(name, arglist) \
+    (*g_thread_functions_for_glib_use . name) arglist
+#define G_THREAD_CF(name, fail, arg) \
+    (g_thread_supported () ? G_THREAD_UF (name, arg) : (fail))
+/* keep in mind, all those mutexes and static mutexes are not 
+ * recursive in general, don't rely on that
+ */
+#define        g_thread_supported()    (g_threads_got_initialized)
+#define g_mutex_new()            G_THREAD_UF (mutex_new,      ())
+#define g_mutex_lock(mutex)      G_THREAD_CF (mutex_lock,     (void)0, (mutex))
+#define g_mutex_trylock(mutex)   G_THREAD_CF (mutex_trylock,  TRUE,    (mutex))
+#define g_mutex_unlock(mutex)    G_THREAD_CF (mutex_unlock,   (void)0, (mutex))
+#define g_mutex_free(mutex)      G_THREAD_CF (mutex_free,     (void)0, (mutex))
+#define g_cond_new()             G_THREAD_UF (cond_new,       ())
+#define g_cond_signal(cond)      G_THREAD_CF (cond_signal,    (void)0, (cond))
+#define g_cond_broadcast(cond)   G_THREAD_CF (cond_broadcast, (void)0, (cond))
+#define g_cond_wait(cond, mutex) G_THREAD_CF (cond_wait,      (void)0, (cond, \
+                                                                        mutex))
+#define g_cond_free(cond)        G_THREAD_CF (cond_free,      (void)0, (cond))
+#define g_cond_timed_wait(cond, mutex, abs_time) G_THREAD_CF (cond_timed_wait, \
+                                                              TRUE, \
+                                                              (cond, mutex, \
+                                                              abs_time))
+#define g_private_new(destructor)        G_THREAD_UF (private_new, (destructor))
+#define g_private_get(private_key)       G_THREAD_CF (private_get, \
+                                                       ((gpointer)private_key), \
+                                                       (private_key))
+#define g_private_set(private_key, value) G_THREAD_CF (private_set, \
+                                                       (void) (private_key = \
+                                                        (GPrivate*) (value)), \
+                                                       (private_key, value))
+/* GStaticMutexes can be statically initialized with the value
+ * G_STATIC_MUTEX_INIT, and then they can directly be used, that is
+ * much easier, than having to explicitly allocate the mutex before
+ * use
+ */
+#define g_static_mutex_lock(mutex) \
+    g_mutex_lock (g_static_mutex_get_mutex (mutex))
+#define g_static_mutex_trylock(mutex) \
+    g_mutex_trylock (g_static_mutex_get_mutex (mutex))
+#define g_static_mutex_unlock(mutex) \
+    g_mutex_unlock (g_static_mutex_get_mutex (mutex)) 
+struct _GStaticPrivate
+{
+  guint index;
+};
+#define G_STATIC_PRIVATE_INIT { 0 }
+gpointer g_static_private_get (GStaticPrivate  *private_key);
+void     g_static_private_set (GStaticPrivate  *private_key, 
+                              gpointer          data,
+                              GDestroyNotify    notify);
+
+/* these are some convenience macros that expand to nothing if GLib was
+ * configured with --deisable-threads. for using StaticMutexes, you
+ * declare them with G_LOCK_DECLARE_STATIC (name) or G_LOCK_DECLARE (name)
+ * if you need to export the mutex. name is a unique identifier for the
+ * protected varibale or code portion. locking, testing and unlocking of
+ * such mutexes can be done with G_LOCK(), G_UNLOCK() and G_TRYLOCK()
+ * respectively.
+ */
+extern void glib_dummy_decl (void);
+#define G_LOCK_NAME(name)              (g__ ## name ## _lock)
+#ifdef G_THREADS_ENABLED
+#  define G_LOCK_DECLARE_STATIC(name)  static G_LOCK_DECLARE (name)
+#  define G_LOCK_DECLARE(name)         \
+    GStaticMutex G_LOCK_NAME (name) = G_STATIC_MUTEX_INIT 
+
+#  ifdef G_DEBUG_LOCKS
+#    define G_LOCK(name)               G_STMT_START{             \
+        g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,                          \
+              "file %s: line %d (%s): locking: %s ",             \
+              __FILE__,        __LINE__, G_GNUC_PRETTY_FUNCTION, \
+               #name);                                            \
+        g_static_mutex_lock (G_LOCK_NAME (name));                 \
+     }G_STMT_END
+#    define G_UNLOCK(name)             G_STMT_START{             \
+        g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,                          \
+              "file %s: line %d (%s): unlocking: %s ",           \
+              __FILE__,        __LINE__, G_GNUC_PRETTY_FUNCTION, \
+               #name);                                            \
+       g_static_mutex_unlock (G_LOCK_NAME (name));                \
+     }G_STMT_END
+#    define G_TRYLOCK(name)            G_STMT_START{             \
+        g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,                          \
+              "file %s: line %d (%s): try locking: %s ",         \
+              __FILE__,        __LINE__, G_GNUC_PRETTY_FUNCTION, \
+               #name);                                            \
+     }G_STMT_END,      g_static_mutex_trylock (G_LOCK_NAME (name))
+#  else         /* !G_DEBUG_LOCKS */
+#    define G_LOCK(name) g_static_mutex_lock      (G_LOCK_NAME (name)) 
+#    define G_UNLOCK(name) g_static_mutex_unlock   (G_LOCK_NAME (name))
+#    define G_TRYLOCK(name) g_static_mutex_trylock (G_LOCK_NAME (name))
+#  endif /* !G_DEBUG_LOCKS */
+#else  /* !G_THREADS_ENABLED */
+#  define G_LOCK_DECLARE_STATIC(name)  extern void glib_dummy_decl (void)
+#  define G_LOCK_DECLARE(name)         extern void glib_dummy_decl (void)
+#  define G_LOCK(name)
+#  define G_UNLOCK(name)
+#  define G_TRYLOCK(name)              (FALSE)
+#endif /* !G_THREADS_ENABLED */
 
 #ifdef __cplusplus
 }