diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WTF/wtf/glib | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WTF/wtf/glib')
-rw-r--r-- | Source/WTF/wtf/glib/GLibUtilities.cpp | 65 | ||||
-rw-r--r-- | Source/WTF/wtf/glib/GLibUtilities.h | 37 | ||||
-rw-r--r-- | Source/WTF/wtf/glib/GMutexLocker.h | 102 | ||||
-rw-r--r-- | Source/WTF/wtf/glib/GRefPtr.cpp | 161 | ||||
-rw-r--r-- | Source/WTF/wtf/glib/GRefPtr.h | 261 | ||||
-rw-r--r-- | Source/WTF/wtf/glib/GTypedefs.h | 111 | ||||
-rw-r--r-- | Source/WTF/wtf/glib/GUniquePtr.h | 128 | ||||
-rw-r--r-- | Source/WTF/wtf/glib/MainThreadGLib.cpp | 81 | ||||
-rw-r--r-- | Source/WTF/wtf/glib/RunLoopGLib.cpp | 215 |
9 files changed, 1161 insertions, 0 deletions
diff --git a/Source/WTF/wtf/glib/GLibUtilities.cpp b/Source/WTF/wtf/glib/GLibUtilities.cpp new file mode 100644 index 000000000..5629b5715 --- /dev/null +++ b/Source/WTF/wtf/glib/GLibUtilities.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010 Igalia, S.L. + * + * 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; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "GLibUtilities.h" + +#if OS(WINDOWS) +#include <windows.h> +#include <wtf/text/WTFString.h> +#else +#include <limits.h> +#include <unistd.h> +#endif + +#if OS(LINUX) +CString getCurrentExecutablePath() +{ + static char readLinkBuffer[PATH_MAX]; + ssize_t result = readlink("/proc/self/exe", readLinkBuffer, PATH_MAX); + if (result == -1) + return CString(); + return CString(readLinkBuffer, result); +} +#elif OS(HURD) +CString getCurrentExecutablePath() +{ + return CString(); +} +#elif OS(UNIX) +CString getCurrentExecutablePath() +{ + static char readLinkBuffer[PATH_MAX]; + ssize_t result = readlink("/proc/curproc/file", readLinkBuffer, PATH_MAX); + if (result == -1) + return CString(); + return CString(readLinkBuffer, result); +} +#elif OS(WINDOWS) +CString getCurrentExecutablePath() +{ + static WCHAR buffer[MAX_PATH]; + DWORD length = GetModuleFileNameW(0, buffer, MAX_PATH); + if (!length || (length == MAX_PATH && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) + return CString(); + + String path(buffer, length); + return path.utf8(); +} +#endif diff --git a/Source/WTF/wtf/glib/GLibUtilities.h b/Source/WTF/wtf/glib/GLibUtilities.h new file mode 100644 index 000000000..da22596b1 --- /dev/null +++ b/Source/WTF/wtf/glib/GLibUtilities.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 Igalia, S.L. + * + * 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; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef GLibUtilities_h +#define GLibUtilities_h + +#include <wtf/Assertions.h> +#include <wtf/text/CString.h> + +CString getCurrentExecutablePath(); + +// These might be added to glib in the future, but in the meantime they're defined here. +#ifndef GULONG_TO_POINTER +#define GULONG_TO_POINTER(ul) ((gpointer) (gulong) (ul)) +#endif + +#ifndef GPOINTER_TO_ULONG +#define GPOINTER_TO_ULONG(p) ((gulong) (p)) +#endif + +#endif diff --git a/Source/WTF/wtf/glib/GMutexLocker.h b/Source/WTF/wtf/glib/GMutexLocker.h new file mode 100644 index 000000000..5efbff000 --- /dev/null +++ b/Source/WTF/wtf/glib/GMutexLocker.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2013 Collabora Ltd. + * + * 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; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef GMutexLocker_h +#define GMutexLocker_h + +#if USE(GLIB) + +#include <glib.h> +#include <wtf/Noncopyable.h> + +namespace WTF { + +template<typename T> +struct MutexWrapper; + +template<> +struct MutexWrapper<GMutex> { + static void lock(GMutex* mutex) + { + g_mutex_lock(mutex); + } + + static void unlock(GMutex* mutex) + { + g_mutex_unlock(mutex); + } +}; + +template<> +struct MutexWrapper<GRecMutex> { + static void lock(GRecMutex* mutex) + { + g_rec_mutex_lock(mutex); + } + + static void unlock(GRecMutex* mutex) + { + g_rec_mutex_unlock(mutex); + } +}; + +template<typename T> +class GMutexLocker { + WTF_MAKE_NONCOPYABLE(GMutexLocker); +public: + explicit GMutexLocker(T& mutex) + : m_mutex(mutex) + , m_locked(false) + { + lock(); + } + + ~GMutexLocker() + { + unlock(); + } + + void lock() + { + if (m_locked) + return; + + MutexWrapper<T>::lock(&m_mutex); + m_locked = true; + } + + void unlock() + { + if (!m_locked) + return; + + m_locked = false; + MutexWrapper<T>::unlock(&m_mutex); + } + +private: + T& m_mutex; + bool m_locked; +}; + +} // namespace WTF + +#endif // USE(GLIB) + +#endif // GMutexLocker_h diff --git a/Source/WTF/wtf/glib/GRefPtr.cpp b/Source/WTF/wtf/glib/GRefPtr.cpp new file mode 100644 index 000000000..c522095af --- /dev/null +++ b/Source/WTF/wtf/glib/GRefPtr.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2009 Martin Robinson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "GRefPtr.h" + +#if USE(GLIB) + +#include <glib-object.h> +#include <glib.h> + +namespace WTF { + +template <> GHashTable* refGPtr(GHashTable* ptr) +{ + if (ptr) + g_hash_table_ref(ptr); + return ptr; +} + +template <> void derefGPtr(GHashTable* ptr) +{ + if (ptr) + g_hash_table_unref(ptr); +} + +template <> GMainContext* refGPtr(GMainContext* ptr) +{ + if (ptr) + g_main_context_ref(ptr); + return ptr; +} + +template <> void derefGPtr(GMainContext* ptr) +{ + if (ptr) + g_main_context_unref(ptr); +} + +template <> GMainLoop* refGPtr(GMainLoop* ptr) +{ + if (ptr) + g_main_loop_ref(ptr); + return ptr; +} + +template <> void derefGPtr(GMainLoop* ptr) +{ + if (ptr) + g_main_loop_unref(ptr); +} + +template <> GBytes* refGPtr(GBytes* ptr) +{ + if (ptr) + g_bytes_ref(ptr); + return ptr; +} + +template <> void derefGPtr(GBytes* ptr) +{ + if (ptr) + g_bytes_unref(ptr); +} + +template <> GVariant* refGPtr(GVariant* ptr) +{ + if (ptr) + g_variant_ref_sink(ptr); + return ptr; +} + +template <> void derefGPtr(GVariant* ptr) +{ + if (ptr) + g_variant_unref(ptr); +} + +template <> GVariantBuilder* refGPtr(GVariantBuilder* ptr) +{ + if (ptr) + g_variant_builder_ref(ptr); + return ptr; +} + +template <> void derefGPtr(GVariantBuilder* ptr) +{ + if (ptr) + g_variant_builder_unref(ptr); +} + +template <> GSource* refGPtr(GSource* ptr) +{ + if (ptr) + g_source_ref(ptr); + return ptr; +} + +template <> void derefGPtr(GSource* ptr) +{ + if (ptr) + g_source_unref(ptr); +} + +template <> GPtrArray* refGPtr(GPtrArray* ptr) +{ + if (ptr) + g_ptr_array_ref(ptr); + return ptr; +} + +template <> void derefGPtr(GPtrArray* ptr) +{ + if (ptr) + g_ptr_array_unref(ptr); +} + +template <> GByteArray* refGPtr(GByteArray* ptr) +{ + if (ptr) + g_byte_array_ref(ptr); + return ptr; +} + +template <> void derefGPtr(GByteArray* ptr) +{ + if (ptr) + g_byte_array_unref(ptr); +} + +template <> GClosure* refGPtr(GClosure* ptr) +{ + if (ptr) + g_closure_ref(ptr); + return ptr; +} + +template <> void derefGPtr(GClosure* ptr) +{ + if (ptr) + g_closure_unref(ptr); +} + +} // namespace WTF + +#endif // USE(GLIB) diff --git a/Source/WTF/wtf/glib/GRefPtr.h b/Source/WTF/wtf/glib/GRefPtr.h new file mode 100644 index 000000000..d05084b66 --- /dev/null +++ b/Source/WTF/wtf/glib/GRefPtr.h @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2009 Martin Robinson + * + * 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; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef WTF_GRefPtr_h +#define WTF_GRefPtr_h + +#if USE(GLIB) + +#include <wtf/GetPtr.h> +#include <wtf/RefPtr.h> +#include <algorithm> + +extern "C" void g_object_unref(gpointer); +extern "C" gpointer g_object_ref_sink(gpointer); + +namespace WTF { + +enum GRefPtrAdoptType { GRefPtrAdopt }; +template <typename T> inline T* refGPtr(T*); +template <typename T> inline void derefGPtr(T*); +template <typename T> class GRefPtr; +template <typename T> GRefPtr<T> adoptGRef(T*); + +template <typename T> class GRefPtr { +public: + typedef T ValueType; + typedef ValueType* PtrType; + + GRefPtr() : m_ptr(0) { } + + GRefPtr(T* ptr) + : m_ptr(ptr) + { + if (ptr) + refGPtr(ptr); + } + + GRefPtr(const GRefPtr& o) + : m_ptr(o.m_ptr) + { + if (T* ptr = m_ptr) + refGPtr(ptr); + } + + template <typename U> GRefPtr(const GRefPtr<U>& o) + : m_ptr(o.get()) + { + if (T* ptr = m_ptr) + refGPtr(ptr); + } + + GRefPtr(GRefPtr&& o) : m_ptr(o.leakRef()) { } + template <typename U> GRefPtr(GRefPtr<U>&& o) : m_ptr(o.leakRef()) { } + + ~GRefPtr() + { + if (T* ptr = m_ptr) + derefGPtr(ptr); + } + + void clear() + { + T* ptr = m_ptr; + m_ptr = 0; + if (ptr) + derefGPtr(ptr); + } + + T* leakRef() WARN_UNUSED_RETURN + { + T* ptr = m_ptr; + m_ptr = 0; + return ptr; + } + + T*& outPtr() + { + ASSERT(!m_ptr); + return m_ptr; + } + + // Hash table deleted values, which are only constructed and never copied or destroyed. + GRefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { } + bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } + + T* get() const { return m_ptr; } + T& operator*() const { return *m_ptr; } + ALWAYS_INLINE T* operator->() const { return m_ptr; } + + bool operator!() const { return !m_ptr; } + + // This conversion operator allows implicit conversion to bool but not to other integer types. + typedef T* GRefPtr::*UnspecifiedBoolType; + operator UnspecifiedBoolType() const { return m_ptr ? &GRefPtr::m_ptr : 0; } + + GRefPtr& operator=(const GRefPtr&); + GRefPtr& operator=(GRefPtr&&); + GRefPtr& operator=(T*); + template <typename U> GRefPtr& operator=(const GRefPtr<U>&); + + void swap(GRefPtr&); + friend GRefPtr adoptGRef<T>(T*); + +private: + static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } + // Adopting constructor. + GRefPtr(T* ptr, GRefPtrAdoptType) : m_ptr(ptr) {} + + T* m_ptr; +}; + +template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(const GRefPtr<T>& o) +{ + T* optr = o.get(); + if (optr) + refGPtr(optr); + T* ptr = m_ptr; + m_ptr = optr; + if (ptr) + derefGPtr(ptr); + return *this; +} + +template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(GRefPtr<T>&& o) +{ + GRefPtr ptr = WTFMove(o); + swap(ptr); + return *this; +} + +template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(T* optr) +{ + T* ptr = m_ptr; + if (optr) + refGPtr(optr); + m_ptr = optr; + if (ptr) + derefGPtr(ptr); + return *this; +} + +template <class T> inline void GRefPtr<T>::swap(GRefPtr<T>& o) +{ + std::swap(m_ptr, o.m_ptr); +} + +template <class T> inline void swap(GRefPtr<T>& a, GRefPtr<T>& b) +{ + a.swap(b); +} + +template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, const GRefPtr<U>& b) +{ + return a.get() == b.get(); +} + +template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, U* b) +{ + return a.get() == b; +} + +template <typename T, typename U> inline bool operator==(T* a, const GRefPtr<U>& b) +{ + return a == b.get(); +} + +template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, const GRefPtr<U>& b) +{ + return a.get() != b.get(); +} + +template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, U* b) +{ + return a.get() != b; +} + +template <typename T, typename U> inline bool operator!=(T* a, const GRefPtr<U>& b) +{ + return a != b.get(); +} + +template <typename T, typename U> inline GRefPtr<T> static_pointer_cast(const GRefPtr<U>& p) +{ + return GRefPtr<T>(static_cast<T*>(p.get())); +} + +template <typename T, typename U> inline GRefPtr<T> const_pointer_cast(const GRefPtr<U>& p) +{ + return GRefPtr<T>(const_cast<T*>(p.get())); +} + +template <typename T> struct IsSmartPtr<GRefPtr<T>> { + static const bool value = true; +}; + +template <typename T> GRefPtr<T> adoptGRef(T* p) +{ + return GRefPtr<T>(p, GRefPtrAdopt); +} + +template <> WTF_EXPORT_PRIVATE GHashTable* refGPtr(GHashTable* ptr); +template <> WTF_EXPORT_PRIVATE void derefGPtr(GHashTable* ptr); +template <> WTF_EXPORT_PRIVATE GMainContext* refGPtr(GMainContext* ptr); +template <> WTF_EXPORT_PRIVATE void derefGPtr(GMainContext* ptr); +template <> WTF_EXPORT_PRIVATE GMainLoop* refGPtr(GMainLoop* ptr); +template <> WTF_EXPORT_PRIVATE void derefGPtr(GMainLoop* ptr); +template <> WTF_EXPORT_PRIVATE GVariant* refGPtr(GVariant* ptr); +template <> WTF_EXPORT_PRIVATE void derefGPtr(GVariant* ptr); +template <> WTF_EXPORT_PRIVATE GVariantBuilder* refGPtr(GVariantBuilder* ptr); +template <> WTF_EXPORT_PRIVATE void derefGPtr(GVariantBuilder* ptr); +template <> WTF_EXPORT_PRIVATE GSource* refGPtr(GSource* ptr); +template <> WTF_EXPORT_PRIVATE void derefGPtr(GSource* ptr); +template <> WTF_EXPORT_PRIVATE GPtrArray* refGPtr(GPtrArray*); +template <> WTF_EXPORT_PRIVATE void derefGPtr(GPtrArray*); +template <> WTF_EXPORT_PRIVATE GByteArray* refGPtr(GByteArray*); +template <> WTF_EXPORT_PRIVATE void derefGPtr(GByteArray*); +template <> WTF_EXPORT_PRIVATE GBytes* refGPtr(GBytes*); +template <> WTF_EXPORT_PRIVATE void derefGPtr(GBytes*); +template <> WTF_EXPORT_PRIVATE GClosure* refGPtr(GClosure*); +template <> WTF_EXPORT_PRIVATE void derefGPtr(GClosure*); + +template <typename T> inline T* refGPtr(T* ptr) +{ + if (ptr) + g_object_ref_sink(ptr); + return ptr; +} + +template <typename T> inline void derefGPtr(T* ptr) +{ + if (ptr) + g_object_unref(ptr); +} + +} // namespace WTF + +using WTF::GRefPtr; +using WTF::adoptGRef; + +#endif // USE(GLIB) + +#endif // WTF_GRefPtr_h diff --git a/Source/WTF/wtf/glib/GTypedefs.h b/Source/WTF/wtf/glib/GTypedefs.h new file mode 100644 index 000000000..51053c03d --- /dev/null +++ b/Source/WTF/wtf/glib/GTypedefs.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2010 Igalia, S.L. + * + * 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; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WTF_GTypedefs_h +#define WTF_GTypedefs_h + +/* Vanilla C code does not seem to be able to handle forward-declaration typedefs. */ +#ifdef __cplusplus + +typedef char gchar; +typedef double gdouble; +typedef float gfloat; +typedef int gint; +typedef gint gboolean; +typedef long glong; +typedef short gshort; +typedef unsigned char guchar; +typedef unsigned int guint; +typedef unsigned long gulong; +typedef unsigned short gushort; +typedef void* gpointer; + +typedef struct _GAsyncResult GAsyncResult; +typedef struct _GCancellable GCancellable; +typedef struct _GCharsetConverter GCharsetConverter; +typedef struct _GDir GDir; +typedef struct _GdkAtom* GdkAtom; +typedef struct _GdkCursor GdkCursor; +typedef struct _GdkDragContext GdkDragContext; +typedef struct _GdkEventConfigure GdkEventConfigure; +typedef struct _GdkEventExpose GdkEventExpose; +typedef struct _GdkPixbuf GdkPixbuf; +typedef struct _GError GError; +typedef struct _GFile GFile; +typedef struct _GHashTable GHashTable; +typedef struct _GInputStream GInputStream; +typedef struct _GList GList; +typedef struct _GMainContext GMainContext; +typedef struct _GMainLoop GMainLoop; +typedef struct _GPatternSpec GPatternSpec; +typedef struct _GPollableOutputStream GPollableOutputStream; +typedef struct _GSList GSList; +typedef struct _GSocketClient GSocketClient; +typedef struct _GSocketConnection GSocketConnection; +typedef struct _GSource GSource; +typedef struct _GVariant GVariant; +typedef struct _GVariantBuilder GVariantBuilder; +typedef struct _GVariantIter GVariantIter; +typedef union _GdkEvent GdkEvent; +typedef struct _GTimer GTimer; +typedef struct _GKeyFile GKeyFile; +typedef struct _GPtrArray GPtrArray; +typedef struct _GByteArray GByteArray; +typedef struct _GBytes GBytes; +typedef struct _GClosure GClosure; + +#if USE(CAIRO) +typedef struct _cairo_surface cairo_surface_t; +typedef struct _cairo_rectangle_int cairo_rectangle_int_t; +#endif + +#if USE(CLUTTER) +typedef struct _ClutterActor ClutterActor; +typedef struct _GraphicsLayerActor GraphicsLayerActor; +#endif + +#if PLATFORM(GTK) +typedef struct _GtkAction GtkAction; +typedef struct _GtkAdjustment GtkAdjustment; +typedef struct _GtkBorder GtkBorder; +typedef struct _GtkClipboard GtkClipboard; +typedef struct _GtkContainer GtkContainer; +typedef struct _GtkIconInfo GtkIconInfo; +typedef struct _GtkMenu GtkMenu; +typedef struct _GtkMenuItem GtkMenuItem; +typedef struct _GtkObject GtkObject; +typedef struct _GtkSelectionData GtkSelectionData; +typedef struct _GtkStyle GtkStyle; +typedef struct _GtkTargetList GtkTargetList; +typedef struct _GtkThemeParts GtkThemeParts; +typedef struct _GtkWidget GtkWidget; +typedef struct _GtkWindow GtkWindow; + +#ifdef GTK_API_VERSION_2 +typedef struct _GdkRectangle GdkRectangle; +typedef struct _GdkDrawable GdkWindow; +#else +typedef struct _GdkWindow GdkWindow; +typedef struct _GtkStyleContext GtkStyleContext; +#endif + +#endif + +#endif +#endif // WTF_GTypedefs_h diff --git a/Source/WTF/wtf/glib/GUniquePtr.h b/Source/WTF/wtf/glib/GUniquePtr.h new file mode 100644 index 000000000..e1cff8dde --- /dev/null +++ b/Source/WTF/wtf/glib/GUniquePtr.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * 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; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef GUniquePtr_h +#define GUniquePtr_h + +#if USE(GLIB) + +#include <gio/gio.h> +#include <wtf/Noncopyable.h> + +namespace WTF { + +template<typename T> +struct GPtrDeleter { + void operator()(T* ptr) const { g_free(ptr); } +}; + +template<typename T> +using GUniquePtr = std::unique_ptr<T, GPtrDeleter<T>>; + +#define FOR_EACH_GLIB_DELETER(macro) \ + macro(GError, g_error_free) \ + macro(GList, g_list_free) \ + macro(GSList, g_slist_free) \ + macro(GPatternSpec, g_pattern_spec_free) \ + macro(GDir, g_dir_close) \ + macro(GTimer, g_timer_destroy) \ + macro(GKeyFile, g_key_file_free) \ + macro(char*, g_strfreev) \ + macro(GVariantIter, g_variant_iter_free) + +#define WTF_DEFINE_GPTR_DELETER(typeName, deleterFunc) \ + template<> struct GPtrDeleter<typeName> \ + { \ + void operator() (typeName* ptr) const \ + { \ + deleterFunc(ptr); \ + } \ + }; + +FOR_EACH_GLIB_DELETER(WTF_DEFINE_GPTR_DELETER) +#undef FOR_EACH_GLIB_DELETER + +template <typename T> class GUniqueOutPtr { + WTF_MAKE_NONCOPYABLE(GUniqueOutPtr); +public: + GUniqueOutPtr() + : m_ptr(nullptr) + { + } + + ~GUniqueOutPtr() + { + reset(); + } + + T*& outPtr() + { + reset(); + return m_ptr; + } + + GUniquePtr<T> release() + { + GUniquePtr<T> ptr(m_ptr); + m_ptr = nullptr; + return ptr; + } + + T& operator*() const + { + ASSERT(m_ptr); + return *m_ptr; + } + + T* operator->() const + { + ASSERT(m_ptr); + return m_ptr; + } + + T* get() const { return m_ptr; } + + bool operator!() const { return !m_ptr; } + + // This conversion operator allows implicit conversion to bool but not to other integer types. + typedef T* GUniqueOutPtr::*UnspecifiedBoolType; + operator UnspecifiedBoolType() const { return m_ptr ? &GUniqueOutPtr::m_ptr : 0; } + +private: + void reset() + { + if (m_ptr) { + GUniquePtr<T> deletePtr(m_ptr); + m_ptr = nullptr; + } + } + + T* m_ptr; +}; + +} // namespace WTF + +using WTF::GUniquePtr; +using WTF::GUniqueOutPtr; + +#endif // USE(GLIB) + +#endif // GUniquePtr_h + diff --git a/Source/WTF/wtf/glib/MainThreadGLib.cpp b/Source/WTF/wtf/glib/MainThreadGLib.cpp new file mode 100644 index 000000000..c2fa56fcf --- /dev/null +++ b/Source/WTF/wtf/glib/MainThreadGLib.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "MainThread.h" + +#include <glib.h> +#include <wtf/RunLoop.h> + +static pthread_t mainThreadPthread; + +namespace WTF { + +class MainThreadDispatcher { +public: + MainThreadDispatcher() + : m_timer(RunLoop::main(), this, &MainThreadDispatcher::fired) + { + m_timer.setPriority(G_PRIORITY_HIGH_IDLE + 20); + } + + void schedule() + { + m_timer.startOneShot(0); + } + +private: + void fired() + { + dispatchFunctionsFromMainThread(); + } + + RunLoop::Timer<MainThreadDispatcher> m_timer; +}; + +void initializeMainThreadPlatform() +{ + mainThreadPthread = pthread_self(); +} + +bool isMainThread() +{ + ASSERT(mainThreadPthread); + return pthread_equal(pthread_self(), mainThreadPthread); +} + +void scheduleDispatchFunctionsOnMainThread() +{ + // Use a RunLoop::Timer instead of RunLoop::dispatch() to be able to use a different priority and + // avoid the double queue because dispatchOnMainThread also queues the functions. + static MainThreadDispatcher dispatcher; + dispatcher.schedule(); +} + +} // namespace WTF diff --git a/Source/WTF/wtf/glib/RunLoopGLib.cpp b/Source/WTF/wtf/glib/RunLoopGLib.cpp new file mode 100644 index 000000000..927ce3254 --- /dev/null +++ b/Source/WTF/wtf/glib/RunLoopGLib.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "RunLoop.h" + +#include <glib.h> +#include <wtf/MainThread.h> + +namespace WTF { + +static GSourceFuncs runLoopSourceFunctions = { + nullptr, // prepare + nullptr, // check + // dispatch + [](GSource* source, GSourceFunc callback, gpointer userData) -> gboolean + { + if (g_source_get_ready_time(source) == -1) + return G_SOURCE_CONTINUE; + g_source_set_ready_time(source, -1); + return callback(userData); + }, + nullptr, // finalize + nullptr, // closure_callback + nullptr, // closure_marshall +}; + +RunLoop::RunLoop() +{ + m_mainContext = g_main_context_get_thread_default(); + if (!m_mainContext) + m_mainContext = isMainThread() ? g_main_context_default() : adoptGRef(g_main_context_new()); + ASSERT(m_mainContext); + + GRefPtr<GMainLoop> innermostLoop = adoptGRef(g_main_loop_new(m_mainContext.get(), FALSE)); + ASSERT(innermostLoop); + m_mainLoops.append(innermostLoop); + + m_source = adoptGRef(g_source_new(&runLoopSourceFunctions, sizeof(GSource))); + g_source_set_name(m_source.get(), "[WebKit] RunLoop work"); + g_source_set_can_recurse(m_source.get(), TRUE); + g_source_set_callback(m_source.get(), [](gpointer userData) -> gboolean { + static_cast<RunLoop*>(userData)->performWork(); + return G_SOURCE_CONTINUE; + }, this, nullptr); + g_source_attach(m_source.get(), m_mainContext.get()); +} + +RunLoop::~RunLoop() +{ + g_source_destroy(m_source.get()); + + for (int i = m_mainLoops.size() - 1; i >= 0; --i) { + if (!g_main_loop_is_running(m_mainLoops[i].get())) + continue; + g_main_loop_quit(m_mainLoops[i].get()); + } +} + +void RunLoop::run() +{ + RunLoop& runLoop = RunLoop::current(); + GMainContext* mainContext = runLoop.m_mainContext.get(); + + // The innermost main loop should always be there. + ASSERT(!runLoop.m_mainLoops.isEmpty()); + + GMainLoop* innermostLoop = runLoop.m_mainLoops[0].get(); + if (!g_main_loop_is_running(innermostLoop)) { + g_main_context_push_thread_default(mainContext); + g_main_loop_run(innermostLoop); + g_main_context_pop_thread_default(mainContext); + return; + } + + // Create and run a nested loop if the innermost one was already running. + GMainLoop* nestedMainLoop = g_main_loop_new(mainContext, FALSE); + runLoop.m_mainLoops.append(adoptGRef(nestedMainLoop)); + + g_main_context_push_thread_default(mainContext); + g_main_loop_run(nestedMainLoop); + g_main_context_pop_thread_default(mainContext); + + runLoop.m_mainLoops.removeLast(); +} + +void RunLoop::stop() +{ + // The innermost main loop should always be there. + ASSERT(!m_mainLoops.isEmpty()); + GRefPtr<GMainLoop> lastMainLoop = m_mainLoops.last(); + if (g_main_loop_is_running(lastMainLoop.get())) + g_main_loop_quit(lastMainLoop.get()); +} + +void RunLoop::wakeUp() +{ + g_source_set_ready_time(m_source.get(), g_get_monotonic_time()); +} + +class DispatchAfterContext { + WTF_MAKE_FAST_ALLOCATED; +public: + DispatchAfterContext(Function<void ()>&& function) + : m_function(WTFMove(function)) + { + } + + void dispatch() + { + m_function(); + } + +private: + Function<void ()> m_function; +}; + +void RunLoop::dispatchAfter(std::chrono::nanoseconds duration, Function<void ()>&& function) +{ + GRefPtr<GSource> source = adoptGRef(g_timeout_source_new(std::chrono::duration_cast<std::chrono::milliseconds>(duration).count())); + g_source_set_name(source.get(), "[WebKit] RunLoop dispatchAfter"); + + std::unique_ptr<DispatchAfterContext> context = std::make_unique<DispatchAfterContext>(WTFMove(function)); + g_source_set_callback(source.get(), [](gpointer userData) -> gboolean { + std::unique_ptr<DispatchAfterContext> context(static_cast<DispatchAfterContext*>(userData)); + context->dispatch(); + return G_SOURCE_REMOVE; + }, context.release(), nullptr); + g_source_attach(source.get(), m_mainContext.get()); +} + +RunLoop::TimerBase::TimerBase(RunLoop& runLoop) + : m_runLoop(runLoop) + , m_source(adoptGRef(g_source_new(&runLoopSourceFunctions, sizeof(GSource)))) +{ + g_source_set_name(m_source.get(), "[WebKit] RunLoop::Timer work"); + g_source_set_callback(m_source.get(), [](gpointer userData) -> gboolean { + RunLoop::TimerBase* timer = static_cast<RunLoop::TimerBase*>(userData); + timer->fired(); + if (timer->m_isRepeating) + timer->updateReadyTime(); + return G_SOURCE_CONTINUE; + }, this, nullptr); + g_source_attach(m_source.get(), m_runLoop.m_mainContext.get()); +} + +RunLoop::TimerBase::~TimerBase() +{ + g_source_destroy(m_source.get()); +} + +void RunLoop::TimerBase::setPriority(int priority) +{ + g_source_set_priority(m_source.get(), priority); +} + +void RunLoop::TimerBase::updateReadyTime() +{ + if (!m_fireInterval.count()) { + g_source_set_ready_time(m_source.get(), 0); + return; + } + + gint64 currentTime = g_get_monotonic_time(); + gint64 targetTime = currentTime + std::min<gint64>(G_MAXINT64 - currentTime, m_fireInterval.count()); + ASSERT(targetTime >= currentTime); + g_source_set_ready_time(m_source.get(), targetTime); +} + +void RunLoop::TimerBase::start(double fireInterval, bool repeat) +{ + auto intervalDuration = std::chrono::duration<double>(fireInterval); + auto safeDuration = std::chrono::microseconds::max(); + if (intervalDuration < safeDuration) + safeDuration = std::chrono::duration_cast<std::chrono::microseconds>(intervalDuration); + + m_fireInterval = safeDuration; + m_isRepeating = repeat; + updateReadyTime(); +} + +void RunLoop::TimerBase::stop() +{ + g_source_set_ready_time(m_source.get(), -1); +} + +bool RunLoop::TimerBase::isActive() const +{ + return g_source_get_ready_time(m_source.get()) != -1; +} + +} // namespace WTF |