/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* 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, see .Free
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include
#include
#include
#include
#include
#include
#include "gtkimmodule.h"
#include "gtkimmoduleprivate.h"
#include "gtkimcontextsimple.h"
#include "gtkmodulesprivate.h"
#include "gtksettings.h"
#include "gtkprivate.h"
#include "gtkutilsprivate.h"
#include "gtkintl.h"
#ifdef GDK_WINDOWING_X11
#include "x11/gdkx.h"
#include "gtkimcontextxim.h"
#endif
#ifdef GDK_WINDOWING_WAYLAND
#include "wayland/gdkwayland.h"
#include "gtkimcontextwayland.h"
#endif
#ifdef GDK_WINDOWING_BROADWAY
#include "broadway/gdkbroadway.h"
#include "gtkimcontextbroadway.h"
#endif
#ifdef GDK_WINDOWING_WIN32
#include "win32/gdkwin32.h"
#include "gtkimcontextime.h"
#endif
#ifdef GDK_WINDOWING_QUARTZ
#include "quartz/gdkquartz.h"
#include "gtkimcontextquartz.h"
#endif
#ifdef G_OS_WIN32
#include
#endif
#define SIMPLE_ID "gtk-im-context-simple"
#define NONE_ID "gtk-im-context-none"
/**
* _gtk_im_module_create:
* @context_id: the context ID for the context type to create
*
* Create an IM context of a type specified by the string
* ID @context_id.
*
* Returns: a newly created input context of or @context_id, or
* if that could not be created, a newly created GtkIMContextSimple.
*/
GtkIMContext *
_gtk_im_module_create (const gchar *context_id)
{
GIOExtensionPoint *ep;
GIOExtension *ext;
GType type;
GtkIMContext *context = NULL;
if (strcmp (context_id, NONE_ID) == 0)
return NULL;
ep = g_io_extension_point_lookup (GTK_IM_MODULE_EXTENSION_POINT_NAME);
ext = g_io_extension_point_get_extension_by_name (ep, context_id);
if (ext)
{
type = g_io_extension_get_type (ext);
context = g_object_new (type, NULL);
}
return context;
}
static gboolean
is_platform (const char *context_id)
{
return g_strcmp0 (context_id, "wayland") == 0 ||
g_strcmp0 (context_id, "broadway") == 0 ||
g_strcmp0 (context_id, "xim") == 0 ||
g_strcmp0 (context_id, "quartz") == 0 ||
g_strcmp0 (context_id, "ime") == 0;
}
static gboolean
match_backend (const char *context_id)
{
#ifdef GDK_WINDOWING_WAYLAND
if (g_strcmp0 (context_id, "wayland") == 0)
return GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ());
#endif
#ifdef GDK_WINDOWING_BROADWAY
if (g_strcmp0 (context_id, "broadway") == 0)
return GDK_IS_BROADWAY_DISPLAY (gdk_display_get_default ());
#endif
#ifdef GDK_WINDOWING_X11
if (g_strcmp0 (context_id, "xim") == 0)
return GDK_IS_X11_DISPLAY (gdk_display_get_default ());
#endif
#ifdef GDK_WINDOWING_WIN32
if (g_strcmp0 (context_id, "ime") == 0)
return GDK_IS_WIN32_DISPLAY (gdk_display_get_default ());
#endif
#ifdef GDK_WINDOWING_QUARTZ
if (g_strcmp0 (context_id, "quartz") == 0)
return GDK_IS_QUARTZ_DISPLAY (gdk_display_get_default ());
#endif
return TRUE;
}
static const gchar *
lookup_immodule (gchar **immodules_list)
{
while (immodules_list && *immodules_list)
{
if (g_strcmp0 (*immodules_list, SIMPLE_ID) == 0)
return SIMPLE_ID;
else if (g_strcmp0 (*immodules_list, NONE_ID) == 0)
return NONE_ID;
else
{
GIOExtensionPoint *ep;
GIOExtension *ext;
ep = g_io_extension_point_lookup (GTK_IM_MODULE_EXTENSION_POINT_NAME);
ext = g_io_extension_point_get_extension_by_name (ep, *immodules_list);
if (ext)
return g_io_extension_get_name (ext);
}
immodules_list++;
}
return NULL;
}
/**
* _gtk_im_module_get_default_context_id:
*
* Return the context_id of the best IM context type
* for the given window.
*
* Returns: the context ID (will never be %NULL)
*/
const gchar *
_gtk_im_module_get_default_context_id (void)
{
const gchar *context_id = NULL;
const gchar *envvar;
GtkSettings *settings;
char *tmp;
envvar = g_getenv ("GTK_IM_MODULE");
if (envvar)
{
char **immodules;
immodules = g_strsplit (envvar, ":", 0);
context_id = lookup_immodule (immodules);
g_strfreev (immodules);
if (context_id)
return context_id;
}
/* Check if the certain immodule is set in XSETTINGS. */
settings = gtk_settings_get_default ();
g_object_get (G_OBJECT (settings), "gtk-im-module", &tmp, NULL);
if (tmp)
{
char **immodules;
immodules = g_strsplit (tmp, ":", 0);
context_id = lookup_immodule (immodules);
g_strfreev (immodules);
g_free (tmp);
if (context_id)
return context_id;
}
GIOExtensionPoint *ep;
GList *list, *l;
ep = g_io_extension_point_lookup (GTK_IM_MODULE_EXTENSION_POINT_NAME);
list = g_io_extension_point_get_extensions (ep);
for (l = list; l; l = l->next)
{
GIOExtension *ext = l->data;
const char *context_id;
context_id = g_io_extension_get_name (ext);
if (match_backend (context_id))
return context_id;
// FIXME: locale matching
if (!is_platform (context_id))
return context_id;
}
return context_id ? context_id : SIMPLE_ID;
}
void
gtk_im_modules_init (void)
{
GIOExtensionPoint *ep;
GIOModuleScope *scope;
char **paths;
int i;
GTK_NOTE (MODULES,
g_print ("Registering extension point %s\n", GTK_IM_MODULE_EXTENSION_POINT_NAME));
ep = g_io_extension_point_register (GTK_IM_MODULE_EXTENSION_POINT_NAME);
g_io_extension_point_set_required_type (ep, GTK_TYPE_IM_CONTEXT);
g_type_ensure (gtk_im_context_simple_get_type ());
#ifdef GDK_WINDOWING_X11
g_type_ensure (gtk_im_context_xim_get_type ());
#endif
#ifdef GDK_WINDOWING_WAYLAND
g_type_ensure (gtk_im_context_wayland_get_type ());
#endif
#ifdef GDK_WINDOWING_BROADWAY
g_type_ensure (gtk_im_context_broadway_get_type ());
#endif
#ifdef GDK_WINDOWING_WIN32
g_type_ensure (gtk_im_context_ime_get_type ());
#endif
#ifdef GDK_WINDOWING_QUARTZ
g_type_ensure (gtk_im_context_quartz_get_type ());
#endif
scope = g_io_module_scope_new (G_IO_MODULE_SCOPE_BLOCK_DUPLICATES);
paths = _gtk_get_module_path ("immodules");
for (i = 0; paths[i]; i++)
{
GTK_NOTE (MODULES,
g_print ("Scanning io modules in %s\n", paths[i]));
g_io_modules_scan_all_in_directory_with_scope (paths[i], scope);
}
g_strfreev (paths);
g_io_module_scope_free (scope);
if (GTK_DEBUG_CHECK (MODULES))
{
GList *list, *l;
list = g_io_extension_point_get_extensions (ep);
for (l = list; l; l = l->next)
{
GIOExtension *ext = l->data;
g_print ("extension: %s: type %s\n",
g_io_extension_get_name (ext),
g_type_name (g_io_extension_get_type (ext)));
}
}
}