mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 13:11:13 +00:00
Convert immodules to use an extension point
Add an extension point called gtk-im-module, which requires the type GtkIMContext. Simplify the loading by using GIO infrastructure. Drop the locale filtering for now, I don't think it is really necessary nowadays. Convert existing platform modules to gio modules. Sill to do: Drop the conditional build machinery. Either always include them, or never.
This commit is contained in:
parent
e6bf832514
commit
29bcc38ae6
@ -15,9 +15,4 @@ if [ -z "$DESTDIR" ]; then
|
||||
|
||||
echo Updating icon cache...
|
||||
gtk-update-icon-cache -q -t -f ${gtk_datadir}/icons/hicolor
|
||||
|
||||
echo Updating input method modules cache...
|
||||
gtk_imdir=${gtk_libdir}/gtk-${gtk_api_version}/${gtk_abi_version}
|
||||
mkdir -p ${gtk_imdir}
|
||||
gtk4-query-immodules > ${gtk_imdir}/immodules.cache
|
||||
fi
|
||||
|
@ -125,7 +125,6 @@
|
||||
#include <gtk/gtkiconview.h>
|
||||
#include <gtk/gtkimage.h>
|
||||
#include <gtk/gtkimcontext.h>
|
||||
#include <gtk/gtkimcontextinfo.h>
|
||||
#include <gtk/gtkimcontextsimple.h>
|
||||
#include <gtk/gtkimmulticontext.h>
|
||||
#include <gtk/gtkinfobar.h>
|
||||
|
@ -1,44 +0,0 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2000 Red Hat Software
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_IM_CONTEXT_INFO_H__
|
||||
#define __GTK_IM_CONTEXT_INFO_H__
|
||||
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkIMContextInfo GtkIMContextInfo;
|
||||
|
||||
struct _GtkIMContextInfo
|
||||
{
|
||||
const gchar *context_id;
|
||||
const gchar *context_name;
|
||||
const gchar *domain;
|
||||
const gchar *domain_dirname;
|
||||
const gchar *default_locales;
|
||||
};
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_IM_CONTEXT_INFO_H__ */
|
@ -40,6 +40,7 @@
|
||||
#include "gtkdebug.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkcomposetable.h"
|
||||
#include "gtkimmodule.h"
|
||||
|
||||
#include "gtkimcontextsimpleprivate.h"
|
||||
#include "gtkimcontextsimpleseqs.h"
|
||||
@ -164,7 +165,12 @@ static void gtk_im_context_simple_get_preedit_string (GtkIMContext
|
||||
static void gtk_im_context_simple_set_client_widget (GtkIMContext *context,
|
||||
GtkWidget *widget);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkIMContextSimple, gtk_im_context_simple, GTK_TYPE_IM_CONTEXT)
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkIMContextSimple, gtk_im_context_simple, GTK_TYPE_IM_CONTEXT,
|
||||
G_ADD_PRIVATE (GtkIMContextSimple)
|
||||
g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME,
|
||||
g_define_type_id,
|
||||
"gtk-im-context-simple",
|
||||
10))
|
||||
|
||||
static void
|
||||
gtk_im_context_simple_class_init (GtkIMContextSimpleClass *class)
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <gmodule.h>
|
||||
#include "gtkimmodule.h"
|
||||
#include "gtkimmoduleprivate.h"
|
||||
#include "gtkimcontextsimple.h"
|
||||
#include "gtkmodulesprivate.h"
|
||||
@ -59,594 +60,9 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#undef GDK_DEPRECATED
|
||||
#undef GDK_DEPRECATED_FOR
|
||||
#define GDK_DEPRECATED
|
||||
#define GDK_DEPRECATED_FOR(f)
|
||||
|
||||
/* We need to call getc() a lot in a loop. This is suboptimal,
|
||||
* as getc() does thread locking on the FILE it is given.
|
||||
* To optimize that, lock the file first, then call getc(),
|
||||
* then unlock.
|
||||
* If locking functions are not present in libc, fall back
|
||||
* to the suboptimal getc().
|
||||
*/
|
||||
#if !defined(HAVE_FLOCKFILE) && !defined(HAVE__LOCK_FILE)
|
||||
# define flockfile(f) (void)1
|
||||
# define funlockfile(f) (void)1
|
||||
# define getc_unlocked(f) getc(f)
|
||||
#elif !defined(HAVE_FLOCKFILE) && defined(HAVE__LOCK_FILE)
|
||||
# define flockfile(f) _lock_file(f)
|
||||
# define funlockfile(f) _unlock_file(f)
|
||||
# define getc_unlocked(f) _getc_nolock(f)
|
||||
#endif
|
||||
|
||||
#define SIMPLE_ID "gtk-im-context-simple"
|
||||
#define NONE_ID "gtk-im-context-none"
|
||||
|
||||
/**
|
||||
* GtkIMContextInfo:
|
||||
* @context_id: The unique identification string of the input method.
|
||||
* @context_name: The human-readable name of the input method.
|
||||
* @domain: Translation domain to be used with dgettext()
|
||||
* @domain_dirname: Name of locale directory for use with bindtextdomain()
|
||||
* @default_locales: A colon-separated list of locales where this input method
|
||||
* should be the default. The asterisk “*” sets the default for all locales.
|
||||
*
|
||||
* Bookkeeping information about a loadable input method.
|
||||
*/
|
||||
|
||||
typedef struct _GtkIMModule GtkIMModule;
|
||||
typedef struct _GtkIMModuleClass GtkIMModuleClass;
|
||||
|
||||
#define GTK_TYPE_IM_MODULE (gtk_im_module_get_type ())
|
||||
#define GTK_IM_MODULE(im_module) (G_TYPE_CHECK_INSTANCE_CAST ((im_module), GTK_TYPE_IM_MODULE, GtkIMModule))
|
||||
#define GTK_IS_IM_MODULE(im_module) (G_TYPE_CHECK_INSTANCE_TYPE ((im_module), GTK_TYPE_IM_MODULE))
|
||||
|
||||
struct _GtkIMModule
|
||||
{
|
||||
GTypeModule parent_instance;
|
||||
|
||||
gboolean builtin;
|
||||
|
||||
GModule *library;
|
||||
|
||||
void (*list) (const GtkIMContextInfo ***contexts,
|
||||
guint *n_contexts);
|
||||
void (*init) (GTypeModule *module);
|
||||
void (*exit) (void);
|
||||
GtkIMContext *(*create) (const gchar *context_id);
|
||||
|
||||
GtkIMContextInfo **contexts;
|
||||
guint n_contexts;
|
||||
|
||||
gchar *path;
|
||||
};
|
||||
|
||||
struct _GtkIMModuleClass
|
||||
{
|
||||
GTypeModuleClass parent_class;
|
||||
};
|
||||
|
||||
static GType gtk_im_module_get_type (void);
|
||||
|
||||
static gint n_loaded_contexts = 0;
|
||||
static GHashTable *contexts_hash = NULL;
|
||||
static GSList *modules_list = NULL;
|
||||
|
||||
static gboolean
|
||||
gtk_im_module_load (GTypeModule *module)
|
||||
{
|
||||
GtkIMModule *im_module = GTK_IM_MODULE (module);
|
||||
|
||||
if (!im_module->builtin)
|
||||
{
|
||||
im_module->library = g_module_open (im_module->path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
|
||||
if (!im_module->library)
|
||||
{
|
||||
g_warning ("%s", g_module_error());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* extract symbols from the lib */
|
||||
if (!g_module_symbol (im_module->library, "im_module_init",
|
||||
(gpointer *)&im_module->init) ||
|
||||
!g_module_symbol (im_module->library, "im_module_exit",
|
||||
(gpointer *)&im_module->exit) ||
|
||||
!g_module_symbol (im_module->library, "im_module_list",
|
||||
(gpointer *)&im_module->list) ||
|
||||
!g_module_symbol (im_module->library, "im_module_create",
|
||||
(gpointer *)&im_module->create))
|
||||
{
|
||||
g_warning ("%s", g_module_error());
|
||||
g_module_close (im_module->library);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* call the module's init function to let it */
|
||||
/* setup anything it needs to set up. */
|
||||
im_module->init (module);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_module_unload (GTypeModule *module)
|
||||
{
|
||||
GtkIMModule *im_module = GTK_IM_MODULE (module);
|
||||
|
||||
im_module->exit();
|
||||
|
||||
if (!im_module->builtin)
|
||||
{
|
||||
g_module_close (im_module->library);
|
||||
im_module->library = NULL;
|
||||
|
||||
im_module->init = NULL;
|
||||
im_module->exit = NULL;
|
||||
im_module->list = NULL;
|
||||
im_module->create = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (GtkIMModule, gtk_im_module, G_TYPE_TYPE_MODULE)
|
||||
|
||||
/* This only will ever be called if an error occurs during
|
||||
* initialization
|
||||
*/
|
||||
static void
|
||||
gtk_im_module_finalize (GObject *object)
|
||||
{
|
||||
GtkIMModule *module = GTK_IM_MODULE (object);
|
||||
|
||||
g_free (module->path);
|
||||
|
||||
G_OBJECT_CLASS (gtk_im_module_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_module_class_init (GtkIMModuleClass *class)
|
||||
{
|
||||
GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
module_class->load = gtk_im_module_load;
|
||||
module_class->unload = gtk_im_module_unload;
|
||||
|
||||
gobject_class->finalize = gtk_im_module_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_module_init (GtkIMModule* object)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
free_info (GtkIMContextInfo *info)
|
||||
{
|
||||
g_free ((char *)info->context_id);
|
||||
g_free ((char *)info->context_name);
|
||||
g_free ((char *)info->domain);
|
||||
g_free ((char *)info->domain_dirname);
|
||||
g_free ((char *)info->default_locales);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
static void
|
||||
add_module (GtkIMModule *module, GSList *infos)
|
||||
{
|
||||
GSList *tmp_list = infos;
|
||||
gint i = 0;
|
||||
gint n = g_slist_length (infos);
|
||||
module->contexts = g_new (GtkIMContextInfo *, n);
|
||||
|
||||
while (tmp_list)
|
||||
{
|
||||
GtkIMContextInfo *info = tmp_list->data;
|
||||
|
||||
if (g_hash_table_lookup (contexts_hash, info->context_id))
|
||||
{
|
||||
free_info (info); /* Duplicate */
|
||||
}
|
||||
else
|
||||
{
|
||||
g_hash_table_insert (contexts_hash, (char *)info->context_id, module);
|
||||
module->contexts[i++] = tmp_list->data;
|
||||
n_loaded_contexts++;
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
g_slist_free (infos);
|
||||
module->n_contexts = i;
|
||||
|
||||
modules_list = g_slist_prepend (modules_list, module);
|
||||
}
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
|
||||
static void
|
||||
correct_libdir_prefix (gchar **path)
|
||||
{
|
||||
/* GTK_LIBDIR is the build-time libdir */
|
||||
if (strncmp (*path, GTK_LIBDIR, strlen (GTK_LIBDIR)) == 0)
|
||||
{
|
||||
/* This is an entry put there by make install on the
|
||||
* packager's system. On Windows a prebuilt GTK+
|
||||
* package can be installed in a random
|
||||
* location. The gtk.immodules file distributed in
|
||||
* such a package contains paths from the package
|
||||
* builder's machine. Replace the path with the real
|
||||
* one on this machine.
|
||||
*/
|
||||
gchar *tem = *path;
|
||||
*path = g_strconcat (_gtk_get_libdir (), tem + strlen (GTK_LIBDIR), NULL);
|
||||
g_free (tem);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
correct_localedir_prefix (gchar **path)
|
||||
{
|
||||
/* See above */
|
||||
if (strncmp (*path, GTK_LOCALEDIR, strlen (GTK_LOCALEDIR)) == 0)
|
||||
{
|
||||
gchar *tem = *path;
|
||||
*path = g_strconcat (_gtk_get_localedir (), tem + strlen (GTK_LOCALEDIR), NULL);
|
||||
g_free (tem);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
G_GNUC_UNUSED static GtkIMModule *
|
||||
add_builtin_module (const gchar *module_name,
|
||||
const GtkIMContextInfo **contexts,
|
||||
int n_contexts)
|
||||
{
|
||||
GtkIMModule *module = g_object_new (GTK_TYPE_IM_MODULE, NULL);
|
||||
GSList *infos = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_contexts; i++)
|
||||
{
|
||||
GtkIMContextInfo *info = g_new (GtkIMContextInfo, 1);
|
||||
info->context_id = g_strdup (contexts[i]->context_id);
|
||||
info->context_name = g_strdup (contexts[i]->context_name);
|
||||
info->domain = g_strdup (contexts[i]->domain);
|
||||
info->domain_dirname = g_strdup (contexts[i]->domain_dirname);
|
||||
#ifdef G_OS_WIN32
|
||||
correct_localedir_prefix ((char **) &info->domain_dirname);
|
||||
#endif
|
||||
info->default_locales = g_strdup (contexts[i]->default_locales);
|
||||
infos = g_slist_prepend (infos, info);
|
||||
}
|
||||
|
||||
module->builtin = TRUE;
|
||||
g_type_module_set_name (G_TYPE_MODULE (module), module_name);
|
||||
add_module (module, infos);
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_get_im_module_path:
|
||||
*
|
||||
* Obtains the path in which to look for IM modules. See the documentation
|
||||
* of the `GTK_PATH`
|
||||
* environment variable for more details about looking up modules. This
|
||||
* function is useful solely for utilities supplied with GTK+ and should
|
||||
* not be used by applications under normal circumstances.
|
||||
*
|
||||
* Returns: (type filename): a newly-allocated string containing the
|
||||
* path in which to look for IM modules.
|
||||
*/
|
||||
gchar *
|
||||
gtk_get_im_module_path (void)
|
||||
{
|
||||
gchar **paths = _gtk_get_module_path ("immodules");
|
||||
gchar *result = g_strjoinv (G_SEARCHPATH_SEPARATOR_S, paths);
|
||||
g_strfreev (paths);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_get_im_module_file:
|
||||
*
|
||||
* Obtains the path to the IM modules file. See the documentation
|
||||
* of the `GTK_IM_MODULE_FILE`
|
||||
* environment variable for more details.
|
||||
*
|
||||
* Returns: (type filename): a newly-allocated string containing the
|
||||
* name of the file listing the IM modules available for loading
|
||||
*/
|
||||
gchar *
|
||||
gtk_get_im_module_file (void)
|
||||
{
|
||||
const gchar *var = g_getenv ("GTK_IM_MODULE_FILE");
|
||||
gchar *result = NULL;
|
||||
|
||||
if (var)
|
||||
result = g_strdup (var);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
gchar *path;
|
||||
|
||||
var = g_getenv ("GTK_EXE_PREFIX");
|
||||
|
||||
if (var)
|
||||
path = g_build_filename (var, "lib", "gtk-4.0", GTK_BINARY_VERSION, "immodules.cache", NULL);
|
||||
else
|
||||
path = g_build_filename (_gtk_get_libdir (), "gtk-4.0", GTK_BINARY_VERSION, "immodules.cache", NULL);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_module_initialize (void)
|
||||
{
|
||||
GString *line_buf = g_string_new (NULL);
|
||||
GString *tmp_buf = g_string_new (NULL);
|
||||
gchar *filename = gtk_get_im_module_file();
|
||||
FILE *file;
|
||||
gboolean have_error = FALSE;
|
||||
|
||||
GtkIMModule *module = NULL;
|
||||
GSList *infos = NULL;
|
||||
|
||||
contexts_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
#define do_builtin(m) \
|
||||
{ \
|
||||
const GtkIMContextInfo **contexts; \
|
||||
int n_contexts; \
|
||||
extern void _gtk_immodule_ ## m ## _list (const GtkIMContextInfo ***contexts, \
|
||||
int *n_contexts); \
|
||||
extern void _gtk_immodule_ ## m ## _init (GTypeModule *module); \
|
||||
extern void _gtk_immodule_ ## m ## _exit (void); \
|
||||
extern GtkIMContext *_gtk_immodule_ ## m ## _create (const gchar *context_id); \
|
||||
\
|
||||
_gtk_immodule_ ## m ## _list (&contexts, &n_contexts); \
|
||||
module = add_builtin_module (#m, contexts, n_contexts); \
|
||||
module->init = _gtk_immodule_ ## m ## _init; \
|
||||
module->exit = _gtk_immodule_ ## m ## _exit; \
|
||||
module->create = _gtk_immodule_ ## m ## _create; \
|
||||
module = NULL; \
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_IM_ime
|
||||
do_builtin (ime);
|
||||
#endif
|
||||
#ifdef INCLUDE_IM_xim
|
||||
do_builtin (xim);
|
||||
#endif
|
||||
#ifdef INCLUDE_IM_broadway
|
||||
do_builtin (broadway);
|
||||
#endif
|
||||
#ifdef INCLUDE_IM_wayland
|
||||
do_builtin (wayland);
|
||||
#endif
|
||||
|
||||
#undef do_builtin
|
||||
|
||||
file = g_fopen (filename, "r");
|
||||
if (!file)
|
||||
{
|
||||
/* In case someone wants only the default input method,
|
||||
* we allow no file at all.
|
||||
*/
|
||||
g_string_free (line_buf, TRUE);
|
||||
g_string_free (tmp_buf, TRUE);
|
||||
g_free (filename);
|
||||
return;
|
||||
}
|
||||
|
||||
while (!have_error && gtk_read_line (file, line_buf))
|
||||
{
|
||||
const char *p;
|
||||
|
||||
p = line_buf->str;
|
||||
|
||||
if (!gtk_skip_space (&p))
|
||||
{
|
||||
/* Blank line marking the end of a module
|
||||
*/
|
||||
if (module && *p != '#')
|
||||
{
|
||||
add_module (module, infos);
|
||||
module = NULL;
|
||||
infos = NULL;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!module)
|
||||
{
|
||||
/* Read a module location
|
||||
*/
|
||||
module = g_object_new (GTK_TYPE_IM_MODULE, NULL);
|
||||
|
||||
if (!gtk_scan_string (&p, tmp_buf) || gtk_skip_space (&p))
|
||||
{
|
||||
g_warning ("Error parsing context info in '%s'\n %s", filename, line_buf->str);
|
||||
have_error = TRUE;
|
||||
}
|
||||
|
||||
module->path = g_strdup (tmp_buf->str);
|
||||
#ifdef G_OS_WIN32
|
||||
correct_libdir_prefix (&module->path);
|
||||
#endif
|
||||
g_type_module_set_name (G_TYPE_MODULE (module), module->path);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkIMContextInfo *info = g_new0 (GtkIMContextInfo, 1);
|
||||
|
||||
/* Read information about a context type
|
||||
*/
|
||||
if (!gtk_scan_string (&p, tmp_buf))
|
||||
goto context_error;
|
||||
info->context_id = g_strdup (tmp_buf->str);
|
||||
|
||||
if (!gtk_scan_string (&p, tmp_buf))
|
||||
goto context_error;
|
||||
info->context_name = g_strdup (tmp_buf->str);
|
||||
|
||||
if (!gtk_scan_string (&p, tmp_buf))
|
||||
goto context_error;
|
||||
info->domain = g_strdup (tmp_buf->str);
|
||||
|
||||
if (!gtk_scan_string (&p, tmp_buf))
|
||||
goto context_error;
|
||||
|
||||
info->domain_dirname = g_strdup (tmp_buf->str);
|
||||
#ifdef G_OS_WIN32
|
||||
correct_localedir_prefix ((char **) &info->domain_dirname);
|
||||
#endif
|
||||
|
||||
if (!gtk_scan_string (&p, tmp_buf))
|
||||
goto context_error;
|
||||
info->default_locales = g_strdup (tmp_buf->str);
|
||||
|
||||
if (gtk_skip_space (&p))
|
||||
goto context_error;
|
||||
|
||||
infos = g_slist_prepend (infos, info);
|
||||
continue;
|
||||
|
||||
context_error:
|
||||
g_warning ("Error parsing context info in '%s'\n %s", filename, line_buf->str);
|
||||
have_error = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_error)
|
||||
{
|
||||
g_slist_free_full (infos, (GDestroyNotify)free_info);
|
||||
g_object_unref (module);
|
||||
}
|
||||
else if (module)
|
||||
add_module (module, infos);
|
||||
|
||||
fclose (file);
|
||||
g_string_free (line_buf, TRUE);
|
||||
g_string_free (tmp_buf, TRUE);
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
static gint
|
||||
compare_gtkimcontextinfo_name (const GtkIMContextInfo **a,
|
||||
const GtkIMContextInfo **b)
|
||||
{
|
||||
return g_utf8_collate ((*a)->context_name, (*b)->context_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_im_module_list:
|
||||
* @contexts: location to store an array of pointers to #GtkIMContextInfo
|
||||
* this array should be freed with g_free() when you are finished.
|
||||
* The structures it points are statically allocated and should
|
||||
* not be modified or freed.
|
||||
* @n_contexts: the length of the array stored in @contexts
|
||||
*
|
||||
* List all available types of input method context
|
||||
*/
|
||||
void
|
||||
_gtk_im_module_list (const GtkIMContextInfo ***contexts,
|
||||
guint *n_contexts)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
static
|
||||
#ifndef G_OS_WIN32
|
||||
const
|
||||
#endif
|
||||
GtkIMContextInfo simple_context_info = {
|
||||
SIMPLE_ID,
|
||||
NC_("input method menu", "Simple"),
|
||||
GETTEXT_PACKAGE,
|
||||
#ifdef GTK_LOCALEDIR
|
||||
GTK_LOCALEDIR,
|
||||
#else
|
||||
"",
|
||||
#endif
|
||||
""
|
||||
};
|
||||
|
||||
static
|
||||
#ifndef G_OS_WIN32
|
||||
const
|
||||
#endif
|
||||
GtkIMContextInfo none_context_info = {
|
||||
NONE_ID,
|
||||
NC_("input method menu", "None"),
|
||||
GETTEXT_PACKAGE,
|
||||
#ifdef GTK_LOCALEDIR
|
||||
GTK_LOCALEDIR,
|
||||
#else
|
||||
"",
|
||||
#endif
|
||||
""
|
||||
};
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
static gboolean beenhere = FALSE;
|
||||
#endif
|
||||
|
||||
if (!contexts_hash)
|
||||
gtk_im_module_initialize ();
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
if (!beenhere)
|
||||
{
|
||||
beenhere = TRUE;
|
||||
/* correct_localedir_prefix() requires its parameter to be a
|
||||
* malloced string
|
||||
*/
|
||||
simple_context_info.domain_dirname = g_strdup (simple_context_info.domain_dirname);
|
||||
correct_localedir_prefix ((char **) &simple_context_info.domain_dirname);
|
||||
none_context_info.domain_dirname = g_strdup (none_context_info.domain_dirname);
|
||||
correct_localedir_prefix ((char **) &none_context_info.domain_dirname);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (n_contexts)
|
||||
*n_contexts = n_loaded_contexts + 2;
|
||||
|
||||
if (contexts)
|
||||
{
|
||||
GSList *tmp_list;
|
||||
int i;
|
||||
|
||||
*contexts = g_new (const GtkIMContextInfo *, n_loaded_contexts + 2);
|
||||
|
||||
(*contexts)[n++] = &none_context_info;
|
||||
(*contexts)[n++] = &simple_context_info;
|
||||
|
||||
tmp_list = modules_list;
|
||||
while (tmp_list)
|
||||
{
|
||||
GtkIMModule *module = tmp_list->data;
|
||||
|
||||
for (i=0; i<module->n_contexts; i++)
|
||||
(*contexts)[n++] = module->contexts[i];
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
/* first elements (Simple and None) should always be at top */
|
||||
qsort ((*contexts)+2, n-2, sizeof (GtkIMContextInfo *), (GCompareFunc)compare_gtkimcontextinfo_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_im_module_create:
|
||||
* @context_id: the context ID for the context type to create
|
||||
@ -660,85 +76,54 @@ _gtk_im_module_list (const GtkIMContextInfo ***contexts,
|
||||
GtkIMContext *
|
||||
_gtk_im_module_create (const gchar *context_id)
|
||||
{
|
||||
GtkIMModule *im_module;
|
||||
GIOExtensionPoint *ep;
|
||||
GIOExtension *ext;
|
||||
GType type;
|
||||
GtkIMContext *context = NULL;
|
||||
|
||||
if (strcmp (context_id, NONE_ID) == 0)
|
||||
return NULL;
|
||||
|
||||
if (!contexts_hash)
|
||||
gtk_im_module_initialize ();
|
||||
|
||||
if (strcmp (context_id, SIMPLE_ID) != 0)
|
||||
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)
|
||||
{
|
||||
im_module = g_hash_table_lookup (contexts_hash, context_id);
|
||||
if (!im_module)
|
||||
{
|
||||
g_warning ("Attempt to load unknown IM context type '%s'", context_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_type_module_use (G_TYPE_MODULE (im_module)))
|
||||
{
|
||||
context = im_module->create (context_id);
|
||||
g_type_module_unuse (G_TYPE_MODULE (im_module));
|
||||
type = g_io_extension_get_type (ext);
|
||||
context = g_object_new (type, NULL);
|
||||
}
|
||||
|
||||
if (!context)
|
||||
g_warning ("Loading IM context type '%s' failed", context_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!context)
|
||||
return gtk_im_context_simple_new ();
|
||||
else
|
||||
return context;
|
||||
}
|
||||
|
||||
/* Match @locale against @against.
|
||||
*
|
||||
* 'en_US' against “en_US” => 4
|
||||
* 'en_US' against “en” => 3
|
||||
* 'en', “en_UK” against “en_US” => 2
|
||||
* all locales, against “*” => 1
|
||||
*/
|
||||
static gint
|
||||
match_locale (const gchar *locale,
|
||||
const gchar *against,
|
||||
gint against_len)
|
||||
static gboolean
|
||||
is_platform (const char *context_id)
|
||||
{
|
||||
if (strcmp (against, "*") == 0)
|
||||
return 1;
|
||||
|
||||
if (g_ascii_strcasecmp (locale, against) == 0)
|
||||
return 4;
|
||||
|
||||
if (g_ascii_strncasecmp (locale, against, 2) == 0)
|
||||
return (against_len == 2) ? 3 : 2;
|
||||
|
||||
return 0;
|
||||
return g_strcmp0 (context_id, "wayland") == 0 ||
|
||||
g_strcmp0 (context_id, "broadway") == 0 ||
|
||||
g_strcmp0 (context_id, "xim") == 0 ||
|
||||
g_strcmp0 (context_id, "ime") == 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
match_backend (GtkIMContextInfo *context)
|
||||
match_backend (const char *context_id)
|
||||
{
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (g_strcmp0 (context->context_id, "wayland") == 0)
|
||||
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->context_id, "broadway") == 0)
|
||||
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->context_id, "xim") == 0)
|
||||
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->context_id, "ime") == 0)
|
||||
if (g_strcmp0 (context_id, "ime") == 0)
|
||||
return GDK_IS_WIN32_DISPLAY (gdk_display_get_default ());
|
||||
#endif
|
||||
|
||||
@ -756,12 +141,13 @@ lookup_immodule (gchar **immodules_list)
|
||||
return NONE_ID;
|
||||
else
|
||||
{
|
||||
gboolean found;
|
||||
gchar *context_id;
|
||||
found = g_hash_table_lookup_extended (contexts_hash, *immodules_list,
|
||||
(gpointer *) &context_id, NULL);
|
||||
if (found)
|
||||
return context_id;
|
||||
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++;
|
||||
}
|
||||
@ -769,67 +155,6 @@ lookup_immodule (gchar **immodules_list)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
|
||||
/* max size for LOCALE_SISO639LANGNAME and LOCALE_SISO3166CTRYNAME is 9 */
|
||||
#define MAX_NAME_SIZE 9
|
||||
|
||||
static gchar *
|
||||
get_current_input_language (void)
|
||||
{
|
||||
LCID lcid;
|
||||
LANGID langid;
|
||||
HKL kblayout;
|
||||
int name_size;
|
||||
wchar_t name[MAX_NAME_SIZE];
|
||||
gchar *language;
|
||||
gchar *country;
|
||||
gchar *full;
|
||||
|
||||
/* Current thread's keyboard layout */
|
||||
kblayout = GetKeyboardLayout(0);
|
||||
/* lowest word in the HKL is the LANGID */
|
||||
langid = LOWORD (kblayout);
|
||||
/* LCID is the LANGID without order */
|
||||
lcid = langid;
|
||||
|
||||
/* Get Language ID */
|
||||
name_size = GetLocaleInfoW (lcid, LOCALE_SISO639LANGNAME, NULL, 0);
|
||||
if (name_size <= 1)
|
||||
return NULL;
|
||||
|
||||
g_assert (name_size <= MAX_NAME_SIZE);
|
||||
GetLocaleInfoW (lcid, LOCALE_SISO639LANGNAME, name, name_size);
|
||||
|
||||
language = g_utf16_to_utf8 (name, name_size, NULL, NULL, NULL);
|
||||
if (!language)
|
||||
return NULL;
|
||||
|
||||
if (SUBLANGID (langid) == SUBLANG_NEUTRAL)
|
||||
return language;
|
||||
|
||||
/* Get Country ID */
|
||||
name_size = GetLocaleInfoW (lcid, LOCALE_SISO3166CTRYNAME, NULL, 0);
|
||||
if (name_size <= 1)
|
||||
return language;
|
||||
|
||||
g_assert (name_size <= MAX_NAME_SIZE);
|
||||
GetLocaleInfoW (lcid, LOCALE_SISO3166CTRYNAME, name, name_size);
|
||||
|
||||
country = g_utf16_to_utf8 (name, name_size, NULL, NULL, NULL);
|
||||
if (!country)
|
||||
return language;
|
||||
|
||||
full = g_strdup_printf ("%s_%s", language, country);
|
||||
|
||||
g_free (language);
|
||||
g_free (country);
|
||||
|
||||
return full;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* _gtk_im_module_get_default_context_id:
|
||||
*
|
||||
@ -841,20 +166,15 @@ get_current_input_language (void)
|
||||
const gchar *
|
||||
_gtk_im_module_get_default_context_id (void)
|
||||
{
|
||||
GSList *tmp_list;
|
||||
const gchar *context_id = NULL;
|
||||
gint best_goodness = 0;
|
||||
gint i;
|
||||
gchar *tmp_locale, *tmp, **immodules;
|
||||
const gchar *envvar;
|
||||
GtkSettings *settings;
|
||||
|
||||
if (!contexts_hash)
|
||||
gtk_im_module_initialize ();
|
||||
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);
|
||||
@ -868,6 +188,8 @@ _gtk_im_module_get_default_context_id (void)
|
||||
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);
|
||||
@ -877,57 +199,68 @@ _gtk_im_module_get_default_context_id (void)
|
||||
return context_id;
|
||||
}
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
/* Read current input locale from the current keyboard info */
|
||||
tmp_locale = get_current_input_language ();
|
||||
if (!tmp_locale)
|
||||
/* Default to system locale when input language is unknown */
|
||||
tmp_locale = _gtk_get_lc_ctype ();
|
||||
#else
|
||||
tmp_locale = _gtk_get_lc_ctype ();
|
||||
#endif
|
||||
GIOExtensionPoint *ep;
|
||||
GList *list, *l;
|
||||
|
||||
/* Strip the locale code down to the essentials
|
||||
*/
|
||||
tmp = strchr (tmp_locale, '.');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
tmp = strchr (tmp_locale, '@');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
tmp_list = modules_list;
|
||||
while (tmp_list)
|
||||
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)
|
||||
{
|
||||
GtkIMModule *module = tmp_list->data;
|
||||
GIOExtension *ext = l->data;
|
||||
const char *context_id;
|
||||
|
||||
for (i = 0; i < module->n_contexts; i++)
|
||||
{
|
||||
const gchar *p;
|
||||
context_id = g_io_extension_get_name (ext);
|
||||
if (match_backend (context_id))
|
||||
return context_id;
|
||||
|
||||
if (!match_backend (module->contexts[i]))
|
||||
continue;
|
||||
|
||||
p = module->contexts[i]->default_locales;
|
||||
while (p)
|
||||
{
|
||||
const gchar *q = strchr (p, ':');
|
||||
gint goodness = match_locale (tmp_locale, p, q ? q - p : strlen (p));
|
||||
|
||||
if (goodness > best_goodness)
|
||||
{
|
||||
context_id = module->contexts[i]->context_id;
|
||||
best_goodness = goodness;
|
||||
// FIXME: locale matching
|
||||
if (!is_platform (context_id))
|
||||
return context_id;
|
||||
}
|
||||
|
||||
p = q ? q + 1 : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
g_free (tmp_locale);
|
||||
|
||||
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 ());
|
||||
// other builtin im context types go here
|
||||
|
||||
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);
|
||||
|
||||
{
|
||||
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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,15 +20,12 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* The following entry points are exported by each input method module
|
||||
*/
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
void im_module_list (const GtkIMContextInfo ***contexts,
|
||||
guint *n_contexts);
|
||||
void im_module_init (GtkModule *module);
|
||||
void im_module_exit (void);
|
||||
GtkIMContext *im_module_create (const gchar *context_id);
|
||||
*/
|
||||
void gtk_im_modules_init (void);
|
||||
|
||||
#define GTK_IM_MODULE_EXTENSION_POINT_NAME "gtk-im-module"
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_IM_MODULE_H__ */
|
||||
|
@ -20,21 +20,12 @@
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include "gtkimcontext.h"
|
||||
#include "gtkimcontextinfo.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _gtk_im_module_list (const GtkIMContextInfo ***contexts,
|
||||
guint *n_contexts);
|
||||
GtkIMContext * _gtk_im_module_create (const gchar *context_id);
|
||||
const gchar * _gtk_im_module_get_default_context_id (void);
|
||||
|
||||
/* Needs to be exported API for gtk-queryimmodules */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gchar * gtk_get_im_module_path (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gchar * gtk_get_im_module_file (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_IM_MODULE_PRIVATE_H__ */
|
||||
|
@ -130,6 +130,7 @@
|
||||
#include "gtkwindowprivate.h"
|
||||
#include "gtkwindowgroup.h"
|
||||
#include "gtkprintbackend.h"
|
||||
#include "gtkimmodule.h"
|
||||
|
||||
#include "a11y/gtkaccessibility.h"
|
||||
|
||||
@ -628,6 +629,8 @@ gettext_initialization (void)
|
||||
static void
|
||||
default_display_notify_cb (GdkDisplayManager *dm)
|
||||
{
|
||||
gtk_print_backends_init ();
|
||||
gtk_im_modules_init ();
|
||||
_gtk_accessibility_init ();
|
||||
debug_flags[0].display = gdk_display_get_default ();
|
||||
}
|
||||
@ -656,8 +659,6 @@ do_post_parse_initialization (void)
|
||||
|
||||
_gtk_accel_map_init ();
|
||||
|
||||
gtk_print_backends_init ();
|
||||
|
||||
gtk_initialized = TRUE;
|
||||
|
||||
display_manager = gdk_display_manager_get ();
|
||||
|
@ -464,7 +464,6 @@ gtk_public_headers = files([
|
||||
'gtkiconview.h',
|
||||
'gtkimage.h',
|
||||
'gtkimcontext.h',
|
||||
'gtkimcontextinfo.h',
|
||||
'gtkimcontextsimple.h',
|
||||
'gtkimmodule.h',
|
||||
'gtkimmulticontext.h',
|
||||
@ -893,7 +892,7 @@ foreach m: dyn_im_method_defs # populated in modules/input/meson.build
|
||||
im_args = m[2]
|
||||
im_libs = m[3]
|
||||
|
||||
shared_module('im-@0@'.format(im_name), im_srcs, gen_headers,
|
||||
shared_module('libim-@0@'.format(im_name), im_srcs, gen_headers,
|
||||
c_args: im_args,
|
||||
include_directories: [confinc, gdkinc, gtkinc],
|
||||
dependencies: gtk_deps + im_libs,
|
||||
@ -1045,7 +1044,6 @@ gtk_tools = [
|
||||
['gtk4-builder-tool', ['gtk-builder-tool.c']],
|
||||
['gtk4-update-icon-cache', ['updateiconcache.c', 'gtkiconcachevalidator.c']],
|
||||
['gtk4-encode-symbolic-svg', ['encodesymbolic.c', 'gdkpixbufutils.c']],
|
||||
['gtk4-query-immodules', ['queryimmodules.c', 'gtkutils.c']],
|
||||
]
|
||||
|
||||
if os_unix
|
||||
|
@ -1,247 +0,0 @@
|
||||
/* GTK+
|
||||
* querymodules.c:
|
||||
*
|
||||
* Copyright (C) 2000-2010 Red Hat Software
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gprintf.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_LA_MODULES
|
||||
#define SOEXT ".la"
|
||||
#else
|
||||
#define SOEXT ("." G_MODULE_SUFFIX)
|
||||
#endif
|
||||
|
||||
#include "gtk/gtkimcontextinfo.h"
|
||||
#include "gtk/gtkimmoduleprivate.h"
|
||||
#include "gtk/gtkversion.h"
|
||||
#include "gtk/gtkutilsprivate.h"
|
||||
|
||||
static void
|
||||
escape_string (GString *contents, const char *str)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
char c = *str++;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\0':
|
||||
goto done;
|
||||
case '\n':
|
||||
g_string_append (contents, "\\n");
|
||||
break;
|
||||
case '\"':
|
||||
g_string_append (contents, "\\\"");
|
||||
break;
|
||||
#ifdef G_OS_WIN32
|
||||
/* Replace backslashes in path with forward slashes, so that
|
||||
* it reads in without problems.
|
||||
*/
|
||||
case '\\':
|
||||
g_string_append (contents, "/");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
g_string_append_c (contents, c);
|
||||
}
|
||||
}
|
||||
|
||||
done:;
|
||||
}
|
||||
|
||||
static void
|
||||
print_escaped (GString *contents, const char *str)
|
||||
{
|
||||
g_string_append_c (contents, '"');
|
||||
escape_string (contents, str);
|
||||
g_string_append_c (contents, '"');
|
||||
g_string_append_c (contents, ' ');
|
||||
}
|
||||
|
||||
static gboolean
|
||||
query_module (const char *dir, const char *name, GString *contents)
|
||||
{
|
||||
void (*list) (const GtkIMContextInfo ***contexts,
|
||||
guint *n_contexts);
|
||||
|
||||
gpointer list_ptr;
|
||||
gpointer init_ptr;
|
||||
gpointer exit_ptr;
|
||||
gpointer create_ptr;
|
||||
|
||||
GModule *module;
|
||||
gchar *path;
|
||||
gboolean error = FALSE;
|
||||
|
||||
if (g_path_is_absolute (name))
|
||||
path = g_strdup (name);
|
||||
else
|
||||
path = g_build_filename (dir, name, NULL);
|
||||
|
||||
module = g_module_open (path, 0);
|
||||
|
||||
if (!module)
|
||||
{
|
||||
g_fprintf (stderr, "Cannot load module %s: %s\n", path, g_module_error());
|
||||
error = TRUE;
|
||||
}
|
||||
|
||||
if (module &&
|
||||
g_module_symbol (module, "im_module_list", &list_ptr) &&
|
||||
g_module_symbol (module, "im_module_init", &init_ptr) &&
|
||||
g_module_symbol (module, "im_module_exit", &exit_ptr) &&
|
||||
g_module_symbol (module, "im_module_create", &create_ptr))
|
||||
{
|
||||
const GtkIMContextInfo **contexts;
|
||||
guint n_contexts;
|
||||
int i;
|
||||
|
||||
list = list_ptr;
|
||||
|
||||
print_escaped (contents, path);
|
||||
g_string_append_c (contents, '\n');
|
||||
|
||||
(*list) (&contexts, &n_contexts);
|
||||
|
||||
for (i = 0; i < n_contexts; i++)
|
||||
{
|
||||
print_escaped (contents, contexts[i]->context_id);
|
||||
print_escaped (contents, contexts[i]->context_name);
|
||||
print_escaped (contents, contexts[i]->domain);
|
||||
print_escaped (contents, contexts[i]->domain_dirname);
|
||||
print_escaped (contents, contexts[i]->default_locales);
|
||||
g_string_append_c (contents, '\n');
|
||||
}
|
||||
g_string_append_c (contents, '\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
g_fprintf (stderr, "%s does not export GTK+ IM module API: %s\n", path,
|
||||
g_module_error ());
|
||||
error = TRUE;
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
if (module)
|
||||
g_module_close (module);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
char *cwd;
|
||||
int i;
|
||||
char *path;
|
||||
gboolean error = FALSE;
|
||||
gchar *cache_file = NULL;
|
||||
gint first_file = 1;
|
||||
GString *contents;
|
||||
|
||||
if (argc > 1 && strcmp (argv[1], "--update-cache") == 0)
|
||||
{
|
||||
cache_file = gtk_get_im_module_file ();
|
||||
first_file = 2;
|
||||
}
|
||||
|
||||
contents = g_string_new ("");
|
||||
g_string_append_printf (contents,
|
||||
"# GTK+ Input Method Modules file\n"
|
||||
"# Automatically generated file, do not edit\n"
|
||||
"# Created by %s from gtk+-%d.%d.%d\n"
|
||||
"#\n",
|
||||
argv[0],
|
||||
GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
|
||||
|
||||
if (argc == first_file) /* No file arguments given */
|
||||
{
|
||||
char **dirs;
|
||||
GHashTable *dirs_done;
|
||||
|
||||
path = gtk_get_im_module_path ();
|
||||
|
||||
g_string_append_printf (contents, "# ModulesPath = %s\n#\n", path);
|
||||
|
||||
dirs = gtk_split_file_list (path);
|
||||
dirs_done = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
|
||||
|
||||
for (i = 0; dirs[i]; i++)
|
||||
if (!g_hash_table_lookup (dirs_done, dirs[i]))
|
||||
{
|
||||
GDir *dir = g_dir_open (dirs[i], 0, NULL);
|
||||
if (dir)
|
||||
{
|
||||
const char *dent;
|
||||
GList *list = NULL, *iterator = NULL;
|
||||
|
||||
while ((dent = g_dir_read_name (dir)))
|
||||
list = g_list_prepend (list, g_strdup (dent));
|
||||
|
||||
list = g_list_sort (list, (GCompareFunc) strcmp);
|
||||
for (iterator = list; iterator; iterator = iterator->next)
|
||||
{
|
||||
if (g_str_has_suffix (iterator->data, SOEXT))
|
||||
error |= query_module (dirs[i], iterator->data, contents);
|
||||
}
|
||||
|
||||
g_list_free_full (list, g_free);
|
||||
g_dir_close (dir);
|
||||
}
|
||||
|
||||
g_hash_table_insert (dirs_done, dirs[i], GUINT_TO_POINTER (TRUE));
|
||||
}
|
||||
|
||||
g_hash_table_destroy (dirs_done);
|
||||
}
|
||||
else
|
||||
{
|
||||
cwd = g_get_current_dir ();
|
||||
|
||||
for (i = first_file; i < argc; i++)
|
||||
error |= query_module (cwd, argv[i], contents);
|
||||
|
||||
g_free (cwd);
|
||||
}
|
||||
|
||||
if (!error)
|
||||
{
|
||||
if (cache_file)
|
||||
{
|
||||
GError *err;
|
||||
|
||||
err = NULL;
|
||||
if (!g_file_set_contents (cache_file, contents->str, -1, &err))
|
||||
{
|
||||
g_fprintf (stderr, "%s\n", err->message);
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
g_print ("%s\n", contents->str);
|
||||
}
|
||||
|
||||
return error ? 1 : 0;
|
||||
}
|
@ -125,29 +125,38 @@ static void cb_client_widget_hierarchy_changed (GtkWidget *widget,
|
||||
GtkWidget *widget2,
|
||||
GtkIMContextIME *context_ime);
|
||||
|
||||
GType gtk_type_im_context_ime = 0;
|
||||
static GObjectClass *parent_class;
|
||||
#define GTK_TYPE_IM_CONTEXT_IME (gtk_im_context_ime_get_type ())
|
||||
#define GTK_IM_CONTEXT_IME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_IME, GtkIMContextIME))
|
||||
|
||||
G_DEFINE_DYNAMIC_TYPE (GtkIMContextIME, gtk_im_context_ime, GTK_TYPE_IM_CONTEXT)
|
||||
|
||||
void
|
||||
gtk_im_context_ime_register_type (GTypeModule *type_module)
|
||||
g_io_module_load (GIOModule *module)
|
||||
{
|
||||
const GTypeInfo im_context_ime_info = {
|
||||
sizeof (GtkIMContextIMEClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) gtk_im_context_ime_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (GtkIMContextIME),
|
||||
0,
|
||||
(GInstanceInitFunc) gtk_im_context_ime_init,
|
||||
g_type_module_use (G_TYPE_MODULE (module));
|
||||
|
||||
gtk_im_context_ime_register_type (G_TYPE_MODULE (module));
|
||||
|
||||
g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME,
|
||||
GTK_TYPE_IM_CONTEXT_IME,
|
||||
"ime",
|
||||
10);
|
||||
}
|
||||
|
||||
void
|
||||
g_io_module_unload (GIOModule *module)
|
||||
{
|
||||
}
|
||||
|
||||
char **
|
||||
g_io_module_query (void)
|
||||
{
|
||||
char *eps[] = {
|
||||
GTK_IM_MODULE_EXTENSION_POINT_NAME,
|
||||
NULL
|
||||
};
|
||||
|
||||
gtk_type_im_context_ime =
|
||||
g_type_module_register_type (type_module,
|
||||
GTK_TYPE_IM_CONTEXT,
|
||||
"GtkIMContextIME", &im_context_ime_info, 0);
|
||||
return g_strdupv (eps);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -156,8 +165,6 @@ gtk_im_context_ime_class_init (GtkIMContextIMEClass *class)
|
||||
GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (class);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
gobject_class->finalize = gtk_im_context_ime_finalize;
|
||||
gobject_class->dispose = gtk_im_context_ime_dispose;
|
||||
gobject_class->set_property = gtk_im_context_ime_set_property;
|
||||
@ -173,6 +180,10 @@ gtk_im_context_ime_class_init (GtkIMContextIMEClass *class)
|
||||
im_context_class->set_use_preedit = gtk_im_context_ime_set_use_preedit;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_ime_class_finalize (GtkIMContextIMEClass *class)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_ime_init (GtkIMContextIME *context_ime)
|
||||
|
@ -21,8 +21,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
extern GType gtk_type_im_context_ime;
|
||||
|
||||
#define GTK_TYPE_IM_CONTEXT_IME gtk_type_im_context_ime
|
||||
#define GTK_IM_CONTEXT_IME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_IME, GtkIMContextIME))
|
||||
#define GTK_IM_CONTEXT_IME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_IM_CONTEXT_IME, GtkIMContextIMEClass))
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gtkimmodule.h"
|
||||
#include "gtkimcontextxim.h"
|
||||
|
||||
#include "gtk/gtkintl.h"
|
||||
@ -145,38 +146,43 @@ static void xim_info_display_closed (GdkDisplay *display,
|
||||
gboolean is_error,
|
||||
GtkXIMInfo *info);
|
||||
|
||||
static GObjectClass *parent_class;
|
||||
G_DEFINE_DYNAMIC_TYPE (GtkIMContextXIM, gtk_im_context_xim, GTK_TYPE_IM_CONTEXT)
|
||||
|
||||
GType gtk_type_im_context_xim = 0;
|
||||
void
|
||||
g_io_module_load (GIOModule *module)
|
||||
{
|
||||
g_type_module_use (G_TYPE_MODULE (module));
|
||||
|
||||
g_print ("load io module for x11\n");
|
||||
gtk_im_context_xim_register_type (G_TYPE_MODULE (module));
|
||||
|
||||
g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME,
|
||||
GTK_TYPE_IM_CONTEXT_XIM,
|
||||
"xim",
|
||||
10);
|
||||
}
|
||||
|
||||
void
|
||||
g_io_module_unload (GIOModule *module)
|
||||
{
|
||||
}
|
||||
|
||||
char **
|
||||
g_io_module_query (void)
|
||||
{
|
||||
char *eps[] = {
|
||||
GTK_IM_MODULE_EXTENSION_POINT_NAME,
|
||||
NULL
|
||||
};
|
||||
|
||||
return g_strdupv (eps);
|
||||
}
|
||||
|
||||
static GSList *open_ims = NULL;
|
||||
|
||||
/* List of status windows for different toplevels */
|
||||
static GSList *status_windows = NULL;
|
||||
|
||||
void
|
||||
gtk_im_context_xim_register_type (GTypeModule *type_module)
|
||||
{
|
||||
const GTypeInfo im_context_xim_info =
|
||||
{
|
||||
sizeof (GtkIMContextXIMClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) gtk_im_context_xim_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (GtkIMContextXIM),
|
||||
0,
|
||||
(GInstanceInitFunc) gtk_im_context_xim_init,
|
||||
};
|
||||
|
||||
gtk_type_im_context_xim =
|
||||
g_type_module_register_type (type_module,
|
||||
GTK_TYPE_IM_CONTEXT,
|
||||
"GtkIMContextXIM",
|
||||
&im_context_xim_info, 0);
|
||||
}
|
||||
|
||||
#define PREEDIT_MASK (XIMPreeditCallbacks | XIMPreeditPosition | \
|
||||
XIMPreeditArea | XIMPreeditNothing | XIMPreeditNone)
|
||||
#define STATUS_MASK (XIMStatusCallbacks | XIMStatusArea | \
|
||||
@ -475,8 +481,6 @@ gtk_im_context_xim_class_init (GtkIMContextXIMClass *class)
|
||||
GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (class);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
im_context_class->set_client_widget = gtk_im_context_xim_set_client_widget;
|
||||
im_context_class->filter_keypress = gtk_im_context_xim_filter_keypress;
|
||||
im_context_class->reset = gtk_im_context_xim_reset;
|
||||
@ -488,6 +492,11 @@ gtk_im_context_xim_class_init (GtkIMContextXIMClass *class)
|
||||
gobject_class->finalize = gtk_im_context_xim_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_xim_class_finalize (GtkIMContextXIMClass *class)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_xim_init (GtkIMContextXIM *im_context_xim)
|
||||
{
|
||||
@ -534,7 +543,7 @@ gtk_im_context_xim_finalize (GObject *obj)
|
||||
g_free (context_xim->locale);
|
||||
g_free (context_xim->mb_charset);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (obj);
|
||||
G_OBJECT_CLASS (gtk_im_context_xim_parent_class)->finalize (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -23,9 +23,7 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
extern GType gtk_type_im_context_xim;
|
||||
|
||||
#define GTK_TYPE_IM_CONTEXT_XIM (gtk_type_im_context_xim)
|
||||
#define GTK_TYPE_IM_CONTEXT_XIM (gtk_im_context_xim_get_type ())
|
||||
#define GTK_IM_CONTEXT_XIM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIM))
|
||||
#define GTK_IM_CONTEXT_XIM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))
|
||||
#define GTK_IS_IM_CONTEXT_XIM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_IM_CONTEXT_XIM))
|
||||
@ -41,7 +39,6 @@ struct _GtkIMContextXIMClass
|
||||
GtkIMContextClass parent_class;
|
||||
};
|
||||
|
||||
void gtk_im_context_xim_register_type (GTypeModule *type_module);
|
||||
GtkIMContext *gtk_im_context_xim_new (void);
|
||||
|
||||
void gtk_im_context_xim_shutdown (void);
|
||||
|
@ -27,9 +27,9 @@
|
||||
|
||||
#include "gdk/broadway/gdkbroadway.h"
|
||||
|
||||
#define GTK_IM_CONTEXT_TYPE_BROADWAY (type_broadway)
|
||||
#define GTK_IM_CONTEXT_BROADWAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_IM_CONTEXT_TYPE_BROADWAY, GtkIMContextBroadway))
|
||||
#define GTK_IM_CONTEXT_BROADWAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_IM_CONTEXT_TYPE_BROADWAY, GtkIMContextBroadwayClass))
|
||||
#define GTK_TYPE_IM_CONTEXT_BROADWAY (gtk_im_context_broadway_get_type ())
|
||||
#define GTK_IM_CONTEXT_BROADWAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_BROADWAY, GtkIMContextBroadway))
|
||||
#define GTK_IM_CONTEXT_BROADWAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_IM_CONTEXT_BROADWAY, GtkIMContextBroadwayClass))
|
||||
|
||||
typedef struct _GtkIMContextBroadway
|
||||
{
|
||||
@ -42,28 +42,38 @@ typedef struct _GtkIMContextBroadwayClass
|
||||
GtkIMContextSimpleClass parent_class;
|
||||
} GtkIMContextBroadwayClass;
|
||||
|
||||
GType type_broadway = 0;
|
||||
static GObjectClass *parent_class;
|
||||
G_DEFINE_DYNAMIC_TYPE (GtkIMContextBroadway, gtk_im_context_broadway, GTK_TYPE_IM_CONTEXT_SIMPLE)
|
||||
|
||||
static const GtkIMContextInfo imbroadway_info =
|
||||
void
|
||||
g_io_module_load (GIOModule *module)
|
||||
{
|
||||
"broadway", /* ID */
|
||||
NC_("input method menu", "Broadway"), /* Human readable name */
|
||||
GETTEXT_PACKAGE, /* Translation domain */
|
||||
GTK_LOCALEDIR, /* Dir for bindtextdomain (not strictly needed for "gtk+") */
|
||||
"", /* Languages for which this module is the default */
|
||||
};
|
||||
g_type_module_use (G_TYPE_MODULE (module));
|
||||
|
||||
static const GtkIMContextInfo *info_list[] =
|
||||
g_print ("load io module for broadway\n");
|
||||
gtk_im_context_broadway_register_type (G_TYPE_MODULE (module));
|
||||
|
||||
g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME,
|
||||
GTK_TYPE_IM_CONTEXT_BROADWAY,
|
||||
"broadway",
|
||||
10);
|
||||
}
|
||||
|
||||
void
|
||||
g_io_module_unload (GIOModule *module)
|
||||
{
|
||||
&imbroadway_info,
|
||||
};
|
||||
}
|
||||
|
||||
char **
|
||||
g_io_module_query (void)
|
||||
{
|
||||
char *eps[] = {
|
||||
GTK_IM_MODULE_EXTENSION_POINT_NAME,
|
||||
NULL
|
||||
};
|
||||
|
||||
return g_strdupv (eps);
|
||||
}
|
||||
|
||||
#ifndef INCLUDE_IM_broadway
|
||||
#define MODULE_ENTRY(type,function) G_MODULE_EXPORT type im_module_ ## function
|
||||
#else
|
||||
#define MODULE_ENTRY(type, function) type _gtk_immodule_broadway_ ## function
|
||||
#endif
|
||||
|
||||
static void
|
||||
broadway_set_client_widget (GtkIMContext *context, GtkWidget *widget)
|
||||
@ -100,9 +110,9 @@ broadway_focus_out (GtkIMContext *context)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_broadway_class_init (GtkIMContextClass *klass)
|
||||
gtk_im_context_broadway_class_init (GtkIMContextBroadwayClass *class)
|
||||
{
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
GtkIMContextClass *klass = GTK_IM_CONTEXT_CLASS (class);
|
||||
|
||||
klass->focus_in = broadway_focus_in;
|
||||
klass->focus_out = broadway_focus_out;
|
||||
@ -110,52 +120,11 @@ gtk_im_context_broadway_class_init (GtkIMContextClass *klass)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_broadway_init (GtkIMContext *im_context)
|
||||
gtk_im_context_broadway_class_finalize (GtkIMContextBroadwayClass *class)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_broadway_register_type (GTypeModule *module)
|
||||
{
|
||||
const GTypeInfo object_info =
|
||||
{
|
||||
sizeof (GtkIMContextBroadwayClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) gtk_im_context_broadway_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (GtkIMContextBroadway),
|
||||
0,
|
||||
(GInstanceInitFunc) gtk_im_context_broadway_init,
|
||||
};
|
||||
|
||||
type_broadway =
|
||||
g_type_module_register_type (module,
|
||||
GTK_TYPE_IM_CONTEXT_SIMPLE,
|
||||
"GtkIMContextBroadway",
|
||||
&object_info, 0);
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, init) (GTypeModule * module)
|
||||
{
|
||||
gtk_im_context_broadway_register_type (module);
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, exit) (void)
|
||||
gtk_im_context_broadway_init (GtkIMContextBroadway *im_context)
|
||||
{
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, list) (const GtkIMContextInfo *** contexts, int *n_contexts)
|
||||
{
|
||||
*contexts = info_list;
|
||||
*n_contexts = G_N_ELEMENTS (info_list);
|
||||
}
|
||||
|
||||
MODULE_ENTRY (GtkIMContext *, create) (const gchar * context_id)
|
||||
{
|
||||
if (!strcmp (context_id, "broadway"))
|
||||
return g_object_new (type_broadway, NULL);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* gtkimmoduleime
|
||||
* Copyright (C) 2003 Takuro Ashie
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "gtk/gtkintl.h"
|
||||
#include "gtk/gtkimmodule.h"
|
||||
#include "gtkimcontextime.h"
|
||||
|
||||
static const GtkIMContextInfo ime_info = {
|
||||
"ime",
|
||||
NC_("input method menu", "Windows IME"),
|
||||
GETTEXT_PACKAGE,
|
||||
"",
|
||||
"ja:ko:zh",
|
||||
};
|
||||
|
||||
static const GtkIMContextInfo *info_list[] = {
|
||||
&ime_info,
|
||||
};
|
||||
|
||||
#ifndef INCLUDE_IM_ime
|
||||
#define MODULE_ENTRY(type,function) G_MODULE_EXPORT type im_module_ ## function
|
||||
#else
|
||||
#define MODULE_ENTRY(type, function) type _gtk_immodule_ime_ ## function
|
||||
#endif
|
||||
|
||||
MODULE_ENTRY (void, init) (GTypeModule * module)
|
||||
{
|
||||
gtk_im_context_ime_register_type (module);
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, exit) (void)
|
||||
{
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, list) (const GtkIMContextInfo *** contexts, int *n_contexts)
|
||||
{
|
||||
*contexts = info_list;
|
||||
*n_contexts = G_N_ELEMENTS (info_list);
|
||||
}
|
||||
|
||||
MODULE_ENTRY (GtkIMContext *, create) (const gchar * context_id)
|
||||
{
|
||||
g_return_val_if_fail (context_id, NULL);
|
||||
|
||||
if (!strcmp (context_id, "ime"))
|
||||
return g_object_new (GTK_TYPE_IM_CONTEXT_IME, NULL);
|
||||
else
|
||||
return NULL;
|
||||
}
|
@ -32,6 +32,7 @@
|
||||
#define GTK_IM_CONTEXT_QUARTZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_IM_CONTEXT_TYPE_QUARTZ, GtkIMContextQuartz))
|
||||
#define GTK_IM_CONTEXT_QUARTZ_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_IM_CONTEXT_TYPE_QUARTZ, GtkIMContextQuartzClass))
|
||||
|
||||
|
||||
typedef struct _GtkIMContextQuartz
|
||||
{
|
||||
GtkIMContext parent;
|
||||
@ -49,28 +50,41 @@ typedef struct _GtkIMContextQuartzClass
|
||||
GtkIMContextClass parent_class;
|
||||
} GtkIMContextQuartzClass;
|
||||
|
||||
GType type_quartz = 0;
|
||||
static GObjectClass *parent_class;
|
||||
G_DEFINE_DYNAMIC_TYPE (GtkIMContextQuartz, gtk_im_context_quartz, GTK_TYPE_IM_CONTEXT)
|
||||
|
||||
static const GtkIMContextInfo imquartz_info =
|
||||
void
|
||||
g_io_module_load (GIOModule *module)
|
||||
{
|
||||
g_type_module_use (G_TYPE_MODULE (module));
|
||||
|
||||
g_print ("load io module for quartz\n");
|
||||
gtk_im_context_quartz_register_type (G_TYPE_MODULE (module));
|
||||
|
||||
g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME,
|
||||
GTK_TYPE_IM_CONTEXT_BROADWAY,
|
||||
"quartz",
|
||||
NC_("input method menu", "Mac OS X Quartz"),
|
||||
GETTEXT_PACKAGE,
|
||||
GTK_LOCALEDIR,
|
||||
"ja:ko:zh:*",
|
||||
};
|
||||
10);
|
||||
}
|
||||
|
||||
static const GtkIMContextInfo *info_list[] =
|
||||
void
|
||||
g_io_module_unload (GIOModule *module)
|
||||
{
|
||||
&imquartz_info,
|
||||
};
|
||||
}
|
||||
|
||||
char **
|
||||
g_io_module_query (void)
|
||||
{
|
||||
char *eps[] = {
|
||||
GTK_IM_MODULE_EXTENSION_POINT_NAME,
|
||||
NULL
|
||||
};
|
||||
|
||||
return g_strdupv (eps);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef INCLUDE_IM_quartz
|
||||
#define MODULE_ENTRY(type,function) G_MODULE_EXPORT type im_module_ ## function
|
||||
#else
|
||||
#define MODULE_ENTRY(type, function) type _gtk_immodule_quartz_ ## function
|
||||
#endif
|
||||
|
||||
static void
|
||||
quartz_get_preedit_string (GtkIMContext *context,
|
||||
@ -359,16 +373,16 @@ imquartz_finalize (GObject *obj)
|
||||
g_signal_handlers_disconnect_by_func (qc->slave, (gpointer)commit_cb, qc);
|
||||
g_object_unref (qc->slave);
|
||||
|
||||
parent_class->finalize (obj);
|
||||
gtk_im_context_quartz_parent_class->finalize (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_quartz_class_init (GtkIMContextClass *klass)
|
||||
gtk_im_context_quartz_class_init (GtkIMContextQuartzClass *class)
|
||||
{
|
||||
GTK_NOTE (MISC, g_print ("gtk_im_context_quartz_class_init\n"));
|
||||
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
GtkIMContextClass *klass = GTK_IM_CONTEXT_CLASS (class);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
klass->get_preedit_string = quartz_get_preedit_string;
|
||||
klass->filter_keypress = quartz_filter_keypress;
|
||||
@ -383,11 +397,15 @@ gtk_im_context_quartz_class_init (GtkIMContextClass *klass)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_quartz_init (GtkIMContext *im_context)
|
||||
gtk_im_context_quartz_class_finalize (GtkIMContextQuartzClass *class)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_quartz_init (GtkIMContextQuartz *qc)
|
||||
{
|
||||
GTK_NOTE (MISC, g_print ("gtk_im_context_quartz_init\n"));
|
||||
|
||||
GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (im_context);
|
||||
qc->preedit_str = g_strdup ("");
|
||||
qc->cursor_index = 0;
|
||||
qc->selected_len = 0;
|
||||
@ -397,54 +415,3 @@ gtk_im_context_quartz_init (GtkIMContext *im_context)
|
||||
qc->slave = g_object_new (GTK_TYPE_IM_CONTEXT_SIMPLE, NULL);
|
||||
g_signal_connect (G_OBJECT (qc->slave), "commit", G_CALLBACK (commit_cb), qc);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_quartz_register_type (GTypeModule *module)
|
||||
{
|
||||
const GTypeInfo object_info =
|
||||
{
|
||||
sizeof (GtkIMContextQuartzClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) gtk_im_context_quartz_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (GtkIMContextQuartz),
|
||||
0,
|
||||
(GInstanceInitFunc) gtk_im_context_quartz_init,
|
||||
};
|
||||
|
||||
type_quartz =
|
||||
g_type_module_register_type (module,
|
||||
GTK_TYPE_IM_CONTEXT,
|
||||
"GtkIMContextQuartz",
|
||||
&object_info, 0);
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, init) (GTypeModule * module)
|
||||
{
|
||||
gtk_im_context_quartz_register_type (module);
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, exit) (void)
|
||||
{
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, list) (const GtkIMContextInfo *** contexts, int *n_contexts)
|
||||
{
|
||||
*contexts = info_list;
|
||||
*n_contexts = G_N_ELEMENTS (info_list);
|
||||
}
|
||||
|
||||
MODULE_ENTRY (GtkIMContext *, create) (const gchar * context_id)
|
||||
{
|
||||
g_return_val_if_fail (context_id, NULL);
|
||||
|
||||
if (!strcmp (context_id, "quartz"))
|
||||
{
|
||||
GTK_NOTE (MISC, g_print ("immodule_quartz create\n"));
|
||||
return g_object_new (type_quartz, NULL);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
@ -70,31 +70,47 @@ struct _GtkIMContextWayland
|
||||
guint use_preedit : 1;
|
||||
};
|
||||
|
||||
GType type_wayland = 0;
|
||||
static GObjectClass *parent_class;
|
||||
static GtkIMContextWaylandGlobal *global = NULL;
|
||||
|
||||
static const GtkIMContextInfo imwayland_info =
|
||||
static void gtk_im_context_wayland_global_init (GdkDisplay *display);
|
||||
|
||||
#define GTK_TYPE_IM_CONTEXT_WAYLAND (gtk_im_context_wayland_get_type ())
|
||||
#define GTK_IM_CONTEXT_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_WAYLAND, GtkIMContextWayland))
|
||||
|
||||
G_DEFINE_DYNAMIC_TYPE (GtkIMContextWayland, gtk_im_context_wayland, GTK_TYPE_IM_CONTEXT_SIMPLE)
|
||||
|
||||
void
|
||||
g_io_module_load (GIOModule *module)
|
||||
{
|
||||
"wayland", /* ID */
|
||||
NC_("input method menu", "Wayland"), /* Human readable name */
|
||||
GETTEXT_PACKAGE, /* Translation domain */
|
||||
GTK_LOCALEDIR, /* Dir for bindtextdomain (not strictly needed for "gtk+") */
|
||||
"", /* Languages for which this module is the default */
|
||||
};
|
||||
g_type_module_use (G_TYPE_MODULE (module));
|
||||
|
||||
static const GtkIMContextInfo *info_list[] =
|
||||
g_print ("load io module for wayland\n");
|
||||
gtk_im_context_wayland_register_type (G_TYPE_MODULE (module));
|
||||
gtk_im_context_wayland_global_init (gdk_display_get_default ());
|
||||
|
||||
g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME,
|
||||
GTK_TYPE_IM_CONTEXT_WAYLAND,
|
||||
"wayland",
|
||||
10);
|
||||
}
|
||||
|
||||
void
|
||||
g_io_module_unload (GIOModule *module)
|
||||
{
|
||||
&imwayland_info,
|
||||
};
|
||||
}
|
||||
|
||||
char **
|
||||
g_io_module_query (void)
|
||||
{
|
||||
char *eps[] = {
|
||||
GTK_IM_MODULE_EXTENSION_POINT_NAME,
|
||||
NULL
|
||||
};
|
||||
|
||||
return g_strdupv (eps);
|
||||
}
|
||||
|
||||
#define GTK_IM_CONTEXT_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), type_wayland, GtkIMContextWayland))
|
||||
|
||||
#ifndef INCLUDE_IM_wayland
|
||||
#define MODULE_ENTRY(type,function) G_MODULE_EXPORT type im_module_ ## function
|
||||
#else
|
||||
#define MODULE_ENTRY(type, function) type _gtk_immodule_wayland_ ## function
|
||||
#endif
|
||||
|
||||
static void
|
||||
reset_preedit (GtkIMContextWayland *context)
|
||||
@ -237,7 +253,8 @@ static const struct wl_registry_listener registry_listener = {
|
||||
static void
|
||||
gtk_im_context_wayland_global_init (GdkDisplay *display)
|
||||
{
|
||||
g_return_if_fail (global == NULL);
|
||||
if (global)
|
||||
return;
|
||||
|
||||
global = g_new0 (GtkIMContextWaylandGlobal, 1);
|
||||
global->display = gdk_wayland_display_get_wl_display (display);
|
||||
@ -395,7 +412,7 @@ gtk_im_context_wayland_finalize (GObject *object)
|
||||
g_clear_object (&context->widget);
|
||||
g_clear_object (&context->gesture);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (gtk_im_context_wayland_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -472,7 +489,7 @@ gtk_im_context_wayland_get_preedit_string (GtkIMContext *context,
|
||||
GtkIMContextWayland *context_wayland = GTK_IM_CONTEXT_WAYLAND (context);
|
||||
gchar *preedit_str;
|
||||
|
||||
GTK_IM_CONTEXT_CLASS (parent_class)->get_preedit_string (context, str, attrs, cursor_pos);
|
||||
GTK_IM_CONTEXT_CLASS (gtk_im_context_wayland_parent_class)->get_preedit_string (context, str, attrs, cursor_pos);
|
||||
|
||||
/* If the parent implementation returns a len>0 string, go with it */
|
||||
if (str && *str && **str)
|
||||
@ -499,7 +516,7 @@ gtk_im_context_wayland_filter_keypress (GtkIMContext *context,
|
||||
GdkEventKey *key)
|
||||
{
|
||||
/* This is done by the compositor */
|
||||
return GTK_IM_CONTEXT_CLASS (parent_class)->filter_keypress (context, key);
|
||||
return GTK_IM_CONTEXT_CLASS (gtk_im_context_wayland_parent_class)->filter_keypress (context, key);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -535,7 +552,7 @@ gtk_im_context_wayland_reset (GtkIMContext *context)
|
||||
{
|
||||
reset_preedit (GTK_IM_CONTEXT_WAYLAND (context));
|
||||
|
||||
GTK_IM_CONTEXT_CLASS (parent_class)->reset (context);
|
||||
GTK_IM_CONTEXT_CLASS (gtk_im_context_wayland_parent_class)->reset (context);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -613,8 +630,11 @@ gtk_im_context_wayland_class_init (GtkIMContextWaylandClass *klass)
|
||||
im_context_class->set_use_preedit = gtk_im_context_wayland_set_use_preedit;
|
||||
im_context_class->set_surrounding = gtk_im_context_wayland_set_surrounding;
|
||||
im_context_class->get_surrounding = gtk_im_context_wayland_get_surrounding;
|
||||
}
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
static void
|
||||
gtk_im_context_wayland_class_finalize (GtkIMContextWaylandClass *class)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
@ -633,46 +653,3 @@ gtk_im_context_wayland_init (GtkIMContextWayland *context)
|
||||
g_signal_connect_swapped (context, "notify::input-hints",
|
||||
G_CALLBACK (on_content_type_changed), context);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_wayland_register_type (GTypeModule *module)
|
||||
{
|
||||
const GTypeInfo object_info = {
|
||||
sizeof (GtkIMContextWaylandClass),
|
||||
NULL, NULL,
|
||||
(GClassInitFunc) gtk_im_context_wayland_class_init,
|
||||
NULL, NULL,
|
||||
sizeof (GtkIMContextWayland),
|
||||
0,
|
||||
(GInstanceInitFunc) gtk_im_context_wayland_init,
|
||||
};
|
||||
|
||||
type_wayland = g_type_module_register_type (module,
|
||||
GTK_TYPE_IM_CONTEXT_SIMPLE,
|
||||
"GtkIMContextWayland",
|
||||
&object_info, 0);
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, init) (GTypeModule * module)
|
||||
{
|
||||
gtk_im_context_wayland_register_type (module);
|
||||
gtk_im_context_wayland_global_init (gdk_display_get_default ());
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, exit) (void)
|
||||
{
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, list) (const GtkIMContextInfo *** contexts, int *n_contexts)
|
||||
{
|
||||
*contexts = info_list;
|
||||
*n_contexts = G_N_ELEMENTS (info_list);
|
||||
}
|
||||
|
||||
MODULE_ENTRY (GtkIMContext *, create) (const gchar * context_id)
|
||||
{
|
||||
if (strcmp (context_id, "wayland") == 0)
|
||||
return g_object_new (type_wayland, NULL);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,65 +0,0 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gtk/gtkintl.h"
|
||||
#include "gtk/gtkimmodule.h"
|
||||
#include "gtkimcontextxim.h"
|
||||
#include <string.h>
|
||||
|
||||
static const GtkIMContextInfo xim_ja_info = {
|
||||
"xim", /* ID */
|
||||
NC_("input method menu", "X Input Method"), /* Human readable name */
|
||||
GETTEXT_PACKAGE, /* Translation domain */
|
||||
GTK_LOCALEDIR, /* Dir for bindtextdomain (not strictly needed for "gtk+") */
|
||||
"ko:ja:th:zh" /* Languages for which this module is the default */
|
||||
};
|
||||
|
||||
static const GtkIMContextInfo *info_list[] = {
|
||||
&xim_ja_info
|
||||
};
|
||||
|
||||
#ifndef INCLUDE_IM_xim
|
||||
#define MODULE_ENTRY(type, function) G_MODULE_EXPORT type im_module_ ## function
|
||||
#else
|
||||
#define MODULE_ENTRY(type, function) type _gtk_immodule_xim_ ## function
|
||||
#endif
|
||||
|
||||
MODULE_ENTRY (void, init) (GTypeModule *type_module)
|
||||
{
|
||||
gtk_im_context_xim_register_type (type_module);
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, exit) (void)
|
||||
{
|
||||
gtk_im_context_xim_shutdown ();
|
||||
}
|
||||
|
||||
MODULE_ENTRY (void, list) (const GtkIMContextInfo ***contexts,
|
||||
int *n_contexts)
|
||||
{
|
||||
*contexts = info_list;
|
||||
*n_contexts = G_N_ELEMENTS (info_list);
|
||||
}
|
||||
|
||||
MODULE_ENTRY (GtkIMContext *, create) (const gchar *context_id)
|
||||
{
|
||||
if (strcmp (context_id, "xim") == 0)
|
||||
return gtk_im_context_xim_new ();
|
||||
else
|
||||
return NULL;
|
||||
}
|
@ -87,8 +87,8 @@ endforeach
|
||||
method_defs = [
|
||||
['broadway', files('imbroadway.c')],
|
||||
['quartz', ('imquartz.c'), [], ('-xobjective-c')],
|
||||
['xim', files('gtkimcontextxim.c', 'imxim.c')],
|
||||
['ime', files('gtkimcontextime.c', 'imime.c'), ['imm32']],
|
||||
['xim', files('gtkimcontextxim.c')],
|
||||
['ime', files('gtkimcontextime.c'), ['imm32']],
|
||||
['wayland', im_wayland_sources],
|
||||
]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user