#include "cog-modules.h"
#include "cog-platform-private.h"
#include "cog-viewport.h"
G_DEFINE_QUARK(COG_PLATFORM_ERROR, cog_platform_error)
G_DEFINE_QUARK(COG_PLATFORM_EGL_ERROR, cog_platform_egl_error)
G_DEFINE_QUARK(COG_PLATFORM_WPE_ERROR, cog_platform_wpe_error)
G_DEFINE_ABSTRACT_TYPE(CogPlatform, cog_platform, G_TYPE_OBJECT)
static CogPlatform *platform_singleton = NULL;
enum {
VIEWPORT_CREATED,
VIEWPORT_DISPOSED,
N_SIGNALS,
};
static unsigned s_signals[N_SIGNALS] = {
0,
};
static gboolean
cog_platform_is_supported(void)
{
return TRUE;
}
static void
cog_platform_viewport_noop(CogPlatform *self, CogViewport *viewport)
{
}
static void
cog_platform_class_init(CogPlatformClass *klass)
{
klass->viewport_created = cog_platform_viewport_noop;
klass->viewport_disposed = cog_platform_viewport_noop;
klass->is_supported = cog_platform_is_supported;
s_signals[VIEWPORT_CREATED] = g_signal_new("viewport-created", COG_TYPE_PLATFORM, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(CogPlatformClass, viewport_created), NULL, NULL, NULL,
G_TYPE_NONE, 1, COG_TYPE_VIEWPORT);
s_signals[VIEWPORT_DISPOSED] = g_signal_new("viewport-disposed", COG_TYPE_PLATFORM, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(CogPlatformClass, viewport_disposed), NULL, NULL, NULL,
G_TYPE_NONE, 1, COG_TYPE_VIEWPORT);
}
static void
cog_platform_init(CogPlatform *platform)
{
}
static inline gboolean
cog_platform_ensure_singleton(const char *name)
{
if (g_once_init_enter(&platform_singleton)) {
cog_modules_add_directory(NULL);
GType platform_type =
cog_modules_get_preferred(COG_MODULES_PLATFORM, name, G_STRUCT_OFFSET(CogPlatformClass, is_supported));
if (platform_type == G_TYPE_INVALID) {
if (name)
g_error("Requested platform '%s' not usable.", name);
else
g_error("Could not find an usable platform.");
}
g_debug("%s: %s requested, %s chosen.", G_STRFUNC, name ?: "None", g_type_name(platform_type));
g_once_init_leave(&platform_singleton, g_object_new(platform_type, NULL));
return FALSE;
}
return TRUE;
}
void
cog_init(const char *platform_name, const char *module_path)
{
cog_modules_add_directory(module_path);
gboolean already_initialized = cog_platform_ensure_singleton(platform_name ?: g_getenv("COG_PLATFORM_NAME"));
g_return_if_fail(!already_initialized);
}
CogPlatform *
cog_platform_get(void)
{
cog_platform_ensure_singleton(NULL);
return platform_singleton;
}
gboolean
cog_platform_setup(CogPlatform *platform, CogShell *shell, const char *params, GError **error)
{
g_return_val_if_fail(COG_IS_PLATFORM(platform), FALSE);
g_return_val_if_fail(COG_IS_SHELL(shell), FALSE);
if (G_IS_INITABLE(platform) && !g_initable_init(G_INITABLE(platform), NULL , error))
return FALSE;
if (!params || params[0] == '\0')
params = g_getenv("COG_PLATFORM_PARAMS") ?: "";
return COG_PLATFORM_GET_CLASS(platform)->setup(platform, shell, params, error);
}
WebKitWebViewBackend*
cog_platform_get_view_backend (CogPlatform *platform,
WebKitWebView *related_view,
GError **error)
{
g_return_val_if_fail(COG_IS_PLATFORM(platform), NULL);
CogPlatformClass *klass = COG_PLATFORM_GET_CLASS(platform);
return klass->get_view_backend(platform, related_view, error);
}
void
cog_platform_init_web_view (CogPlatform *platform,
WebKitWebView *view)
{
g_return_if_fail(COG_IS_PLATFORM(platform));
CogPlatformClass *klass = COG_PLATFORM_GET_CLASS(platform);
if (klass->init_web_view) {
if (klass->get_view_type) {
#if GLIB_CHECK_VERSION(2, 63, 1)
g_warning_once("%s: class %s defines both .get_view_type and .init_web_view, "
"the latter should be removed.",
G_STRFUNC, G_OBJECT_CLASS_NAME(platform));
#else
static bool warned = false;
if (!warned) {
warned = true;
g_warning("%s: class %s defines both .get_view_type and .init_web_view, "
"the latter should be removed.",
G_STRFUNC, G_OBJECT_CLASS_NAME(platform));
}
#endif
return;
}
klass->init_web_view(platform, view);
}
}
WebKitInputMethodContext *
cog_platform_create_im_context(CogViewport *viewport)
{
CogPlatform *platform = cog_platform_get();
g_return_val_if_fail(COG_IS_PLATFORM(platform), NULL);
CogPlatformClass *klass = COG_PLATFORM_GET_CLASS(platform);
if (klass->create_im_context)
return klass->create_im_context(viewport);
return NULL;
}
void
cog_platform_notify_viewport_created(CogViewport *viewport)
{
g_assert(platform_singleton != NULL);
g_signal_emit(platform_singleton, s_signals[VIEWPORT_CREATED], 0, viewport);
}
void
cog_platform_notify_viewport_disposed(CogViewport *viewport)
{
g_assert(platform_singleton != NULL);
g_signal_emit(platform_singleton, s_signals[VIEWPORT_DISPOSED], 0, viewport);
}