scim-1.4.15/0000755000175000017500000000000012422143415012137 5ustar tzhuantzhuanscim-1.4.15/utils/0000755000175000017500000000000012422143415013277 5ustar tzhuantzhuanscim-1.4.15/utils/scimtrayicon.h0000644000175000017500000000557412422143415016167 0ustar tzhuantzhuan/* scimtrayicon.h * converted from eggtrayicon.h in libegg. * * Copyright (C) 2002 Anders Carlsson * * 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef __SCIM_TRAY_ICON_H__ #define __SCIM_TRAY_ICON_H__ #include #if GTK_CHECK_VERSION(2, 24, 0) #else #include #endif #if GTK_CHECK_VERSION(3, 0, 0) #include #endif #include G_BEGIN_DECLS #define SCIM_TYPE_TRAY_ICON (scim_tray_icon_get_type ()) #define SCIM_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SCIM_TYPE_TRAY_ICON, ScimTrayIcon)) #define SCIM_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SCIM_TYPE_TRAY_ICON, ScimTrayIconClass)) #define SCIM_IS_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SCIM_TYPE_TRAY_ICON)) #define SCIM_IS_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SCIM_TYPE_TRAY_ICON)) #define SCIM_TRAY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SCIM_TYPE_TRAY_ICON, ScimTrayIconClass)) typedef struct _ScimTrayIcon ScimTrayIcon; typedef struct _ScimTrayIconClass ScimTrayIconClass; struct _ScimTrayIcon { GtkPlug parent_instance; guint stamp; Atom selection_atom; Atom manager_atom; Atom system_tray_opcode_atom; Atom orientation_atom; Window manager_window; GtkOrientation orientation; }; struct _ScimTrayIconClass { GtkPlugClass parent_class; }; GType scim_tray_icon_get_type (void); ScimTrayIcon *scim_tray_icon_new_for_screen (GdkScreen *screen, const gchar *name); ScimTrayIcon *scim_tray_icon_new (const gchar *name); guint scim_tray_icon_send_message (ScimTrayIcon *icon, gint timeout, const char *message, gint len); void scim_tray_icon_cancel_message (ScimTrayIcon *icon, guint id); GtkOrientation scim_tray_icon_get_orientation (ScimTrayIcon *icon); G_END_DECLS #endif /* __SCIM_TRAY_ICON_H__ */ /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/utils/scimtrayicon.c0000644000175000017500000003770412422143415016162 0ustar tzhuantzhuan/* scimtrayicon.c * converted from eggtrayicon.c in libegg. * * Copyright (C) 2002 Anders Carlsson * * 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include #include #include "scimtrayicon.h" #include "scim_private.h" #include #include #define SYSTEM_TRAY_REQUEST_DOCK 0 #define SYSTEM_TRAY_BEGIN_MESSAGE 1 #define SYSTEM_TRAY_CANCEL_MESSAGE 2 #define SYSTEM_TRAY_ORIENTATION_HORZ 0 #define SYSTEM_TRAY_ORIENTATION_VERT 1 enum { PROP_0, PROP_ORIENTATION }; static GtkPlugClass *parent_class = NULL; static void scim_tray_icon_init (ScimTrayIcon *icon); static void scim_tray_icon_class_init (ScimTrayIconClass *klass); static void scim_tray_icon_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void scim_tray_icon_realize (GtkWidget *widget); static void scim_tray_icon_unrealize (GtkWidget *widget); static void scim_tray_icon_update_manager_window (ScimTrayIcon *icon); GType scim_tray_icon_get_type (void) { static GType our_type = 0; if (our_type == 0) { static const GTypeInfo our_info = { sizeof (ScimTrayIconClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) scim_tray_icon_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (ScimTrayIcon), 0, /* n_preallocs */ (GInstanceInitFunc) scim_tray_icon_init, 0 }; our_type = g_type_register_static (GTK_TYPE_PLUG, "ScimTrayIcon", &our_info, 0); } return our_type; } static void scim_tray_icon_init (ScimTrayIcon *icon) { icon->stamp = 1; icon->orientation = GTK_ORIENTATION_HORIZONTAL; gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK); } static void scim_tray_icon_class_init (ScimTrayIconClass *klass) { GObjectClass *gobject_class = (GObjectClass *)klass; GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; parent_class = g_type_class_peek_parent (klass); gobject_class->get_property = scim_tray_icon_get_property; widget_class->realize = scim_tray_icon_realize; widget_class->unrealize = scim_tray_icon_unrealize; g_object_class_install_property (gobject_class, PROP_ORIENTATION, g_param_spec_enum ("orientation", _("Orientation"), _("The orientation of the tray."), GTK_TYPE_ORIENTATION, GTK_ORIENTATION_HORIZONTAL, G_PARAM_READABLE)); } static void scim_tray_icon_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { ScimTrayIcon *icon = SCIM_TRAY_ICON (object); switch (prop_id) { case PROP_ORIENTATION: g_value_set_enum (value, icon->orientation); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void scim_tray_icon_get_orientation_property (ScimTrayIcon *icon) { Display *xdisplay; Atom type; int format; union { gulong *prop; guchar *prop_ch; } prop = { NULL }; gulong nitems; gulong bytes_after; int error, result; g_assert (icon->manager_window != None); xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); gdk_error_trap_push (); type = None; result = XGetWindowProperty (xdisplay, icon->manager_window, icon->orientation_atom, 0, G_MAXLONG, FALSE, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &(prop.prop_ch)); error = gdk_error_trap_pop (); if (error || result != Success) return; if (type == XA_CARDINAL) { GtkOrientation orientation; orientation = (prop.prop [0] == SYSTEM_TRAY_ORIENTATION_HORZ) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; if (icon->orientation != orientation) { icon->orientation = orientation; g_object_notify (G_OBJECT (icon), "orientation"); } } if (prop.prop) XFree (prop.prop); } static GdkFilterReturn scim_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data) { ScimTrayIcon *icon = user_data; XEvent *xev = (XEvent *)xevent; if (xev->xany.type == ClientMessage && xev->xclient.message_type == icon->manager_atom && xev->xclient.data.l[1] == icon->selection_atom) { scim_tray_icon_update_manager_window (icon); } else if (xev->xany.window == icon->manager_window) { if (xev->xany.type == PropertyNotify && xev->xproperty.atom == icon->orientation_atom) { scim_tray_icon_get_orientation_property (icon); } if (xev->xany.type == DestroyNotify) { scim_tray_icon_update_manager_window (icon); } } return GDK_FILTER_CONTINUE; } static void scim_tray_icon_unrealize (GtkWidget *widget) { ScimTrayIcon *icon = SCIM_TRAY_ICON (widget); GdkWindow *root_window; if (icon->manager_window != None) { GdkWindow *gdkwin; #if GTK_CHECK_VERSION(3, 0, 0) gdkwin = gdk_x11_window_lookup_for_display (gtk_widget_get_display (widget), #else gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (widget), #endif icon->manager_window); gdk_window_remove_filter (gdkwin, scim_tray_icon_manager_filter, icon); } root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget)); gdk_window_remove_filter (root_window, scim_tray_icon_manager_filter, icon); if (GTK_WIDGET_CLASS (parent_class)->unrealize) (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); } static void scim_tray_icon_send_manager_message (ScimTrayIcon *icon, long message, Window window, long data1, long data2, long data3) { XClientMessageEvent ev; Display *display; ev.type = ClientMessage; ev.window = window; ev.message_type = icon->system_tray_opcode_atom; ev.format = 32; #if GTK_CHECK_VERSION(2, 14, 0) ev.data.l[0] = gdk_x11_get_server_time (gtk_widget_get_window (GTK_WIDGET (icon))); #else ev.data.l[0] = gdk_x11_get_server_time (GTK_WIDGET (icon)->window); #endif ev.data.l[1] = message; ev.data.l[2] = data1; ev.data.l[3] = data2; ev.data.l[4] = data3; display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); gdk_error_trap_push (); XSendEvent (display, icon->manager_window, False, NoEventMask, (XEvent *)&ev); XSync (display, False); gint error_code = gdk_error_trap_pop (); } static void scim_tray_icon_send_dock_request (ScimTrayIcon *icon) { scim_tray_icon_send_manager_message (icon, SYSTEM_TRAY_REQUEST_DOCK, icon->manager_window, gtk_plug_get_id (GTK_PLUG (icon)), 0, 0); } static void scim_tray_icon_update_manager_window (ScimTrayIcon *icon) { Display *xdisplay; xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); if (icon->manager_window != None) { GdkWindow *gdkwin; #if GTK_CHECK_VERSION(3, 0, 0) gdkwin = gdk_x11_window_lookup_for_display ( #else gdkwin = gdk_window_lookup_for_display ( #endif gtk_widget_get_display (GTK_WIDGET (icon)), icon->manager_window); gdk_window_remove_filter (gdkwin, scim_tray_icon_manager_filter, icon); } XGrabServer (xdisplay); icon->manager_window = XGetSelectionOwner (xdisplay, icon->selection_atom); if (icon->manager_window != None) XSelectInput (xdisplay, icon->manager_window, StructureNotifyMask|PropertyChangeMask); XUngrabServer (xdisplay); XFlush (xdisplay); if (icon->manager_window != None) { GdkWindow *gdkwin; #if GTK_CHECK_VERSION(3, 0, 0) gdkwin = gdk_x11_window_lookup_for_display ( #else gdkwin = gdk_window_lookup_for_display ( #endif gtk_widget_get_display (GTK_WIDGET (icon)), icon->manager_window); gdk_window_add_filter (gdkwin, scim_tray_icon_manager_filter, icon); /* Send a request that we'd like to dock */ scim_tray_icon_send_dock_request (icon); scim_tray_icon_get_orientation_property (icon); } } static gboolean transparent_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { #if GTK_CHECK_VERSION(3, 0, 0) #else #if GTK_CHECK_VERSION(2, 14, 0) gdk_window_clear_area (gtk_widget_get_window (widget), event->area.x, event->area.y, #else gdk_window_clear_area (widget->window, event->area.x, event->area.y, #endif event->area.width, event->area.height); #endif return FALSE; } static void make_transparent_again (GtkWidget *widget, GtkStyle *previous_style, gpointer user_data) { #if GTK_CHECK_VERSION(3, 0, 0) #elif GTK_CHECK_VERSION(2, 14, 0) gdk_window_set_back_pixmap (gtk_widget_get_window (widget), NULL, TRUE); #else gdk_window_set_back_pixmap (widget->window, NULL, TRUE); #endif } static void make_transparent (GtkWidget *widget, gpointer user_data) { #if GTK_CHECK_VERSION(2, 18, 0) if (!gtk_widget_get_has_window (widget) || gtk_widget_get_app_paintable (widget)) #else if (GTK_WIDGET_NO_WINDOW (widget) || GTK_WIDGET_APP_PAINTABLE (widget)) #endif return; gtk_widget_set_app_paintable (widget, TRUE); G_GNUC_BEGIN_IGNORE_DEPRECATIONS gtk_widget_set_double_buffered (widget, FALSE); G_GNUC_END_IGNORE_DEPRECATIONS #if GTK_CHECK_VERSION(3, 0, 0) #elif GTK_CHECK_VERSION(2, 14, 0) gdk_window_set_back_pixmap (gtk_widget_get_window (widget), NULL, TRUE); #else gdk_window_set_back_pixmap (widget->window, NULL, TRUE); #endif g_signal_connect (widget, "expose_event", G_CALLBACK (transparent_expose_event), NULL); g_signal_connect_after (widget, "style_set", G_CALLBACK (make_transparent_again), NULL); } static void scim_tray_icon_realize (GtkWidget *widget) { ScimTrayIcon *icon = SCIM_TRAY_ICON (widget); GdkScreen *screen; GdkDisplay *display; Display *xdisplay; char buffer[256]; GdkWindow *root_window; if (GTK_WIDGET_CLASS (parent_class)->realize) GTK_WIDGET_CLASS (parent_class)->realize (widget); make_transparent (widget, NULL); screen = gtk_widget_get_screen (widget); display = gdk_screen_get_display (screen); xdisplay = gdk_x11_display_get_xdisplay (display); /* Now see if there's a manager window around */ g_snprintf (buffer, sizeof (buffer), "_NET_SYSTEM_TRAY_S%d", gdk_screen_get_number (screen)); icon->selection_atom = XInternAtom (xdisplay, buffer, False); icon->manager_atom = XInternAtom (xdisplay, "MANAGER", False); icon->system_tray_opcode_atom = XInternAtom (xdisplay, "_NET_SYSTEM_TRAY_OPCODE", False); icon->orientation_atom = XInternAtom (xdisplay, "_NET_SYSTEM_TRAY_ORIENTATION", False); scim_tray_icon_update_manager_window (icon); root_window = gdk_screen_get_root_window (screen); /* Add a root window filter so that we get changes on MANAGER */ gdk_window_add_filter (root_window, scim_tray_icon_manager_filter, icon); } ScimTrayIcon * scim_tray_icon_new_for_xscreen (Screen *xscreen, const char *name) { GdkDisplay *display; GdkScreen *screen; display = gdk_x11_lookup_xdisplay (DisplayOfScreen (xscreen)); screen = gdk_display_get_screen (display, XScreenNumberOfScreen (xscreen)); return scim_tray_icon_new_for_screen (screen, name); } ScimTrayIcon * scim_tray_icon_new_for_screen (GdkScreen *screen, const char *name) { g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); return g_object_new (SCIM_TYPE_TRAY_ICON, "screen", screen, "title", name, NULL); } ScimTrayIcon* scim_tray_icon_new (const gchar *name) { return g_object_new (SCIM_TYPE_TRAY_ICON, "title", name, NULL); } guint scim_tray_icon_send_message (ScimTrayIcon *icon, gint timeout, const gchar *message, gint len) { guint stamp; g_return_val_if_fail (SCIM_IS_TRAY_ICON (icon), 0); g_return_val_if_fail (timeout >= 0, 0); g_return_val_if_fail (message != NULL, 0); if (icon->manager_window == None) return 0; if (len < 0) len = strlen (message); stamp = icon->stamp++; /* Get ready to send the message */ scim_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE, (Window)gtk_plug_get_id (GTK_PLUG (icon)), timeout, len, stamp); /* Now to send the actual message */ gdk_error_trap_push (); while (len > 0) { XClientMessageEvent ev; Display *xdisplay; xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); ev.type = ClientMessage; ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon)); ev.format = 8; ev.message_type = XInternAtom (xdisplay, "_NET_SYSTEM_TRAY_MESSAGE_DATA", False); if (len > 20) { memcpy (&ev.data, message, 20); len -= 20; message += 20; } else { memcpy (&ev.data, message, len); len = 0; } XSendEvent (xdisplay, icon->manager_window, False, StructureNotifyMask, (XEvent *)&ev); XSync (xdisplay, False); } gint error_code = gdk_error_trap_pop (); return stamp; } void scim_tray_icon_cancel_message (ScimTrayIcon *icon, guint id) { g_return_if_fail (SCIM_IS_TRAY_ICON (icon)); g_return_if_fail (id > 0); scim_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE, (Window)gtk_plug_get_id (GTK_PLUG (icon)), id, 0, 0); } GtkOrientation scim_tray_icon_get_orientation (ScimTrayIcon *icon) { g_return_val_if_fail (SCIM_IS_TRAY_ICON (icon), GTK_ORIENTATION_HORIZONTAL); return icon->orientation; } /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/utils/scimstringview.h0000644000175000017500000001276512422143415016540 0ustar tzhuantzhuan#ifndef __SCIM_STRING_VIEW_H__ #define __SCIM_STRING_VIEW_H__ #include #include G_BEGIN_DECLS #define SCIM_TYPE_STRING_VIEW (scim_string_view_get_type ()) #define SCIM_STRING_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SCIM_TYPE_STRING_VIEW, ScimStringView)) #define SCIM_STRING_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SCIM_TYPE_STRING_VIEW, ScimStringViewClass)) #define SCIM_IS_STRING_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SCIM_TYPE_STRING_VIEW)) #define SCIM_IS_STRING_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SCIM_TYPE_STRING_VIEW)) #define SCIM_STRING_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SCIM_TYPE_STRING_VIEW, ScimStringViewClass)) typedef struct _ScimStringView ScimStringView; typedef struct _ScimStringViewClass ScimStringViewClass; struct _ScimStringView { GtkWidget widget; gchar *text; guint16 text_length; /* length in use, in chars */ guint16 text_max_length; /*< private >*/ GdkWindow *text_area; gint current_pos; PangoLayout *cached_layout; PangoAttrList *attrs; PangoAttrList *effective_attrs; guint has_frame : 1; guint draw_cursor : 1; guint cursor_visible : 1; guint auto_move_cursor : 1; guint forward_event : 1; guint auto_resize : 1; guint blink_timeout; guint recompute_idle; gint scroll_offset; gint ascent; /* font ascent, in pango units */ gint descent; /* font descent, in pango units */ gint max_width; gint highlight_start; gint highlight_end; guint16 text_size; /* allocated size, in bytes */ guint16 n_bytes; /* length in use, in bytes */ gint width_chars; }; struct _ScimStringViewClass { GtkWidgetClass parent_class; void (* move_cursor) (ScimStringView *string_view, guint position); }; void scim_string_view_register_type (GTypeModule *type_module); GType scim_string_view_get_type (void) G_GNUC_CONST; GtkWidget* scim_string_view_new (void); void scim_string_view_set_has_frame (ScimStringView *entry, gboolean setting); gboolean scim_string_view_get_has_frame (ScimStringView *entry); /* text is truncated if needed */ void scim_string_view_set_max_length (ScimStringView *entry, gint max); gint scim_string_view_get_max_length (ScimStringView *entry); void scim_string_view_set_width_chars (ScimStringView *entry, gint n_chars); gint scim_string_view_get_width_chars (ScimStringView *entry); /* Somewhat more convenient than the GtkEditable generic functions */ void scim_string_view_set_text (ScimStringView *entry, const gchar *text); /* returns a reference to the text */ const gchar* scim_string_view_get_text (ScimStringView *entry); void scim_string_view_set_position (ScimStringView *entry, gint position); gint scim_string_view_get_position (ScimStringView *entry); void scim_string_view_set_max_width (ScimStringView *entry, gint width); gint scim_string_view_get_max_width (ScimStringView *entry); void scim_string_view_set_draw_cursor (ScimStringView *entry, gboolean width); gboolean scim_string_view_get_draw_cursor (ScimStringView *entry); void scim_string_view_set_auto_move_cursor (ScimStringView *entry, gboolean setting); gboolean scim_string_view_get_auto_move_cursor (ScimStringView *entry); void scim_string_view_set_forward_event (ScimStringView *entry, gboolean setting); gboolean scim_string_view_get_forward_event (ScimStringView *entry); void scim_string_view_set_auto_resize (ScimStringView *entry, gboolean setting); gboolean scim_string_view_get_auto_resize (ScimStringView *entry); PangoLayout* scim_string_view_get_layout (ScimStringView *entry); void scim_string_view_get_layout_offsets (ScimStringView *entry, gint *x, gint *y); void scim_string_view_set_highlight (ScimStringView *entry, gint start, gint end); void scim_string_view_get_highlight (ScimStringView *entry, gint *start, gint *end); void scim_string_view_set_attributes (ScimStringView *entry, PangoAttrList *attrs); PangoAttrList *scim_string_view_get_attributes (ScimStringView *entry); G_END_DECLS #endif /* __scim_string_view_H__ */ /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/utils/scimstringview.c0000644000175000017500000023246212422143415016531 0ustar tzhuantzhuan#include #include #include #include #include #if GTK_CHECK_VERSION(2, 22, 0) #else #include #include #include #include #include #include #endif #include "scim_private.h" #include "scimstringview.h" #define MIN_STRING_VIEW_WIDTH 64 #define MAX_STRING_VIEW_WIDTH 400 #define DRAW_TIMEOUT 20 #define INNER_BORDER 2 /* Initial size of buffer, in bytes */ #define MIN_SIZE 16 /* Maximum size of text buffer, in bytes */ #define MAX_SIZE G_MAXUSHORT enum { PROP_0, PROP_DRAW_CURSOR, PROP_CURSOR_POSITION, PROP_AUTO_MOVE_CURSOR, PROP_FORWARD_EVENT, PROP_AUTO_RESIZE, PROP_MAX_LENGTH, PROP_MAX_WIDTH, PROP_HAS_FRAME, PROP_WIDTH_CHARS, PROP_SCROLL_OFFSET, PROP_TEXT }; enum { MOVE_CURSOR, LAST_SIGNAL }; /* GObject, GtkObject methods */ static void scim_string_view_class_init (ScimStringViewClass *klass); static void scim_string_view_init (ScimStringView *string_view); static void scim_string_view_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void scim_string_view_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void scim_string_view_finalize (GObject *object); /* GtkWidget methods */ static void scim_string_view_realize (GtkWidget *widget); static void scim_string_view_unrealize (GtkWidget *widget); static void scim_string_view_size_request (GtkWidget *widget, GtkRequisition *requisition); #if GTK_CHECK_VERSION(3, 0, 0) static void scim_widget_get_preferred_width (GtkWidget *widget, gint *minimal_width, gint *natural_width); static void scim_widget_get_preferred_height (GtkWidget *widget, gint *minimal_height, gint *natural_height); #endif static void scim_string_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation); #if GTK_CHECK_VERSION(3, 0, 0) static void scim_string_view_draw_frame (GtkWidget *widget, cairo_t *cr); static gint scim_string_view_draw (GtkWidget *widget, cairo_t *cr); #else static void scim_string_view_draw_frame (GtkWidget *widget); static gint scim_string_view_expose (GtkWidget *widget, GdkEventExpose *event); #endif static gint scim_string_view_button_press (GtkWidget *widget, GdkEventButton *event); static gint scim_string_view_focus_in (GtkWidget *widget, GdkEventFocus *event); static gint scim_string_view_focus_out (GtkWidget *widget, GdkEventFocus *event); static void scim_string_view_style_set (GtkWidget *widget, GtkStyle *previous_style); static void scim_string_view_direction_changed (GtkWidget *widget, GtkTextDirection previous_dir); static void scim_string_view_state_changed (GtkWidget *widget, GtkStateType previous_state); /* Internal routines */ static void scim_string_view_draw_text (ScimStringView *view); static void scim_string_view_draw_cursor (ScimStringView *view); static PangoLayout *scim_string_view_ensure_layout (ScimStringView *view); static void scim_string_view_queue_draw (ScimStringView *view); static void scim_string_view_recompute (ScimStringView *view); static gint scim_string_view_find_position (ScimStringView *view, gint x); static gint scim_string_view_get_cursor_locations (ScimStringView *view, gint *strong_x, gint *weak_x); static void scim_string_view_adjust_scroll (ScimStringView *view); static void get_text_area_size (ScimStringView *string_view, gint *x, gint *y, gint *width, gint *height); static void get_widget_window_size (ScimStringView *string_view, gint *x, gint *y, gint *width, gint *height); static void scim_string_view_keymap_direction_changed (GdkKeymap *keymap, ScimStringView *string_view); static void scim_string_view_check_cursor_blink (ScimStringView *string_view); static void scim_string_view_move_cursor (ScimStringView *string_view, guint position); static GtkWidgetClass *parent_class = NULL; static gint string_view_signals[LAST_SIGNAL] = { 0 }; static GType string_view_type = 0; void scim_string_view_register_type (GTypeModule *type_module) { static const GTypeInfo string_view_info = { sizeof (ScimStringViewClass), NULL, NULL, (GClassInitFunc) scim_string_view_class_init, NULL, NULL, sizeof (ScimStringView), 0, (GInstanceInitFunc) scim_string_view_init, 0 }; if (!string_view_type) { if (type_module) string_view_type = g_type_module_register_type (type_module, GTK_TYPE_WIDGET, "SCIM_ScimStringView", &string_view_info, (GTypeFlags) 0); else string_view_type = g_type_register_static (GTK_TYPE_WIDGET, "SCIM_ScimStringView", &string_view_info, (GTypeFlags) 0); } } GType scim_string_view_get_type (void) { if (!string_view_type) scim_string_view_register_type (NULL); return string_view_type; } static void scim_string_view_class_init (ScimStringViewClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS (class); #if GTK_CHECK_VERSION(3, 0, 0) #else GtkObjectClass *object_class; #endif GtkWidgetClass *widget_class; #if GTK_CHECK_VERSION(3, 0, 0) #else object_class = (GtkObjectClass*) class; #endif widget_class = (GtkWidgetClass*) class; parent_class = g_type_class_ref (GTK_TYPE_WIDGET); gobject_class->finalize = scim_string_view_finalize; gobject_class->set_property = scim_string_view_set_property; gobject_class->get_property = scim_string_view_get_property; widget_class->realize = scim_string_view_realize; widget_class->unrealize = scim_string_view_unrealize; #if GTK_CHECK_VERSION(3, 0, 0) widget_class->get_preferred_width = scim_widget_get_preferred_width; widget_class->get_preferred_height = scim_widget_get_preferred_height; #else widget_class->size_request = scim_string_view_size_request; #endif widget_class->size_allocate = scim_string_view_size_allocate; #if GTK_CHECK_VERSION(3, 0, 0) widget_class->draw = scim_string_view_draw; #else widget_class->expose_event = scim_string_view_expose; #endif widget_class->button_press_event = scim_string_view_button_press; widget_class->focus_in_event = scim_string_view_focus_in; widget_class->focus_out_event = scim_string_view_focus_out; widget_class->style_set = scim_string_view_style_set; widget_class->direction_changed = scim_string_view_direction_changed; widget_class->state_changed = scim_string_view_state_changed; class->move_cursor = scim_string_view_move_cursor; g_object_class_install_property (gobject_class, PROP_CURSOR_POSITION, g_param_spec_int ("cursor_position", _("Cursor Position"), _("The current position of the insertion cursor in chars."), 0, MAX_SIZE, 0, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, PROP_MAX_LENGTH, g_param_spec_int ("max_length", _("Maximum length"), _("Maximum number of characters for this string view. Zero if no maximum."), 0, MAX_SIZE, 0, G_PARAM_READABLE | G_PARAM_WRITABLE)); g_object_class_install_property (gobject_class, PROP_MAX_WIDTH, g_param_spec_int ("max_width", _("Maximum width"), _("Maximum width of this string view."), 0, MAX_STRING_VIEW_WIDTH, 0, G_PARAM_READABLE | G_PARAM_WRITABLE)); g_object_class_install_property (gobject_class, PROP_HAS_FRAME, g_param_spec_boolean ("has_frame", _("Has Frame"), _("FALSE removes outside bevel from string view."), TRUE, G_PARAM_READABLE | G_PARAM_WRITABLE)); g_object_class_install_property (gobject_class, PROP_DRAW_CURSOR, g_param_spec_boolean ("draw_cursor", _("Draw cursor"), _("TRUE draw blinking cursor."), TRUE, G_PARAM_READABLE | G_PARAM_WRITABLE)); g_object_class_install_property (gobject_class, PROP_AUTO_MOVE_CURSOR, g_param_spec_boolean ("auto_move_cursor", _("Auto move cursor"), _("TRUE auto move cursor position when mouse clicking."), FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE)); g_object_class_install_property (gobject_class, PROP_FORWARD_EVENT, g_param_spec_boolean ("forward_event", _("Forward button press event"), _("TRUE forward button press event to user program."), FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE)); g_object_class_install_property (gobject_class, PROP_FORWARD_EVENT, g_param_spec_boolean ("auto_resize", _("Auto resize the widget to fit the string"), _("TRUE Auto resize on."), FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE)); g_object_class_install_property (gobject_class, PROP_WIDTH_CHARS, g_param_spec_int ("width_chars", _("Width in chars"), _("Number of characters to leave space for in the string view."), -1, G_MAXINT, -1, G_PARAM_READABLE | G_PARAM_WRITABLE)); g_object_class_install_property (gobject_class, PROP_SCROLL_OFFSET, g_param_spec_int ("scroll_offset", _("Scroll offset"), _("Number of pixels of the string view scrolled off the screen to the left"), 0, G_MAXINT, 0, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, PROP_TEXT, g_param_spec_string ("text", _("Text"), _("The contents of the string view"), "", G_PARAM_READABLE | G_PARAM_WRITABLE)); string_view_signals[MOVE_CURSOR] = g_signal_new ("move_cursor", #if GTK_CHECK_VERSION(3, 0, 0) G_TYPE_FROM_CLASS (gobject_class), #else G_TYPE_FROM_CLASS (object_class), #endif G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (ScimStringViewClass, move_cursor), NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); } static void scim_string_view_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { ScimStringView *view = SCIM_STRING_VIEW (object); switch (prop_id) { case PROP_MAX_LENGTH: scim_string_view_set_max_length (view, g_value_get_int (value)); break; case PROP_MAX_WIDTH: scim_string_view_set_max_width (view, g_value_get_int (value)); break; case PROP_HAS_FRAME: scim_string_view_set_has_frame (view, g_value_get_boolean (value)); break; case PROP_DRAW_CURSOR: scim_string_view_set_draw_cursor (view, g_value_get_boolean (value)); break; case PROP_AUTO_MOVE_CURSOR: scim_string_view_set_auto_move_cursor (view, g_value_get_boolean (value)); break; case PROP_FORWARD_EVENT: scim_string_view_set_forward_event (view, g_value_get_boolean (value)); break; case PROP_AUTO_RESIZE: scim_string_view_set_auto_resize (view, g_value_get_boolean (value)); break; case PROP_WIDTH_CHARS: scim_string_view_set_width_chars (view, g_value_get_int (value)); break; case PROP_TEXT: scim_string_view_set_text (view, g_value_get_string (value)); break; case PROP_SCROLL_OFFSET: case PROP_CURSOR_POSITION: default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void scim_string_view_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { ScimStringView *view = SCIM_STRING_VIEW (object); switch (prop_id) { case PROP_CURSOR_POSITION: g_value_set_int (value, view->current_pos); break; case PROP_MAX_LENGTH: g_value_set_int (value, view->text_max_length); break; case PROP_MAX_WIDTH: g_value_set_int (value, view->max_width); break; case PROP_HAS_FRAME: g_value_set_boolean (value, view->has_frame); break; case PROP_DRAW_CURSOR: g_value_set_boolean (value, view->draw_cursor); break; case PROP_AUTO_MOVE_CURSOR: g_value_set_boolean (value, view->auto_move_cursor); break; case PROP_FORWARD_EVENT: g_value_set_boolean (value, view->forward_event); break; case PROP_AUTO_RESIZE: g_value_set_boolean (value, view->auto_resize); break; case PROP_WIDTH_CHARS: g_value_set_int (value, view->width_chars); break; case PROP_SCROLL_OFFSET: g_value_set_int (value, view->scroll_offset); break; case PROP_TEXT: g_value_set_string (value, scim_string_view_get_text (view)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void scim_string_view_init (ScimStringView *string_view) { #if GTK_CHECK_VERSION(2, 18, 0) gtk_widget_set_can_focus (GTK_WIDGET (string_view), TRUE); #else GTK_WIDGET_SET_FLAGS (string_view, GTK_CAN_FOCUS); #endif string_view->text_size = MIN_SIZE; string_view->text = g_malloc (string_view->text_size); string_view->text[0] = '\0'; string_view->width_chars = -1; string_view->has_frame = TRUE; string_view->draw_cursor = TRUE; string_view->auto_move_cursor = FALSE; string_view->forward_event = FALSE; string_view->max_width = -1; string_view->highlight_start = -1; string_view->highlight_end = -1; } static void scim_string_view_finalize (GObject *object) { ScimStringView *view = SCIM_STRING_VIEW (object); if (view->cached_layout) g_object_unref (G_OBJECT (view->cached_layout)); if (view->blink_timeout) g_source_remove (view->blink_timeout); if (view->recompute_idle) g_source_remove (view->recompute_idle); view->text_size = 0; if (view->text) g_free (view->text); view->text = NULL; if (view->attrs) pango_attr_list_unref (view->attrs); G_OBJECT_CLASS (parent_class)->finalize (object); } static void scim_string_view_realize (GtkWidget *widget) { ScimStringView *string_view; GdkWindowAttr attributes; gint attributes_mask; #if GTK_CHECK_VERSION(2, 20, 0) gtk_widget_set_realized (widget, TRUE); #else GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); #endif string_view = SCIM_STRING_VIEW (widget); attributes.window_type = GDK_WINDOW_CHILD; get_widget_window_size (string_view, &attributes.x, &attributes.y, &attributes.width, &attributes.height); attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual (widget); #if GTK_CHECK_VERSION(3, 0, 0) #else attributes.colormap = gtk_widget_get_colormap (widget); #endif attributes.event_mask = gtk_widget_get_events (widget); attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); #if GTK_CHECK_VERSION(3, 0, 0) attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; #else attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; #endif #if GTK_CHECK_VERSION(3, 0, 0) gtk_widget_set_window (widget, gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask)); #else widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); #endif #if GTK_CHECK_VERSION(2, 14, 0) gdk_window_set_user_data (gtk_widget_get_window (widget), string_view); #else gdk_window_set_user_data (widget->window, string_view); #endif get_text_area_size (string_view, &attributes.x, &attributes.y, &attributes.width, &attributes.height); attributes.cursor = gdk_cursor_new (GDK_XTERM); attributes_mask |= GDK_WA_CURSOR; #if GTK_CHECK_VERSION(2, 14, 0) string_view->text_area = gdk_window_new (gtk_widget_get_window (widget), &attributes, attributes_mask); #else string_view->text_area = gdk_window_new (widget->window, &attributes, attributes_mask); #endif gdk_window_set_user_data (string_view->text_area, string_view); #if GTK_CHECK_VERSION(3, 0, 0) g_object_unref (attributes.cursor); #else gdk_cursor_unref (attributes.cursor); #endif #if GTK_CHECK_VERSION(3, 0, 0) GtkStyleContext *style = gtk_widget_get_style_context (widget); GdkRGBA bg_color; gtk_style_context_get_background_color (style, gtk_widget_get_state_flags (widget), &bg_color); gdk_window_set_background_rgba (gtk_widget_get_window (widget), &bg_color); gdk_window_set_background_rgba (string_view->text_area, &bg_color); #else widget->style = gtk_style_attach (widget->style, gtk_widget_get_window (widget)); #if GTK_CHECK_VERSION(2, 14, 0) gdk_window_set_background (gtk_widget_get_window (widget), &widget->style->base[gtk_widget_get_state (widget)]); gdk_window_set_background (string_view->text_area, &widget->style->base[gtk_widget_get_state (widget)]); #else gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]); gdk_window_set_background (string_view->text_area, &widget->style->base[GTK_WIDGET_STATE (widget)]); #endif #endif gdk_window_show (string_view->text_area); scim_string_view_adjust_scroll (string_view); } static void scim_string_view_unrealize (GtkWidget *widget) { ScimStringView *string_view = SCIM_STRING_VIEW (widget); if (string_view->text_area) { gdk_window_set_user_data (string_view->text_area, NULL); gdk_window_destroy (string_view->text_area); string_view->text_area = NULL; } if (GTK_WIDGET_CLASS (parent_class)->unrealize) (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); } static void get_borders (ScimStringView *string_view, gint *xborder, gint *yborder) { GtkWidget *widget = GTK_WIDGET (string_view); gint focus_width; gboolean interior_focus; gtk_widget_style_get (widget, "interior-focus", &interior_focus, "focus-line-width", &focus_width, NULL); if (string_view->has_frame) { #if GTK_CHECK_VERSION(3, 0, 0) GtkStyleContext *style_context = gtk_widget_get_style_context (widget); GtkBorder border; gtk_style_context_get_border (style_context, gtk_widget_get_state_flags (widget), &border); *xborder = border.left; *yborder = border.top; #else *xborder = widget->style->xthickness; *yborder = widget->style->ythickness; #endif } else { *xborder = 0; *yborder = 0; } if (!interior_focus) { *xborder += focus_width; *yborder += focus_width; } } static void scim_string_view_size_request (GtkWidget *widget, GtkRequisition *requisition) { ScimStringView *string_view = SCIM_STRING_VIEW (widget); PangoFontMetrics *metrics; gint xborder, yborder; PangoContext *context; PangoLayout *layout; int width, height; context = gtk_widget_get_pango_context (widget); metrics = pango_context_get_metrics (context, #if GTK_CHECK_VERSION(3, 0, 0) pango_context_get_font_description (context), #else widget->style->font_desc, #endif pango_context_get_language (context)); string_view->ascent = pango_font_metrics_get_ascent (metrics); string_view->descent = pango_font_metrics_get_descent (metrics); get_borders (string_view, &xborder, &yborder); xborder += INNER_BORDER; yborder += INNER_BORDER; if (string_view->auto_resize) { layout = scim_string_view_ensure_layout (string_view); pango_layout_get_pixel_size (layout, &width, &height); requisition->width = ((widthwidth_chars < 0) requisition->width = MIN_STRING_VIEW_WIDTH; else { gint char_width = pango_font_metrics_get_approximate_char_width (metrics); requisition->width = PANGO_PIXELS (char_width) * string_view->width_chars; } } if (string_view->max_width > 0 && requisition->width > string_view->max_width) requisition->width = string_view->max_width; requisition->width += xborder * 2; requisition->height = PANGO_PIXELS (string_view->ascent + string_view->descent) + yborder * 2; pango_font_metrics_unref (metrics); } #if GTK_CHECK_VERSION(3, 0, 0) static void scim_widget_get_preferred_width (GtkWidget *widget, gint *minimal_width, gint *natural_width) { GtkRequisition requisition; scim_string_view_size_request (widget, &requisition); *minimal_width = *natural_width = requisition.width; } static void scim_widget_get_preferred_height (GtkWidget *widget, gint *minimal_height, gint *natural_height) { GtkRequisition requisition; scim_string_view_size_request (widget, &requisition); *minimal_height = *natural_height = requisition.height; } #endif static void get_text_area_size (ScimStringView *string_view, gint *x, gint *y, gint *width, gint *height) { gint xborder, yborder; GtkRequisition requisition; GtkWidget *widget = GTK_WIDGET (string_view); #if GTK_CHECK_VERSION(3, 0, 0) gtk_widget_get_preferred_size (widget, &requisition, NULL); #else gtk_widget_get_child_requisition (widget, &requisition); #endif get_borders (string_view, &xborder, &yborder); if (x) *x = xborder; if (y) *y = yborder; if (width) { #if GTK_CHECK_VERSION(3, 0, 0) GtkAllocation allocation; gtk_widget_get_allocation (widget, &allocation); *width = allocation.width - xborder * 2; #else *width = GTK_WIDGET (string_view)->allocation.width - xborder * 2; #endif } if (height) *height = requisition.height - yborder * 2; } static void get_widget_window_size (ScimStringView *string_view, gint *x, gint *y, gint *width, gint *height) { GtkRequisition requisition; GtkWidget *widget = GTK_WIDGET (string_view); // FIXME #if GTK_CHECK_VERSION(3, 0, 0) gtk_widget_get_preferred_size (widget, &requisition, NULL); #else gtk_widget_get_child_requisition (widget, &requisition); #endif #if GTK_CHECK_VERSION(3, 0, 0) GtkAllocation allocation; gtk_widget_get_allocation (widget, &allocation); #else #endif if (x) { #if GTK_CHECK_VERSION(3, 0, 0) *x = allocation.x; #else *x = widget->allocation.x; #endif } if (y) { #if GTK_CHECK_VERSION(3, 0, 0) *y = allocation.y + (allocation.height - requisition.height) / 2; #else *y = widget->allocation.y + (widget->allocation.height - requisition.height) / 2; #endif } if (width) #if GTK_CHECK_VERSION(3, 0, 0) *width = allocation.width; #else *width = widget->allocation.width; #endif if (height) *height = requisition.height; } static void scim_string_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { ScimStringView *string_view = SCIM_STRING_VIEW (widget); #if GTK_CHECK_VERSION(3, 0, 0) gtk_widget_set_allocation (widget, allocation); #else widget->allocation = *allocation; #endif #if GTK_CHECK_VERSION(2, 20, 0) if (gtk_widget_get_realized (widget)) #else if (GTK_WIDGET_REALIZED (widget)) #endif { /* We call gtk_widget_get_child_requisition, since we want (for * backwards compatibility reasons) the realization here to * be affected by the usize of the string_view, if set */ gint x, y, width, height; get_widget_window_size (string_view, &x, &y, &width, &height); #if GTK_CHECK_VERSION(2, 14, 0) gdk_window_move_resize (gtk_widget_get_window (widget), #else gdk_window_move_resize (widget->window, #endif x, y, width, height); get_text_area_size (string_view, &x, &y, &width, &height); gdk_window_move_resize (string_view->text_area, x, y, width, height); scim_string_view_recompute (string_view); } } static void #if GTK_CHECK_VERSION(3, 0, 0) scim_string_view_draw_frame (GtkWidget *widget, cairo_t *cr) #else scim_string_view_draw_frame (GtkWidget *widget) #endif { gint x = 0, y = 0; gint width, height; gboolean interior_focus; gint focus_width; gtk_widget_style_get (widget, "interior-focus", &interior_focus, "focus-line-width", &focus_width, NULL); #if GTK_CHECK_VERSION(2, 24, 0) width = gdk_window_get_width(gtk_widget_get_window (widget)); height = gdk_window_get_height(gtk_widget_get_window (widget)); #elif GTK_CHECK_VERSION(2, 14, 0) gdk_window_get_size (gtk_widget_get_window (widget), &width, &height); #else gdk_window_get_size (widget->window, &width, &height); #endif #if GTK_CHECK_VERSION(2, 18, 0) if (gtk_widget_has_focus (widget) && !interior_focus) #else if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus) #endif { x += focus_width; y += focus_width; width -= 2 * focus_width; height -= 2 * focus_width; } #if GTK_CHECK_VERSION(3, 0, 0) GtkStyleContext *style = gtk_widget_get_style_context(widget); gtk_style_context_save (style); gtk_style_context_set_state (style, GTK_STATE_FLAG_NORMAL); gtk_render_frame (style, cr, x, y, width, height); #else #if GTK_CHECK_VERSION(2, 14, 0) gtk_paint_shadow (widget->style, gtk_widget_get_window (widget), #else gtk_paint_shadow (widget->style, widget->window, #endif GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, widget, "entry", x, y, width, height); #endif #if GTK_CHECK_VERSION(2, 18, 0) if (gtk_widget_has_focus (widget) && !interior_focus) #else if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus) #endif { x -= focus_width; y -= focus_width; width += 2 * focus_width; height += 2 * focus_width; #if GTK_CHECK_VERSION(3, 0, 0) GtkStyleContext *style = gtk_widget_get_style_context(widget); gtk_style_context_save (style); gtk_style_context_set_state (style, gtk_widget_get_state_flags (widget)); gtk_render_focus (style, cr, 0, 0, width, height); #else #if GTK_CHECK_VERSION(2, 18, 0) gtk_paint_focus (widget->style, gtk_widget_get_window (widget), gtk_widget_get_state (widget), #elif GTK_CHECK_VERSION(2, 14, 0) gtk_paint_focus (widget->style, gtk_widget_get_window (widget), GTK_WIDGET_STATE (widget), #else gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), #endif NULL, widget, "entry", 0, 0, width, height); #endif } } static gint #if GTK_CHECK_VERSION(3, 0, 0) scim_string_view_draw (GtkWidget *widget, cairo_t *cr) #else scim_string_view_expose (GtkWidget *widget, GdkEventExpose *event) #endif { ScimStringView *string_view = SCIM_STRING_VIEW (widget); #if GTK_CHECK_VERSION(3, 0, 0) if (gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget))) scim_string_view_draw_frame (widget, cr); else if (gtk_cairo_should_draw_window (cr, string_view->text_area)) #else #if GTK_CHECK_VERSION(2, 14, 0) if (gtk_widget_get_window (widget) == event->window) #else if (widget->window == event->window) #endif scim_string_view_draw_frame (widget); else if (string_view->text_area == event->window) #endif { gint area_width, area_height; get_text_area_size (string_view, NULL, NULL, &area_width, &area_height); #if GTK_CHECK_VERSION(3, 0, 0) GtkStyleContext *style = gtk_widget_get_style_context(widget); gtk_style_context_save (style); gtk_style_context_set_state (style, gtk_widget_get_state_flags (widget)); gtk_render_frame (style, cr, 0, 0, area_width, area_height); #else gtk_paint_flat_box (widget->style, string_view->text_area, #if GTK_CHECK_VERSION(2, 18, 0) gtk_widget_get_state (widget), GTK_SHADOW_NONE, #else GTK_WIDGET_STATE(widget), GTK_SHADOW_NONE, #endif NULL, widget, "entry_bg", 0, 0, area_width, area_height); #endif scim_string_view_draw_text (SCIM_STRING_VIEW (widget)); if (string_view->cursor_visible && string_view->draw_cursor) scim_string_view_draw_cursor (SCIM_STRING_VIEW (widget)); } return FALSE; } static gint scim_string_view_button_press (GtkWidget *widget, GdkEventButton *event) { ScimStringView *string_view = SCIM_STRING_VIEW (widget); gint tmp_pos; if (event->window != string_view->text_area) return FALSE; tmp_pos = scim_string_view_find_position (string_view, event->x + string_view->scroll_offset); if (event->button == 1) { g_signal_emit (G_OBJECT (widget), string_view_signals [MOVE_CURSOR], 0, tmp_pos); return !string_view->forward_event; } return FALSE; } static gint scim_string_view_focus_in (GtkWidget *widget, GdkEventFocus *event) { ScimStringView *string_view = SCIM_STRING_VIEW (widget); gtk_widget_queue_draw (widget); g_signal_connect (gdk_keymap_get_default (), "direction_changed", G_CALLBACK (scim_string_view_keymap_direction_changed), string_view); scim_string_view_check_cursor_blink (string_view); return FALSE; } static gint scim_string_view_focus_out (GtkWidget *widget, GdkEventFocus *event) { ScimStringView *string_view = SCIM_STRING_VIEW (widget); gtk_widget_queue_draw (widget); scim_string_view_check_cursor_blink (string_view); g_signal_handlers_disconnect_by_func (gdk_keymap_get_default (), (gpointer) scim_string_view_keymap_direction_changed, string_view); return FALSE; } static void scim_string_view_direction_changed (GtkWidget *widget, GtkTextDirection previous_dir) { ScimStringView *string_view = SCIM_STRING_VIEW (widget); scim_string_view_recompute (string_view); GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir); } static void scim_string_view_state_changed (GtkWidget *widget, GtkStateType previous_state) { ScimStringView *string_view = SCIM_STRING_VIEW (widget); #if GTK_CHECK_VERSION(2, 20, 0) if (gtk_widget_get_realized (widget)) #else if (GTK_WIDGET_REALIZED (widget)) #endif { #if GTK_CHECK_VERSION(3, 0, 0) GtkStyleContext *style = gtk_widget_get_style_context (widget); GdkRGBA bg_color; gtk_style_context_get_background_color (style, gtk_widget_get_state_flags (widget), &bg_color); gdk_window_set_background_rgba (gtk_widget_get_window (widget), &bg_color); gdk_window_set_background_rgba (string_view->text_area, &bg_color); #else #if GTK_CHECK_VERSION(2, 18, 0) gdk_window_set_background (gtk_widget_get_window (widget), &widget->style->base[gtk_widget_get_state (widget)]); gdk_window_set_background (string_view->text_area, &widget->style->base[gtk_widget_get_state (widget)]); #else gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]); gdk_window_set_background (string_view->text_area, &widget->style->base[GTK_WIDGET_STATE (widget)]); #endif #endif } gtk_widget_queue_draw (widget); } static void scim_string_view_style_set (GtkWidget *widget, GtkStyle *previous_style) { ScimStringView *string_view = SCIM_STRING_VIEW (widget); #if GTK_CHECK_VERSION(2, 20, 0) if (previous_style && gtk_widget_get_realized (widget)) #else if (previous_style && GTK_WIDGET_REALIZED (widget)) #endif { scim_string_view_recompute (string_view); #if GTK_CHECK_VERSION(3, 0, 0) GtkStyleContext *style = gtk_widget_get_style_context (widget); GdkRGBA bg_color; gtk_style_context_get_background_color (style, gtk_widget_get_state_flags (widget), &bg_color); gdk_window_set_background_rgba (gtk_widget_get_window (widget), &bg_color); gdk_window_set_background_rgba (string_view->text_area, &bg_color); #else #if GTK_CHECK_VERSION(2, 18, 0) gdk_window_set_background (gtk_widget_get_window (widget), &widget->style->base[gtk_widget_get_state (widget)]); gdk_window_set_background (string_view->text_area, &widget->style->base[gtk_widget_get_state (widget)]); #else gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]); gdk_window_set_background (string_view->text_area, &widget->style->base[GTK_WIDGET_STATE (widget)]); #endif #endif } } /* Default signal handlers */ static void scim_string_view_keymap_direction_changed (GdkKeymap *keymap, ScimStringView *string_view) { scim_string_view_queue_draw (string_view); } /* Internal functions */ static void scim_string_view_reset_layout (ScimStringView *string_view) { if (string_view->cached_layout) { g_object_unref (G_OBJECT (string_view->cached_layout)); string_view->cached_layout = NULL; } } static gboolean recompute_idle_func (gpointer data) { ScimStringView *string_view; #if !GTK_CHECK_VERSION(2, 12, 0) GDK_THREADS_ENTER (); #endif string_view = SCIM_STRING_VIEW (data); scim_string_view_adjust_scroll (string_view); scim_string_view_queue_draw (string_view); string_view->recompute_idle = 0; #if !GTK_CHECK_VERSION(2, 12, 0) GDK_THREADS_LEAVE (); #endif return FALSE; } static void scim_string_view_recompute (ScimStringView *string_view) { scim_string_view_reset_layout (string_view); scim_string_view_check_cursor_blink (string_view); if (!string_view->recompute_idle) { string_view->recompute_idle = #if GTK_CHECK_VERSION(2, 12, 0) gdk_threads_add_idle_full #else g_idle_add_full #endif (G_PRIORITY_HIGH_IDLE + 15, /* between resize and redraw */ recompute_idle_func, string_view, NULL); } } static PangoLayout * scim_string_view_create_layout (ScimStringView *string_view) { PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET (string_view), NULL); if (!string_view->attrs) string_view->attrs = pango_attr_list_new (); pango_layout_set_single_paragraph_mode (layout, TRUE); pango_layout_set_text (layout, string_view->text, string_view->n_bytes); pango_layout_set_attributes (layout, string_view->attrs); return layout; } static PangoLayout * scim_string_view_ensure_layout (ScimStringView *string_view) { if (!string_view->cached_layout) { string_view->cached_layout = scim_string_view_create_layout (string_view); } return string_view->cached_layout; } static void get_layout_position (ScimStringView *string_view, gint *x, gint *y) { PangoLayout *layout; PangoRectangle logical_rect; gint area_width, area_height; gint y_pos; PangoLayoutLine *line; layout = scim_string_view_ensure_layout (string_view); get_text_area_size (string_view, NULL, NULL, &area_width, &area_height); area_height = PANGO_SCALE * (area_height - 2 * INNER_BORDER); line = pango_layout_get_lines (layout)->data; pango_layout_line_get_extents (line, NULL, &logical_rect); /* Align primarily for locale's ascent/descent */ y_pos = ((area_height - string_view->ascent - string_view->descent) / 2 + string_view->ascent + logical_rect.y); /* Now see if we need to adjust to fit in actual drawn string */ if (logical_rect.height > area_height) y_pos = (area_height - logical_rect.height) / 2; else if (y_pos < 0) y_pos = 0; else if (y_pos + logical_rect.height > area_height) y_pos = area_height - logical_rect.height; y_pos = INNER_BORDER + y_pos / PANGO_SCALE; if (x) *x = INNER_BORDER - string_view->scroll_offset; if (y) *y = y_pos; } static void scim_string_view_draw_text (ScimStringView *string_view) { GtkWidget *widget; #if GTK_CHECK_VERSION(2, 18, 0) if (gtk_widget_is_drawable (GTK_WIDGET (string_view))) #else if (GTK_WIDGET_DRAWABLE (string_view)) #endif { PangoLayout *layout = scim_string_view_ensure_layout (string_view); gint x, y; widget = GTK_WIDGET (string_view); get_layout_position (string_view, &x, &y); #if GTK_CHECK_VERSION(3, 0, 0) cairo_t *cr = gdk_cairo_create (string_view->text_area); GdkRGBA rgba; gtk_style_context_get_color (gtk_widget_get_style_context (widget), gtk_widget_get_state_flags (widget), &rgba); gdk_cairo_set_source_rgba (cr, &rgba); cairo_move_to (cr, x, y); pango_cairo_show_layout (cr, layout); cairo_destroy (cr); #else gdk_draw_layout (string_view->text_area, widget->style->text_gc [widget->state], x, y, layout); #endif if (string_view->highlight_start >=0 && string_view->highlight_start < string_view->highlight_end && string_view->highlight_start < string_view->text_length) { gint *ranges; gint n_ranges, i; gint start_pos = string_view->highlight_start; gint end_pos = (string_view->text_length > string_view->highlight_end)? string_view->highlight_end : string_view->text_length; PangoRectangle logical_rect; const gchar *text = pango_layout_get_text (layout); gint start_index = g_utf8_offset_to_pointer (text, start_pos) - text; gint end_index = g_utf8_offset_to_pointer (text, end_pos) - text; #if GTK_CHECK_VERSION(3, 0, 0) cairo_region_t *clip_region = cairo_region_create (); GdkRGBA selection_rgba; GdkRGBA text_rgba; #else GdkRegion *clip_region = gdk_region_new (); GdkGC *text_gc; GdkGC *selection_gc; #endif PangoLayoutLine *line; line = pango_layout_get_lines (layout)->data; pango_layout_line_get_x_ranges (line, start_index, end_index, &ranges, &n_ranges); pango_layout_get_extents (layout, NULL, &logical_rect); #if GTK_CHECK_VERSION(3, 0, 0) gtk_style_context_get_background_color ( gtk_widget_get_style_context (widget), GTK_STATE_FLAG_ACTIVE, &selection_rgba); gtk_style_context_get_color ( gtk_widget_get_style_context (widget), GTK_STATE_ACTIVE, &text_rgba); #else selection_gc = widget->style->base_gc [GTK_STATE_ACTIVE]; text_gc = widget->style->text_gc [GTK_STATE_ACTIVE]; #endif for (i=0; i < n_ranges; ++i) { #if GTK_CHECK_VERSION(3, 0, 0) cairo_rectangle_int_t rect; #else GdkRectangle rect; #endif rect.x = INNER_BORDER - string_view->scroll_offset + ranges[2*i] / PANGO_SCALE; rect.y = y; rect.width = (ranges[2*i + 1] - ranges[2*i]) / PANGO_SCALE; rect.height = logical_rect.height / PANGO_SCALE; #if GTK_CHECK_VERSION(3, 0, 0) cairo_t *cr = gdk_cairo_create (string_view->text_area); cairo_set_source_surface (cr, cairo_get_target (cr), 0, 0); cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT); gdk_cairo_set_source_rgba (cr, &selection_rgba); cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height); cairo_fill (cr); cairo_destroy (cr); cairo_region_union_rectangle (clip_region, &rect); #else gdk_draw_rectangle (string_view->text_area, selection_gc, TRUE, rect.x, rect.y, rect.width, rect.height); gdk_region_union_with_rect (clip_region, &rect); #endif } #if GTK_CHECK_VERSION(3, 0, 0) cairo_t *cr = gdk_cairo_create (string_view->text_area); gdk_cairo_region (cr, clip_region); cairo_clip (cr); gdk_cairo_set_source_rgba (cr, &text_rgba); cairo_move_to (cr, x, y); pango_cairo_show_layout (cr, layout); cairo_destroy (cr); cairo_region_destroy (clip_region); #else gdk_gc_set_clip_region (text_gc, clip_region); gdk_draw_layout (string_view->text_area, text_gc, x, y, layout); gdk_gc_set_clip_region (text_gc, NULL); gdk_region_destroy (clip_region); #endif g_free (ranges); } } } #if !GTK_CHECK_VERSION(2, 3, 5) typedef struct _CursorInfo CursorInfo; struct _CursorInfo { GType for_type; GdkGC *primary_gc; GdkGC *secondary_gc; }; static GdkGC * make_cursor_gc (GtkWidget *widget, const gchar *property_name, const GdkColor *fallback) { GdkGCValues gc_values; GdkGCValuesMask gc_values_mask; GdkColor *cursor_color; gtk_widget_style_get (widget, property_name, &cursor_color, NULL); gc_values_mask = GDK_GC_FOREGROUND; if (cursor_color) { gc_values.foreground = *cursor_color; gdk_color_free (cursor_color); } else gc_values.foreground = *fallback; gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground); return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask); } static GdkGC * get_insertion_cursor_gc (GtkWidget *widget, gboolean is_primary) { CursorInfo *cursor_info; cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info"); if (!cursor_info) { cursor_info = g_new (CursorInfo, 1); g_object_set_data (G_OBJECT (widget->style), "gtk-style-cursor-info", cursor_info); cursor_info->primary_gc = NULL; cursor_info->secondary_gc = NULL; cursor_info->for_type = G_TYPE_INVALID; } /* We have to keep track of the type because gtk_widget_style_get() * can return different results when called on the same property and * same style but for different widgets. :-(. That is, * GtkEntry::cursor-color = "red" in a style will modify the cursor * color for entries but not for text view. */ if (cursor_info->for_type != G_OBJECT_TYPE (widget)) { cursor_info->for_type = G_OBJECT_TYPE (widget); if (cursor_info->primary_gc) { gtk_gc_release (cursor_info->primary_gc); cursor_info->primary_gc = NULL; } if (cursor_info->secondary_gc) { gtk_gc_release (cursor_info->secondary_gc); cursor_info->secondary_gc = NULL; } } if (is_primary) { if (!cursor_info->primary_gc) cursor_info->primary_gc = make_cursor_gc (widget, "cursor-color", &widget->style->black); return cursor_info->primary_gc; } else { static const GdkColor gray = { 0, 0x8888, 0x8888, 0x8888 }; if (!cursor_info->secondary_gc) cursor_info->secondary_gc = make_cursor_gc (widget, "secondary-cursor-color", &gray); return cursor_info->secondary_gc; } } static void draw_insertion_cursor (GtkWidget *widget, GdkDrawable *drawable, GdkGC *gc, GdkRectangle *location, GtkTextDirection direction, gboolean draw_arrow) { gint stem_width; gint arrow_width; gint x, y; gint i; gfloat cursor_aspect_ratio; gint offset; g_return_if_fail (direction != GTK_TEXT_DIR_NONE); gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL); stem_width = location->height * cursor_aspect_ratio + 1; arrow_width = stem_width + 1; /* put (stem_width % 2) on the proper side of the cursor */ if (direction == GTK_TEXT_DIR_LTR) offset = stem_width / 2; else offset = stem_width - stem_width / 2; for (i = 0; i < stem_width; i++) gdk_draw_line (drawable, gc, location->x + i - offset, location->y, location->x + i - offset, location->y + location->height - 1); if (draw_arrow) { if (direction == GTK_TEXT_DIR_RTL) { x = location->x - offset - 1; y = location->y + location->height - arrow_width * 2 - arrow_width + 1; for (i = 0; i < arrow_width; i++) { gdk_draw_line (drawable, gc, x, y + i + 1, x, y + 2 * arrow_width - i - 1); x --; } } else if (direction == GTK_TEXT_DIR_LTR) { x = location->x + stem_width - offset; y = location->y + location->height - arrow_width * 2 - arrow_width + 1; for (i = 0; i < arrow_width; i++) { gdk_draw_line (drawable, gc, x, y + i + 1, x, y + 2 * arrow_width - i - 1); x++; } } } } static void scim_string_view_draw_insertion_cursor (GtkWidget *widget, GdkDrawable *drawable, PangoLayout *layout, GdkRectangle *area, GdkRectangle *location, gboolean is_primary, GtkTextDirection direction, gboolean draw_arrow, gint index) { GdkGC *gc; g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (GDK_IS_DRAWABLE (drawable)); g_return_if_fail (location != NULL); g_return_if_fail (direction != GTK_TEXT_DIR_NONE); gc = get_insertion_cursor_gc (widget, is_primary); if (area) gdk_gc_set_clip_rectangle (gc, area); draw_insertion_cursor (widget, drawable, gc, location, direction, draw_arrow); if (area) gdk_gc_set_clip_rectangle (gc, NULL); } #else static void scim_string_view_draw_insertion_cursor (GtkWidget *widget, #if GTK_CHECK_VERSION(3, 0, 0) GdkWindow *drawable, #else GdkDrawable *drawable, #endif PangoLayout *layout, GdkRectangle *area, GdkRectangle *location, gboolean is_primary, GtkTextDirection direction, gboolean draw_arrow, gint index) { #if GTK_CHECK_VERSION(3, 0, 0) cairo_t *cr = gdk_cairo_create (drawable); /* #if GTK_CHECK_VERSION(3, 4, 0) GtkStyleContext *context = gtk_widget_get_style_context (widget); gtk_render_insertion_cursor ( context, cr, (gdouble)location->x, (gdouble)location->y, layout, index, direction == GTK_TEXT_DIR_LTR ? PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL ); #else */ G_GNUC_BEGIN_IGNORE_DEPRECATIONS gtk_draw_insertion_cursor (widget, cr, location, is_primary, direction, draw_arrow); G_GNUC_END_IGNORE_DEPRECATIONS /* #endif */ cairo_destroy (cr); #else gtk_draw_insertion_cursor (widget, drawable, area, location, is_primary, direction, draw_arrow); #endif } #endif static void scim_string_view_draw_cursor (ScimStringView *string_view) { GtkTextDirection keymap_direction = (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; GtkTextDirection widget_direction = gtk_widget_get_direction (GTK_WIDGET (string_view)); #if GTK_CHECK_VERSION(2, 18, 0) if (gtk_widget_is_drawable (GTK_WIDGET (string_view))) #else if (GTK_WIDGET_DRAWABLE (string_view)) #endif { GtkWidget *widget = GTK_WIDGET (string_view); GdkRectangle cursor_location; GdkRectangle clip_area; gboolean split_cursor; gint xoffset = INNER_BORDER - string_view->scroll_offset; gint strong_x, weak_x; gint text_area_height; gint text_area_width; GtkTextDirection dir1 = GTK_TEXT_DIR_NONE; GtkTextDirection dir2 = GTK_TEXT_DIR_NONE; gint x1 = 0; gint x2 = 0; #if GTK_CHECK_VERSION(2, 24, 0) text_area_width = gdk_window_get_width (string_view->text_area); text_area_height = gdk_window_get_height (string_view->text_area); #else gdk_window_get_size (string_view->text_area, &text_area_width, &text_area_height); #endif gint index = scim_string_view_get_cursor_locations (string_view, &strong_x, &weak_x); g_object_get (gtk_widget_get_settings (widget), "gtk-split-cursor", &split_cursor, NULL); dir1 = widget_direction; if (split_cursor) { x1 = strong_x; if (weak_x != strong_x) { dir2 = (widget_direction == GTK_TEXT_DIR_LTR) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR; x2 = weak_x; } } else { if (keymap_direction == widget_direction) x1 = strong_x; else x1 = weak_x; } cursor_location.x = xoffset + x1; cursor_location.y = INNER_BORDER; cursor_location.width = 0; cursor_location.height = text_area_height - 2 * INNER_BORDER ; clip_area.x = 0; clip_area.y = 0; clip_area.width = text_area_width; clip_area.height = text_area_height; scim_string_view_draw_insertion_cursor (widget, string_view->text_area, scim_string_view_ensure_layout (string_view), &clip_area, &cursor_location, TRUE, dir1, dir2 != GTK_TEXT_DIR_NONE, index); if (dir2 != GTK_TEXT_DIR_NONE) { cursor_location.x = xoffset + x2; scim_string_view_draw_insertion_cursor (widget, string_view->text_area, scim_string_view_ensure_layout (string_view), &clip_area, &cursor_location, FALSE, dir2, TRUE, index); } } } static void scim_string_view_queue_draw (ScimStringView *string_view) { #if GTK_CHECK_VERSION(2, 20, 0) if (gtk_widget_get_realized (GTK_WIDGET (string_view))) #else if (GTK_WIDGET_REALIZED (string_view)) #endif gdk_window_invalidate_rect (string_view->text_area, NULL, FALSE); } static gint scim_string_view_find_position (ScimStringView *string_view, gint x) { PangoLayout *layout; PangoLayoutLine *line; gint index; gint pos; gboolean trailing; layout = scim_string_view_ensure_layout (string_view); line = pango_layout_get_lines (layout)->data; pango_layout_line_x_to_index (line, x * PANGO_SCALE, &index, &trailing); pos = g_utf8_pointer_to_offset (string_view->text, string_view->text + index); pos += trailing; return pos; } static gint scim_string_view_get_cursor_locations (ScimStringView *string_view, gint *strong_x, gint *weak_x) { PangoLayout *layout = scim_string_view_ensure_layout (string_view); const gchar *text; PangoRectangle strong_pos, weak_pos; gint index; text = pango_layout_get_text (layout); index = g_utf8_offset_to_pointer (text, string_view->current_pos) - text; pango_layout_get_cursor_pos (layout, index, &strong_pos, &weak_pos); if (strong_x) *strong_x = strong_pos.x / PANGO_SCALE; if (weak_x) *weak_x = weak_pos.x / PANGO_SCALE; return index; } static void scim_string_view_adjust_scroll (ScimStringView *string_view) { gint min_offset, max_offset; gint text_area_width; gint strong_x, weak_x; gint strong_xoffset, weak_xoffset; PangoLayout *layout; PangoLayoutLine *line; PangoRectangle logical_rect; #if GTK_CHECK_VERSION(2, 20, 0) if (!gtk_widget_get_realized (GTK_WIDGET (string_view))) #else if (!GTK_WIDGET_REALIZED (string_view)) #endif return; #if GTK_CHECK_VERSION(2, 24, 0) text_area_width = gdk_window_get_width(string_view->text_area); #else gdk_window_get_size (string_view->text_area, &text_area_width, NULL); #endif text_area_width -= 2 * INNER_BORDER; layout = scim_string_view_ensure_layout (string_view); line = pango_layout_get_lines (layout)->data; pango_layout_line_get_extents (line, NULL, &logical_rect); /* Display as much text as we can */ if (gtk_widget_get_direction (GTK_WIDGET (string_view)) == GTK_TEXT_DIR_LTR) { min_offset = 0; max_offset = MAX (min_offset, logical_rect.width / PANGO_SCALE - text_area_width); } else { max_offset = logical_rect.width / PANGO_SCALE - text_area_width; min_offset = MIN (0, max_offset); } string_view->scroll_offset = CLAMP (string_view->scroll_offset, min_offset, max_offset); /* And make sure cursors are on screen. Note that the cursor is * actually drawn one pixel into the INNER_BORDER space on * the right, when the scroll is at the utmost right. This * looks better to to me than confining the cursor inside the * border entirely, though it means that the cursor gets one * pixel closer to the the edge of the widget on the right than * on the left. This might need changing if one changed * INNER_BORDER from 2 to 1, as one would do on a * small-screen-real-estate display. * * We always make sure that the strong cursor is on screen, and * put the weak cursor on screen if possible. */ scim_string_view_get_cursor_locations (string_view, &strong_x, &weak_x); strong_xoffset = strong_x - string_view->scroll_offset; if (strong_xoffset < 0) { string_view->scroll_offset += strong_xoffset; strong_xoffset = 0; } else if (strong_xoffset > text_area_width) { string_view->scroll_offset += strong_xoffset - text_area_width; strong_xoffset = text_area_width; } weak_xoffset = weak_x - string_view->scroll_offset; if (weak_xoffset < 0 && strong_xoffset - weak_xoffset <= text_area_width) { string_view->scroll_offset += weak_xoffset; } else if (weak_xoffset > text_area_width && strong_xoffset - (weak_xoffset - text_area_width) >= 0) { string_view->scroll_offset += weak_xoffset - text_area_width; } g_object_notify (G_OBJECT (string_view), "scroll_offset"); } static void scim_string_view_move_cursor (ScimStringView *string_view, guint position) { if (string_view->auto_move_cursor) scim_string_view_set_position (string_view, position); } /* Public API */ GtkWidget* scim_string_view_new (void) { return GTK_WIDGET (g_object_new (SCIM_TYPE_STRING_VIEW, NULL)); } void scim_string_view_set_position (ScimStringView *string_view, gint position) { gboolean changed = FALSE; g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); g_object_freeze_notify (G_OBJECT (string_view)); if (position != -1 && string_view->current_pos != position) { string_view->current_pos = (position > string_view->text_length)?(string_view->text_length):position; changed = TRUE; g_object_notify (G_OBJECT (string_view), "cursor_position"); } g_object_thaw_notify (G_OBJECT (string_view)); if (changed) scim_string_view_recompute (string_view); } gint scim_string_view_get_position (ScimStringView *string_view) { g_return_val_if_fail (SCIM_IS_STRING_VIEW (string_view), FALSE); return string_view->current_pos; } void scim_string_view_set_max_width (ScimStringView *string_view, gint width) { g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); if (string_view->max_width == width) return; if (width > 0 && width < MIN_STRING_VIEW_WIDTH) width = MIN_STRING_VIEW_WIDTH; string_view->max_width = width; g_object_notify (G_OBJECT (string_view), "cursor_position"); scim_string_view_recompute (string_view); } gint scim_string_view_get_max_width (ScimStringView *string_view) { g_return_val_if_fail (SCIM_IS_STRING_VIEW (string_view), FALSE); return string_view->max_width; } void scim_string_view_set_draw_cursor (ScimStringView *string_view, gboolean setting) { g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); setting = (setting != FALSE); if (string_view->draw_cursor == setting) return; string_view->draw_cursor = setting; gtk_widget_queue_draw (GTK_WIDGET (string_view)); g_object_notify (G_OBJECT (string_view), "draw_cursor"); } gboolean scim_string_view_get_draw_cursor (ScimStringView *string_view) { g_return_val_if_fail (SCIM_IS_STRING_VIEW (string_view), FALSE); return string_view->draw_cursor; } void scim_string_view_set_auto_move_cursor (ScimStringView *string_view, gboolean setting) { g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); setting = (setting != FALSE); if (string_view->auto_move_cursor == setting) return; string_view->auto_move_cursor = setting; g_object_notify (G_OBJECT (string_view), "auto_move_cursor"); } gboolean scim_string_view_get_auto_move_cursor (ScimStringView *string_view) { g_return_val_if_fail (SCIM_IS_STRING_VIEW (string_view), FALSE); return string_view->auto_move_cursor; } void scim_string_view_set_forward_event (ScimStringView *string_view, gboolean setting) { g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); setting = (setting != FALSE); if (string_view->forward_event == setting) return; string_view->forward_event = setting; g_object_notify (G_OBJECT (string_view), "forward_event"); } void scim_string_view_set_auto_resize (ScimStringView *string_view, gboolean setting) { g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); setting = (setting != FALSE); if (string_view->auto_resize == setting) return; string_view->auto_resize = setting; g_object_notify (G_OBJECT (string_view), "auto_resize"); } gboolean scim_string_view_get_auto_resize (ScimStringView *string_view) { g_return_val_if_fail (SCIM_IS_STRING_VIEW (string_view), FALSE); return string_view->auto_resize; } gboolean scim_string_view_get_forward_event (ScimStringView *string_view) { g_return_val_if_fail (SCIM_IS_STRING_VIEW (string_view), FALSE); return string_view->forward_event; } const gchar* scim_string_view_get_text (ScimStringView *string_view) { g_return_val_if_fail (SCIM_IS_STRING_VIEW (string_view), NULL); return string_view->text; } void scim_string_view_set_text (ScimStringView *string_view, const gchar *text) { gint new_text_length; gint new_nbytes; g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); g_return_if_fail (text != NULL); /* Actually setting the text will affect the cursor and selection; * if the contents don't actually change, this will look odd to the user. */ if (strcmp (string_view->text, text) == 0) return; new_nbytes = strlen (text); new_text_length= g_utf8_strlen (text, new_nbytes); if (string_view->text_max_length > 0 && new_text_length > string_view->text_max_length) { gdk_beep (); new_text_length = string_view->text_max_length; new_nbytes= g_utf8_offset_to_pointer (text, new_text_length) - text; } if (new_nbytes >= string_view->text_size) { string_view->text = g_realloc (string_view->text, new_nbytes + 1); string_view->text_size = new_nbytes + 1; } memcpy (string_view->text, text, new_nbytes); string_view->n_bytes = new_nbytes; string_view->text_length = new_text_length; /* NUL terminate for safety and convenience */ string_view->text[string_view->n_bytes] = '\0'; if (string_view->current_pos > string_view->text_length) string_view->current_pos = string_view->text_length; if (string_view->auto_resize) gtk_widget_queue_resize (GTK_WIDGET (string_view)); scim_string_view_recompute (string_view); g_object_notify (G_OBJECT (string_view), "text"); } /** * scim_string_view_set_max_length: * @string_view: a #ScimStringView. * @max: the maximum length of the string_view, or 0 for no maximum. * (other than the maximum length of entries.) The value passed in will * be clamped to the range 0-65536. * * Sets the maximum allowed length of the contents of the widget. If * the current contents are longer than the given length, then they * will be truncated to fit. **/ void scim_string_view_set_max_length (ScimStringView *string_view, gint max) { gint nbytes; g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); max = CLAMP (max, 0, MAX_SIZE); if (max > 0 && string_view->text_length > max) { string_view->text_length = max; nbytes = g_utf8_offset_to_pointer (string_view->text, max) - string_view->text; string_view->text_size = nbytes + 1; string_view->text = g_realloc (string_view->text, string_view->text_size); string_view->text [nbytes] = '\0'; string_view->n_bytes = nbytes; string_view->text_length = max; if (string_view->current_pos > string_view->text_length) string_view->current_pos = string_view->text_length; if (string_view->auto_resize) gtk_widget_queue_resize (GTK_WIDGET (string_view)); scim_string_view_recompute (string_view); } string_view->text_max_length = max; g_object_notify (G_OBJECT (string_view), "max_length"); } /** * scim_string_view_get_max_length: * @string_view: a #ScimStringView * * Retrieves the maximum allowed length of the text in * @string_view. See scim_string_view_set_max_length(). * * Return value: the maximum allowed number of characters * in #ScimStringView, or 0 if there is no maximum. **/ gint scim_string_view_get_max_length (ScimStringView *string_view) { g_return_val_if_fail (SCIM_IS_STRING_VIEW (string_view), 0); return string_view->text_max_length; } /** * scim_string_view_set_width_chars: * @string_view: a #ScimStringView * @n_chars: width in chars * * Changes the size request of the string_view to be about the right size * for @n_chars characters. Note that it changes the size * request, the size can still be affected by * how you pack the widget into containers. If @n_chars is -1, the * size reverts to the default string_view size. * **/ void scim_string_view_set_width_chars (ScimStringView *string_view, gint n_chars) { g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); if (string_view->width_chars != n_chars) { string_view->width_chars = n_chars; g_object_notify (G_OBJECT (string_view), "width_chars"); gtk_widget_queue_resize (GTK_WIDGET (string_view)); } } /** * scim_string_view_get_width_chars: * @string_view: a #ScimStringView * * Gets the value set by scim_string_view_set_width_chars(). * * Return value: number of chars to request space for, or negative if unset **/ gint scim_string_view_get_width_chars (ScimStringView *string_view) { g_return_val_if_fail (SCIM_IS_STRING_VIEW (string_view), 0); return string_view->width_chars; } /** * scim_string_view_set_has_frame: * @string_view: a #ScimStringView * @setting: new value * * Sets whether the string_view has a beveled frame around it. **/ void scim_string_view_set_has_frame (ScimStringView *string_view, gboolean setting) { g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); setting = (setting != FALSE); if (string_view->has_frame == setting) return; gtk_widget_queue_resize (GTK_WIDGET (string_view)); string_view->has_frame = setting; g_object_notify (G_OBJECT (string_view), "has_frame"); } /** * scim_string_view_get_has_frame: * @string_view: a #ScimStringView * * Gets the value set by scim_string_view_set_has_frame(). * * Return value: whether the string_view has a beveled frame **/ gboolean scim_string_view_get_has_frame (ScimStringView *string_view) { g_return_val_if_fail (SCIM_IS_STRING_VIEW (string_view), FALSE); return string_view->has_frame; } /** * scim_string_view_get_layout: * @string_view: a #ScimStringView * * Gets the #PangoLayout used to display the string_view. * The layout is useful to e.g. convert text positions to * pixel positions, in combination with scim_string_view_get_layout_offsets(). * The returned layout is owned by the string_view so need not be * freed by the caller. * * Keep in mind that the layout text may contain a preedit string, so * scim_string_view_layout_index_to_text_index() and * scim_string_view_text_index_to_layout_index() are needed to convert byte * indices in the layout to byte indices in the string_view contents. * * Return value: the #PangoLayout for this string_view **/ PangoLayout* scim_string_view_get_layout (ScimStringView *string_view) { PangoLayout *layout; g_return_val_if_fail (SCIM_IS_STRING_VIEW (string_view), NULL); layout = scim_string_view_ensure_layout (string_view); return layout; } /** * scim_string_view_get_layout_offsets: * @string_view: a #ScimStringView * @x: location to store X offset of layout, or %NULL * @y: location to store Y offset of layout, or %NULL * * * Obtains the position of the #PangoLayout used to render text * in the string_view, in widget coordinates. Useful if you want to line * up the text in an string_view with some other text, e.g. when using the * string_view to implement editable cells in a sheet widget. * * Also useful to convert mouse events into coordinates inside the * #PangoLayout, e.g. to take some action if some part of the string_view text * is clicked. * * Note that as the user scrolls around in the string_view the offsets will * change; you'll need to connect to the "notify::scroll_offset" * signal to track this. Remember when using the #PangoLayout * functions you need to convert to and from pixels using * PANGO_PIXELS() or #PANGO_SCALE. * * Keep in mind that the layout text may contain a preedit string, so * scim_string_view_layout_index_to_text_index() and * scim_string_view_text_index_to_layout_index() are needed to convert byte * indices in the layout to byte indices in the string_view contents. * **/ void scim_string_view_get_layout_offsets (ScimStringView *string_view, gint *x, gint *y) { gint text_area_x, text_area_y; g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); /* this gets coords relative to text area */ get_layout_position (string_view, x, y); /* convert to widget coords */ get_text_area_size (string_view, &text_area_x, &text_area_y, NULL, NULL); if (x) *x += text_area_x; if (y) *y += text_area_y; } void scim_string_view_set_highlight (ScimStringView *string_view, gint start, gint end) { g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); string_view->highlight_start = start; string_view->highlight_end = end; gtk_widget_queue_draw (GTK_WIDGET (string_view)); } void scim_string_view_get_highlight (ScimStringView *string_view, gint *start, gint *end) { g_return_if_fail (SCIM_IS_STRING_VIEW (string_view)); if (start) *start = string_view->highlight_start; if (end) *end = string_view->highlight_end; } void scim_string_view_set_attributes (ScimStringView *entry, PangoAttrList *attrs) { g_return_if_fail (SCIM_IS_STRING_VIEW (entry)); if (attrs) pango_attr_list_ref (attrs); if (entry->attrs) pango_attr_list_unref (entry->attrs); entry->attrs = attrs; scim_string_view_recompute (entry); } PangoAttrList * scim_string_view_get_attributes (ScimStringView *entry) { g_return_val_if_fail (SCIM_IS_STRING_VIEW (entry), NULL); return entry->attrs; } #define CURSOR_ON_MULTIPLIER 0.66 #define CURSOR_OFF_MULTIPLIER 0.34 #define CURSOR_PEND_MULTIPLIER 1.0 static gboolean cursor_blinks (ScimStringView *string_view) { GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (string_view)); gboolean blink; g_object_get (G_OBJECT (settings), "gtk-cursor-blink", &blink, NULL); return blink; } static gint get_cursor_time (ScimStringView *string_view) { GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (string_view)); gint time; g_object_get (G_OBJECT (settings), "gtk-cursor-blink-time", &time, NULL); return time; } static void show_cursor (ScimStringView *string_view) { if (!string_view->cursor_visible) { string_view->cursor_visible = TRUE; gtk_widget_queue_draw (GTK_WIDGET (string_view)); } } static void hide_cursor (ScimStringView *string_view) { if (string_view->cursor_visible) { string_view->cursor_visible = FALSE; gtk_widget_queue_draw (GTK_WIDGET (string_view)); } } /* * Blink! */ static gint blink_cb (gpointer data) { ScimStringView *string_view; #if !GTK_CHECK_VERSION(2, 12, 0) GDK_THREADS_ENTER (); #endif string_view = SCIM_STRING_VIEW (data); if (string_view->cursor_visible) { hide_cursor (string_view); string_view->blink_timeout = g_timeout_add (get_cursor_time (string_view) * CURSOR_OFF_MULTIPLIER, blink_cb, string_view); } else { show_cursor (string_view); string_view->blink_timeout = g_timeout_add (get_cursor_time (string_view) * CURSOR_ON_MULTIPLIER, blink_cb, string_view); } #if !GTK_CHECK_VERSION(2, 12, 0) GDK_THREADS_LEAVE (); #endif /* Remove ourselves */ return FALSE; } static void scim_string_view_check_cursor_blink (ScimStringView *string_view) { if (cursor_blinks (string_view)) { if (!string_view->blink_timeout) { string_view->blink_timeout = g_timeout_add (get_cursor_time (string_view) * CURSOR_ON_MULTIPLIER, blink_cb, string_view); show_cursor (string_view); } } else { if (string_view->blink_timeout) { g_source_remove (string_view->blink_timeout); string_view->blink_timeout = 0; } string_view->cursor_visible = TRUE; } } /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/utils/scimkeyselection.h0000644000175000017500000000767512422143415017041 0ustar tzhuantzhuan#ifndef __SCIM_KEY_SELECTION_H__ #define __SCIM_KEY_SELECTION_H__ #include #include G_BEGIN_DECLS #define SCIM_TYPE_KEY_SELECTION (scim_key_selection_get_type ()) #define SCIM_KEY_SELECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SCIM_TYPE_KEY_SELECTION, ScimKeySelection)) #define SCIM_KEY_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SCIM_TYPE_KEY_SELECTION, ScimKeySelectionClass)) #define SCIM_IS_KEY_SELECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SCIM_TYPE_KEY_SELECTION)) #define SCIM_IS_KEY_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SCIM_TYPE_KEY_SELECTION)) #define SCIM_KEY_SELECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SCIM_TYPE_KEY_SELECTION, ScimKeySelectionClass)) #define SCIM_TYPE_KEY_SELECTION_DIALOG (scim_key_selection_dialog_get_type ()) #define SCIM_KEY_SELECTION_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SCIM_TYPE_KEY_SELECTION_DIALOG, ScimKeySelectionDialog)) #define SCIM_KEY_SELECTION_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SCIM_TYPE_KEY_SELECTION_DIALOG, ScimKeySelectionDialogClass)) #define SCIM_IS_KEY_SELECTION_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SCIM_TYPE_KEY_SELECTION_DIALOG)) #define SCIM_IS_KEY_SELECTION_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SCIM_TYPE_KEY_SELECTION_DIALOG)) #define SCIM_KEY_SELECTION_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SCIM_TYPE_KEY_SELECTION_DIALOG, ScimKeySelectionDialogClass)) typedef struct _ScimKeySelection ScimKeySelection; typedef struct _ScimKeySelectionClass ScimKeySelectionClass; typedef struct _ScimKeySelectionDialog ScimKeySelectionDialog; typedef struct _ScimKeySelectionDialogClass ScimKeySelectionDialogClass; struct _ScimKeySelection { GtkVBox vbox; GtkWidget *toggle_ctrl; GtkWidget *toggle_alt; GtkWidget *toggle_shift; GtkWidget *toggle_meta; GtkWidget *toggle_super; GtkWidget *toggle_hyper; GtkWidget *toggle_capslock; GtkWidget *toggle_release; GtkWidget *key_code; GtkWidget *list_view; GtkTreeSelection *list_selection; GtkListStore *list_model; gchar *keys; }; struct _ScimKeySelectionClass { GtkVBoxClass parent_class; void (*changed) (ScimKeySelection *keyselection); }; struct _ScimKeySelectionDialog { GtkDialog parent_instance; GtkWidget *keysel; #if GTK_CHECK_VERSION(3, 0, 0) GtkWidget *content_area; #else GtkWidget *main_vbox; #endif GtkWidget *action_area; GtkWidget *ok_button; GtkWidget *cancel_button; }; struct _ScimKeySelectionDialogClass { GtkDialogClass parent_class; /* Padding for future expansion */ void (*_gtk_reserved1) (void); void (*_gtk_reserved2) (void); void (*_gtk_reserved3) (void); void (*_gtk_reserved4) (void); }; GType scim_key_selection_get_type (void) G_GNUC_CONST; GtkWidget* scim_key_selection_new (void); void scim_key_selection_set_keys (ScimKeySelection *keyselection, const gchar *keys); void scim_key_selection_append_keys (ScimKeySelection *keyselection, const gchar *keys); const gchar* scim_key_selection_get_keys (ScimKeySelection *keyselection); GType scim_key_selection_dialog_get_type (void) G_GNUC_CONST; GtkWidget* scim_key_selection_dialog_new (const gchar *title); void scim_key_selection_dialog_set_keys (ScimKeySelectionDialog *ksd, const gchar *keys); const gchar* scim_key_selection_dialog_get_keys (ScimKeySelectionDialog *ksd); G_END_DECLS #endif /* __GTK_KEY_SELECTION_H__ */ /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/utils/scimkeyselection.cpp0000644000175000017500000006766012422143415017374 0ustar tzhuantzhuan#include #include #include #include #include #include #define Uses_SCIM_EVENT #include "scim_private.h" #include "scim.h" #include "scimkeyselection.h" #ifdef GDK_WINDOWING_X11 #include #include #include "scim_x11_utils.h" #endif using namespace scim; enum { KEY_SELECTION_CHANGED, LAST_SIGNAL }; struct KeyGrabData { KeyEvent key; }; /* GObject, GtkObject methods */ static void scim_key_selection_class_init (ScimKeySelectionClass *klass); static void scim_key_selection_init (ScimKeySelection *keyselection); static void scim_key_selection_finalize (GObject *object); static void scim_key_selection_add_key_button_callback (GtkButton *button, ScimKeySelection *keyselection); static void scim_key_selection_del_key_button_callback (GtkButton *button, ScimKeySelection *keyselection); static void scim_key_selection_list_changed_callback (GtkTreeSelection *selection, ScimKeySelection *keyselection); static void scim_key_grab_button_callback (GtkButton *button, ScimKeySelection *keyselection); static gboolean scim_key_grab_press_callback (GtkDialog *dialog, GdkEventKey *event, KeyGrabData *data); static gboolean scim_key_grab_release_callback (GtkDialog *dialog, GdkEventKey *event, KeyGrabData *data); static void scim_key_selection_set_key_event (ScimKeySelection *keyselection, KeyEvent event); static GtkWidgetClass *parent_class = NULL; static gint key_selection_signals[LAST_SIGNAL] = { 0 }; static GType key_selection_type = 0; void scim_key_selection_register_type (GTypeModule *type_module) { static const GTypeInfo key_selection_info = { sizeof (ScimKeySelectionClass), NULL, NULL, (GClassInitFunc) scim_key_selection_class_init, NULL, NULL, sizeof (ScimKeySelection), 0, (GInstanceInitFunc) scim_key_selection_init, 0 }; if (!key_selection_type) { if (type_module) key_selection_type = g_type_module_register_type ( type_module, #if GTK_CHECK_VERSION(3, 0, 0) GTK_TYPE_BOX, #else GTK_TYPE_VBOX, #endif "SCIM_ScimKeySelection", &key_selection_info, (GTypeFlags) 0); else key_selection_type = g_type_register_static ( #if GTK_CHECK_VERSION(3, 0, 0) GTK_TYPE_BOX, #else GTK_TYPE_VBOX, #endif "SCIM_ScimKeySelection", &key_selection_info, (GTypeFlags) 0); } } GType scim_key_selection_get_type (void) { if (!key_selection_type) scim_key_selection_register_type (NULL); return key_selection_type; } static void scim_key_selection_class_init (ScimKeySelectionClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); #if GTK_CHECK_VERSION(3, 0, 0) #else GtkObjectClass *object_class; GtkWidgetClass *widget_class; object_class = (GtkObjectClass*) klass; widget_class = (GtkWidgetClass*) klass; #endif parent_class = (GtkWidgetClass*) g_type_class_peek_parent (klass); gobject_class->finalize = scim_key_selection_finalize; key_selection_signals[KEY_SELECTION_CHANGED] = g_signal_new ("key-selection-changed", #if GTK_CHECK_VERSION(3, 0, 0) G_TYPE_FROM_CLASS (gobject_class), #else G_TYPE_FROM_CLASS (object_class), #endif G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (ScimKeySelectionClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); klass->changed = NULL; } static void scim_key_selection_init (ScimKeySelection *keyselection) { GtkWidget *table; GtkWidget *hbox; GtkWidget *frame; GtkWidget *label; GtkWidget *scrolledwindow; GtkWidget *button; GtkCellRenderer *list_cell; GtkTreeViewColumn *list_column; frame = gtk_frame_new (NULL); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (keyselection), frame, TRUE, TRUE, 0); label = gtk_label_new (NULL); gtk_label_set_text_with_mnemonic (GTK_LABEL (label), _("Selected _Keys:")); gtk_widget_show (label); gtk_frame_set_label_widget (GTK_FRAME (frame), label); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); // Create keys list view scrolledwindow = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolledwindow); gtk_container_add (GTK_CONTAINER(frame), scrolledwindow); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_SHADOW_ETCHED_IN); keyselection->list_view = gtk_tree_view_new (); gtk_widget_show (keyselection->list_view); gtk_container_add (GTK_CONTAINER (scrolledwindow), keyselection->list_view); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (keyselection->list_view), FALSE); gtk_label_set_mnemonic_widget (GTK_LABEL (label), keyselection->list_view); keyselection->list_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (keyselection->list_view)); gtk_tree_selection_set_mode (keyselection->list_selection, GTK_SELECTION_BROWSE); g_signal_connect (G_OBJECT (keyselection->list_selection), "changed", G_CALLBACK (scim_key_selection_list_changed_callback), keyselection); // Create key list column. list_cell = gtk_cell_renderer_text_new (); list_column = gtk_tree_view_column_new_with_attributes ( NULL, list_cell, "text", 0, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (keyselection->list_view), list_column); // Create key list model keyselection->list_model = gtk_list_store_new (1, G_TYPE_STRING); gtk_tree_view_set_model (GTK_TREE_VIEW (keyselection->list_view), GTK_TREE_MODEL (keyselection->list_model)); #if GTK_CHECK_VERSION(3, 4, 0) table = gtk_grid_new (); gtk_grid_set_row_spacing (GTK_GRID(table), 4); gtk_grid_set_column_spacing (GTK_GRID(table), 4); #else table = gtk_table_new (2, 3, FALSE); #endif gtk_widget_show (table); gtk_box_pack_start (GTK_BOX (keyselection), table, FALSE, FALSE, 0); label = gtk_label_new (_("Key Code:")); gtk_widget_show (label); #if GTK_CHECK_VERSION(3, 4, 0) gtk_widget_set_halign (label, GTK_ALIGN_FILL); gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1); #else gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 4, 4); #endif #if GTK_CHECK_VERSION(3, 14, 0) gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_widget_set_valign (label, GTK_ALIGN_CENTER); #else gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); #endif #if GTK_CHECK_VERSION(3, 2, 0) hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); #else hbox = gtk_hbox_new (FALSE, 0); #endif gtk_widget_show (hbox); #if GTK_CHECK_VERSION(3, 4, 0) gtk_widget_set_halign (hbox, GTK_ALIGN_FILL); gtk_grid_attach (GTK_GRID (table), hbox, 1, 0, 1, 1); #else gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 0, 1, (GtkAttachOptions) (GTK_FILL|GTK_EXPAND), (GtkAttachOptions) (0), 4, 4); #endif keyselection->key_code = gtk_entry_new (); gtk_widget_show (keyselection->key_code); gtk_box_pack_start (GTK_BOX (hbox), keyselection->key_code, TRUE, TRUE, 2); gtk_editable_set_editable (GTK_EDITABLE (keyselection->key_code), FALSE); button = gtk_button_new_with_label (_("...")); gtk_widget_show (button); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 2); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (scim_key_grab_button_callback), keyselection); label = gtk_label_new (_("Modifiers:")); gtk_widget_show (label); #if GTK_CHECK_VERSION(3, 4, 0) gtk_widget_set_halign (label, GTK_ALIGN_FILL); gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1); #else gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 4, 4); #endif #if GTK_CHECK_VERSION(3, 14, 0) gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_widget_set_valign (label, GTK_ALIGN_CENTER); #else gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); #endif #if GTK_CHECK_VERSION(3, 2, 0) hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); #else hbox = gtk_hbox_new (FALSE, 0); #endif gtk_widget_show (hbox); #if GTK_CHECK_VERSION(3, 2, 0) gtk_widget_set_halign (hbox, GTK_ALIGN_FILL); gtk_grid_attach (GTK_GRID (table), hbox, 1, 1, 1, 1); #else gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 1, 2, (GtkAttachOptions) (GTK_FILL|GTK_EXPAND), (GtkAttachOptions) (0), 4, 4); #endif keyselection->toggle_ctrl = gtk_check_button_new_with_mnemonic (_("_Ctrl")); gtk_widget_show (keyselection->toggle_ctrl); gtk_box_pack_start (GTK_BOX (hbox), keyselection->toggle_ctrl, TRUE, TRUE, 2); keyselection->toggle_alt = gtk_check_button_new_with_mnemonic (_("A_lt")); gtk_widget_show (keyselection->toggle_alt); gtk_box_pack_start (GTK_BOX (hbox), keyselection->toggle_alt, TRUE, TRUE, 2); keyselection->toggle_shift = gtk_check_button_new_with_mnemonic (_("_Shift")); gtk_widget_show (keyselection->toggle_shift); gtk_box_pack_start (GTK_BOX (hbox), keyselection->toggle_shift, TRUE, TRUE, 2); keyselection->toggle_release = gtk_check_button_new_with_mnemonic (_("_Release")); gtk_widget_show (keyselection->toggle_release); gtk_box_pack_start (GTK_BOX (hbox), keyselection->toggle_release, TRUE, TRUE, 2); #if GTK_CHECK_VERSION(3, 2, 0) hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); #else hbox = gtk_hbox_new (FALSE, 0); #endif gtk_widget_show (hbox); #if GTK_CHECK_VERSION(3, 4, 0) gtk_widget_set_halign (hbox, GTK_ALIGN_FILL); gtk_grid_attach (GTK_GRID (table), hbox, 1, 2, 1, 1); #else gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 2, 3, (GtkAttachOptions) (GTK_FILL|GTK_EXPAND), (GtkAttachOptions) (0), 4, 4); #endif keyselection->toggle_meta = gtk_check_button_new_with_mnemonic (_("_Meta")); gtk_widget_show (keyselection->toggle_meta); gtk_box_pack_start (GTK_BOX (hbox), keyselection->toggle_meta, TRUE, TRUE, 2); keyselection->toggle_super = gtk_check_button_new_with_mnemonic (_("S_uper")); gtk_widget_show (keyselection->toggle_super); gtk_box_pack_start (GTK_BOX (hbox), keyselection->toggle_super, TRUE, TRUE, 2); keyselection->toggle_hyper = gtk_check_button_new_with_mnemonic (_("_Hyper")); gtk_widget_show (keyselection->toggle_hyper); gtk_box_pack_start (GTK_BOX (hbox), keyselection->toggle_hyper, TRUE, TRUE, 2); keyselection->toggle_capslock = gtk_check_button_new_with_mnemonic (_("Ca_psLock")); gtk_widget_show (keyselection->toggle_capslock); gtk_box_pack_start (GTK_BOX (hbox), keyselection->toggle_capslock, TRUE, TRUE, 2); #if GTK_CHECK_VERSION(3, 2, 0) hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); #else hbox = gtk_hbox_new (TRUE, 0); #endif gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (keyselection), hbox, FALSE, FALSE, 4); #if GTK_CHECK_VERSION(3, 14, 0) button = gtk_button_new_from_icon_name ("list-add", GTK_ICON_SIZE_BUTTON); #else button = gtk_button_new_from_stock ("gtk-add"); #endif gtk_widget_show (button); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 4); g_signal_connect ((gpointer) button, "clicked", G_CALLBACK (scim_key_selection_add_key_button_callback), keyselection); #if GTK_CHECK_VERSION(3, 14, 0) button = gtk_button_new_from_icon_name ("list-delete", GTK_ICON_SIZE_BUTTON); #else button = gtk_button_new_from_stock ("gtk-delete"); #endif gtk_widget_show (button); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 4); g_signal_connect ((gpointer) button, "clicked", G_CALLBACK (scim_key_selection_del_key_button_callback), keyselection); // Create key names list keyselection->keys = NULL; } static void scim_key_selection_finalize (GObject *object) { ScimKeySelection *keyselection = SCIM_KEY_SELECTION (object); if (keyselection->keys) g_free (keyselection->keys); G_OBJECT_CLASS (parent_class)->finalize (object); } static void scim_key_selection_add_key_button_callback (GtkButton *button, ScimKeySelection *keyselection) { GtkTreeIter iter; String key; String key_code; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (keyselection->toggle_ctrl))) key += String ("Control+"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (keyselection->toggle_alt))) key += String ("Alt+"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (keyselection->toggle_shift))) key += String ("Shift+"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (keyselection->toggle_meta))) key += String ("Meta+"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (keyselection->toggle_super))) key += String ("Super+"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (keyselection->toggle_hyper))) key += String ("Hyper+"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (keyselection->toggle_capslock))) key += String ("CapsLock+"); key_code = String (gtk_entry_get_text (GTK_ENTRY (keyselection->key_code))); if (!key_code.length ()){ // empty key code is not allowed. GtkWidget *dialog; dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Please enter a Key Code first.")); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); return; } key += key_code; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (keyselection->toggle_release))) key += String ("+KeyRelease"); if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (keyselection->list_model), &iter)) { gchar * keystr; do { gtk_tree_model_get (GTK_TREE_MODEL (keyselection->list_model), &iter, 0, &keystr, -1); if (keystr && String (keystr) == key) return; } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (keyselection->list_model), &iter)); } gtk_list_store_append (keyselection->list_model, &iter); gtk_list_store_set (keyselection->list_model, &iter, 0, key.c_str (), -1); g_signal_emit_by_name (keyselection, "key-selection-changed"); } static void scim_key_selection_del_key_button_callback (GtkButton *button, ScimKeySelection *keyselection) { GtkTreeIter iter; GtkTreeModel *model; if (gtk_tree_selection_get_selected (keyselection->list_selection, &model, &iter)) { gtk_list_store_remove (keyselection->list_model, &iter); g_signal_emit_by_name (keyselection, "key-selection-changed"); } } static void scim_key_grab_button_callback (GtkButton *button, ScimKeySelection *keyselection) { KeyGrabData key_grab_data; GtkWidget *dialog; dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL, _("Press a key (or a key combination).\n" "This dialog will be closed when the key is released.")); gtk_window_set_title (GTK_WINDOW (dialog), _("Grabbing a key.")); g_signal_connect (G_OBJECT (dialog), "key-press-event", G_CALLBACK (scim_key_grab_press_callback), &key_grab_data); g_signal_connect (G_OBJECT (dialog), "key-release-event", G_CALLBACK (scim_key_grab_release_callback), &key_grab_data); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { scim_key_selection_set_key_event (keyselection, key_grab_data.key); } gtk_widget_destroy (dialog); } static KeyEvent keyevent_gdk_to_scim (const GdkEventKey &gdkevent) { KeyEvent key; // Use Key Symbole provided by gtk. key.code = gdkevent.keyval; #ifdef GDK_WINDOWING_X11 key.mask = scim_x11_keymask_x11_to_scim (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), gdkevent.state); #else if (gdkevent.state & GDK_SHIFT_MASK) key.mask |=SCIM_KEY_ShiftMask; if (gdkevent.state & GDK_LOCK_MASK) key.mask |=SCIM_KEY_CapsLockMask; if (gdkevent.state & GDK_CONTROL_MASK) key.mask |=SCIM_KEY_ControlMask; if (gdkevent.state & GDK_MOD1_MASK) key.mask |=SCIM_KEY_AltMask; if (gdkevent.state & GDK_MOD2_MASK) key.mask |=SCIM_KEY_NumLockMask; #endif if (gdkevent.type == GDK_KEY_RELEASE) key.mask |= SCIM_KEY_ReleaseMask; return key; } static gboolean scim_key_grab_press_callback (GtkDialog *dialog, GdkEventKey *event, KeyGrabData *data) { data->key = keyevent_gdk_to_scim (*event); return TRUE; } static gboolean scim_key_grab_release_callback (GtkDialog *dialog, GdkEventKey *event, KeyGrabData *data) { KeyEvent key = keyevent_gdk_to_scim (*event); if (key.code == data->key.code) { data->key.mask = key.mask; if (data->key.code >= SCIM_KEY_Shift_L && data->key.code <= SCIM_KEY_Hyper_R) data->key.mask |= SCIM_KEY_ReleaseMask; else data->key.mask &= (~ SCIM_KEY_ReleaseMask); gtk_dialog_response (dialog, GTK_RESPONSE_OK); } else { gtk_dialog_response (dialog, GTK_RESPONSE_CANCEL); } return TRUE; } /* public api */ GtkWidget* scim_key_selection_new (void) { return GTK_WIDGET (g_object_new (SCIM_TYPE_KEY_SELECTION, #if GTK_CHECK_VERSION(3, 0, 0) "orientation", GTK_ORIENTATION_VERTICAL, #endif NULL)); } void scim_key_selection_append_keys (ScimKeySelection *keyselection, const gchar *keys) { g_return_if_fail (SCIM_IS_KEY_SELECTION (keyselection)); g_return_if_fail (keys != NULL); KeyEventList keylist; if (!scim_string_to_key_list (keylist, keys)) return; GtkTreeIter iter; GtkTreeModel *model; String str; for (size_t i = 0; i < keylist.size (); ++ i) { if (scim_key_to_string (str, keylist [i])) { gtk_list_store_append (keyselection->list_model, &iter); gtk_list_store_set (keyselection->list_model, &iter, 0, str.c_str (), -1); } } } void scim_key_selection_set_keys (ScimKeySelection *keyselection, const gchar *keys) { g_return_if_fail (SCIM_IS_KEY_SELECTION (keyselection)); gtk_list_store_clear (keyselection->list_model); scim_key_selection_append_keys (keyselection, keys); } const gchar* scim_key_selection_get_keys (ScimKeySelection *keyselection) { g_return_val_if_fail (SCIM_IS_KEY_SELECTION (keyselection), NULL); if (keyselection->keys) g_free (keyselection->keys); keyselection->keys = NULL; GtkTreeIter iter; if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (keyselection->list_model), &iter)) { std::vector keylist; gchar * keystr; do { gtk_tree_model_get (GTK_TREE_MODEL (keyselection->list_model), &iter, 0, &keystr, -1); if (keystr) keylist.push_back (keystr); } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (keyselection->list_model), &iter)); if (keylist.size ()) keyselection->keys = g_strdup (scim_combine_string_list (keylist).c_str ()); } return keyselection->keys; } static void scim_key_selection_list_changed_callback (GtkTreeSelection *selection, ScimKeySelection *keyselection) { GtkTreeModel *model; GtkTreeIter iter; gchar *keystr; KeyEvent keyevent; if (gtk_tree_selection_get_selected (selection, &model, &iter)) { gtk_tree_model_get (model, &iter, 0, &keystr, -1); if (scim_string_to_key (keyevent, String (keystr))) scim_key_selection_set_key_event (keyselection, keyevent); } } static void scim_key_selection_set_key_event (ScimKeySelection *keyselection, KeyEvent event) { g_return_if_fail (SCIM_IS_KEY_SELECTION (keyselection)); gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (keyselection->toggle_ctrl), event.is_control_down ()); gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (keyselection->toggle_alt), event.is_alt_down ()); gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (keyselection->toggle_shift), event.is_shift_down ()); gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (keyselection->toggle_meta), event.is_meta_down ()); gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (keyselection->toggle_super), event.is_super_down ()); gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (keyselection->toggle_hyper), event.is_hyper_down ()); gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (keyselection->toggle_capslock), event.is_caps_lock_down ()); gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (keyselection->toggle_release), event.is_key_release ()); event.mask = 0; String str; if (scim_key_to_string (str, event)) { gtk_entry_set_text (GTK_ENTRY (keyselection->key_code), str.c_str ()); } } /***************************************************************************** * ScimKeySelectionDialog *****************************************************************************/ static GtkWidgetClass *dialog_parent_class = NULL; static GType key_selection_dialog_type = 0; static void scim_key_selection_dialog_class_init (ScimKeySelectionDialogClass *klass); static void scim_key_selection_dialog_init (ScimKeySelectionDialog *keyseldialog); void scim_key_selection_dialog_register_type (GTypeModule *type_module) { static const GTypeInfo key_selection_dialog_info = { sizeof (ScimKeySelectionDialogClass), NULL, NULL, (GClassInitFunc) scim_key_selection_dialog_class_init, NULL, NULL, sizeof (ScimKeySelectionDialog), 0, (GInstanceInitFunc) scim_key_selection_dialog_init, 0 }; if (!key_selection_dialog_type) { if (type_module) key_selection_dialog_type = g_type_module_register_type ( type_module, GTK_TYPE_DIALOG, "SCIM_ScimKeySelectionDialog", &key_selection_dialog_info, (GTypeFlags) 0); else key_selection_dialog_type = g_type_register_static ( GTK_TYPE_DIALOG, "SCIM_ScimKeySelectionDialog", &key_selection_dialog_info, (GTypeFlags) 0); } } GType scim_key_selection_dialog_get_type (void) { if (!key_selection_dialog_type) scim_key_selection_dialog_register_type (NULL); return key_selection_dialog_type; } static void scim_key_selection_dialog_class_init (ScimKeySelectionDialogClass *klass) { dialog_parent_class = (GtkWidgetClass*) g_type_class_peek_parent (klass); } static void scim_key_selection_dialog_init (ScimKeySelectionDialog *keyseldialog) { GtkDialog *dialog; #if !GTK_CHECK_VERSION(3, 10, 0) gtk_widget_push_composite_child (); #endif dialog = GTK_DIALOG (keyseldialog); gtk_container_set_border_width (GTK_CONTAINER (keyseldialog), 4); gtk_window_set_resizable (GTK_WINDOW (keyseldialog), TRUE); #if GTK_CHECK_VERSION(3, 0, 0) keyseldialog->content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); #else keyseldialog->main_vbox = dialog->vbox; #endif keyseldialog->keysel = scim_key_selection_new (); gtk_container_set_border_width (GTK_CONTAINER (keyseldialog->keysel), 4); gtk_widget_show (keyseldialog->keysel); #if GTK_CHECK_VERSION(3, 0, 0) gtk_box_pack_start (GTK_BOX (keyseldialog->content_area), #else gtk_box_pack_start (GTK_BOX (keyseldialog->main_vbox), #endif keyseldialog->keysel, TRUE, TRUE, 0); /* Create the action area */ #if GTK_CHECK_VERSION(3, 0, 0) G_GNUC_BEGIN_IGNORE_DEPRECATIONS keyseldialog->action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog)); G_GNUC_END_IGNORE_DEPRECATIONS #else keyseldialog->action_area = dialog->action_area; #endif keyseldialog->cancel_button = gtk_dialog_add_button (dialog, #if GTK_CHECK_VERSION(3, 10, 0) _("_Cancel"), #else GTK_STOCK_CANCEL, #endif GTK_RESPONSE_CANCEL); keyseldialog->ok_button = gtk_dialog_add_button (dialog, #if GTK_CHECK_VERSION(3, 10, 0) _("_OK"), #else GTK_STOCK_OK, #endif GTK_RESPONSE_OK); gtk_widget_grab_default (keyseldialog->ok_button); gtk_window_set_title (GTK_WINDOW (keyseldialog), _("Key Selection")); #if GTK_CHECK_VERSION(2, 22, 0) #else gtk_dialog_set_has_separator (GTK_DIALOG (dialog), TRUE); #endif #if !GTK_CHECK_VERSION(3, 10, 0) gtk_widget_pop_composite_child (); #endif } GtkWidget* scim_key_selection_dialog_new (const gchar *title) { ScimKeySelectionDialog *keyseldialog; keyseldialog= (ScimKeySelectionDialog *) g_object_new (SCIM_TYPE_KEY_SELECTION_DIALOG, NULL); if (title) gtk_window_set_title (GTK_WINDOW (keyseldialog), title); return GTK_WIDGET (keyseldialog); } const gchar* scim_key_selection_dialog_get_keys (ScimKeySelectionDialog *ksd) { return scim_key_selection_get_keys (SCIM_KEY_SELECTION (ksd->keysel)); } void scim_key_selection_dialog_set_keys (ScimKeySelectionDialog *ksd, const gchar *keys) { return scim_key_selection_set_keys (SCIM_KEY_SELECTION (ksd->keysel), keys); } /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/utils/scim_x11_utils.h0000644000175000017500000000324412422143415016317 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_x11_utils.h,v 1.1 2005/05/11 09:52:11 suzhe Exp $ */ #ifndef __SCIM_X11_UTILS_H__ #define __SCIM_X11_UTILS_H__ #define Uses_SCIM_EVENT #include #include /** * @brief Translate a X11 KeyEvent to a scim KeyEvent according to the given Display */ scim::KeyEvent scim_x11_keyevent_x11_to_scim (Display *display, const XKeyEvent &xkey); /** * @brief Translate a scim KeyEvent to a X11 KeyEvent according to the given Display */ XKeyEvent scim_x11_keyevent_scim_to_x11 (Display *display, const scim::KeyEvent &scimkey); /** * @brief Translate X11 key state to scim key mask. */ scim::uint16 scim_x11_keymask_x11_to_scim (Display *display, unsigned int xkeystate); /** * @brief Translate scim key mask to X11 key state. */ unsigned int scim_x11_keymask_scim_to_x11 (Display *display, scim::uint16 scimkeymask); #endif scim-1.4.15/utils/scim_x11_utils.cpp0000644000175000017500000001751112422143415016654 0ustar tzhuantzhuan#define Uses_SCIM_EVENT #include #include #include #include #include "scim_private.h" #include "scim.h" #include "scim_x11_utils.h" using namespace scim; static Time get_time (void); static void initialize_modifier_bits (Display *display); static Display *__current_display = 0; static int __current_alt_mask = Mod1Mask; static int __current_meta_mask = 0; static int __current_super_mask = 0; static int __current_hyper_mask = 0; static int __current_numlock_mask = Mod2Mask; static Time get_time (void) { int tint; struct timeval tv; struct timezone tz; /* is not used since ages */ gettimeofday (&tv, &tz); tint = (int) tv.tv_sec * 1000; tint = tint / 1000 * 1000; tint = tint + tv.tv_usec / 1000; return ((Time) tint); } static void initialize_modifier_bits (Display *display) { if (__current_display == display) return; __current_display = display; if (display == 0) { __current_alt_mask = Mod1Mask; __current_meta_mask = ShiftMask | Mod1Mask; __current_super_mask = 0; __current_hyper_mask = 0; __current_numlock_mask = Mod2Mask; return; } XModifierKeymap *mods; ::KeyCode ctrl_l = XKeysymToKeycode (display, XK_Control_L); ::KeyCode ctrl_r = XKeysymToKeycode (display, XK_Control_R); ::KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L); ::KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R); ::KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L); ::KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R); ::KeyCode super_l = XKeysymToKeycode (display, XK_Super_L); ::KeyCode super_r = XKeysymToKeycode (display, XK_Super_R); ::KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L); ::KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R); ::KeyCode numlock = XKeysymToKeycode (display, XK_Num_Lock); int i, j; mods = XGetModifierMapping (display); __current_alt_mask = 0; __current_meta_mask = 0; __current_super_mask = 0; __current_hyper_mask = 0; __current_numlock_mask = 0; /* We skip the first three sets for Shift, Lock, and Control. The remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */ for (i = 3; i < 8; i++) { for (j = 0; j < mods->max_keypermod; j++) { ::KeyCode code = mods->modifiermap [i * mods->max_keypermod + j]; if (! code) continue; if (code == alt_l || code == alt_r) __current_alt_mask |= (1 << i); else if (code == meta_l || code == meta_r) __current_meta_mask |= (1 << i); else if (code == super_l || code == super_r) __current_super_mask |= (1 << i); else if (code == hyper_l || code == hyper_r) __current_hyper_mask |= (1 << i); else if (code == numlock) __current_numlock_mask |= (1 << i); } } /* Check whether there is a combine keys mapped to Meta */ if (__current_meta_mask == 0) { char buf [32]; XKeyEvent xkey; KeySym keysym_l, keysym_r; xkey.type = KeyPress; xkey.display = display; xkey.serial = 0L; xkey.send_event = False; xkey.x = xkey.y = xkey.x_root = xkey.y_root = 0; xkey.time = 0; xkey.same_screen = False; xkey.subwindow = None; xkey.window = None; xkey.root = DefaultRootWindow (display); xkey.state = ShiftMask; xkey.keycode = meta_l; XLookupString (&xkey, buf, 32, &keysym_l, 0); xkey.keycode = meta_r; XLookupString (&xkey, buf, 32, &keysym_r, 0); if ((meta_l == alt_l && keysym_l == XK_Meta_L) || (meta_r == alt_r && keysym_r == XK_Meta_R)) __current_meta_mask = ShiftMask + __current_alt_mask; else if ((meta_l == ctrl_l && keysym_l == XK_Meta_L) || (meta_r == ctrl_r && keysym_r == XK_Meta_R)) __current_meta_mask = ShiftMask + ControlMask; } XFreeModifiermap (mods); } KeyEvent scim_x11_keyevent_x11_to_scim (Display *display, const XKeyEvent &xkey) { KeyEvent scimkey; KeySym keysym; XKeyEvent key = xkey; char buf [32]; initialize_modifier_bits (display); XLookupString (&key, buf, 32, &keysym, 0); scimkey.code = keysym; scimkey.mask = scim_x11_keymask_x11_to_scim (display, xkey.state); if (key.type == KeyRelease) scimkey.mask |= SCIM_KEY_ReleaseMask; if (scimkey.code == SCIM_KEY_backslash) { int keysym_size = 0; KeySym *keysyms = XGetKeyboardMapping (display, xkey.keycode, 1, &keysym_size); if (keysyms != NULL) { if (keysyms[0] == XK_backslash && (keysym_size > 1 && keysyms[1] == XK_underscore)) scimkey.mask |= SCIM_KEY_QuirkKanaRoMask; XFree (keysyms); } } return scimkey; } XKeyEvent scim_x11_keyevent_scim_to_x11 (Display *display, const KeyEvent &scimkey) { XKeyEvent xkey; initialize_modifier_bits (display); xkey.type = (scimkey.mask & SCIM_KEY_ReleaseMask) ? KeyRelease : KeyPress; xkey.display = display; xkey.serial = 0L; xkey.send_event = False; xkey.x = xkey.y = xkey.x_root = xkey.y_root = 0; xkey.time = get_time (); xkey.same_screen = False; xkey.subwindow = None; xkey.window = None; if (display) { xkey.root = DefaultRootWindow (display); xkey.keycode = XKeysymToKeycode (display, (KeySym) scimkey.code); } else { xkey.root = None; xkey.keycode = 0; } xkey.state = scim_x11_keymask_scim_to_x11 (display, scimkey.mask); return xkey; } uint16 scim_x11_keymask_x11_to_scim (Display *display, unsigned int xkeystate) { uint16 mask = 0; initialize_modifier_bits (display); // Check Meta mask first, because it's maybe a mask combination. if (__current_meta_mask && (xkeystate & __current_meta_mask) == __current_meta_mask) { mask |= SCIM_KEY_MetaMask; xkeystate &= ~__current_meta_mask; } if (xkeystate & ShiftMask) { mask |= SCIM_KEY_ShiftMask; xkeystate &= ~ShiftMask; } if (xkeystate & LockMask) { mask |= SCIM_KEY_CapsLockMask; xkeystate &= ~LockMask; } if (xkeystate & ControlMask) { mask |= SCIM_KEY_ControlMask; xkeystate &= ~ControlMask; } if (__current_alt_mask && (xkeystate & __current_alt_mask) == __current_alt_mask) { mask |= SCIM_KEY_AltMask; xkeystate &= ~__current_alt_mask; } if (__current_super_mask && (xkeystate & __current_super_mask) == __current_super_mask) { mask |= SCIM_KEY_SuperMask; xkeystate &= ~__current_super_mask; } if (__current_hyper_mask && (xkeystate & __current_hyper_mask) == __current_hyper_mask) { mask |= SCIM_KEY_HyperMask; xkeystate &= ~__current_hyper_mask; } if (__current_numlock_mask && (xkeystate & __current_numlock_mask) == __current_numlock_mask) { mask |= SCIM_KEY_NumLockMask; } return mask; } unsigned int scim_x11_keymask_scim_to_x11 (Display *display, uint16 scimkeymask) { unsigned int state = 0; initialize_modifier_bits (display); if (scimkeymask & SCIM_KEY_ShiftMask) state |= ShiftMask; if (scimkeymask & SCIM_KEY_CapsLockMask) state |= LockMask; if (scimkeymask & SCIM_KEY_ControlMask) state |= ControlMask; if (scimkeymask & SCIM_KEY_AltMask) state |= __current_alt_mask; if (scimkeymask & SCIM_KEY_MetaMask) state |= __current_meta_mask; if (scimkeymask & SCIM_KEY_SuperMask) state |= __current_super_mask; if (scimkeymask & SCIM_KEY_HyperMask) state |= __current_hyper_mask; if (scimkeymask & SCIM_KEY_NumLockMask) state |= __current_numlock_mask; return state; } scim-1.4.15/utils/Makefile.am0000644000175000017500000000476712422143415015351 0ustar tzhuantzhuan## Makefile.am -- Process this file with automake to produce Makefile.in ## Copyright (C) 2002 James Su ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2, or (at your option) ## any later version. ## ## This program 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 General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. MAINTAINERCLEANFILES = Makefile.in AM_CPPFLAGS = -I$(top_builddir) \ -I$(top_builddir)/src \ -I$(top_srcdir) \ -I$(top_srcdir)/src \ -I$(top_srcdir)/intl \ -I$(top_srcdir)/data \ -I$(top_srcdir)/utils if SCIM_BUILD_TRAY_ICON TRAY_ICON_HEADER=scimtrayicon.h TRAY_ICON_SOURCE=scimtrayicon.c endif if SCIM_BUILD_X11_UTILS libscimx11utilsincludedir = $(includedir)/scim@SCIM_EPOCH@/x11 libscimx11utilsinclude_HEADERS = scim_x11_utils.h X11_UTILS = libscim-x11utils@SCIM_EPOCH@.la endif if SCIM_BUILD_GTK_UTILS libscimgtkutilsincludedir = $(includedir)/scim@SCIM_EPOCH@/gtk libscimgtkutilsinclude_HEADERS = scimstringview.h scimkeyselection.h $(TRAY_ICON_HEADER) GTK_UTILS = libscim-gtkutils@SCIM_EPOCH@.la endif lib_LTLIBRARIES = $(X11_UTILS) $(GTK_UTILS) libscim_gtkutils@SCIM_EPOCH@_la_SOURCES = scimstringview.c \ scimkeyselection.cpp \ $(TRAY_ICON_SOURCE) libscim_gtkutils@SCIM_EPOCH@_la_CFLAGS = @GTK_CFLAGS@ libscim_gtkutils@SCIM_EPOCH@_la_CXXFLAGS= @GTK_CFLAGS@ libscim_gtkutils@SCIM_EPOCH@_la_LDFLAGS= -version-info $(SCIM_CURRENT):$(SCIM_REVISION):$(SCIM_AGE) \ -export-dynamic \ @LIBTOOL_EXPORT_OPTIONS@ \ @LTLIBINTL@ \ @GTK_LIBS@ libscim_gtkutils@SCIM_EPOCH@_la_LIBADD= $(top_builddir)/src/libscim@SCIM_EPOCH@.la $(X11_UTILS) libscim_x11utils@SCIM_EPOCH@_la_SOURCES = scim_x11_utils.cpp libscim_x11utils@SCIM_EPOCH@_la_CFLAGS= @X_CFLAGS@ libscim_x11utils@SCIM_EPOCH@_la_CXXFLAGS= @X_CFLAGS@ libscim_x11utils@SCIM_EPOCH@_la_LDFLAGS= -version-info $(SCIM_CURRENT):$(SCIM_REVISION):$(SCIM_AGE) \ -export-dynamic \ @LIBTOOL_EXPORT_OPTIONS@ \ @LTLIBINTL@ \ @X_LIBS@ libscim_x11utils@SCIM_EPOCH@_la_LIBAD = $(top_builddir)/src/libscim@SCIM_EPOCH@.la scim-1.4.15/tests/0000755000175000017500000000000012422143415013301 5ustar tzhuantzhuanscim-1.4.15/tests/testsocketserver.cpp0000644000175000017500000000554112422143415017431 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2004 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: testsocketserver.cpp,v 1.2 2005/01/05 13:41:13 suzhe Exp $ * */ #define Uses_SCIM_SOCKET #define Uses_SCIM_SOCKET_TRANSACTION #define Uses_C_STRING #include "scim_private.h" #include "scim.h" #include void accept_callback (scim::SocketServer *server, const scim::Socket &client) { std::cerr << "Accept client: " << client.get_id () << "\n"; } void receive_callback (scim::SocketServer *server, const scim::Socket &client) { char buffer [32768]; int size; if (client.wait_for_data (100) <= 0) { std::cerr << "Error! timeout.\n"; return; } if ((size = client.read_with_timeout (buffer, 32768, 100)) > 0) { buffer [size] = 0; std::cerr << "Read " << size << " chars from client: " << client.get_id () << "\n"; std::cerr << buffer << "\n"; if (client.write (buffer, size) == size) { std::cerr << "Write back ok!\n"; } else { std::cerr << "Write back failed!\n"; } } else { std::cerr << "Error! Close the client.\n"; server->close_connection (client); return; } if (strcmp (buffer, "exit") == 0) server->shutdown (); std::cerr << "\n"; } void exception_callback (scim::SocketServer *server, const scim::Socket &client) { std::cerr << "Client: " << client.get_id () << " got an exception\n"; } int main (int argc, char **argv) { scim::SocketAddress address; scim::SocketAddress address2; scim::SocketServer server; scim::DebugOutput::set_verbose_level (4); if (argc > 1) address.set_address (argv[1]); else address.set_address ("inet:localhost:12345"); address2 = address; server.signal_connect_accept (slot (accept_callback)); server.signal_connect_receive (slot (receive_callback)); server.signal_connect_exception (slot (exception_callback)); if (server.create (address2)) { if (!server.run ()) { std::cerr << "Error occurred when server running: " << server.get_error_message () << "\n"; } else { std::cerr << "Server exit OK.\n"; } } else { std::cerr << "Error creating server: " << server.get_error_message () << "\n"; } return 0; } /* vi:ts=4:nowrap:ai */ scim-1.4.15/tests/testsocketclient.cpp0000644000175000017500000001715012422143415017400 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2004 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: testsocketclient.cpp,v 1.3 2005/01/05 13:41:13 suzhe Exp $ * */ #define Uses_SCIM_SOCKET #define Uses_SCIM_SOCKET_TRANSACTION #include #include "scim.h" #include #include static const char * test_string [] = { "This is a very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long test string.", "This is a very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long test string.", "This is a very very very very very very very very very very very very very very very very very very very very long test string.", "This is a very very very very very very very very very very very very very very very very very very very long test string.", "This is a very very very very very very very very very very very very very very very very very very long test string.", "This is a very very very very very very very very very very very very very very very very very long test string.", "This is a very very very very very very very very very very very very very very very very long test string.", "This is a very very very very very very very very very very very very very very very long test string.", "This is a very very very very very very very very very very very very very very long test string.", "This is a very very very very very very very very very very very very very long test string.", "This is a very very very very very very very very very very very very long test string.", "This is a very very very very very very very very very very very long test string.", "This is a very very very very very very very very very very long test string.", "This is a very very very very very very very very very long test string.", "This is a very very very very very very very very long test string.", "This is a very very very very very very very long test string.", "This is a very very very very very very long test string.", "This is a very very very very very long test string.", "This is a very very very very long test string.", "This is a very very very long test string.", "This is a very very long test string.", "This is a very long test string.", "This is a long test string.", "This is a test string.", "This is a string.", "Is a string.", "A string.", "String.", "A", "exit", NULL }; int main (int argc, char *argv[]) { scim::SocketAddress address; scim::SocketClient client; scim::DebugOutput::set_verbose_level (4); int size; const char **ptr = test_string; if (argc > 1) address.set_address (argv [1]); else address.set_address ("inet:localhost:12345"); if (client.connect (address)) { while (*ptr) { char tmp [4096]; if ((size = client.write (*ptr, std::strlen (*ptr))) > 0) { std::cout << "Write " << size << " bytes to socket server ok!\n"; if (client.read_with_timeout (tmp, size, 1000) == size && std::strncmp (*ptr, tmp, size) == 0) { std::cout << "Read back ok!\n"; } else { std::cerr << "Read back failed!\n"; } } else { std::cerr << "Write failed!\n"; break; } ++ ptr; sleep (1); } } return 0; } /* vi:ts=4:nowrap:ai */ scim-1.4.15/tests/testpanel.cpp0000644000175000017500000001176412422143415016015 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2004 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: testpanel.cpp,v 1.15 2005/01/13 14:54:26 suzhe Exp $ * */ #define Uses_SCIM_SOCKET #define Uses_SCIM_TRANSACTION #define Uses_SCIM_HELPER #define Uses_STL_IOSTREAM #include "scim_private.h" #include "scim.h" #include #include #include #include using namespace scim; const char * str1 = "SCIM shurufamianbanceshichengxu \n\n"; const char * str2 = "It's a forwarded string.\n\n"; const char * str3 = "直接提交给客户程序的字符串.\n\n"; Property prop1 ("/TestPanel/Menu1", "Menu1", "", "This is menu1."); Property prop2 ("/TestPanel/Menu1/Item1", "Item 1", "", "This is item 1 of menu1."); Property prop3 ("/TestPanel/Menu1/Item2", "Item 2", "", "This is item 2 of menu1."); Property prop4 ("/TestPanel/Menu1/Item3", "Item 3", "", "This is item 3 of menu1."); Property prop5 ("/TestPanel/Menu1/Submenu1", "Submenu 1", "", "This is a submenu of menu1."); Property prop6 ("/TestPanel/Menu1/Submenu1/Item4", "Item 4", "", "This is item 4 of menu1."); Property prop7 ("/TestPanel/Menu1/Submenu1/Item5", "Item 5", "", "This is item 5 of menu1."); Property prop8 ("/TestPanel/Menu1/Submenu1/TestInput", "TestInput", "", "Test input emulation."); Property prop9 ("/TestPanel/Menu1/Item6", "Item 6", "", "This is item 6 of menu1."); Property prop10 ("/TestPanel/Button1", "Button1", "", "This is button1."); void slot_exit (const HelperAgent *agent, int ic, const String &uuid) { std::cout << "slot_exit (" << ic << ", " << uuid << ")\n"; exit (0); } void slot_update_screen (const HelperAgent *agent, int ic, const String &uuid, int screen) { std::cout << "slot_update_screen (" << ic << ", " << uuid << ", " << screen << ")\n"; } void slot_update_spot_location (const HelperAgent *agent, int ic, const String &uuid, int x, int y) { std::cout << "slot_update_spot_location (" << ic << ", " << uuid << ", " << x << ", " << y << ")\n"; } void slot_trigger_property (const HelperAgent *agent, int ic, const String &uuid, const String &property) { std::cout << "slot_trigger_property (" << ic << ", " << uuid << ", " << property << ")\n"; if (property == prop10) { prop1.show (! prop1.visible ()); agent->update_property (prop1); } else if (property == prop2) { prop8.set_active (!prop8.active ()); agent->update_property (prop8); } else if (property == prop8) { sleep (1); for (const char *p = str1; *p; ++p) { KeyEvent key; key.code = *p; if (isupper (*p)) key.mask = SCIM_KEY_ShiftMask; if (*p == '\n') key.code = SCIM_KEY_Return; agent->send_key_event (ic, uuid, key); usleep (100000); } sleep (3); for (const char *p = str2; *p; ++p) { KeyEvent key; key.code = *p; if (isupper (*p)) key.mask = SCIM_KEY_ShiftMask; if (*p == '\n') key.code = SCIM_KEY_Return; agent->forward_key_event (ic, uuid, key); usleep (100000); } sleep (3); agent->commit_string (ic, uuid, utf8_mbstowcs (str3)); } } int main (int argc, char *argv[]) { HelperInfo info ("e135e0ee-5588-423e-a027-f07d769c12a3", "Test", "", "It's a test helper.", SCIM_HELPER_STAND_ALONE | SCIM_HELPER_NEED_SCREEN_INFO | SCIM_HELPER_NEED_SPOT_LOCATION_INFO); HelperAgent agent; String display (getenv ("DISPLAY")); int id; fd_set fds; id = agent.open_connection (info, display); if (id < 0) { std::cerr << "Unable to open the connection to Panel.\n"; return -1; } agent.signal_connect_exit (slot (slot_exit)); agent.signal_connect_update_screen (slot (slot_update_screen)); agent.signal_connect_update_spot_location (slot (slot_update_spot_location)); agent.signal_connect_trigger_property (slot (slot_trigger_property)); PropertyList properties; properties.push_back (prop1); properties.push_back (prop2); properties.push_back (prop3); properties.push_back (prop4); properties.push_back (prop5); properties.push_back (prop6); properties.push_back (prop7); properties.push_back (prop8); properties.push_back (prop9); properties.push_back (prop10); agent.register_properties (properties); while (1) { FD_ZERO (&fds); FD_SET (id, &fds); if (select (id + 1, &fds, 0, 0, 0) < 0) break; std::cout << "Got event.\n"; agent.filter_event (); } return 0; } /* vi:ts=4:nowrap:ai */ scim-1.4.15/tests/testlang.cpp0000644000175000017500000000301412422143415015624 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2004 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: testlang.cpp,v 1.2.4.1 2006/09/24 16:00:52 suzhe Exp $ * */ #include "scim.h" using namespace scim; int main () { String locale; String language; locale = scim_get_current_locale (); language = scim_get_locale_language (locale); std::cout << "Current locale: " << locale << "\n"; std::cout << "Current encoding: " << scim_get_locale_encoding (locale) << "\n"; std::cout << "Current language: " << language << " (" << scim_get_language_name (language) << ")\n"; std::cout << "Related locales: " << scim_get_language_locales (language) << "\n"; std::cout << "Normalized language of " << language.substr (0,2) << " is " << scim_get_normalized_language (language.substr (0,2)) << "\n"; } scim-1.4.15/tests/testiconvert.cpp0000644000175000017500000000516112422143415016541 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2004 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: testiconvert.cpp,v 1.2 2005/01/05 13:41:13 suzhe Exp $ * */ #define Uses_SCIM_ICONV #include #include "scim.h" static const char * utf8_strings [] = { "Hello World! 世界你好!アカハザカダハフカハサダフワエロイアカサダジフハワエハラカジハサダフ", "Hello World! 世界你好!世界你好!世界你好!世界你好!", "Hello World! 世界你好!世界你好!世界你好!", "Hello World! 世界你好!世界你好!", "Hello World! 世界你好!", "Japanese いあえらかそいだはふあ", NULL }; int main () { scim::IConvert to_utf8 ("UTF-8"); scim::IConvert to_gb18030 ("GB18030"); scim::IConvert to_big5 ("BIG5"); scim::IConvert to_eucjp ("EUC-JP"); scim::String mbs, utf; scim::WideString wcs; const char **ptr = utf8_strings; while (*ptr) { std::cout << "Convert: " << *ptr << "\n"; if (to_utf8.convert (wcs, *ptr, std::strlen (*ptr))) { std::cout << "--> UTF-8 OK! "; if (to_gb18030.convert (mbs, wcs) && to_gb18030.convert (wcs, mbs)) { std::cout << "--> GB18030 OK!\n"; std::cout << " GB18030: " << mbs << "\n"; } else { std::cout << "--> GB18030 Failed!\n"; } if (to_big5.convert (mbs, wcs) && to_big5.convert (wcs, mbs)) { std::cout << "--> BIG5 OK!\n"; std::cout << " BIG5: " << mbs << "\n"; } else { std::cout << "--> BIG5 Failed!\n"; } if (to_eucjp.convert (mbs, wcs) && to_eucjp.convert (wcs, mbs)) { std::cout << "--> EUC-JP OK!\n"; std::cout << " EUC-JP: " << mbs << "\n"; } else { std::cout << "--> EUC-JP Failed!\n"; } } else { std::cout << "--> UTF-8 Failed!\n"; } if (to_utf8.test_convert (*ptr, std::strlen (*ptr))) { std::cout << "Test UTF-8 OK!\n"; } else { std::cout << "Test UTF-8 Failed!\n"; } ++ptr; } } scim-1.4.15/tests/scim_test_imengine.h0000644000175000017500000000425612422143415017326 0ustar tzhuantzhuan/** @file scim_rawcode_imengine.h * definition of RawCode related classes. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_test_imengine.h,v 1.2 2005/02/02 15:25:34 suzhe Exp $ */ #if !defined (__SCIM_TEST_SERVER_H) #define __SCIM_TEST_SERVER_H using namespace scim; class TestFactory : public IMEngineFactoryBase { friend class TestInstance; public: TestFactory (); virtual ~TestFactory (); virtual WideString get_name () const; virtual WideString get_authors () const; virtual WideString get_credits () const; virtual WideString get_help () const; virtual String get_uuid () const; virtual String get_icon_file () const; virtual String get_language () const; virtual IMEngineInstancePointer create_instance (const String& encoding, int id = -1); }; class TestInstance : public IMEngineInstanceBase { bool m_helper_started; bool m_focused; bool m_work; Transaction m_trans; public: TestInstance (TestFactory *factory, const String& encoding, int id = -1); virtual ~TestInstance (); virtual bool process_key_event (const KeyEvent& key); virtual void process_helper_event (const String &helper_uuid, const Transaction &trans); virtual void reset (); virtual void focus_in (); virtual void focus_out (); }; #endif /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/tests/scim_test_imengine.cpp0000644000175000017500000001576412422143415017667 0ustar tzhuantzhuan/** @file scim_test_imengine.cpp * implementation of class TestInstance. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_test_imengine.cpp,v 1.6 2005/05/11 09:52:10 suzhe Exp $ * */ #define Uses_SCIM_IMENGINE #define Uses_SCIM_ICONV #define Uses_SCIM_CONFIG_BASE #define Uses_SCIM_CONFIG_PATH #define Uses_SCIM_TRANS_COMMANDS #include "scim_private.h" #include "scim.h" #include "scim_test_imengine.h" #define scim_module_init test_imengine_LTX_scim_module_init #define scim_module_exit test_imengine_LTX_scim_module_exit #define scim_imengine_module_init test_imengine_LTX_scim_imengine_module_init #define scim_imengine_module_create_factory test_imengine_LTX_scim_imengine_module_create_factory #define SCIM_PROP_STATUS "/IMEngine/Test/Status" #define SCIM_TEST_ICON_FILE (SCIM_ICONDIR "/keyboard.png") #define TEST_HELPER "5d82379b-ba6e-4adc-9d81-ca49d1791b55" using namespace scim; static Pointer _scim_test_factory; static ConfigPointer _scim_config; static const char * _DEFAULT_LANGUAGES = N_( "zh_CN,zh_TW,zh_HK,zh_SG,ja_JP,ko_KR"); extern "C" { void scim_module_init (void) { } void scim_module_exit (void) { _scim_test_factory.reset (); _scim_config.reset (); } unsigned int scim_imengine_module_init (const ConfigPointer &config) { _scim_config = config; return 1; } IMEngineFactoryPointer scim_imengine_module_create_factory (unsigned int factory) { String languages; if (factory != 0) return NULL; if (_scim_test_factory.null ()) { _scim_test_factory = new TestFactory (); } return _scim_test_factory; } } // implementation of Test TestFactory::TestFactory () { set_languages (String (_(_DEFAULT_LANGUAGES))); } TestFactory::~TestFactory () { } WideString TestFactory::get_name () const { return utf8_mbstowcs (_("TEST")); } WideString TestFactory::get_authors () const { return utf8_mbstowcs (String ( _("(C) 2002-2004 James Su "))); } WideString TestFactory::get_credits () const { return WideString (); } WideString TestFactory::get_help () const { return WideString (); } String TestFactory::get_uuid () const { return String ("29904635-8afa-4e21-9138-0edb556150e7"); } String TestFactory::get_icon_file () const { return String (SCIM_TEST_ICON_FILE); } String TestFactory::get_language () const { return scim_validate_language ("other"); } IMEngineInstancePointer TestFactory::create_instance (const String& encoding, int id) { return new TestInstance (this, encoding, id); } // implementation of TestInstance TestInstance::TestInstance (TestFactory *factory, const String& encoding, int id) : IMEngineInstanceBase (factory, encoding, id), m_helper_started (false), m_focused (false), m_work (false) { } TestInstance::~TestInstance () { if (m_helper_started) { std::cerr << "TestInstance::~TestInstance () stop_helper\n"; stop_helper (TEST_HELPER); } } bool TestInstance::process_key_event (const KeyEvent& key) { if (!m_focused) return false; if (key.is_key_release ()) return true; KeyEvent newkey = key.map_to_layout (SCIM_KEYBOARD_Default); if (newkey.code == SCIM_KEY_F12) { m_work = !m_work; return true; } if (m_work) { commit_string (utf8_mbstowcs (newkey.get_key_string () + String ("\n"))); } else { m_trans.clear (); m_trans.put_command (SCIM_TRANS_CMD_REQUEST); m_trans.put_command (SCIM_TRANS_CMD_PROCESS_KEY_EVENT); m_trans.put_data (newkey); WideString text; int cursor; get_surrounding_text (text, cursor); m_trans.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT); m_trans.put_data (text); send_helper_event (TEST_HELPER, m_trans); return false; } return true; } void TestInstance::process_helper_event (const String &helper_uuid, const Transaction &trans) { std::cerr << "TestInstance::process_helper_event ()\n"; TransactionReader reader (trans); if (helper_uuid == TEST_HELPER) { int cmd; if (reader.get_command (cmd) && cmd == SCIM_TRANS_CMD_REQUEST && reader.get_command (cmd)) { if (cmd == SCIM_TRANS_CMD_START_HELPER) { m_helper_started = true; if (m_focused) { m_trans.clear (); m_trans.put_command (SCIM_TRANS_CMD_REQUEST); m_trans.put_command (SCIM_TRANS_CMD_FOCUS_IN); send_helper_event (TEST_HELPER, m_trans); } } else if (cmd == SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT) { delete_surrounding_text (-1,2); m_trans.clear (); m_trans.put_command (SCIM_TRANS_CMD_REQUEST); WideString text; int cursor; get_surrounding_text (text, cursor); m_trans.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT); m_trans.put_data (text); send_helper_event (TEST_HELPER, m_trans); } } } } void TestInstance::reset () { } void TestInstance::focus_in () { std::cerr << "TestInstance::focus_in\n"; m_focused = true; if (m_helper_started) { m_trans.clear (); m_trans.put_command (SCIM_TRANS_CMD_REQUEST); m_trans.put_command (SCIM_TRANS_CMD_FOCUS_IN); std::cerr << " send_helper_event (" << TEST_HELPER ")\n"; send_helper_event (TEST_HELPER, m_trans); } else { std::cerr << " start_helper (" << TEST_HELPER ")\n"; start_helper (TEST_HELPER); } } void TestInstance::focus_out () { std::cerr << "TestInstance::focus_out\n"; m_focused = false; if (m_helper_started) { m_trans.clear (); m_trans.put_command (SCIM_TRANS_CMD_REQUEST); m_trans.put_command (SCIM_TRANS_CMD_FOCUS_OUT); std::cerr << " send_helper_event (" << TEST_HELPER ")\n"; send_helper_event (TEST_HELPER, m_trans); } } /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/tests/scim_test_helper.cpp0000644000175000017500000002220412422143415017336 0ustar tzhuantzhuan/** @file scim_test_helper.cpp * implementation of Test Helper module. */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_test_helper.cpp,v 1.3 2005/01/15 11:34:03 suzhe Exp $ */ #define Uses_SCIM_CONFIG_BASE #define Uses_SCIM_CONFIG_PATH #define Uses_SCIM_MODULE #define Uses_SCIM_IMENGINE_MODULE #define Uses_SCIM_HELPER #define Uses_STL_MAP #include "scim_private.h" #include "scim.h" #include #define scim_module_init test_helper_LTX_scim_module_init #define scim_module_exit test_helper_LTX_scim_module_exit #define scim_helper_module_number_of_helpers test_helper_LTX_scim_helper_module_number_of_helpers #define scim_helper_module_get_helper_info test_helper_LTX_scim_helper_module_get_helper_info #define scim_helper_module_run_helper test_helper_LTX_scim_helper_module_run_helper using namespace scim; static HelperInfo __helper_info (String ("5d82379b-ba6e-4adc-9d81-ca49d1791b55"), String (_("Test")), String (""), String (_("A test helper.")), SCIM_HELPER_AUTO_RESTART|SCIM_HELPER_NEED_SCREEN_INFO|SCIM_HELPER_NEED_SPOT_LOCATION_INFO); static void run (const String &display); //Module Interface extern "C" { void scim_module_init (void) { } void scim_module_exit (void) { } unsigned int scim_helper_module_number_of_helpers (void) { return 1; } bool scim_helper_module_get_helper_info (unsigned int idx, HelperInfo &info) { if (idx == 0) { info = __helper_info; return true; } return false; } void scim_helper_module_run_helper (const String &uuid, const ConfigPointer &config, const String &display) { SCIM_DEBUG_MAIN(1) << "test_LTX_scim_helper_module_run_helper ()\n"; if (uuid == "5d82379b-ba6e-4adc-9d81-ca49d1791b55") { run (display); } SCIM_DEBUG_MAIN(1) << "exit test_LTX_scim_helper_module_run_helper ()\n"; } } static GtkWidget *main_window; static GtkWidget *keystring; static GtkWidget *surrounding; static int cur_ic = -1; static String cur_uuid; static void slot_exit (const HelperAgent *, int ic, const String &uuid) { std::cout << "slot_exit (" << ic << ", " << uuid << ")\n"; gtk_main_quit (); } static void slot_attach_input_context (const HelperAgent *agent, int ic, const String &uuid) { std::cout << "slot_attach_input_context (" << ic << ", " << uuid << ")\n"; // Inform the focused IMEngineInstance (which starts this helper) that this helper // is started successfully. Transaction trans; trans.put_command (SCIM_TRANS_CMD_REQUEST); trans.put_command (SCIM_TRANS_CMD_START_HELPER); agent->send_imengine_event (ic, uuid, trans); } static void slot_detach_input_context (const HelperAgent *agent, int ic, const String &uuid) { std::cout << "slot_detach_input_context (" << ic << ", " << uuid << ")\n"; } static void slot_update_screen (const HelperAgent *, int ic, const String &uuid, int screen) { std::cout << "slot_update_screen (" << ic << ", " << uuid << ", " << screen << ")\n"; if (gdk_display_get_n_screens (gdk_display_get_default ()) > screen) { GdkScreen *scr = gdk_display_get_screen (gdk_display_get_default (), screen); if (scr) gtk_window_set_screen (GTK_WINDOW (main_window), scr); } } static void slot_update_spot_location (const HelperAgent *, int ic, const String &uuid, int x, int y) { std::cout << "slot_update_spot_location (" << ic << ", " << uuid << ", " << x << ", " << y << ")\n"; gtk_window_move (GTK_WINDOW (main_window), x + 16, y + 16); } static void slot_process_imengine_event (const HelperAgent *, int ic, const String &uuid, const Transaction &trans) { std::cout << "slot_process_imengine_event (" << ic << ", " << uuid << ")\n"; if (uuid == "29904635-8afa-4e21-9138-0edb556150e7") { TransactionReader reader (trans); int cmd; KeyEvent key; WideString wstr; if (reader.get_command (cmd) && cmd == SCIM_TRANS_CMD_REQUEST) { while (reader.get_command (cmd)) { switch (cmd) { case SCIM_TRANS_CMD_PROCESS_KEY_EVENT: { if (reader.get_data (key)) gtk_label_set_text (GTK_LABEL (keystring), key.get_key_string ().c_str ()); break; } case SCIM_TRANS_CMD_FOCUS_IN: { cur_ic = ic; cur_uuid = uuid; gtk_widget_show (main_window); break; } case SCIM_TRANS_CMD_FOCUS_OUT: { cur_ic = -1; cur_uuid = String (""); gtk_widget_hide (main_window); break; } case SCIM_TRANS_CMD_GET_SURROUNDING_TEXT: { if (reader.get_data (wstr)) gtk_label_set_text (GTK_LABEL(surrounding), utf8_wcstombs (wstr).c_str ()); break; } } } } } } static void delete_button_clicked_callback (GtkButton *button, gpointer user_data) { HelperAgent *agent = static_cast (user_data); if (agent && cur_ic >= 0) { Transaction trans; trans.put_command (SCIM_TRANS_CMD_REQUEST); trans.put_command (SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT); agent->send_imengine_event (cur_ic, cur_uuid, trans); } } static gboolean agent_input_handler (GIOChannel *source, GIOCondition condition, gpointer user_data) { if (condition == G_IO_IN) { std::cerr << "agent_input_handler G_IO_IN\n"; HelperAgent *agent = static_cast (user_data); if (agent && agent->has_pending_event ()) agent->filter_event (); } else if (condition == G_IO_ERR || condition == G_IO_HUP) { std::cerr << "agent_input_handler G_IO_ERR|G_IO_HUP\n"; gtk_main_quit (); } return TRUE; } static void run (const String &display) { char **argv = new char * [4]; int argc = 1; argv [0] = const_cast("test-helper"); argv [1] = 0; HelperAgent agent; GtkWidget *vbox; GtkWidget *button; setenv ("DISPLAY", display.c_str (), 1); gtk_init (&argc, &argv); main_window = gtk_window_new (GTK_WINDOW_POPUP); #if GTK_CHECK_VERSION(3, 0, 0) gtk_window_set_resizable (GTK_WINDOW (main_window), FALSE); #else gtk_window_set_policy (GTK_WINDOW (main_window), FALSE, FALSE, TRUE); #endif gtk_widget_hide (main_window); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add(GTK_CONTAINER(main_window), vbox); gtk_widget_show (vbox); keystring = gtk_label_new (0); gtk_box_pack_start (GTK_BOX (vbox), keystring, FALSE, FALSE, 0); gtk_widget_show (keystring); surrounding = gtk_label_new (0); gtk_box_pack_start (GTK_BOX (vbox), surrounding, FALSE, FALSE, 0); gtk_widget_show (surrounding); button = gtk_button_new_with_label ("Delete Surrounding"); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); gtk_widget_show (button); g_signal_connect (G_OBJECT(button), "clicked", G_CALLBACK (delete_button_clicked_callback), (gpointer) &agent); agent.signal_connect_exit (slot (slot_exit)); agent.signal_connect_attach_input_context (slot (slot_attach_input_context)); agent.signal_connect_detach_input_context (slot (slot_detach_input_context)); agent.signal_connect_update_screen (slot (slot_update_screen)); agent.signal_connect_update_spot_location (slot (slot_update_spot_location)); agent.signal_connect_process_imengine_event (slot (slot_process_imengine_event)); int fd = agent.open_connection (__helper_info, display); GIOChannel *ch = g_io_channel_unix_new (fd); if (fd < 0 || !ch) { std::cerr << "Unable to open the connection to Panel.\n"; exit (-1); } g_io_add_watch (ch, G_IO_IN, agent_input_handler, (gpointer) &agent); g_io_add_watch (ch, G_IO_ERR, agent_input_handler, (gpointer) &agent); g_io_add_watch (ch, G_IO_HUP, agent_input_handler, (gpointer) &agent); gtk_main (); } /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/tests/Makefile.am0000644000175000017500000000417312422143415015342 0ustar tzhuantzhuanMAINTAINERCLEANFILES = Makefile.in AM_CPPFLAGS = -I$(top_builddir) \ -I$(top_builddir)/src \ -I$(top_srcdir) \ -I$(top_srcdir)/intl \ -I$(top_srcdir)/src \ -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \ -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \ -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \ -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \ -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \ -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" if SCIM_BUILD_TESTS CONFIG_TEST_PROGS = testsocketserver \ testsocketclient \ testiconvert \ testpanel \ testlang CONFIG_TEST_HELPER = test-helper.la CONFIG_TEST_IMENGINE = test-imengine.la endif noinst_HEADERS = scim_test_imengine.h noinst_PROGRAMS = $(CONFIG_TEST_PROGS) testsocketserver_SOURCES = testsocketserver.cpp testsocketserver_LDADD = $(top_builddir)/src/libscim@SCIM_EPOCH@.la testsocketclient_SOURCES = testsocketclient.cpp testsocketclient_LDADD = $(top_builddir)/src/libscim@SCIM_EPOCH@.la testiconvert_SOURCES = testiconvert.cpp testiconvert_LDADD = $(top_builddir)/src/libscim@SCIM_EPOCH@.la testpanel_SOURCES = testpanel.cpp testpanel_LDADD = $(top_builddir)/src/libscim@SCIM_EPOCH@.la testlang_SOURCES = testlang.cpp testlang_LDADD = $(top_builddir)/src/libscim@SCIM_EPOCH@.la helpermoduledir = $(libdir)/scim@SCIM_EPOCH@/$(SCIM_BINARY_VERSION)/Helper helpermodule_LTLIBRARIES= $(CONFIG_TEST_HELPER) test_helper_la_SOURCES = scim_test_helper.cpp test_helper_la_CXXFLAGS = @GTK_CFLAGS@ test_helper_la_LDFLAGS = -avoid-version \ -rpath $(helpermoduledir) \ -module \ @LIBTOOL_EXPORT_OPTIONS@ \ @GTK_LIBS@ \ @LTLIBINTL@ test_helper_la_LIBADD = $(top_builddir)/src/libscim@SCIM_EPOCH@.la imenginemoduledir = $(libdir)/scim@SCIM_EPOCH@/$(SCIM_BINARY_VERSION)/IMEngine imenginemodule_LTLIBRARIES= $(CONFIG_TEST_IMENGINE) test_imengine_la_SOURCES= scim_test_imengine.cpp test_imengine_la_LDFLAGS= -avoid-version \ -rpath $(imenginemoduledir) \ -module \ @LIBTOOL_EXPORT_OPTIONS@ \ @LTLIBINTL@ test_imengine_la_LIBADD = $(top_builddir)/src/libscim@SCIM_EPOCH@.la scim-1.4.15/svn2cl.xsl0000644000175000017500000003754412422143415014113 0ustar tzhuantzhuan ]> &newl; &newl; &space;&space; &newl; &newl; &newl; &space;&space; &newl;&newl; :&space; [r ]&space; &newl; &newl; &tab;*&space; &space; ,&space; ,&space; . &tab;&space;&space; &newl; &newl;&tab;&space;&space; &newl;&newl; &newl; scim-1.4.15/svn2cl.sh0000755000175000017500000002523712422143415013716 0ustar tzhuantzhuan#!/bin/sh # svn2cl.sh - front end shell script for svn2cl.xsl, calls xsltproc # with the correct parameters # # Copyright (C) 2005, 2006, 2007 Arthur de Jong. # # 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. The name of the author may not be used to endorse or promote # products derived from this software without specific prior # written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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. # exit on any failures set -e # report unset variables set -u # svn2cl version VERSION="0.9" # set default parameters PWD=`pwd` STRIPPREFIX="AUTOMATICALLY-DETERMINED" LINELEN=75 GROUPBYDAY="no" INCLUDEREV="no" BREAKBEFOREMSG="no" REPARAGRAPH="no" SEPARATEDAYLOGS="no" CHANGELOG="" OUTSTYLE="cl" SVNLOGCMD="svn --verbose --xml log" SVNINFOCMD="svn info" AUTHORSFILE="" IGNORE_MESSAGE_STARTING="" TITLE="ChangeLog" REVISION_LINK="#r" TMPFILES="" # do command line checking prog=`basename $0` while [ $# -gt 0 ] do case "$1" in --strip-prefix) STRIPPREFIX="$2" shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } ;; --strip-prefix=*) STRIPPREFIX=`echo "$1" | sed 's/^--[a-z-]*=//'` shift ;; --linelen) LINELEN="$2"; shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } ;; --linelen=*) LINELEN=`echo "$1" | sed 's/^--[a-z-]*=//'` shift ;; --group-by-day) GROUPBYDAY="yes"; shift ;; --separate-daylogs) SEPARATEDAYLOGS="yes" shift ;; -i|--include-rev) INCLUDEREV="yes"; shift ;; --break-before-msg|--breaks-before-msg) # FIXME: if next argument is numeric use that as a parameter BREAKBEFOREMSG="yes" shift ;; --break-before-msg=*|--breaks-before-msg=*) BREAKBEFOREMSG=`echo "$1" | sed 's/^--[a-z-]*=//'` shift ;; --reparagraph) REPARAGRAPH="yes" shift ;; --title) TITLE="$2" shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } ;; --title=*) TITLE=`echo "$1" | sed 's/^--[a-z-]*=//'` shift ;; --revision-link) REVISION_LINK="$2" shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } ;; --revision-link=*) REVISION_LINK=`echo "$1" | sed 's/^--[a-z-]*=//'` shift ;; --ignore-message-starting) IGNORE_MESSAGE_STARTING="$2" shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } ;; --ignore-message-starting=*) IGNORE_MESSAGE_STARTING=`echo "$1" | sed 's/^--[a-z-]*=//'` shift ;; -f|--file|-o|--output) CHANGELOG="$2" shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } ;; --file=*|--output=*) CHANGELOG=`echo "$1" | sed 's/^--[a-z-]*=//'` shift ;; --stdout) CHANGELOG="-" shift ;; --authors) AUTHORSFILE="$2" shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } ;; --authors=*) AUTHORSFILE=`echo "$1" | sed 's/^--[a-z-]*=//'` shift ;; --html) OUTSTYLE="html" shift ;; -r|--revision|--targets|--limit) # add these as extra options to the command (with argument) arg=`echo "$2" | sed "s/'/'\"'\"'/g"` SVNLOGCMD="$SVNLOGCMD $1 '$arg'" shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } ;; --username|--password|--config-dir) # add these as extra options to the command (with argument) arg=`echo "$2" | sed "s/'/'\"'\"'/g"` SVNLOGCMD="$SVNLOGCMD $1 '$arg'" # also add to svn info command SVNINFOCMD="$SVNINFOCMD $1 '$arg'" shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } ;; --revision=*|--targets=*|--limit=*) # these are single argument versions of the above arg=`echo "$1" | sed "s/'/'\"'\"'/g"` SVNLOGCMD="$SVNLOGCMD '$arg'" shift ;; --username=*|--password=*|--config-dir=*) # these are single argument versions of the above arg=`echo "$1" | sed "s/'/'\"'\"'/g"` SVNLOGCMD="$SVNLOGCMD '$arg'" # also add to svn info command SVNINFOCMD="$SVNINFOCMD '$arg'" shift ;; --stop-on-copy) # add these as simple options SVNLOGCMD="$SVNLOGCMD $1" shift ;; --no-auth-cache|--non-interactive) # add these as simple options SVNLOGCMD="$SVNLOGCMD $1" # also add to svn info command SVNINFOCMD="$SVNINFOCMD $1" shift ;; -V|--version) echo "$prog $VERSION"; echo "Written by Arthur de Jong." echo "" echo "Copyright (C) 2005, 2006, 2007 Arthur de Jong." echo "This is free software; see the source for copying conditions. There is NO" echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." exit 0 ;; -h|--help) echo "Usage: $prog [OPTION]... [PATH]..." echo "Generate a ChangeLog from a subversion repository." echo "" echo " --strip-prefix=NAME prefix to strip from all entries, defaults" echo " path inside the repository" echo " --linelen=NUM maximum length of an output line" echo " --group-by-day group changelog entries by day" echo " --separate-daylogs put a blank line between grouped by day entries" echo " -i, --include-rev include revision numbers" echo " --break-before-msg[=NUM] add a line break (or multiple breaks)" echo " between the paths and the log message" echo " --reparagraph rewrap lines inside a paragraph" echo " --title=NAME title used in html file" echo " --revision-link=NAME link revision numbers in html output" echo " --ignore-message-starting=STRING" echo " ignore messages starting with the string" echo " -o, --output=FILE output to FILE instead of ChangeLog" echo " -f, --file=FILE alias for -o, --output" echo " --stdout output to stdout instead of ChangeLog" echo " --authors=FILE file to read for authors" echo " --html output as html instead of plain text" echo " -h, --help display this help and exit" echo " -V, --version output version information and exit" echo "" echo "PATH arguments and the following options are passed to the svn log" echo "command: -r, --revision, --targets --stop-on-copy, --username," echo "--password, --no-auth-cache, --non-interactive, --config-dir and" echo "--limit (see \`svn help log' for more information)." exit 0 ;; -*) echo "$prog: invalid option -- $1" echo "Try \`$prog --help' for more information." exit 1 ;; *) arg=`echo "$1" | sed "s/'/'\"'\"'/g"` SVNLOGCMD="$SVNLOGCMD '$arg'" SVNINFOCMD="$SVNINFOCMD '$arg'" shift ;; esac done # find the directory that this script resides in prog="$0" while [ -h "$prog" ] do dir=`dirname "$prog"` prog=`ls -ld "$prog" | sed "s/^.*-> \(.*\)/\1/;/^[^/]/s,^,$dir/,"` done dir=`dirname "$prog"` dir=`cd "$dir" && pwd` XSL="$dir/svn2${OUTSTYLE}.xsl" # check if the authors file is formatted as a legacy # colon separated file if [ -n "$AUTHORSFILE" ] && \ egrep '^(#.*|[a-zA-Z0-9].*:)' "$AUTHORSFILE" > /dev/null 2>/dev/null then # create a temporary file tmpfile=`mktemp -t svn2cl.XXXXXX 2> /dev/null || tempfile -s .svn2cl 2> /dev/null || echo "$AUTHORSFILE.$$.xml"` arg=`echo "$tmpfile" | sed "s/'/'\"'\"'/g"` TMPFILES="$TMPFILES '$arg'" # generate an authors.xml file on the fly echo '' > "$tmpfile" sed -n 's/&/\&/g;s//\>/g;s|^\([a-zA-Z0-9][^:]*\):\(.*\)$| \2|p' \ < "$AUTHORSFILE" >> "$tmpfile" echo '' >> "$tmpfile" AUTHORSFILE="$tmpfile" fi # find the absolute path of the authors file # (otherwise xsltproc will find the file relative to svn2cl.xsl) pwd=`pwd` AUTHORSFILE=`echo "$AUTHORSFILE" | sed "/^[^/]/s|^|$pwd/|"` # if no filename was specified, make one up if [ -z "$CHANGELOG" ] then CHANGELOG="ChangeLog" [ "$OUTSTYLE" != "cl" ] && CHANGELOG="$CHANGELOG.$OUTSTYLE" fi # try to determin a prefix to strip from all paths if [ "$STRIPPREFIX" = "AUTOMATICALLY-DETERMINED" ] then STRIPPREFIX=`LANG=C eval "$SVNINFOCMD" 2> /dev/null | awk '/^URL:/{url=$2} /^Repository Root:/{root=$3} END{if(root){print substr(url,length(root)+2)}else{gsub("^.*/","",url);print url}}'` STRIPPREFIX=`echo "$STRIPPREFIX" | sed 's/%20/ /g'` fi # redirect stdout to the changelog file if needed if [ "x$CHANGELOG" != "x-" ] then exec > "$CHANGELOG" fi # actually run the command we need eval "$SVNLOGCMD" | \ xsltproc --stringparam strip-prefix "$STRIPPREFIX" \ --stringparam linelen "$LINELEN" \ --stringparam groupbyday "$GROUPBYDAY" \ --stringparam separate-daylogs "$SEPARATEDAYLOGS" \ --stringparam include-rev "$INCLUDEREV" \ --stringparam breakbeforemsg "$BREAKBEFOREMSG" \ --stringparam reparagraph "$REPARAGRAPH" \ --stringparam authorsfile "$AUTHORSFILE" \ --stringparam title "$TITLE" \ --stringparam revision-link "$REVISION_LINK" \ --stringparam ignore-message-starting "$IGNORE_MESSAGE_STARTING" \ --nowrite \ --nomkdir \ --nonet \ "$XSL" - # clean up temporary files [ -n "$TMPFILES" ] && eval "rm -f $TMPFILES" # we're done (the previous command could return false) exit 0 scim-1.4.15/src/0000755000175000017500000000000012422143415012726 5ustar tzhuantzhuanscim-1.4.15/src/scim_utility.h0000644000175000017500000003140712422143415015622 0ustar tzhuantzhuan/** @file scim_utility.h * @brief various utility functions. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_utility.h,v 1.36 2005/04/09 15:38:39 suzhe Exp $ */ #ifndef __SCIM_UTILITY_H #define __SCIM_UTILITY_H namespace scim { /** * @addtogroup Accessories * @{ */ #define SCIM_PATH_DELIM_STRING "/" #define SCIM_PATH_DELIM '/' // UTF-8 <-> ucs4_t convert /* Return code if invalid. (xxx_mbtowc, xxx_wctomb) */ #define RET_ILSEQ 0 /* Return code if only a shift sequence of n bytes was read. (xxx_mbtowc) */ #define RET_TOOFEW(n) (-1-(n)) /* Return code if output buffer is too small. (xxx_wctomb, xxx_reset) */ #define RET_TOOSMALL -1 /* Replacement character for invalid multibyte sequence or wide character. */ #define BAD_WCHAR ((ucs4_t) 0xfffd) #define BAD_CHAR '?' /** * @brief Convert an utf8 char sequence to ucs4. * * @param pwc destination buffer to store the ucs4 code. * @param src source buffer contains the utf8 char sequence. * @param src_len the size of source buffer. * * @return number of chars in s actually converted. */ int utf8_mbtowc (ucs4_t *pwc, const unsigned char *src, int src_len); /** * @brief Convert an ucs4 code to utf8 char sequence. * * @param dest destination buffer to store utf8 char sequence. * @param wc the ucs4 code to be converted. * @param dest_size the size of destination buffer. * * @return the number of bytes actually written into dest. */ int utf8_wctomb (unsigned char *dest, ucs4_t wc, int dest_size); /** * @brief Convert an utf8 string to an ucs4 string. * * @param str source utf8 string. * @return the destination widestring. */ WideString utf8_mbstowcs (const String & str); /** * @brief Convert an utf8 string to an ucs4 string. * * @param str source utf8 string. * @param len length of the source string. * @return the destination widestring. */ WideString utf8_mbstowcs (const char *str, int len = -1); /** * @brief Convert an ucs4 string to an utf8 string. * * @param wstr source ucs4 string. * * @return the destination utf8 string. */ String utf8_wcstombs (const WideString & wstr); /** * @brief Convert an ucs4 string to an utf8 string. * * @param wstr source ucs4 string. * @param len length of the source string. * * @return the destination utf8 string. */ String utf8_wcstombs (const ucs4_t *wstr, int len = -1); /** * @brief Read a wide char from istream. * * The content in the istream are actually in utf-8 encoding. * * @param is the stream to be read. * * @return if equal to 0 then got the end of the stream or error occurred. */ ucs4_t utf8_read_wchar (std::istream &is); /** * @brief Write a wide char to ostream. * * The content written into the ostream will be converted into utf-8 encoding. * * @param os the stream to be written. * @param wc the wide char to be written to the stream. * @return the same stream object reference. */ std::ostream & utf8_write_wchar (std::ostream &os, ucs4_t wc); /** * @brief Read a wide string from istream. * * The content in the istream are actually in utf-8 encoding. * * @param is the stream to be read. * @param delim the delimiter of the string. * @param rm_delim if the delim should be removed from the destination string. * @return the wide string read from the given stream. */ WideString utf8_read_wstring (std::istream &is, ucs4_t delim = (ucs4_t) '\n', bool rm_delim = true); /** * @brief Write a wide string to ostream. * * The content written into the ostream will be converted into utf-8 encoding. * * @param os the stream to be written. * @param wstr the wide string to be written into the stream. * @return the same stream object reference. */ std::ostream & utf8_write_wstring (std::ostream &os, const WideString & wstr); /** * @brief Convert an uint32 variable into a sequence of bytes. * * @param bytes the buffer to store the result. * @param n the variable to be converted. */ inline void scim_uint32tobytes (unsigned char *bytes, uint32 n) { bytes [0] = (unsigned char) ((n & 0xFF)); bytes [1] = (unsigned char) ((n >> 8) & 0xFF); bytes [2] = (unsigned char) ((n >> 16) & 0xFF); bytes [3] = (unsigned char) ((n >> 24) & 0xFF); } /** * @brief Convert a sequence of bytes into an uint32 value. * * @param bytes the buffer contains the bytes to be converted. * @return the result uint32 value. */ inline uint32 scim_bytestouint32 (const unsigned char *bytes) { return ((uint32) bytes [0]) | (((uint32) bytes [1]) << 8) | (((uint32) bytes [2]) << 16) | (((uint32) bytes [3]) << 24); } /** * @brief Convert an uint16 variable into a sequence of bytes. * * @param bytes the buffer to store the result. * @param n the variable to be converted. */ inline void scim_uint16tobytes (unsigned char *bytes, uint16 n) { bytes [0] = (unsigned char) ((n & 0xFF)); bytes [1] = (unsigned char) ((n >> 8) & 0xFF); } /** * @brief Convert a sequence of bytes into an uint16 value. * * @param bytes the buffer contains the bytes to be converted. * @return the result uint16 value. */ inline uint16 scim_bytestouint16 (const unsigned char *bytes) { return ((uint16) bytes [0]) | (((uint16) bytes [1]) << 8); } /** * @brief Test if the locale is valid, and return the good locale name. * * @param locale the locale to be tested. * @return If the locale is valid, it's the good locale name, otherwise empty. */ String scim_validate_locale (const String& locale); /** * @brief Get the encoding for a locale. * * @param locale the name of the locale. * @return The encoding used by the given locale. */ String scim_get_locale_encoding (const String& locale); /** * @brief Get current system locale. * @return The current system locale. */ String scim_get_current_locale (); /** * @brief Get current system language. * @return The current system language. */ String scim_get_current_language (); /** * @brief Get the max length of the multibyte char of a locale. * * @param locale the name of the locale. * @return the maxlen of this locale. */ int scim_get_locale_maxlen (const String& locale); /** * @brief Split string list into a string vector according to the delim char. * * @param vec the string vector to store the result. * @param str the string to be splitted. * @param delim the delimiter to split the strings. * @return the number of the strings in the result list. */ int scim_split_string_list (std::vector& vec, const String& str, char delim = ','); /** * @brief Combine a string vector into one string list, separated by char delim. * * @param vec the string vector which contains the strings to be combined. * @param delim the delimiter which should be put between two strings. * @return the result string. */ String scim_combine_string_list (const std::vector& vec, char delim = ','); /** * @brief Get machine endian type * @return 1 little endian, 0 big endian */ bool scim_is_little_endian (); /** * @brief Test if wchar_t is using UCS4 encoding. */ bool scim_if_wchar_ucs4_equal (); /** * @brief Convert a half width unicode char to its full width counterpart. */ ucs4_t scim_wchar_to_full_width (ucs4_t code); /** * @brief Convert a full width unicode char to its half width counterpart. */ ucs4_t scim_wchar_to_half_width (ucs4_t code); /** * @brief Get the home dir of current user. */ String scim_get_home_dir (); /** * @brief Get the name of current user. */ String scim_get_user_name (); /** * @brief Get SCIM data dir of current user. */ String scim_get_user_data_dir (); /** * @brief Load a file into memory. * * @param filename the name of the file to be loaded. * @param bufptr the place to store the newly allocated buffer pointer, * if bufptr == NULL then the file is not actually loaded, * just return the file size. * The pointer *bufptr must be deleted afterwards. * @return the size of the data actually loaded (mostly, it's the file size), * zero means load failed. */ size_t scim_load_file (const String &filename, char **bufptr); /** * @brief Make a directory. * * @param dir the dir path to be created. * * @return true if sucess. */ bool scim_make_dir (const String &dir); /** * @brief Get the localized name of a language id. * @param lang the language id. * @return the localized name of this language, in utf8 encoding. */ String scim_get_language_name (const String &lang); /** * @brief Get the English name of a language id. * @param lang the language id. * @return the English name of this language, in utf8 encoding. */ String scim_get_language_name_english (const String &lang); /** * @brief Get the untranslated name of a language id. * @param lang the language id. * @return the untranslated name of this language, in utf8 encoding. */ String scim_get_language_name_untranslated (const String &lang); /** * @brief Get the supported locales for a language. * * For example language zh_CN may support zh_CN.UTF-8, zh_CN.GB18030, zh_CN.GBK, zh_CN.GB2312 locales. * * @param lang the language id. * @return the supported locales separated by comma. */ String scim_get_language_locales (const String &lang); /** * @brief Get the language id for a locale. * @param locale the locale name * @return the language id for this locale. */ String scim_get_locale_language (const String &locale); /** * @brief Test if the language is valid, and return the good language code. * @param lang the language to be tested. * @return If the language is valid, return the good language id, otherwise return "~other". */ String scim_validate_language (const String &lang); /** * @brief Get the normalized language id of a language. * * Some short language id will be normalized to it's full id, for example: * "ja" -> "ja_JP" * "ko" -> "ko_KR" * "zh" -> "zh_CN" * * furthermore, zh_HK will be normalized to zh_TW, zh_SG will be normalized to zh_CN. * * @param lang the original language * @return the normalized language code. */ String scim_get_normalized_language (const String &lang); /** * @brief Launch a SCIM process with specific options. * * @param daemon If true then launch scim in a daemon process, * otherwise the current process will be stopped until * the newly created process exit. * @param config The Config module to be used. * @param imengines The IMEngines to be loaded, separated by comma. * @param frontend The FrontEnd module to be used. * @param argv Additional arguments passed to the new process's FrontEnd. Must * terminated by a NULL pointer. * * @return Return 0 means the process started/exited without any problem, otherwise * means an error occurred. */ int scim_launch (bool daemon, const String &config, const String &imengines, const String &frontend, char * const argv [] = 0); /** * @brief Launch a SCIM Panel process with specific options. * * @param daemon If true then launch scim in a daemon process, * otherwise the current process will be stopped until * the newly created process exit. * @param config The Config module to be used. * @param display The display name on which the panel runs. * eg. for X11 : localhost:0.0 * @param argv Additional arguments passed to the new process's FrontEnd. Must * terminated by a NULL pointer. * * @return Return 0 means the process started/exited without any problem, otherwise * means an error occurred. */ int scim_launch_panel (bool daemon, const String &config, const String &display, char * const argv [] = 0); /** * @brief Sleep some microseconds. * * @param usec The amount of microseconds to be sleeped. */ void scim_usleep (unsigned int usec); /** * @brief Switch process into daemon mode. */ void scim_daemon (); /** @} */ } // namespace scim #endif //__SCIM_UTILITY_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_utility.cpp0000644000175000017500000007667712422143415016177 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_utility.cpp,v 1.48.2.5 2006/11/02 04:11:51 suzhe Exp $ */ #define Uses_SCIM_UTILITY #define Uses_SCIM_CONFIG_PATH #define Uses_C_LOCALE #define Uses_C_ICONV #define Uses_C_STDLIB #define Uses_C_STRING #include #include #include #include #include #include #include #include #include #include #include #include "scim_private.h" #include "scim.h" namespace scim { int utf8_mbtowc (ucs4_t *pwc, const unsigned char *src, int src_len) { if (!pwc) return 0; unsigned char c = src [0]; if (c < 0x80) { *pwc = c; return 1; } else if (c < 0xc2) { return RET_ILSEQ; } else if (c < 0xe0) { if (src_len < 2) return RET_TOOFEW(0); if (!((src [1] ^ 0x80) < 0x40)) return RET_ILSEQ; *pwc = ((ucs4_t) (c & 0x1f) << 6) | (ucs4_t) (src [1] ^ 0x80); return 2; } else if (c < 0xf0) { if (src_len < 3) return RET_TOOFEW(0); if (!((src [1] ^ 0x80) < 0x40 && (src [2] ^ 0x80) < 0x40 && (c >= 0xe1 || src [1] >= 0xa0))) return RET_ILSEQ; *pwc = ((ucs4_t) (c & 0x0f) << 12) | ((ucs4_t) (src [1] ^ 0x80) << 6) | (ucs4_t) (src [2] ^ 0x80); return 3; } else if (c < 0xf8) { if (src_len < 4) return RET_TOOFEW(0); if (!((src [1] ^ 0x80) < 0x40 && (src [2] ^ 0x80) < 0x40 && (src [3] ^ 0x80) < 0x40 && (c >= 0xf1 || src [1] >= 0x90))) return RET_ILSEQ; *pwc = ((ucs4_t) (c & 0x07) << 18) | ((ucs4_t) (src [1] ^ 0x80) << 12) | ((ucs4_t) (src [2] ^ 0x80) << 6) | (ucs4_t) (src [3] ^ 0x80); return 4; } else if (c < 0xfc) { if (src_len < 5) return RET_TOOFEW(0); if (!((src [1] ^ 0x80) < 0x40 && (src [2] ^ 0x80) < 0x40 && (src [3] ^ 0x80) < 0x40 && (src [4] ^ 0x80) < 0x40 && (c >= 0xf9 || src [1] >= 0x88))) return RET_ILSEQ; *pwc = ((ucs4_t) (c & 0x03) << 24) | ((ucs4_t) (src [1] ^ 0x80) << 18) | ((ucs4_t) (src [2] ^ 0x80) << 12) | ((ucs4_t) (src [3] ^ 0x80) << 6) | (ucs4_t) (src [4] ^ 0x80); return 5; } else if (c < 0xfe) { if (src_len < 6) return RET_TOOFEW(0); if (!((src [1] ^ 0x80) < 0x40 && (src [2] ^ 0x80) < 0x40 && (src [3] ^ 0x80) < 0x40 && (src [4] ^ 0x80) < 0x40 && (src [5] ^ 0x80) < 0x40 && (c >= 0xfd || src [1] >= 0x84))) return RET_ILSEQ; *pwc = ((ucs4_t) (c & 0x01) << 30) | ((ucs4_t) (src [1] ^ 0x80) << 24) | ((ucs4_t) (src [2] ^ 0x80) << 18) | ((ucs4_t) (src [3] ^ 0x80) << 12) | ((ucs4_t) (src [4] ^ 0x80) << 6) | (ucs4_t) (src [5] ^ 0x80); return 6; } else return RET_ILSEQ; } int utf8_wctomb (unsigned char *dest, ucs4_t wc, int dest_size) { if (!dest) return 0; int count; if (wc < 0x80) count = 1; else if (wc < 0x800) count = 2; else if (wc < 0x10000) count = 3; else if (wc < 0x200000) count = 4; else if (wc < 0x4000000) count = 5; else if (wc <= 0x7fffffff) count = 6; else return RET_ILSEQ; if (dest_size < count) return RET_TOOSMALL; switch (count) { /* note: code falls through cases! */ case 6: dest [5] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x4000000; case 5: dest [4] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x200000; case 4: dest [3] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x10000; case 3: dest [2] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x800; case 2: dest [1] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0xc0; case 1: dest [0] = wc; } return count; } ucs4_t utf8_read_wchar (std::istream &is) { unsigned char utf8[6]; ucs4_t wc; int count; for (int i=0; i<6; ++i) { is.read ((char*)(utf8+i), sizeof(unsigned char)); if ((count=utf8_mbtowc (&wc, utf8, i+1)) > 0) return wc; if (count == RET_ILSEQ) return 0; } return 0; } WideString utf8_read_wstring (std::istream &is, ucs4_t delim, bool rm_delim) { WideString str; ucs4_t wc; while ((wc = utf8_read_wchar (is)) > 0) { if (wc != delim) str.push_back (wc); else { if (!rm_delim) str.push_back (wc); break; } } return str; } std::ostream & utf8_write_wchar (std::ostream &os, ucs4_t wc) { unsigned char utf8[6]; int count = 0; if ((count=utf8_wctomb (utf8, wc, 6)) > 0) os.write ((char*)utf8, count * sizeof (unsigned char)); return os; } std::ostream & utf8_write_wstring (std::ostream &os, const WideString & wstr) { for (unsigned int i=0; i 0) { wstr.push_back (wc); s += un; sn += un; } return wstr; } WideString utf8_mbstowcs (const char *str, int len) { WideString wstr; if (str) { ucs4_t wc; unsigned int sn = 0; int un = 0; if (len < 0) len = strlen (str); while (sn < len && *str != 0 && (un=utf8_mbtowc (&wc, (const unsigned char *)str, len - sn)) > 0) { wstr.push_back (wc); str += un; sn += un; } } return wstr; } String utf8_wcstombs (const WideString & wstr) { String str; char utf8 [6]; int un = 0; for (unsigned int i = 0; i 0) str.append (utf8, un); } return str; } String utf8_wcstombs (const ucs4_t *wstr, int len) { String str; char utf8 [6]; int un = 0; if (wstr) { if (len < 0) for (len = 0; wstr [len]; ++len) NULL; for (int i = 0; i < len; ++i) { un = utf8_wctomb ((unsigned char*)utf8, wstr [i], 6); if (un > 0) str.append (utf8, un); } } return str; } String scim_validate_locale (const String& locale) { String good; String last = String (setlocale (LC_CTYPE, 0)); if (setlocale (LC_CTYPE, locale.c_str ())) { good = locale; } else { std::vector vec; if (scim_split_string_list (vec, locale, '.') == 2) { if (isupper (vec[1][0])) { for (String::iterator i=vec[1].begin (); i!=vec[1].end (); ++i) *i = (char) tolower (*i); } else { for (String::iterator i=vec[1].begin (); i!=vec[1].end (); ++i) *i = (char) toupper (*i); } if (setlocale (LC_CTYPE, (vec[0] + "." + vec[1]).c_str ())) { good = vec [0] + "." + vec[1]; } } } setlocale (LC_CTYPE, last.c_str ()); return good; } String scim_get_locale_encoding (const String& locale) { String last = String (setlocale (LC_CTYPE, 0)); String encoding; if (setlocale (LC_CTYPE, locale.c_str ())) encoding = String (nl_langinfo (CODESET)); else { std::vector vec; if (scim_split_string_list (vec, locale, '.') == 2) { if (isupper (vec[1][0])) { for (String::iterator i=vec[1].begin (); i!=vec[1].end (); ++i) *i = (char) tolower (*i); } else { for (String::iterator i=vec[1].begin (); i!=vec[1].end (); ++i) *i = (char) toupper (*i); } if (setlocale (LC_CTYPE, (vec[0] + "." + vec[1]).c_str ())) encoding = String (nl_langinfo (CODESET)); } } setlocale (LC_CTYPE, last.c_str ()); return encoding; } int scim_get_locale_maxlen (const String& locale) { int maxlen; String last = String (setlocale (LC_CTYPE, 0)); if (setlocale (LC_CTYPE, locale.c_str ())) maxlen = MB_CUR_MAX; else maxlen = 1; setlocale (LC_CTYPE, last.c_str ()); return maxlen; } int scim_split_string_list (std::vector& vec, const String& str, char delim) { int count = 0; String temp; String::const_iterator bg, ed; vec.clear (); bg = str.begin (); ed = str.begin (); while (bg != str.end () && ed != str.end ()) { for (; ed != str.end (); ++ed) { if (*ed == delim) break; } temp.assign (bg, ed); vec.push_back (temp); ++count; if (ed != str.end ()) bg = ++ ed; } return count; } String scim_combine_string_list (const std::vector& vec, char delim) { String result; for (std::vector::const_iterator i = vec.begin (); i!=vec.end (); ++i) { result += *i; if (i+1 != vec.end ()) result += delim; } return result; } bool scim_if_wchar_ucs4_equal () { if (sizeof (wchar_t) != sizeof (ucs4_t)) return false; iconv_t cd; wchar_t wcbuf [2] = {0,0}; ucs4_t ucsbuf [2] = {0x4E00, 0x0001}; size_t wclen = 2 * sizeof (wchar_t); size_t ucslen = 2 * sizeof (ucs4_t); char *wcp = (char *) wcbuf; ICONV_CONST char *ucsp = (ICONV_CONST char *) ucsbuf; if (scim_is_little_endian ()) cd = iconv_open ("UCS-4LE", "wchar_t"); else cd = iconv_open ("UCS-4BE", "wchar_t"); if (cd == (iconv_t) -1) return false; iconv (cd, &ucsp, &ucslen, &wcp, &wclen); iconv_close (cd); if (wcbuf [0] == (wchar_t) ucsbuf [0] && wcbuf [1] == (wchar_t) ucsbuf [1]) return true; return false; } static struct { ucs4_t half; ucs4_t full; ucs4_t size; } __half_full_table [] = { {0x0020, 0x3000, 1}, {0x0021, 0xFF01, 0x5E}, {0x00A2, 0xFFE0, 2}, {0x00A5, 0xFFE5, 1}, {0x00A6, 0xFFE4, 1}, {0x00AC, 0xFFE2, 1}, {0x00AF, 0xFFE3, 1}, {0x20A9, 0xFFE6, 1}, {0xFF61, 0x3002, 1}, {0xFF62, 0x300C, 2}, {0xFF64, 0x3001, 1}, {0xFF65, 0x30FB, 1}, {0xFF66, 0x30F2, 1}, {0xFF67, 0x30A1, 1}, {0xFF68, 0x30A3, 1}, {0xFF69, 0x30A5, 1}, {0xFF6A, 0x30A7, 1}, {0xFF6B, 0x30A9, 1}, {0xFF6C, 0x30E3, 1}, {0xFF6D, 0x30E5, 1}, {0xFF6E, 0x30E7, 1}, {0xFF6F, 0x30C3, 1}, {0xFF70, 0x30FC, 1}, {0xFF71, 0x30A2, 1}, {0xFF72, 0x30A4, 1}, {0xFF73, 0x30A6, 1}, {0xFF74, 0x30A8, 1}, {0xFF75, 0x30AA, 2}, {0xFF77, 0x30AD, 1}, {0xFF78, 0x30AF, 1}, {0xFF79, 0x30B1, 1}, {0xFF7A, 0x30B3, 1}, {0xFF7B, 0x30B5, 1}, {0xFF7C, 0x30B7, 1}, {0xFF7D, 0x30B9, 1}, {0xFF7E, 0x30BB, 1}, {0xFF7F, 0x30BD, 1}, {0xFF80, 0x30BF, 1}, {0xFF81, 0x30C1, 1}, {0xFF82, 0x30C4, 1}, {0xFF83, 0x30C6, 1}, {0xFF84, 0x30C8, 1}, {0xFF85, 0x30CA, 6}, {0xFF8B, 0x30D2, 1}, {0xFF8C, 0x30D5, 1}, {0xFF8D, 0x30D8, 1}, {0xFF8E, 0x30DB, 1}, {0xFF8F, 0x30DE, 5}, {0xFF94, 0x30E4, 1}, {0xFF95, 0x30E6, 1}, {0xFF96, 0x30E8, 6}, {0xFF9C, 0x30EF, 1}, {0xFF9D, 0x30F3, 1}, {0xFFA0, 0x3164, 1}, {0xFFA1, 0x3131, 30}, {0xFFC2, 0x314F, 6}, {0xFFCA, 0x3155, 6}, {0xFFD2, 0x315B, 9}, {0xFFE9, 0x2190, 4}, {0xFFED, 0x25A0, 1}, {0xFFEE, 0x25CB, 1}, {0,0,0} }; /** * convert a half width unicode char to full width char */ ucs4_t scim_wchar_to_full_width (ucs4_t code) { int i=0; while (__half_full_table [i].size) { if (code >= __half_full_table [i].half && code < __half_full_table [i].half + __half_full_table [i].size) return __half_full_table [i].full + (code - __half_full_table [i].half); ++ i; } return code; } /** * convert a full width unicode char to half width char */ ucs4_t scim_wchar_to_half_width (ucs4_t code) { int i=0; while (__half_full_table [i].size) { if (code >= __half_full_table [i].full && code < __half_full_table [i].full + __half_full_table [i].size) return __half_full_table [i].half + (code - __half_full_table [i].full); ++ i; } return code; } String scim_get_home_dir () { const char * home_dir = 0; struct passwd *pw; home_dir = getenv ("SCIM_HOME"); if (home_dir && *home_dir) { return String (home_dir); } setpwent (); pw = getpwuid (getuid ()); endpwent (); if (pw) { home_dir = pw->pw_dir; } if (!home_dir) { home_dir = getenv ("HOME"); } return String (home_dir); } String scim_get_user_name () { struct passwd *pw; const char *user_name; user_name = getenv ("SCIM_USER"); if (user_name && *user_name) { return String (user_name); } setpwent (); pw = getpwuid (getuid ()); endpwent (); if (pw && pw->pw_name) return String (pw->pw_name); else if ((user_name = getenv ("USER")) != NULL) return String (user_name); char uid_str [10]; snprintf (uid_str, 10, "%u", getuid ()); return String (uid_str); } String scim_get_user_data_dir () { String dir = scim_get_home_dir () + String ("/.scim"); scim_make_dir (dir); return dir; } String scim_get_current_locale () { char *locale = setlocale (LC_MESSAGES, 0); if (locale) return String (locale); return String (); } String scim_get_current_language () { return scim_get_locale_language (scim_get_current_locale ()); } bool scim_is_little_endian () { short endian = 1; return (*((char *)&endian) != 0); } size_t scim_load_file (const String &filename, char **bufptr) { if (!filename.length ()) return 0; struct stat statbuf; if (stat (filename.c_str (), &statbuf) < 0 || !S_ISREG (statbuf.st_mode) || !statbuf.st_size) return 0; if (!bufptr) return statbuf.st_size; FILE *fp = fopen (filename.c_str (), "r"); if (fp == NULL) { *bufptr = 0; return 0; } try { *bufptr = new char [statbuf.st_size]; } catch (...) { fclose (fp); throw; } if (! (*bufptr)) { fclose (fp); return 0; } size_t size = fread (*bufptr, 1, statbuf.st_size, fp); fclose (fp); if (!size) { delete [] *bufptr; *bufptr = 0; } return size; } bool scim_make_dir (const String &dir) { std::vector paths; String path; scim_split_string_list (paths, dir, SCIM_PATH_DELIM); for (size_t i = 0; i < paths.size (); ++i) { path += SCIM_PATH_DELIM_STRING + paths [i]; //Make the dir if it's not exist. if (access (path.c_str (), R_OK) != 0) { mkdir (path.c_str (), S_IRUSR | S_IWUSR | S_IXUSR); if (access (path.c_str (), R_OK) != 0) return false; } } return true; } struct __Language { const char *code; const char *normalized; const char *name; const char *untranslated; const char *locale_suffix; }; static __Language __languages [] = { { "C", NULL, N_("English/Keyboard"), NULL, NULL}, { "am_ET", NULL, N_("Amharic"), NULL, NULL }, { "ar", "ar_EG", N_("Arabic"), NULL, NULL }, { "ar_EG", NULL, N_("Arabic (Egypt)"), NULL, NULL }, { "ar_LB", NULL, N_("Arabic (Lebanon)"), NULL, NULL }, { "as_IN", NULL, N_("Assamese"), NULL, NULL}, { "az_AZ", NULL, N_("Azerbaijani"), NULL, NULL }, { "be_BY", NULL, N_("Belarusian"), "Беларуская мова", NULL }, { "bg_BG", NULL, N_("Bulgarian"), "Български", NULL }, { "bn", "bn_BD", N_("Bengali"), "বাংলা", NULL }, { "bn_BD", NULL, N_("Bengali"), "বাংলা", NULL }, { "bn_IN", NULL, N_("Bengali (India)"), "বাংলা", NULL }, { "bo", NULL, N_("Tibetan"), NULL, NULL }, { "bs_BA", NULL, N_("Bosnian"), NULL, NULL }, { "ca_ES", NULL, N_("Catalan"), "Català", "@euro" }, { "cs_CZ", NULL, N_("Czech"), "čeština", NULL }, { "cy_GB", NULL, N_("Welsh"), "Cymraeg", NULL }, { "da_DK", NULL, N_("Danish"), "dansk", "@euro" }, { "de_DE", NULL, N_("German"), "Deutsch", "@euro" }, { "dv_MV", NULL, N_("Divehi"), "ދިވެހިބަސް", NULL }, { "el_GR", NULL, N_("Greek"), "ελληνικά", NULL }, { "en" , "en_US", N_("English"), "English", NULL }, { "en_AU", NULL, N_("English (Australian)"), "Australian English", NULL }, { "en_CA", NULL, N_("English (Canadian)"), "Canadian English", NULL }, { "en_GB", NULL, N_("English (British)"), "British English", ".iso885915" }, { "en_IE", NULL, N_("English (Ireland)"), "Irish English", NULL }, { "en_US", NULL, N_("English (American)"), "American English", ".iso885915" }, { "eo", NULL, N_("Esperanto"), "Esperanto", NULL }, { "es", "es_ES", N_("Spanish"), "Español", NULL }, { "es_ES", NULL, N_("Spanish"), "Español", "@euro" }, { "es_MX", NULL, N_("Spanish (Mexico)"), "Español (Mexico)", NULL }, { "et_EE", NULL, N_("Estonian"), "Eesti", ".iso885915" }, { "eu_ES", NULL, N_("Basque"), "Euskara", "@euro" }, { "fa_IR", NULL, N_("Persian"), "فارسی", NULL }, { "fi_FI", NULL, N_("Finnish"), "Suomi", "@euro" }, { "fr_FR", NULL, N_("French"), "Français", "@euro" }, { "ga_IE", NULL, N_("Irish"), "Gaeilge", "@euro" }, { "gl_ES", NULL, N_("Galician"), "Galego", "@euro" }, { "gu_IN", NULL, N_("Gujarati"), NULL, NULL }, { "he_IL", NULL, N_("Hebrew"), "עברית", NULL }, { "hi_IN", NULL, N_("Hindi"), "हिंदी", NULL }, { "hr_HR", NULL, N_("Croatian"), "Hrvatski", NULL }, { "hu_HU", NULL, N_("Hungarian"), "Magyar", NULL }, { "hy_AM", NULL, N_("Armenian"), "Հայերէն", NULL }, { "ia" , NULL, N_("Interlingua"), NULL }, { "id_ID", NULL, N_("Indonesian"), "Bahasa Indonesia", NULL }, { "is_IS", NULL, N_("Icelandic"), NULL, NULL }, { "it_IT", NULL, N_("Italian"), "Italiano", "@euro" }, { "iw_IL", NULL, N_("Hebrew"), "עברית", NULL }, { "ja_JP", NULL, N_("Japanese"), "日本語", ".EUC-JP,.SJIS,.eucJP" }, { "ka_GE", NULL, N_("Georgian"), "ქართული", NULL }, { "kk_KZ", NULL, N_("Kazakh"), NULL, NULL }, { "km", NULL, N_("Cambodian"), NULL, NULL }, { "kn_IN", NULL, N_("Kannada"), "ಕನ್ನಡ", NULL }, { "ko_KR", NULL, N_("Korean"), "한국어", ".EUC-KR,.eucKR" }, { "lo_LA", NULL, N_("Laothian"), NULL, NULL }, { "lt_LT", NULL, N_("Lithuanian"), "Lietuvių", NULL }, { "lv_LV", NULL, N_("Latvian"), "Latviešu", NULL }, { "mk_MK", NULL, N_("Macedonian"), NULL, NULL }, { "ml_IN", NULL, N_("Malayalam"), "മലയാളം", NULL }, { "mn_MN", NULL, N_("Mongolian"), "Монгол", NULL }, { "mr_IN", NULL, N_("Marathi"), NULL, NULL }, { "ms_MY", NULL, N_("Malay"), "Bahasa Melayu", NULL }, { "my_MM", NULL, N_("Burmese"), "", NULL }, { "ne_NP", NULL, N_("Nepali"), NULL, NULL }, { "nl_NL", NULL, N_("Dutch"), "Nederlands", "@euro" }, { "nn_NO", NULL, N_("Norwegian (nynorsk)"), "Norsk (nynorsk)", NULL }, { "no_NO", NULL, N_("Norwegian (bokmal)"), "Norsk (bokmål)", NULL }, { "or_IN", NULL, N_("Oriya"), NULL, NULL }, { "pa_IN", NULL, N_("Punjabi"), NULL, NULL }, { "pl_PL", NULL, N_("Polish"), "Polski", NULL }, { "pt", "pt_PT", N_("Portuguese"), "Português", NULL }, { "pt_BR", NULL, N_("Portuguese (Brazil)"), "Português do Brasil", NULL }, { "pt_PT", NULL, N_("Portuguese"), "Português", "@euro" }, { "ro_RO", NULL, N_("Romanian"), "Română", NULL }, { "ru_RU", NULL, N_("Russian"), "русский", ".koi8r" }, { "sd", "sd_IN", N_("Sindhi"), "ﺲﻧڌﻱ", NULL }, { "sd_IN", NULL, N_("Sindhi"), "सिन्धी", "@devanagari" }, { "si_LK", NULL, N_("Sinhala"), "සිංහල", NULL }, { "sk_SK", NULL, N_("Slovak"), "Slovenský", NULL }, { "sl_SI", NULL, N_("Slovenian"), "Slovenščina", NULL }, { "sq_AL", NULL, N_("Albanian"), "Shqip", NULL }, { "sr", "sr_YU", N_("Serbian"), "српски", NULL }, { "sr_CS", NULL, N_("Serbian"), "српски", NULL }, { "sr_YU", NULL, N_("Serbian"), "српски", "@cyrillic" }, { "sv", "sv_SE", N_("Swedish"), "Svenska", NULL }, { "sv_FI", NULL, N_("Swedish (Finland)"), "Svenska (Finland)", "@euro" }, { "sv_SE", NULL, N_("Swedish"), "Svenska", ".iso885915" }, { "ta_IN", NULL, N_("Tamil"), NULL, NULL }, { "te_IN", NULL, N_("Telugu"), NULL, NULL }, { "th_TH", NULL, N_("Thai"), "ไทย", NULL }, { "tr_TR", NULL, N_("Turkish"), "Türkçe", NULL }, { "ug", NULL, N_("Uighur"), NULL, NULL }, { "uk_UA", NULL, N_("Ukrainian"), "Українська", NULL }, { "ur_PK", NULL, N_("Urdu"), NULL, NULL }, { "uz_UZ", NULL, N_("Uzbek"), NULL, "@cyrillic" }, { "vi_VN", NULL, N_("Vietnamese"), "Việt Nam", ".tcvn" }, { "wa_BE", NULL, N_("Walloon"), "Walon", "@euro" }, { "yi" , "yi_US", N_("Yiddish"), "ייִדיש", NULL }, { "yi_US", NULL, N_("Yiddish"), "ייִדיש", NULL }, { "zh", "zh_CN", N_("Chinese"), "中文", NULL }, { "zh_CN", NULL, N_("Chinese (simplified)"), "中文 (简体)", ".GB18030,.GBK,.GB2312,.eucCN" }, { "zh_HK", "zh_TW", N_("Chinese (traditional)"), "中文 (繁體)", NULL }, { "zh_SG", "zh_CN", N_("Chinese (simplified)"), "中文 (简体)", ".GBK" }, { "zh_TW", NULL, N_("Chinese (traditional)"), "中文 (繁體)", ".eucTW" }, { "", "", "", NULL, NULL } }; class __LanguageLess { public: bool operator () (const __Language &lhs, const __Language &rhs) const { return strcmp (lhs.code, rhs.code) < 0; } bool operator () (const __Language &lhs, const String &rhs) const { return strcmp (lhs.code, rhs.c_str ()) < 0; } bool operator () (const String &lhs, const __Language &rhs) const { return strcmp (lhs.c_str (), rhs.code) < 0; } }; static __Language * __find_language (const String &lang) { static __Language *langs_begin = __languages; static __Language *langs_end = __languages + sizeof (__languages) / sizeof (__Language) - 1; String nlang = lang; bool contry_code = false; // Normalize the language name. for (String::iterator it = nlang.begin (); it != nlang.end (); ++it) { if (*it == '-' || *it == '_') { *it = '_'; contry_code = true; } else if (contry_code) { *it = toupper (*it); } else { *it = tolower (*it); } } __Language *result = std::lower_bound (langs_begin, langs_end, nlang, __LanguageLess ()); if (result != langs_end) { if (strncmp (result->code, nlang.c_str (), strlen (result->code)) == 0 || (strncmp (result->code, nlang.c_str (), nlang.length ()) == 0 && strncmp (result->code, (result+1)->code, nlang.length ()) != 0)) return result; } return NULL; } String scim_get_language_name (const String &lang) { return String (_(scim_get_language_name_english (lang).c_str ())); } String scim_get_language_name_english (const String &lang) { __Language *result = __find_language (lang); if (result) return String (result->name); return String ("Other"); } String scim_get_language_name_untranslated (const String &lang) { __Language *result = __find_language (lang); if (result) { if (result->untranslated) return String (result->untranslated); else return String (_(result->name)); } return String (_("Other")); } String scim_get_language_locales (const String &lang) { __Language *result = __find_language (lang); std::vector locales; if (result) { String good; if (strlen (result->code) < 5 && result->normalized) result = __find_language (result->normalized); good = scim_validate_locale (String (result->code) + ".UTF-8"); if (good.length ()) locales.push_back (good); if (result->locale_suffix) { std::vector suffixes; scim_split_string_list (suffixes, result->locale_suffix, ','); for (size_t i = 0; i < suffixes.size (); ++ i) { good = scim_validate_locale (String (result->code) + suffixes [i]); if (good.length ()) locales.push_back (good); } } good = scim_validate_locale (result->code); if (good.length ()) locales.push_back (good); } return scim_combine_string_list (locales, ','); } String scim_get_locale_language (const String &locale) { if (locale.length () == 0) return String (); String str = locale.substr (0, locale.find ('.')); return scim_validate_language (str.substr (0, str.find ('@'))); } String scim_validate_language (const String &lang) { __Language *result = __find_language (lang); if (result) return String (result->code); // Add prefix ~ to let other become the last item when sorting. return String ("~other"); } String scim_get_normalized_language (const String &lang) { __Language *result = __find_language (lang); if (result) { if (result->normalized) return String (result->normalized); else return String (result->code); } // Add prefix ~ to let other become the last item when sorting. return String ("~other"); } #ifndef SCIM_LAUNCHER #define SCIM_LAUNCHER (SCIM_LIBEXECDIR "/scim-launcher") #endif int scim_launch (bool daemon, const String &config, const String &imengines, const String &frontend, char * const argv []) { if (!config.length () || !imengines.length () || !frontend.length ()) return -1; int new_argc = 0; char *new_argv [40]; char verbose_buf [10]; new_argv [new_argc ++] = strdup (SCIM_LAUNCHER); if (daemon) new_argv [new_argc ++] = strdup ("-d"); new_argv [new_argc ++] = strdup ("-c"); new_argv [new_argc ++] = strdup (config.c_str ()); new_argv [new_argc ++] = strdup ("-e"); new_argv [new_argc ++] = strdup (imengines.c_str ()); new_argv [new_argc ++] = strdup ("-f"); new_argv [new_argc ++] = strdup (frontend.c_str ()); if (argv) { for (int i = 0; argv [i] && new_argc < 40 ; ++i, ++new_argc) new_argv [new_argc] = strdup (argv [i]); } new_argv [new_argc] = 0; pid_t child_pid; child_pid = fork (); // Error fork. if (child_pid < 0) return -1; // In child process, start scim-launcher. if (child_pid == 0) { return execv (SCIM_LAUNCHER, new_argv); } // In parent process, wait the child exit. for (int i = 0; i < new_argc; ++i) if (new_argv [i]) free (new_argv [i]); int status; pid_t ret_pid; ret_pid = waitpid (child_pid, &status, 0); if (ret_pid == child_pid && WIFEXITED(status)) return WEXITSTATUS(status); return -1; } #ifndef SCIM_PANEL_PROGRAM #define SCIM_PANEL_PROGRAM (SCIM_LIBEXECDIR "/scim-panel-gtk") #endif int scim_launch_panel (bool daemon, const String &config, const String &display, char * const argv []) { if (!config.length ()) return -1; String panel_program = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_PANEL_PROGRAM, String (SCIM_PANEL_PROGRAM)); if (!panel_program.length ()) panel_program = String (SCIM_PANEL_PROGRAM); if (panel_program [0] != SCIM_PATH_DELIM) { panel_program = String (SCIM_LIBEXECDIR) + String (SCIM_PATH_DELIM_STRING) + panel_program; } //if the file is not exist or is not executable, fallback to default if (access (panel_program.c_str (), X_OK) != 0) panel_program = String (SCIM_PANEL_PROGRAM); int new_argc = 0; char *new_argv [80]; new_argv [new_argc ++] = strdup (panel_program.c_str ()); new_argv [new_argc ++] = strdup ("--display"); new_argv [new_argc ++] = strdup (display.c_str ()); new_argv [new_argc ++] = strdup ("-c"); new_argv [new_argc ++] = strdup (config.c_str ()); if (daemon) new_argv [new_argc ++] = strdup ("-d"); if (argv) { for (int i = 0; argv [i] && new_argc < 40; ++i, ++new_argc) new_argv [new_argc] = strdup (argv [i]); } new_argv [new_argc] = 0; pid_t child_pid; child_pid = fork (); // Error fork. if (child_pid < 0) return -1; // In child process, start scim-launcher. if (child_pid == 0) { return execv (panel_program.c_str (), new_argv); } // In parent process, wait the child exit. for (int i = 0; i < new_argc; ++i) if (new_argv [i]) free (new_argv [i]); int status; pid_t ret_pid; ret_pid = waitpid (child_pid, &status, 0); if (ret_pid == child_pid && WIFEXITED(status)) return WEXITSTATUS(status); return -1; } void scim_usleep (unsigned int usec) { if (usec == 0) return; #if HAVE_NANOSLEEP struct timespec req, rem; req.tv_sec = usec / 1000000; req.tv_nsec = (usec % 1000000) * 1000; while (nanosleep (&req, &rem) == -1 && errno == EINTR && (rem.tv_sec != 0 || rem.tv_nsec != 0)) req = rem; #elif HAVE_USLEEP unsigned int sec = usec / 1000000; usec %= 1000000; for (unsigned int i = 0; i < sec; ++i) sleep (1); usleep (usec); #else unsigned int sec = usec / 1000000; sleep (sec ? sec : 1); #endif } void scim_daemon () { #if HAVE_DAEMON if (daemon (0, 0) == -1) std::cerr << "Error to make SCIM into a daemon!\n"; return; #else pid_t id; id = fork (); if (id == -1) { std::cerr << "Error to make SCIM into a daemon!\n"; return; } else if (id > 0) { _exit (0); } id = fork (); if (id == -1) { std::cerr << "Error to make SCIM into a daemon!\n"; return; } else if (id > 0) { _exit (0); } return; #endif } } // namespace scim /* vi:ts=4:ai:nowrap:expandtab */ scim-1.4.15/src/scim_types.h.in0000644000175000017500000000276512422143415015675 0ustar tzhuantzhuan/** @file scim_types.h * @brief defines some basic data types. */ /* * Smart Common Input Method * * Copyright (c) 2002-2004 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_types.h.in,v 1.2.4.1 2007/04/10 09:18:27 suzhe Exp $ */ #ifndef __SCIM_TYPES_H #define __SCIM_TYPES_H @INCLUDE_STDINT@ #ifdef __FreeBSD__ # include # if __FreeBSD_version > 500035 # define __STDC_ISO_10646__ # endif #endif namespace scim { typedef @UINT16@ uint16; typedef @UINT32@ uint32; typedef @UINT64@ uint64; #ifdef __STDC_ISO_10646__ typedef wchar_t ucs4_t; #else typedef uint32 ucs4_t; #endif typedef std::basic_string String; typedef std::basic_string WideString; } // namespace scim #endif //__SCIM_TYPES_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_transaction.h0000644000175000017500000003123712422143415016445 0ustar tzhuantzhuan/** * @file scim_transaction.h * @brief Transaction class. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_transaction.h,v 1.10 2005/05/24 12:22:51 suzhe Exp $ */ #ifndef __SCIM_TRANSACTION_H #define __SCIM_TRANSACTION_H namespace scim { /** * @addtogroup SocketCommunication * @{ */ /** * @brief Signature of all valid data types which can be store into transaction. */ enum TransactionDataType { SCIM_TRANS_DATA_UNKNOWN, //!< Unknown transaction data type. SCIM_TRANS_DATA_COMMAND, //!< Send/Receive command. SCIM_TRANS_DATA_RAW, //!< Send/Receive raw buffer. SCIM_TRANS_DATA_UINT32, //!< Send/Receive uint32. SCIM_TRANS_DATA_STRING, //!< Send/Receive String. SCIM_TRANS_DATA_WSTRING, //!< Send/Receive WideString. SCIM_TRANS_DATA_KEYEVENT, //!< Send/Receive KeyEvent. SCIM_TRANS_DATA_ATTRIBUTE_LIST, //!< Send/Receive AttributeList. SCIM_TRANS_DATA_LOOKUP_TABLE, //!< Send/Receive LookupTable. SCIM_TRANS_DATA_PROPERTY, //!< Send/Receive Property. SCIM_TRANS_DATA_PROPERTY_LIST, //!< Send/Receive PropertyList. SCIM_TRANS_DATA_VECTOR_UINT32, //!< Send/Receive vector. SCIM_TRANS_DATA_VECTOR_STRING, //!< Send/Receive vector. SCIM_TRANS_DATA_VECTOR_WSTRING, //!< Send/Receive vector. SCIM_TRANS_DATA_TRANSACTION //!< Send/Receive another Transaction. }; /** * @brief An exception class to hold Transaction related errors. * * scim::Transaction and its related classes must throw * scim::TransactionError object when error. */ class TransactionError: public Exception { public: TransactionError (const String& what_arg) : Exception (String("scim::Transaction: ") + what_arg) { } }; class TransactionHolder; class TransactionReader; /** * @brief This class is used to pack up many data and commands into one package * and send them via socket. */ class Transaction { friend class TransactionReader; TransactionHolder * m_holder; TransactionReader * m_reader; Transaction (const Transaction &); const Transaction & operator = (const Transaction &); public: /** * @brief Constructor. * * @param bufsize the initial buffer size, maybe grow afterwards. */ Transaction (size_t bufsize = 512); /** * @brief Destructor. */ ~Transaction (); /** * @brief Check if the transaction is valid. * * @return true if this Transaction object is valid and ready to use. */ bool valid () const; /** * @brief Get the size of this transaction. */ size_t get_size () const; /** * @brief Write the transaction to a socket. * * @param socket the socket to be written to. * @param signature the leading signature to be written * into the socket before the transaction itself, * this signature maybe missing when receive the transaction. * It's useful to check the connection before receiving * a transaction by reading this signature. * * @return true if success. */ bool write_to_socket (const Socket &socket, uint32 signature = 0) const; /** * @brief Read a transaction from a socket. * * @param socket the socket to be read from. * @param timeout time out in millisecond (1/1000 second), -1 means infinity. * * @return true if success. */ bool read_from_socket (const Socket &socket, int timeout = -1); /** * @brief Write the transaction into a buffer. * * @param buf A buffer to store the transaction data. * @param bufsize The size of this buffer. * @return true if success (the buf is large enough). */ bool write_to_buffer (void *buf, size_t bufsize) const; /** * @brief Read a transaction from a buffer. * * @param buf A buffer contains the transaction. * @param bufsize The size of this buffer. * @return true if success. */ bool read_from_buffer (const void *buf, size_t bufsize); /** * @brief Store a command into this transaction. * * @param cmd the command code, like SCIM_TRANS_CMD_FOCUS_IN etc. */ void put_command (int cmd); /** * @brief Store a uint32 value into this transaction. */ void put_data (uint32 val); /** * @brief Store a String object into this transaction. */ void put_data (const String &str); /** * @brief Store a WideString object into this transaction. */ void put_data (const WideString &str); /** * @brief Store a KeyEvent object into this transaction. */ void put_data (const KeyEvent &key); /** * @brief Store an AttributeList object into this transaction. */ void put_data (const AttributeList &attrs); /** * @brief Store a Property object into this transaction. */ void put_data (const Property &property); /** * @brief Store a PropertyList object into this transaction. */ void put_data (const PropertyList &properties); /** * @brief Store a LookupTable object into this transaction. */ void put_data (const LookupTable &table); /** * @brief Store a std::vector object into this transaction. */ void put_data (const std::vector &vec); /** * @brief Store a std::vector object into this transaction. */ void put_data (const std::vector &vec); /** * @brief Store a std::vector object into this transaction. */ void put_data (const std::vector &vec); /** * @brief Store a raw buffer into this transaction. */ void put_data (const char *raw, size_t bufsize); /** * @brief Store another Transaction object into this transaction. */ void put_data (const Transaction &trans); /** * @brief Get the type of the data at current read position. * * @return The type of the data can be read currently. */ TransactionDataType get_data_type () const; /** * @brief Get a command from current read position. */ bool get_command (int &cmd); /** * @brief Get an uint32 value from current read position. */ bool get_data (uint32 &val); /** * @brief Get a String from current read position. */ bool get_data (String &str); /** * @brief Get a WideString from current read position. */ bool get_data (WideString &str); /** * @brief Get a KeyEvent from current read position. */ bool get_data (KeyEvent &key); /** * @brief Get an AttributeList from current read position. */ bool get_data (AttributeList &attrs); /** * @brief Get a Property from current read position. */ bool get_data (Property &property); /** * @brief Get a PropertyList from current read position. */ bool get_data (PropertyList &properties); /** * @brief Get a CommonLookupTable from current read position. */ bool get_data (CommonLookupTable &table); /** * @brief Get a std::vector from current read position. */ bool get_data (std::vector &vec); /** * @brief Get a std::vector from current read position. */ bool get_data (std::vector &vec); /** * @brief Get a std::vector from current read position. */ bool get_data (std::vector &vec); /** * @brief Get a raw buffer from current read position. * * if raw == NULL then return the bufsize and skip this data. * *raw should be deleted afterwards (do not use free!). */ bool get_data (char **raw, size_t &bufsize); /** * @brief Get a Transaction object from current read position. */ bool get_data (Transaction &trans); /** * @brief Skip one data from current read position. */ bool skip_data (); /** * @brief Rewind the current read position, then the data can be read again. */ void rewind (); /** * @brief Clear the transaction, all data in this transaction will be freed. */ void clear (); }; /** * @brief This class is used to read data from a transaction without changing it. */ class TransactionReader { class TransactionReaderImpl; TransactionReaderImpl *m_impl; public: /** * @brief Default constructor. * * Construct an empty TransactionReader object. */ TransactionReader (); /** * @brief Constructor. * * Construct a TransactionReader object and attach to a Transaction object. * * @param trans The Transaction to be read. */ TransactionReader (const Transaction &trans); /** * @brief Destructor. */ ~TransactionReader (); /** * @brief Copy constructor. */ TransactionReader (const TransactionReader &); /** * @brief Copy operator. */ const TransactionReader & operator = (const TransactionReader &); /** * @brief Attach this TransactionReader object to a Transaction. * * An empty TransactionReader object must be attached to a * Transaction object before reading. * * @param trans The Transaction object to be read. */ void attach (const Transaction &trans); /** * @brief Detach this TransactionReader object from * currently attached Transaction object. */ void detach (); /** * @brief Check if the transaction reader is valid. * * @return true if this TransactionReader object * is attached to a Transaction object and ready to be read. */ bool valid () const; /** * @brief Get the type of the data at current read position. * * @return The type of the data can be read currently. */ TransactionDataType get_data_type () const; /** * @brief Get a command from current read position. */ bool get_command (int &cmd); /** * @brief Get an uint32 value from current read position. */ bool get_data (uint32 &val); /** * @brief Get a String from current read position. */ bool get_data (String &str); /** * @brief Get a WideString from current read position. */ bool get_data (WideString &str); /** * @brief Get a KeyEvent from current read position. */ bool get_data (KeyEvent &key); /** * @brief Get an AttributeList from current read position. */ bool get_data (AttributeList &attrs); /** * @brief Get a Property from current read position. */ bool get_data (Property &property); /** * @brief Get a PropertyList from current read position. */ bool get_data (PropertyList &properties); /** * @brief Get a CommonLookupTable from current read position. */ bool get_data (CommonLookupTable &table); /** * @brief Get a std::vector from current read position. */ bool get_data (std::vector &vec); /** * @brief Get a std::vector from current read position. */ bool get_data (std::vector &vec); /** * @brief Get a std::vector from current read position. */ bool get_data (std::vector &vec); /** * @brief Get a raw buffer from current read position. * * if raw == NULL then return the bufsize and skip this data. * *raw should be deleted afterwards (do not use free!). */ bool get_data (char **raw, size_t &bufsize); /** * @brief Get a Transaction object from current read position. */ bool get_data (Transaction &trans); /** * @brief Skip one data from current read position. */ bool skip_data (); /** * @brief Rewind the current read position, then the data can be read again. */ void rewind (); }; /** @} */ } // namespace scim #endif //__SCIM_TRANSACTION_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_transaction.cpp0000644000175000017500000011151612422143415016777 0ustar tzhuantzhuan/** @file scim_transaction.cpp * @brief Implementation of Transaction related classes. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_transaction.cpp,v 1.13.2.1 2006/06/07 09:27:57 suzhe Exp $ * */ #define Uses_SCIM_TRANSACTION #define Uses_STL_ALGORITHM #define Uses_C_STDLIB #define Uses_C_STRING #include "scim_private.h" #include "scim.h" namespace scim { #define SCIM_TRANS_MIN_BUFSIZE 512 #define SCIM_TRANS_MAX_BUFSIZE (1048576*16) #define SCIM_TRANS_MAGIC 0x4d494353 #define SCIM_TRANS_HEADER_SIZE (sizeof (uint32) * 4) class TransactionHolder { mutable int m_ref; public: size_t m_buffer_size; size_t m_write_pos; unsigned char *m_buffer; public: TransactionHolder (size_t bufsize) : m_ref (0), m_buffer_size (std::max ((size_t)SCIM_TRANS_MIN_BUFSIZE, bufsize)), m_write_pos (SCIM_TRANS_HEADER_SIZE), m_buffer ((unsigned char*) malloc (std::max ((size_t)SCIM_TRANS_MIN_BUFSIZE, bufsize))) { if (!m_buffer) throw Exception ("TransactionHolder::TransactionHolder() Out of memory"); } ~TransactionHolder () { free (m_buffer); } bool valid () const { return m_buffer && m_buffer_size; } void ref () const { ++m_ref; } void unref () const { if ((--m_ref) <= 0) delete this; } void request_buffer_size (size_t request) { if (m_write_pos + request >= m_buffer_size) { size_t bufsize = std::max ((size_t) SCIM_TRANS_MIN_BUFSIZE, request + 1) + m_buffer_size; unsigned char *tmp = (unsigned char*) realloc (m_buffer, bufsize); if (!tmp) throw Exception ("TransactionHolder::request_buffer_size() Out of memory"); m_buffer = tmp; m_buffer_size = bufsize; } } uint32 calc_checksum () const { uint32 sum = 0; unsigned char *ptr = m_buffer + SCIM_TRANS_HEADER_SIZE; unsigned char *ptr_end = m_buffer + m_write_pos; while (ptr < ptr_end) { sum += (uint32) (*ptr); sum = (sum << 1) | (sum >> 31); ++ ptr; } return sum; } }; Transaction::Transaction (size_t bufsize) : m_holder (new TransactionHolder (bufsize)), m_reader (new TransactionReader ()) { m_holder->ref (); m_reader->attach (*this); } Transaction::~Transaction () { delete m_reader; m_holder->unref (); } bool Transaction::valid () const { return m_holder->valid (); } bool Transaction::write_to_socket (const Socket &socket, uint32 signature) const { if (socket.valid () && valid ()) { scim_uint32tobytes (m_holder->m_buffer, signature); scim_uint32tobytes (m_holder->m_buffer + sizeof (uint32), SCIM_TRANS_MAGIC); scim_uint32tobytes (m_holder->m_buffer + sizeof (uint32) * 2, m_holder->m_write_pos - SCIM_TRANS_HEADER_SIZE); scim_uint32tobytes (m_holder->m_buffer + sizeof (uint32) * 3, m_holder->calc_checksum ()); return socket.write (m_holder->m_buffer, m_holder->m_write_pos) == (int) m_holder->m_write_pos; } return false; } bool Transaction::read_from_socket (const Socket &socket, int timeout) { if (socket.valid () && valid ()) { unsigned char buf [sizeof (uint32) * 2]; uint32 sign1, sign2; uint32 checksum; int size; int nbytes; nbytes = socket.read_with_timeout (buf, sizeof (uint32) * 2, timeout); if (nbytes < sizeof (uint32) * 2) return false; sign1 = scim_bytestouint32 (buf); sign2 = scim_bytestouint32 (buf + sizeof (uint32)); if (sign1 != SCIM_TRANS_MAGIC && sign2 != SCIM_TRANS_MAGIC) return false; if (sign2 == SCIM_TRANS_MAGIC) { nbytes = socket.read_with_timeout (buf, sizeof (uint32), timeout); if (nbytes < sizeof (uint32)) return false; size = scim_bytestouint32 (buf); } else { size = (int) sign2; } nbytes = socket.read_with_timeout (buf, sizeof (uint32), timeout); if (nbytes < sizeof (uint32)) return false; checksum = scim_bytestouint32 (buf); if (size <= 0 || size > SCIM_TRANS_MAX_BUFSIZE) return false; clear (); m_holder->request_buffer_size (size); while (size != 0) { nbytes = socket.read_with_timeout (m_holder->m_buffer + m_holder->m_write_pos, size, timeout); if (nbytes <= 0) { m_holder->m_write_pos = SCIM_TRANS_HEADER_SIZE; return false; } size -= nbytes; m_holder->m_write_pos += nbytes; } if (checksum != m_holder->calc_checksum ()) { m_holder->m_write_pos = SCIM_TRANS_HEADER_SIZE; return false; } return true; } return false; } size_t Transaction::get_size () const { return m_holder->m_write_pos; } bool Transaction::write_to_buffer (void *buf, size_t bufsize) const { if (valid () && buf && bufsize >= m_holder->m_write_pos) { unsigned char *cbuf = static_cast (buf); memcpy (buf, m_holder->m_buffer, m_holder->m_write_pos); scim_uint32tobytes (cbuf, 0); scim_uint32tobytes (cbuf + sizeof (uint32), SCIM_TRANS_MAGIC); scim_uint32tobytes (cbuf + sizeof (uint32) * 2, m_holder->m_write_pos - SCIM_TRANS_HEADER_SIZE); scim_uint32tobytes (cbuf + sizeof (uint32) * 3, m_holder->calc_checksum ()); return true; } return false; } bool Transaction::read_from_buffer (const void *buf, size_t bufsize) { const unsigned char * cbuf = static_cast (buf); if (valid () && buf && scim_bytestouint32 (cbuf) == 0 && scim_bytestouint32 (cbuf + sizeof (uint32)) == SCIM_TRANS_MAGIC && scim_bytestouint32 (cbuf + sizeof (uint32) * 2) <= bufsize - SCIM_TRANS_HEADER_SIZE) { uint32 size = scim_bytestouint32 (cbuf + sizeof (uint32) * 2) + SCIM_TRANS_HEADER_SIZE; uint32 checksum = scim_bytestouint32 (cbuf + sizeof (uint32) * 3); if (m_holder->m_buffer_size < size) m_holder->request_buffer_size (size - m_holder->m_buffer_size); memcpy (m_holder->m_buffer, buf, size); m_holder->m_write_pos = SCIM_TRANS_HEADER_SIZE; if (checksum == m_holder->calc_checksum ()) return true; } return false; } void Transaction::put_command (int type) { m_holder->request_buffer_size (1 + sizeof (uint32)); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_COMMAND; scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, (uint32) type); m_holder->m_write_pos += sizeof (uint32); } void Transaction::put_data (uint32 val) { m_holder->request_buffer_size (1 + sizeof (val)); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_UINT32; scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, val); m_holder->m_write_pos += sizeof (uint32); } void Transaction::put_data (const String &str) { m_holder->request_buffer_size (1 + str.length () + sizeof (uint32)); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_STRING; scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, str.length ()); m_holder->m_write_pos += sizeof (uint32); if (str.length ()) memcpy (m_holder->m_buffer + m_holder->m_write_pos, str.c_str (), str.length ()); m_holder->m_write_pos += str.length (); } void Transaction::put_data (const WideString &str) { String mbs = utf8_wcstombs (str); m_holder->request_buffer_size (1 + mbs.length () + sizeof (uint32)); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_WSTRING; scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, mbs.length ()); m_holder->m_write_pos += sizeof (uint32); if (mbs.length ()) memcpy (m_holder->m_buffer + m_holder->m_write_pos, mbs.c_str (), mbs.length ()); m_holder->m_write_pos += mbs.length (); } void Transaction::put_data (const KeyEvent &key) { m_holder->request_buffer_size (1 + sizeof (uint32) + sizeof (uint16) * 2); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_KEYEVENT; scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, key.code); m_holder->m_write_pos += sizeof (uint32); scim_uint16tobytes (m_holder->m_buffer + m_holder->m_write_pos, key.mask); m_holder->m_write_pos += sizeof (uint16); scim_uint16tobytes (m_holder->m_buffer + m_holder->m_write_pos, key.layout); m_holder->m_write_pos += sizeof (uint16); } void Transaction::put_data (const AttributeList &attrs) { size_t size = attrs.size () * (sizeof (uint32) * 3 + 1) + sizeof (uint32) + 1; m_holder->request_buffer_size (size); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_ATTRIBUTE_LIST; scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, attrs.size ()); m_holder->m_write_pos += sizeof (uint32); for (size_t i=0; im_buffer [m_holder->m_write_pos++] = (unsigned char) attrs[i].get_type (); scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, attrs[i].get_value ()); m_holder->m_write_pos += sizeof (uint32); scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, attrs[i].get_start ()); m_holder->m_write_pos += sizeof (uint32); scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, attrs[i].get_length ()); m_holder->m_write_pos += sizeof (uint32); } } void Transaction::put_data (const Property &property) { size_t request = property.get_key ().length () + property.get_label ().length () + property.get_icon ().length () + property.get_tip ().length () + (sizeof (uint32) + 1) * 4 + 3; m_holder->request_buffer_size (request); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_PROPERTY; put_data (property.get_key ()); put_data (property.get_label ()); put_data (property.get_icon ()); put_data (property.get_tip ()); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) property.visible (); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) property.active(); } void Transaction::put_data (const PropertyList &properties) { m_holder->request_buffer_size (1 + sizeof(uint32)); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_PROPERTY_LIST; scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, properties.size ()); m_holder->m_write_pos += sizeof (uint32); for (PropertyList::const_iterator it = properties.begin (); it != properties.end (); ++ it) put_data (*it); } void Transaction::put_data (const LookupTable &table) { unsigned char stat = 0; size_t i; m_holder->request_buffer_size (4); //Can be page up. if (table.get_current_page_start ()) stat |= 1; //Can be page down. if (table.get_current_page_start () + table.get_current_page_size () < table.number_of_candidates ()) stat |= 2; //Cursor is visible. if (table.is_cursor_visible ()) stat |= 4; //Pagesize is fixed. if (table.is_page_size_fixed ()) stat |= 8; m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_LOOKUP_TABLE; m_holder->m_buffer [m_holder->m_write_pos++] = stat; m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) table.get_current_page_size (); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) table.get_cursor_pos_in_current_page (); // Store page labels. for (i = 0; i < table.get_current_page_size (); ++i) put_data (table.get_candidate_label (i)); // Store page candidates, attributes. for (i = 0; i < table.get_current_page_size (); ++i) { put_data (table.get_candidate_in_current_page (i)); put_data (table.get_attributes_in_current_page (i)); } } void Transaction::put_data (const std::vector &vec) { size_t size = vec.size () * sizeof (uint32) + sizeof (uint32) + 1; m_holder->request_buffer_size (size); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_VECTOR_UINT32; scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, vec.size ()); m_holder->m_write_pos += sizeof (uint32); for (size_t i=0; im_buffer + m_holder->m_write_pos, vec[i]); m_holder->m_write_pos += sizeof (uint32); } } void Transaction::put_data (const std::vector &vec) { m_holder->request_buffer_size (sizeof(uint32) + 1); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_VECTOR_STRING; scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, vec.size ()); m_holder->m_write_pos += sizeof (uint32); for (size_t i=0; i &vec) { m_holder->request_buffer_size (sizeof(uint32) + 1); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_VECTOR_WSTRING; scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, vec.size ()); m_holder->m_write_pos += sizeof (uint32); for (size_t i=0; irequest_buffer_size (bufsize + sizeof (uint32) + 1); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_RAW; scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, (uint32) bufsize); m_holder->m_write_pos += sizeof (uint32); memcpy (m_holder->m_buffer + m_holder->m_write_pos, raw, bufsize); m_holder->m_write_pos += bufsize; } void Transaction::put_data (const Transaction &trans) { if (!trans.valid ()) return; m_holder->request_buffer_size (trans.m_holder->m_write_pos + sizeof (uint32) + 1); m_holder->m_buffer [m_holder->m_write_pos++] = (unsigned char) SCIM_TRANS_DATA_TRANSACTION; scim_uint32tobytes (m_holder->m_buffer + m_holder->m_write_pos, (uint32) trans.m_holder->m_write_pos); m_holder->m_write_pos += sizeof (uint32); memcpy (m_holder->m_buffer + m_holder->m_write_pos, trans.m_holder->m_buffer, trans.m_holder->m_write_pos); m_holder->m_write_pos += trans.m_holder->m_write_pos; } void Transaction::clear () { m_holder->m_write_pos = SCIM_TRANS_HEADER_SIZE; m_reader->rewind (); } TransactionDataType Transaction::get_data_type () const { return m_reader->get_data_type (); } bool Transaction::get_command (int &type) { return m_reader->get_command (type); } bool Transaction::get_data (uint32 &val) { return m_reader->get_data (val); } bool Transaction::get_data (String &str) { return m_reader->get_data (str); } bool Transaction::get_data (WideString &str) { return m_reader->get_data (str); } bool Transaction::get_data (KeyEvent &key) { return m_reader->get_data (key); } bool Transaction::get_data (AttributeList &attrs) { return m_reader->get_data (attrs); } bool Transaction::get_data (Property &property) { return m_reader->get_data (property); } bool Transaction::get_data (PropertyList &properties) { return m_reader->get_data (properties); } bool Transaction::get_data (CommonLookupTable &table) { return m_reader->get_data (table); } bool Transaction::get_data (std::vector &vec) { return m_reader->get_data (vec); } bool Transaction::get_data (std::vector &vec) { return m_reader->get_data (vec); } bool Transaction::get_data (std::vector &vec) { return m_reader->get_data (vec); } bool Transaction::get_data (char **raw, size_t &bufsize) { return m_reader->get_data (raw, bufsize); } bool Transaction::get_data (Transaction &trans) { return m_reader->get_data (trans); } bool Transaction::skip_data () { return m_reader->skip_data (); } void Transaction::rewind () { return m_reader->rewind (); } // TransactionReader implementation. class TransactionReader::TransactionReaderImpl { public: const TransactionHolder *m_holder; size_t m_read_pos; public: TransactionReaderImpl (const TransactionHolder *holder = 0) : m_holder (holder), m_read_pos (SCIM_TRANS_HEADER_SIZE) { if (m_holder) m_holder->ref (); } ~TransactionReaderImpl () { if (m_holder) m_holder->unref (); } bool valid () const { return m_holder && m_holder->valid (); } void attach (const TransactionHolder *holder) { if (m_holder) m_holder->unref (); m_holder = holder; if (m_holder) m_holder->ref (); m_read_pos = SCIM_TRANS_HEADER_SIZE; } void detach () { if (m_holder) m_holder->unref (); m_holder = 0; m_read_pos = SCIM_TRANS_HEADER_SIZE; } void rewind () { m_read_pos = SCIM_TRANS_HEADER_SIZE; } }; TransactionReader::TransactionReader () : m_impl (new TransactionReaderImpl ()) { } TransactionReader::TransactionReader (const Transaction &trans) : m_impl (new TransactionReaderImpl (trans.m_holder)) { } TransactionReader::TransactionReader (const TransactionReader &reader) : m_impl (new TransactionReaderImpl (reader.m_impl->m_holder)) { } const TransactionReader & TransactionReader::operator = (const TransactionReader &reader) { m_impl->attach (reader.m_impl->m_holder); m_impl->m_read_pos = reader.m_impl->m_read_pos; return *this; } TransactionReader::~TransactionReader () { delete m_impl; } void TransactionReader::attach (const Transaction &trans) { m_impl->attach (trans.m_holder); } void TransactionReader::detach () { m_impl->detach (); } bool TransactionReader::valid () const { return m_impl->valid (); } TransactionDataType TransactionReader::get_data_type () const { if (!valid () || m_impl->m_holder->m_write_pos <= m_impl->m_read_pos) return SCIM_TRANS_DATA_UNKNOWN; return (TransactionDataType) m_impl->m_holder->m_buffer [m_impl->m_read_pos]; } bool TransactionReader::get_command (int &type) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_COMMAND) { if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) + 1)) return false; m_impl->m_read_pos ++; type = (int) scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); return true; } return false; } bool TransactionReader::get_data (uint32 &val) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_UINT32) { if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) + 1)) return false; m_impl->m_read_pos ++; val = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); return true; } return false; } bool TransactionReader::get_data (String &str) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_STRING) { size_t len; size_t old_read_pos = m_impl->m_read_pos; if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) + 1)) return false; m_impl->m_read_pos ++; len = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + len)) { m_impl->m_read_pos = old_read_pos; return false; } if (len) str = String (m_impl->m_holder->m_buffer + m_impl->m_read_pos, m_impl->m_holder->m_buffer + m_impl->m_read_pos + len); else str = String (""); m_impl->m_read_pos += len; return true; } return false; } bool TransactionReader::get_data (WideString &str) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_WSTRING) { String mbs; size_t len; size_t old_read_pos = m_impl->m_read_pos; if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) + 1)) return false; m_impl->m_read_pos ++; len = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + len)) { m_impl->m_read_pos = old_read_pos; return false; } if (len) mbs = String (m_impl->m_holder->m_buffer + m_impl->m_read_pos, m_impl->m_holder->m_buffer + m_impl->m_read_pos + len); else mbs = String (""); m_impl->m_read_pos += len; str = utf8_mbstowcs (mbs); return true; } return false; } bool TransactionReader::get_data (KeyEvent &key) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_KEYEVENT) { if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) * 2 + 1)) return false; m_impl->m_read_pos ++; key.code = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); key.mask = scim_bytestouint16 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint16); key.layout = scim_bytestouint16 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint16); return true; } return false; } bool TransactionReader::get_data (AttributeList &attrs) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_ATTRIBUTE_LIST) { AttributeType type; size_t num; uint32 value; uint32 start; uint32 length; attrs.clear (); if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) + 1)) return false; m_impl->m_read_pos ++; num = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + (sizeof (uint32) * 3 + 1) * num)) { m_impl->m_read_pos -= (sizeof (uint32) + 1); return false; } for (size_t i=0; im_holder->m_buffer [m_impl->m_read_pos]; m_impl->m_read_pos ++; value = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); start = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); length = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); attrs.push_back (Attribute (start, length, type, value)); } return true; } return false; } bool TransactionReader::get_data (Property &property) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_PROPERTY) { size_t old_read_pos = m_impl->m_read_pos; if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) * 4 + 3)) return false; m_impl->m_read_pos ++; String str; if (! get_data (str)) { m_impl->m_read_pos = old_read_pos; return false; } property.set_key (str); if (! get_data (str)) { m_impl->m_read_pos = old_read_pos; return false; } property.set_label (str); if (! get_data (str)) { m_impl->m_read_pos = old_read_pos; return false; } property.set_icon (str); if (! get_data (str)) { m_impl->m_read_pos = old_read_pos; return false; } property.set_tip (str); if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + 2)) { m_impl->m_read_pos = old_read_pos; return false; } property.show ((bool) m_impl->m_holder->m_buffer [m_impl->m_read_pos]); m_impl->m_read_pos ++; property.set_active ((bool) m_impl->m_holder->m_buffer [m_impl->m_read_pos]); m_impl->m_read_pos ++; return true; } return false; } bool TransactionReader::get_data (PropertyList &properties) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_PROPERTY_LIST) { size_t old_read_pos = m_impl->m_read_pos; size_t num; if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) + 1)) return false; m_impl->m_read_pos ++; num = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); properties.clear (); Property prop; for (size_t i = 0; i < num; ++ i) { if (!get_data (prop)) { m_impl->m_read_pos = old_read_pos; return false; } properties.push_back (prop); } return true; } return false; } bool TransactionReader::get_data (CommonLookupTable &table) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_LOOKUP_TABLE) { size_t i; size_t old_read_pos = m_impl->m_read_pos; unsigned char stat; uint32 page_size; uint32 cursor_pos; WideString wstr; AttributeList attrs; std::vector labels; if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + 4)) return false; table.clear (); m_impl->m_read_pos ++; stat = m_impl->m_holder->m_buffer [m_impl->m_read_pos]; m_impl->m_read_pos ++; page_size = (uint32) m_impl->m_holder->m_buffer [m_impl->m_read_pos]; m_impl->m_read_pos ++; cursor_pos = (uint32) m_impl->m_holder->m_buffer [m_impl->m_read_pos]; m_impl->m_read_pos ++; if (page_size > SCIM_LOOKUP_TABLE_MAX_PAGESIZE || (cursor_pos >= page_size && page_size > 0)) { m_impl->m_read_pos = old_read_pos; return false; } table.set_page_size (page_size); for (i = 0; i < page_size; ++i) { if (!get_data (wstr)) { m_impl->m_read_pos = old_read_pos; return false; } labels.push_back (wstr); } table.set_candidate_labels (labels); //Can be paged up. if (stat & 1) table.append_candidate (0x3400); for (i = 0; i < page_size; ++i) { if (get_data (wstr) && get_data (attrs)) { table.append_candidate (wstr, attrs); } else { m_impl->m_read_pos = old_read_pos; return false; } } // Can be paged down. if (stat & 2) table.append_candidate (0x3400); if (stat & 1) { table.set_page_size (1); table.page_down (); table.set_page_size (page_size); } table.set_cursor_pos_in_current_page (cursor_pos); if (stat & 4) table.show_cursor (true); else table.show_cursor (false); if (stat & 8) table.fix_page_size (true); else table.fix_page_size (false); return true; } return false; } bool TransactionReader::get_data (std::vector &vec) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_VECTOR_UINT32) { size_t old_read_pos = m_impl->m_read_pos; size_t num; if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) + 1)) return false; m_impl->m_read_pos ++; num = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) * num)) { m_impl->m_read_pos = old_read_pos; return false; } vec.clear (); for (size_t i=0; im_holder->m_buffer + m_impl->m_read_pos)); m_impl->m_read_pos += sizeof (uint32); } return true; } return false; } bool TransactionReader::get_data (std::vector &vec) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_VECTOR_STRING) { size_t old_read_pos = m_impl->m_read_pos; size_t num; String str; if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) + 1)) return false; m_impl->m_read_pos ++; num = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); vec.clear (); for (size_t i=0; im_read_pos = old_read_pos; return false; } vec.push_back (str); } return true; } return false; } bool TransactionReader::get_data (std::vector &vec) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_VECTOR_WSTRING) { size_t old_read_pos = m_impl->m_read_pos; size_t num; WideString str; if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) + 1)) return false; m_impl->m_read_pos ++; num = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); vec.clear (); for (size_t i=0; im_read_pos = old_read_pos; return false; } vec.push_back (str); } return true; } return false; } bool TransactionReader::get_data (char **raw, size_t &bufsize) { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_RAW) { size_t old_read_pos = m_impl->m_read_pos; if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) + 1)) return false; m_impl->m_read_pos ++; bufsize = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); if (!bufsize || m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + bufsize)) { m_impl->m_read_pos = old_read_pos; return false; } if (raw) { *raw = new char [bufsize]; if (! (*raw)) { m_impl->m_read_pos = old_read_pos; return false; } memcpy (*raw, m_impl->m_holder->m_buffer + m_impl->m_read_pos, bufsize); } m_impl->m_read_pos += bufsize; return true; } return false; } bool TransactionReader::get_data (Transaction &trans) { if (valid () && trans.valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos && m_impl->m_holder->m_buffer [m_impl->m_read_pos] == SCIM_TRANS_DATA_TRANSACTION) { size_t len; size_t old_read_pos = m_impl->m_read_pos; if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) + 1)) return false; m_impl->m_read_pos ++; len = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos); m_impl->m_read_pos += sizeof (uint32); if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + len)) { m_impl->m_read_pos = old_read_pos; return false; } trans.m_holder->request_buffer_size (len); memcpy (trans.m_holder->m_buffer, m_impl->m_holder->m_buffer + m_impl->m_read_pos, len); trans.m_holder->m_write_pos = len; trans.m_reader->rewind (); m_impl->m_read_pos += len; return true; } return false; } bool TransactionReader::skip_data () { if (valid () && m_impl->m_holder->m_write_pos > m_impl->m_read_pos) { switch (m_impl->m_holder->m_buffer [m_impl->m_read_pos]) { case SCIM_TRANS_DATA_COMMAND: { int cmd; return get_command (cmd); } case SCIM_TRANS_DATA_UINT32: { uint32 val; return get_data (val); } case SCIM_TRANS_DATA_STRING: { String str; return get_data (str); } case SCIM_TRANS_DATA_WSTRING: { WideString wstr; return get_data (wstr); } case SCIM_TRANS_DATA_KEYEVENT: { KeyEvent key; return get_data (key); } case SCIM_TRANS_DATA_ATTRIBUTE_LIST: { AttributeList attrs; return get_data (attrs); } case SCIM_TRANS_DATA_PROPERTY: { Property prop; return get_data (prop); } case SCIM_TRANS_DATA_PROPERTY_LIST: { PropertyList proplist; return get_data (proplist); } case SCIM_TRANS_DATA_LOOKUP_TABLE: { CommonLookupTable table; return get_data (table); } case SCIM_TRANS_DATA_VECTOR_UINT32: { std::vector vec; return get_data (vec); } case SCIM_TRANS_DATA_VECTOR_STRING: { std::vector vec; return get_data (vec); } case SCIM_TRANS_DATA_VECTOR_WSTRING: { std::vector vec; return get_data (vec); } case SCIM_TRANS_DATA_RAW: { size_t bufsize; return get_data (NULL, bufsize); } case SCIM_TRANS_DATA_TRANSACTION: { size_t len; if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + sizeof (uint32) + 1)) return false; len = scim_bytestouint32 (m_impl->m_holder->m_buffer + m_impl->m_read_pos + 1); if (m_impl->m_holder->m_write_pos < (m_impl->m_read_pos + len + sizeof (uint32) + 1)) return false; m_impl->m_read_pos += (len + sizeof (uint32) + 1); return true; } } } return false; } void TransactionReader::rewind () { m_impl->rewind (); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_trans_commands.h0000644000175000017500000006246212422143415017134 0ustar tzhuantzhuan/** * @file scim_trans_commands.h * @brief Transaction commands. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_trans_commands.h,v 1.9 2005/06/26 16:35:33 suzhe Exp $ */ #ifndef __SCIM_TRANS_COMMANDS_H #define __SCIM_TRANS_COMMANDS_H namespace scim { /** * @brief Transaction command types used by Socket Frontend/IMEngine/Config, Helper and Panel. * * This commands are used in communication protocols of SocketFrontEnd, SocketIMEngine, SocketConfig, Helper and Panel. * * There are mainly four major protocols used in the communications among each part of SCIM: * - between SocketFrontEnd and SocketIMEngine (SocketFrontEnd is server) * - between SocketFrontEnd and SocketConfig (SocketFrontEnd is server) * - between Panel and FrontEnds (eg. X11 FrontEnd, Gtk IMModule and QT IMModule. Panel is server) * - between Panel and Helper (Panel is server). * * As soon as the socket to the server is established, the client must call function * scim_socket_open_connection() to create the connection and get the magic key for later communication. * * At the same time, the server must call function scim_socket_accept_connection() to * accept the connection and get the same magic key for later client verification. * * The valid types of servers are: * - "SocketFrontEnd"\n * The socket FrontEnd server provides remote IMEngine and Config services. * It accepts "SocketIMEngine" and "SocketConfig" clients. * - "Panel"\n * The Panel server provides GUI and Helper management services. * It accepts "FrontEnd" and "Helper" clients. * * The valid types of clients are: * - "SocketIMEngine"\n * The socket IMEngine client acts as a proxy IMEngine forwarding all requests to SocketFrontEnd. * It can only connect to "SocketFrontEnd" server. * - "SocketConfig"\n * The socket Config client acts as a proxy Config forwarding all request to SocketFrontEnd. * It can only connect to "SocketFrontEnd" server. * - "FrontEnd"\n * If a FrontEnd needs a Panel GUI services, it'll be a "FrontEnd" client of the Panel. * It can only connect to "Panel" server. * - "Helper"\n * All Helper objects should be "Helper" clients of a Panel. * It can only connect to "Panel" server. * * Then the client and the server can communicate with each other via the socket by sending transactions. * * Multiple commands and their data may be put into one transaction with a restricted order. * The data of a command must be put into the transaction just follow the command itself. * * A transaction sent from a socket client to a socket server (eg. SocketIMEngine to SocketFrontEnd) * must be started with a SCIM_TRANS_CMD_REQUEST command followed by an uint32 magic key of the client * (returned by scim_socket_open_connection() function. * * A transaction sent back to a socket client from a socket server must be started with a * SCIM_TRANS_CMD_REPLY command. * * So for example, the layout of a transaction sent from SocketIMEngine to SocketFrontEnd may look like: * - #SCIM_TRANS_CMD_REQUEST * - an uint32 data (the magic key of a client) * - #SCIM_TRANS_CMD_PROCESS_KEY_EVENT * - an uint32 data (the id of the IMEngineInstance object used to process the KeyEvent) * - a scim::KeyEvent data (the KeyEvent to be processed) * * Some commands may be used in more than one protocols for similar purpose, but they may have different * data in different protocol. * * Brief introduction of communication protocols used in SCIM: * * Please refer to the descriptions of each Transaction commands for details. * * -# Protocol used between SocketIMEngine and SocketFrontEnd\n * In this protocol, SocketFrontEnd is socket server, SocketIMEngine is client. * - from SocketIMEngine to SocketFrontEnd:\n * The Transaction sent from SocketIMEngine to SocketFrontEnd must * start with #SCIM_TRANS_CMD_REQUEST and followed by an uint32 magic * key which was returned by scim_socket_open_connection() and * scim_socket_accept_connection().\n * Before parsing the Transaction, * SocketFrontEnd must verify if the magic key is matched. * If the magic key is not matched, then SocketFrontEnd should just * discard this transaction.\n * There can be one or more commands and corresponding data right after the * magic key.\n * The valid commands which can be used here are: * - #SCIM_TRANS_CMD_NEW_INSTANCE * - #SCIM_TRANS_CMD_DELETE_INSTANCE * - #SCIM_TRANS_CMD_DELETE_ALL_INSTANCES * - #SCIM_TRANS_CMD_GET_FACTORY_LIST * - #SCIM_TRANS_CMD_GET_FACTORY_NAME * - #SCIM_TRANS_CMD_GET_FACTORY_AUTHORS * - #SCIM_TRANS_CMD_GET_FACTORY_CREDITS * - #SCIM_TRANS_CMD_GET_FACTORY_HELP * - #SCIM_TRANS_CMD_GET_FACTORY_LOCALES * - #SCIM_TRANS_CMD_GET_FACTORY_ICON_FILE * - #SCIM_TRANS_CMD_GET_FACTORY_LANGUAGE * - #SCIM_TRANS_CMD_PROCESS_KEY_EVENT * - #SCIM_TRANS_CMD_MOVE_PREEDIT_CARET * - #SCIM_TRANS_CMD_SELECT_CANDIDATE * - #SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE * - #SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP * - #SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN * - #SCIM_TRANS_CMD_RESET * - #SCIM_TRANS_CMD_FOCUS_IN * - #SCIM_TRANS_CMD_FOCUS_OUT * - #SCIM_TRANS_CMD_TRIGGER_PROPERTY * - #SCIM_TRANS_CMD_PROCESS_HELPER_EVENT * - #SCIM_TRANS_CMD_UPDATE_CLIENT_CAPABILITIES * - #SCIM_TRANS_CMD_LOAD_FILE * - #SCIM_TRANS_CMD_CLOSE_CONNECTION * - from SocketFrontEnd to SocketIMEngine:\n * The Transaction sent back from SocketFrontEnd to SocketIMEngine must * start with #SCIM_TRANS_CMD_REPLY and end with #SCIM_TRANS_CMD_OK or * #SCIM_TRANS_CMD_FAIL to indicate if the request previously sent by * SocketIMEngine was executed successfully.\n * For some requests, like SCIM_TRANS_CMD_GET_FACTORY_LIST, etc. * only some result data will be returned between #SCIM_TRANS_CMD_REPLY and #SCIM_TRANS_CMD_OK.\n * For some requests, like SCIM_TRANS_CMD_PROCESS_KEY_EVENT, etc. * one or more following commands and corresponding data may be returned between * #SCIM_TRANS_CMD_REPLY and #SCIM_TRANS_CMD_OK commands.\n * The valid commands can be used here are: * - #SCIM_TRANS_CMD_SHOW_PREEDIT_STRING * - #SCIM_TRANS_CMD_SHOW_AUX_STRING * - #SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE * - #SCIM_TRANS_CMD_HIDE_PREEDIT_STRING * - #SCIM_TRANS_CMD_HIDE_AUX_STRING * - #SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE * - #SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET * - #SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING * - #SCIM_TRANS_CMD_UPDATE_AUX_STRING * - #SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE * - #SCIM_TRANS_CMD_COMMIT_STRING * - #SCIM_TRANS_CMD_FORWARD_KEY_EVENT * - #SCIM_TRANS_CMD_REGISTER_PROPERTIES * - #SCIM_TRANS_CMD_UPDATE_PROPERTY * - #SCIM_TRANS_CMD_BEEP * - #SCIM_TRANS_CMD_START_HELPER * - #SCIM_TRANS_CMD_STOP_HELPER * - #SCIM_TRANS_CMD_SEND_HELPER_EVENT * -# Protocol used between SocketConfig and SocketFrontEnd\n * In this protocol, SocketFrontEnd is socket server, SocketConfig is client. * - from SocketConfig to SocketFrontEnd:\n * The Transaction sent from SocketConfig to SocketFrontEnd must * start with #SCIM_TRANS_CMD_REQUEST and followed by an uint32 magic * key which was returned by scim_socket_open_connection() and * scim_socket_accept_connection().\n * Before parsing the Transaction, * SocketFrontEnd must verify if the magic key is matched. * If the magic key is not matched, then SocketFrontEnd should just * discard this transaction.\n * There can be one or more commands and corresponding data right after the * magic key.\n * The valid commands which can be used here are: * - #SCIM_TRANS_CMD_FLUSH_CONFIG * - #SCIM_TRANS_CMD_ERASE_CONFIG * - #SCIM_TRANS_CMD_GET_CONFIG_STRING * - #SCIM_TRANS_CMD_SET_CONFIG_STRING * - #SCIM_TRANS_CMD_GET_CONFIG_INT * - #SCIM_TRANS_CMD_SET_CONFIG_INT * - #SCIM_TRANS_CMD_GET_CONFIG_BOOL * - #SCIM_TRANS_CMD_SET_CONFIG_BOOL * - #SCIM_TRANS_CMD_GET_CONFIG_DOUBLE * - #SCIM_TRANS_CMD_SET_CONFIG_DOUBLE * - #SCIM_TRANS_CMD_GET_CONFIG_VECTOR_STRING * - #SCIM_TRANS_CMD_SET_CONFIG_VECTOR_STRING * - #SCIM_TRANS_CMD_GET_CONFIG_VECTOR_INT * - #SCIM_TRANS_CMD_SET_CONFIG_VECTOR_INT * - #SCIM_TRANS_CMD_RELOAD_CONFIG * - #SCIM_TRANS_CMD_LOAD_FILE * - #SCIM_TRANS_CMD_CLOSE_CONNECTION * - from SocketFrontEnd to SocketConfig:\n * The Transaction sent back from SocketFrontEnd to SocketConfig must * start with #SCIM_TRANS_CMD_REPLY and end with #SCIM_TRANS_CMD_OK or * #SCIM_TRANS_CMD_FAIL to indicate if the request previously sent by * SocketConfig was executed successfully.\n * For some requests, like SCIM_TRANS_CMD_FLUSH_CONFIG, etc. * no result data will be returned.\n * For some requests, like SCIM_TRANS_CMD_GET_CONFIG_STRING, etc. * the corresponding data will be returned between * #SCIM_TRANS_CMD_REPLY and #SCIM_TRANS_CMD_OK commands.\n * -# Protocol used between FrontEnds and Panel\n * In this protocol, Panel (eg. scim-panel-gtk or scim-panel-kde) is socket server, FrontEnds are clients. * - from FrontEnds to Panel:\n * The Transaction sent from FrontEnds to Panel must * start with #SCIM_TRANS_CMD_REQUEST and followed by an uint32 magic * key which was returned by scim_socket_open_connection() and * scim_socket_accept_connection(). Then there must be an uint32 id * for current focused input context right after the magic key.\n * Before parsing the Transaction, * Panel must verify if the magic key is matched. * If the magic key is not matched, then Panel should just * discard this transaction.\n * There can be one or more commands and corresponding data right after the * magic key.\n * The valid commands which can be used here are: * - #SCIM_TRANS_CMD_UPDATE_SCREEN * - #SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION * - #SCIM_TRANS_CMD_PANEL_TURN_ON * - #SCIM_TRANS_CMD_PANEL_TURN_OFF * - #SCIM_TRANS_CMD_PANEL_UPDATE_FACTORY_INFO * - #SCIM_TRANS_CMD_PANEL_SHOW_HELP * - #SCIM_TRANS_CMD_PANEL_SHOW_FACTORY_MENU * - #SCIM_TRANS_CMD_SHOW_PREEDIT_STRING * - #SCIM_TRANS_CMD_SHOW_AUX_STRING * - #SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE * - #SCIM_TRANS_CMD_HIDE_PREEDIT_STRING * - #SCIM_TRANS_CMD_HIDE_AUX_STRING * - #SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE * - #SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET * - #SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING * - #SCIM_TRANS_CMD_UPDATE_AUX_STRING * - #SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE * - #SCIM_TRANS_CMD_REGISTER_PROPERTIES * - #SCIM_TRANS_CMD_UPDATE_PROPERTY * - #SCIM_TRANS_CMD_START_HELPER * - #SCIM_TRANS_CMD_STOP_HELPER * - #SCIM_TRANS_CMD_SEND_HELPER_EVENT * - from Panel to FrontEnds:\n * The Transaction sent from Panel to FrontEnds must * start with #SCIM_TRANS_CMD_REPLY. * For the following commands except * #SCIM_TRANS_CMD_RELOAD_CONFIG and #SCIM_TRANS_CMD_EXIT, * there must be an uint32 id of the currently focused input context * right after the #SCIM_TRANS_CMD_REPLY command. * Then there can be one or more commands and corresponding data following.\n * The valid commands which can be used here are: * - #SCIM_TRANS_CMD_RELOAD_CONFIG * - #SCIM_TRANS_CMD_EXIT * - #SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE * - #SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP * - #SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN * - #SCIM_TRANS_CMD_PROCESS_KEY_EVENT * - #SCIM_TRANS_CMD_MOVE_PREEDIT_CARET * - #SCIM_TRANS_CMD_SELECT_CANDIDATE * - #SCIM_TRANS_CMD_TRIGGER_PROPERTY * - #SCIM_TRANS_CMD_PROCESS_HELPER_EVENT * - #SCIM_TRANS_CMD_COMMIT_STRING * - #SCIM_TRANS_CMD_FORWARD_KEY_EVENT * - #SCIM_TRANS_CMD_PANEL_REQUEST_HELP * - #SCIM_TRANS_CMD_PANEL_REQUEST_FACTORY_MENU * - #SCIM_TRANS_CMD_PANEL_CHANGE_FACTORY * -# Protocol used between Helper and Panel\n * In this protocol, Panel (eg. scim-panel-gtk or scim-panel-kde) is socket server, Helper is client. * - from Helper to Panel:\n * The Transaction sent from Helper to Panel must * start with #SCIM_TRANS_CMD_REQUEST and followed by an uint32 magic * key which was returned by scim_socket_open_connection() and * scim_socket_accept_connection(). * Before parsing the Transaction, * Panel must verify if the magic key is matched. * If the magic key is not matched, then Panel should just * discard this transaction.\n * There can be one or more commands and corresponding data right after the * magic key.\n * The valid commands which can be used here are: * - #SCIM_TRANS_CMD_PANEL_REGISTER_HELPER * - #SCIM_TRANS_CMD_PANEL_SEND_IMENGINE_EVENT * - #SCIM_TRANS_CMD_PANEL_SEND_KEY_EVENT * - #SCIM_TRANS_CMD_REGISTER_PROPERTIES * - #SCIM_TRANS_CMD_UPDATE_PROPERTY * - #SCIM_TRANS_CMD_FORWARD_KEY_EVENT * - #SCIM_TRANS_CMD_COMMIT_STRING * - from Panel to Helper:\n * The Transaction sent from Panel to Helper must * start with #SCIM_TRANS_CMD_REPLY and followed by an * uint32 input context id and a scim::String input context UUID. * Then there can be one or more commands and corresponding data just after the UUID.\n * The valid commands which can be used here are: * - #SCIM_TRANS_CMD_EXIT * - #SCIM_TRANS_CMD_UPDATE_SCREEN * - #SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION * - #SCIM_TRANS_CMD_TRIGGER_PROPERTY * - #SCIM_TRANS_CMD_HELPER_PROCESS_IMENGINE_EVENT * * @addtogroup TransactionCommands * @{ */ /// Unknown command. No use. const int SCIM_TRANS_CMD_UNKNOWN = 0; // Common Commands /** * @brief It's the first command which should be put into the Transaction * sending from a socket client to a socket server. * * The corresponding data for this command is an uint32 magic key * which is returned by scim_socket_open_connection() function. * */ const int SCIM_TRANS_CMD_REQUEST = 1; /** * @brief It's the first command which should be put into the Transaction * sending from a socket server to a socket client. * * The corresponding data for this command is different in * each protocol. Please refer to the previous protocol notes for details. * */ const int SCIM_TRANS_CMD_REPLY = 2; /** * @brief This command is usually used in the Transaction sending from * a socket server to a socket client to indicate that the request * previously sent from the client was executed successfully. * * There is no data for this command. * */ const int SCIM_TRANS_CMD_OK = 3; /** * @brief This command is usually used in the Transaction sending from * a socket server to a socket client to indicate that the request * previously sent from the client was failed to be executed. * * There is no data for this command. * */ const int SCIM_TRANS_CMD_FAIL = 4; /** * @brief This command is used internally by scim_socket_open_connection() and * scim_socket_accept_connection(). * * It's sent from a socket client to a socket server to * request the server to create the connection. * * The corresponding data are: * - (scim::String) a version string (the binary version of SCIM). * - (scim::String) type of the client, eg. "SocketIMEngine", "FrontEnd", "Helper" etc. * * If the socket server accept the connection request, it must send back a Transaction with * following content: * - #SCIM_TRANS_CMD_REPLY * - (scim::String) a comma separated server types which are supported by the server, eg. "SocketFrontEnd" etc. * - (uint32) a magic key used to validate the communication later. * * Then if the client accept the result too, it must send the following content back to the * socket server: * - #SCIM_TRANS_CMD_REPLY * - #SCIM_TRANS_CMD_OK * * Otherwise, the client must return: * - #SCIM_TRANS_CMD_REPLY * - #SCIM_TRANS_CMD_FAIL * * If the socket server do not accept the connection in the first stage, it should discard the request and send * nothing back. * */ const int SCIM_TRANS_CMD_OPEN_CONNECTION = 5; /** * @brief It's used to request the socket server to close the connection forcedly. * * It's currently not used at all. * */ const int SCIM_TRANS_CMD_CLOSE_CONNECTION = 6; /** * @brief Request the socket server to load and send a file to the client. * * The corresponding data is: * - (scim::String) the full file path to be loaded. * * If the file is loaded successfully, then the server should send back: * - #SCIM_TRANS_CMD_REPLY * - (raw buffer) the buffer which holds the file content. * - #SCIM_TRANS_CMD_OK * * Otherwise it should send back: * - #SCIM_TRANS_CMD_REPLY * - #SCIM_TRANS_CMD_FAIL * * This command is only supported by SocketFrontEnd. * */ const int SCIM_TRANS_CMD_LOAD_FILE = 7; /** * @brief Request the socket server to save a buffer into a file. * * The corresponding data is: * - (scim::String) the full file path to be used to save the buffer. * - (raw buffer) the buffer to be saved. * * If the file is saved successfully, then the server should return: * - #SCIM_TRANS_CMD_REPLY * - #SCIM_TRANS_CMD_OK * * Otherwise it should return: * - #SCIM_TRANS_CMD_REPLY * - #SCIM_TRANS_CMD_FAIL * * This command is currently not supported by any servers. * */ const int SCIM_TRANS_CMD_SAVE_FILE = 8; /** * @brief This command should be sent from a socket server to its clients to let them exit. * * No data is associated to this command. * * This command is currently only used by Panel server. * */ const int SCIM_TRANS_CMD_EXIT = 99; // Socket IMEngine to Socket FrontEnd /** * @brief This command is used in SocketIMEngine to SocketFrontEnd and * Panel to FrontEnd protocols to send a KeyEvent to an IMEngineInstance. * * When used in SocketIMEngine to SocketFrontEnd protocol, * the corresponding data is: * - (uint32) the id of the IMEngineInstance to process the KeyEvent. * - (KeyEvent) the KeyEvent object to be processed. * * The Transaction returned from SocketFrontEnd should contain: * - #SCIM_TRANS_CMD_REPLY * - (any valid commands and their corresponding data) * - #SCIM_TRANS_CMD_OK or #SCIM_TRANS_CMD_FAIL to indicate * that if the KeyEvent was processed successfully. * * When used in Panel to FrontEnds protocol, the corresponding data is: * - (KeyEvent) the KeyEvent object to be processed. */ const int SCIM_TRANS_CMD_PROCESS_KEY_EVENT = 100; const int SCIM_TRANS_CMD_MOVE_PREEDIT_CARET = 101; const int SCIM_TRANS_CMD_SELECT_CANDIDATE = 102; const int SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE = 103; const int SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP = 104; const int SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN = 105; const int SCIM_TRANS_CMD_RESET = 106; const int SCIM_TRANS_CMD_FOCUS_IN = 107; const int SCIM_TRANS_CMD_FOCUS_OUT = 108; const int SCIM_TRANS_CMD_TRIGGER_PROPERTY = 109; const int SCIM_TRANS_CMD_PROCESS_HELPER_EVENT = 110; const int SCIM_TRANS_CMD_UPDATE_CLIENT_CAPABILITIES = 111; // Socket FrontEnd to Socket IMEngine // FrontEnds to Panel const int SCIM_TRANS_CMD_SHOW_PREEDIT_STRING = 150; const int SCIM_TRANS_CMD_SHOW_AUX_STRING = 151; const int SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE = 152; const int SCIM_TRANS_CMD_HIDE_PREEDIT_STRING = 153; const int SCIM_TRANS_CMD_HIDE_AUX_STRING = 154; const int SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE = 155; const int SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET = 156; const int SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING = 157; const int SCIM_TRANS_CMD_UPDATE_AUX_STRING = 158; const int SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE = 159; const int SCIM_TRANS_CMD_COMMIT_STRING = 160; const int SCIM_TRANS_CMD_FORWARD_KEY_EVENT = 161; const int SCIM_TRANS_CMD_REGISTER_PROPERTIES = 162; const int SCIM_TRANS_CMD_UPDATE_PROPERTY = 163; const int SCIM_TRANS_CMD_BEEP = 164; const int SCIM_TRANS_CMD_START_HELPER = 165; const int SCIM_TRANS_CMD_STOP_HELPER = 166; const int SCIM_TRANS_CMD_SEND_HELPER_EVENT = 167; const int SCIM_TRANS_CMD_GET_SURROUNDING_TEXT = 168; const int SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT = 169; // Socket IMEngine to Socket FrontEnd const int SCIM_TRANS_CMD_NEW_INSTANCE = 200; const int SCIM_TRANS_CMD_DELETE_INSTANCE = 201; const int SCIM_TRANS_CMD_DELETE_ALL_INSTANCES = 202; const int SCIM_TRANS_CMD_GET_FACTORY_LIST = 203; const int SCIM_TRANS_CMD_GET_FACTORY_NAME = 204; const int SCIM_TRANS_CMD_GET_FACTORY_AUTHORS = 205; const int SCIM_TRANS_CMD_GET_FACTORY_CREDITS = 206; const int SCIM_TRANS_CMD_GET_FACTORY_HELP = 207; const int SCIM_TRANS_CMD_GET_FACTORY_LOCALES = 208; const int SCIM_TRANS_CMD_GET_FACTORY_ICON_FILE = 209; const int SCIM_TRANS_CMD_GET_FACTORY_LANGUAGE = 210; // Socket Config to Socket FrontEnd const int SCIM_TRANS_CMD_FLUSH_CONFIG = 300; const int SCIM_TRANS_CMD_ERASE_CONFIG = 301; const int SCIM_TRANS_CMD_GET_CONFIG_STRING = 302; const int SCIM_TRANS_CMD_SET_CONFIG_STRING = 303; const int SCIM_TRANS_CMD_GET_CONFIG_INT = 304; const int SCIM_TRANS_CMD_SET_CONFIG_INT = 305; const int SCIM_TRANS_CMD_GET_CONFIG_BOOL = 306; const int SCIM_TRANS_CMD_SET_CONFIG_BOOL = 307; const int SCIM_TRANS_CMD_GET_CONFIG_DOUBLE = 308; const int SCIM_TRANS_CMD_SET_CONFIG_DOUBLE = 309; const int SCIM_TRANS_CMD_GET_CONFIG_VECTOR_STRING = 310; const int SCIM_TRANS_CMD_SET_CONFIG_VECTOR_STRING = 311; const int SCIM_TRANS_CMD_GET_CONFIG_VECTOR_INT = 312; const int SCIM_TRANS_CMD_SET_CONFIG_VECTOR_INT = 313; const int SCIM_TRANS_CMD_RELOAD_CONFIG = 314; // Used by Panel and Helper const int SCIM_TRANS_CMD_UPDATE_SCREEN = 400; const int SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION = 401; //Privately used by panel. const int SCIM_TRANS_CMD_PANEL_EXIT = 500; //FrontEnd Client to Panel const int SCIM_TRANS_CMD_PANEL_TURN_ON = 501; const int SCIM_TRANS_CMD_PANEL_TURN_OFF = 502; const int SCIM_TRANS_CMD_PANEL_UPDATE_FACTORY_INFO = 503; const int SCIM_TRANS_CMD_PANEL_SHOW_HELP = 504; const int SCIM_TRANS_CMD_PANEL_SHOW_FACTORY_MENU = 505; const int SCIM_TRANS_CMD_PANEL_REGISTER_INPUT_CONTEXT = 506; const int SCIM_TRANS_CMD_PANEL_REMOVE_INPUT_CONTEXT = 507; //Panel to FrontEnd Client const int SCIM_TRANS_CMD_PANEL_REQUEST_HELP = 520; const int SCIM_TRANS_CMD_PANEL_REQUEST_FACTORY_MENU = 521; const int SCIM_TRANS_CMD_PANEL_CHANGE_FACTORY = 522; //Helper Client To Panel const int SCIM_TRANS_CMD_PANEL_REGISTER_HELPER = 540; const int SCIM_TRANS_CMD_PANEL_SEND_IMENGINE_EVENT = 541; const int SCIM_TRANS_CMD_PANEL_SEND_KEY_EVENT = 542; //Panel to Helper Client const int SCIM_TRANS_CMD_HELPER_PROCESS_IMENGINE_EVENT = 602; const int SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT = 603; const int SCIM_TRANS_CMD_HELPER_DETACH_INPUT_CONTEXT = 604; //HelperManager Commands const int SCIM_TRANS_CMD_HELPER_MANAGER_GET_HELPER_LIST = 700; const int SCIM_TRANS_CMD_HELPER_MANAGER_RUN_HELPER = 701; //Controller Client to Panel const int SCIM_TRANS_CMD_CONTROLLER_REQUEST_FACTORY_MENU = 800; const int SCIM_TRANS_CMD_CONTROLLER_CHANGE_FACTORY = 801; const int SCIM_TRANS_CMD_CONTROLLER_GET_CURRENT_FACTORY = 802; const int SCIM_TRANS_CMD_CONTROLLER_GET_CURRENT_CONTEXT = 803; //Panel to Controller Panel const int SCIM_TRANS_CMD_PANEL_RETURN_CURRENT_FACTORY_INFO = 820; const int SCIM_TRANS_CMD_PANEL_RETURN_CURRENT_CONTEXT = 821; const int SCIM_TRANS_CMD_USER_DEFINED = 10000; /** * @} */ } // namespace scim #endif //__SCIM_TRANS_COMMANDS_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_stl_map.h0000644000175000017500000000343112422143415015552 0ustar tzhuantzhuan/** @file scim_stl_map.h */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_stl_map.h,v 1.1 2005/01/07 15:28:21 suzhe Exp $ */ #ifndef __SCIM_STL_MAP_H #define __SCIM_STL_MAP_H #if ENABLE_HASH_MAP #if defined (HAVE_EXT_HASH_MAP) #define SCIM_USE_STL_EXT_HASH_MAP 1 #include #elif defined (HAVE_HASH_MAP) #define SCIM_USE_STL_HASH_MAP 1 #include #endif #endif #if !defined (SCIM_USE_STL_HASH_MAP) && !defined (SCIM_USE_STL_EXT_HASH_MAP) #define SCIM_USE_STL_MAP 1 #include #endif namespace scim { #if SCIM_USE_STL_EXT_HASH_MAP class scim_hash_string { __gnu_cxx::hash _h; public: size_t operator ()(const String &str) const { return _h (str.c_str ()); } }; #elif SCIM_USE_STL_HASH_MAP class scim_hash_string { std::hash _h; public: size_t operator ()(const String &str) const { return _h (str.c_str ()); } }; #endif } // Namespace #endif //__SCIM_STL_MAP_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_socket.h0000644000175000017500000004300512422143415015404 0ustar tzhuantzhuan/** * @file scim_socket.h * @brief Socket interfaces. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_socket.h,v 1.25 2005/01/25 15:13:15 suzhe Exp $ */ #ifndef __SCIM_SOCKET_H #define __SCIM_SOCKET_H namespace scim { /** * @addtogroup SocketCommunication * @{ */ class Socket; class SocketAddress; class SocketServer; class SocketClient; typedef Slot2 SocketServerSlotSocket; typedef Signal2 SocketServerSignalSocket; /** * @brief An exception class to hold Socket related errors. * * scim::Socket and its derived classes must throw * scim::SocketError object when error. */ class SocketError: public Exception { public: SocketError (const String& what_arg) : Exception (String("scim::Socket: ") + what_arg) { } }; /** * @brief The vaild socket address/protocol family, * * Corresponding to libc PF_LOCAL/AF_LOCAL and PF_INET/AF_INET */ enum SocketFamily { SCIM_SOCKET_UNKNOWN, /**< Unknown or invalid socket address/protocol */ SCIM_SOCKET_LOCAL, /**< Unix local socket address/protocol */ SCIM_SOCKET_INET /**< Internet (ipv4) socket address/protocol */ }; /** * @brief The class to hold a socket address. * * Class SocketAddress encapsulates the details of * socket address, like socketaddr_un and socketaddr_in. * * A SocketAddress object can be constructed from an * address string, which must start with one of the * following prefixes: * - inet: or tcp: * A internet address (ipv4). This kind of address must * include two parts, separated by a colon. The first part * is the ip address, the second part is the port. For example: * inet:127.0.0.1:12345 * - local: or unix: or file: * A unix or local socket address. It's a full path of a socket file. * For example: local:/tmp/scim-socket-frontend */ class SocketAddress { class SocketAddressImpl; SocketAddressImpl *m_impl; public: /** * @brief Constructor. * * @param addr the address string. */ SocketAddress (const String &addr = String ()); /** * @brief Copy constructor. */ SocketAddress (const SocketAddress &addr); /** * @brief Destructor. */ ~SocketAddress (); /** * @brief Copy operator. */ const SocketAddress& operator = (const SocketAddress &addr); /** * @brief Check if this address is valid. * * @return true if this address is valid. */ bool valid () const; /** * @brief Get the family of this socket address. * * @return the family enum value of this address. * * @sa SocketFamily */ SocketFamily get_family () const; /** * @brief Set a new address. * * @param addr the new address string. */ bool set_address (const String &addr); /** * @brief Get the address string. * * @return the address string. */ String get_address () const; /** * @brief Get the internal data of this socket address, * used by class Socket. * * @return the pointer to the data, usually a sockaddr struct. */ const void * get_data () const; /** * @brief Get the size of the internall data. * * @return the size of the internall data returned by get_data (); */ int get_data_length () const; }; /** * @brief Socket communication class. * * Class Socket provides basic operation of socket, * such as bind connect, read, write etc. * * This class object cannot be created directly by user. * Only the object of its derived classes SocketServer and SocketClient * can be created directly. */ class Socket { class SocketImpl; SocketImpl *m_impl; Socket (const Socket&); const Socket& operator = (const Socket&); public: /** * @brief Create a Socket object from an already created socket_id. * * @param id an file id of an existing socket. */ Socket (int id = -1); /** * @brief Destructor */ ~Socket (); /** * @brief Check if the socket is valid. * * @return true if the socket is ready to read and write. */ bool valid () const; /** * @brief Read data from socket. * * @param buf the buffer to store the data. * @param size size of the buffer. * * @return the amount of data actually read, -1 means error occurred. */ int read (void *buf, size_t size) const; /** * @brief read data from socket with a timeout. * * @param buf the buffer to store the data. * @param size size of the buffer, and the amount of data to be read. * @param timeout time out in millisecond (1/1000 second), -1 means infinity. * * @return the amount of data actually read, * 0 means the connection is closed, * -1 means error occurred. */ int read_with_timeout (void *buf, size_t size, int timeout) const; /** * @brief Write data to socket. * * @param buf the buffer stores the data. * @param size size of the data to be sent. * * @return the amount of data acutally sent, or -1 if an error occurred. */ int write (const void *buf, size_t size) const; /** * @brief Wait until there are some data ready to read. * * @param timeout time out in millisecond (1/1000 second), -1 means infinity. * * @return > 0 if data is OK, == 0 if time is out, < 0 if an error occurred. */ int wait_for_data (int timeout = -1) const; /** * @brief Get the number of the last occurred error. * * @return the standard errno value. */ int get_error_number () const; /** * @brief Get the message of the last occurred error. * * @return the error message of the last occurred error. */ String get_error_message () const; /** * @brief Get the socket id. * * @return the file id of this socket object. */ int get_id () const; protected: /** * @brief Initiate a connection on a socket. * * @param addr the address to be connected to. * * @return true if success. */ bool connect (const SocketAddress &addr) const; /** * @brief Bind a socket to an address, used by SocketServer. * * @param addr the address to be binded to. * * @return true if success. */ bool bind (const SocketAddress &addr) const; /** * @brief Listen for connections on a socket. * * @param queue_length the length of the waiting queue. * * @return true if success. */ bool listen (int queue_length = 5) const; /** * @brief Accept a connection on the socket, used by SocketServer. * * @return the id of the accepted client socket, or -1 if an error is occurred. */ int accept () const; /** * @brief Create a socket for specific family. * * @param family the family type. * * @return true if success. */ bool create (SocketFamily family); /** * @brief Close the socket. */ void close (); }; /** * @brief Socket Server class. * * Class SocketServer provides basic operations to create a Socket Server, * such as create, run etc. */ class SocketServer : private Socket { class SocketServerImpl; SocketServerImpl *m_impl; public: /** * @brief Default constructor, do nothing. */ SocketServer (int max_clients = -1); /** * @brief Constructor. * * @param address create a server on this address. * @param max_clients the max number of socket clients, -1 means unlimited. */ SocketServer (const SocketAddress &address, int max_clients = -1); /** * @brief Destructor. */ ~SocketServer (); /** * @brief Test if the server is valid. * * @return true if the socket server is valid and ready to run. */ bool valid () const; /** * @brief Create a socket on an address. * * @param address the address to be listen. * * @return true if OK. */ bool create (const SocketAddress &address); /** * @brief Run the server. * * @return true if it ran successfully. */ bool run (); /** * @brief Check if the server is running. * * @return true if it's running. */ bool is_running () const; /** * @brief Shutdown the server. */ void shutdown (); /** * @brief Close a client connection. * * @param socket the client socket object to be closed. * @return true if the socket was closed successfully. */ bool close_connection (const Socket &socket); /** * @brief Get the number of the last occurred error. * * @return the standard errno value. */ int get_error_number () const; /** * @brief Get the message of the last occurred error. * * @return the error message corresponding to the errno. */ String get_error_message () const; /** * @brief Get the max number of socket clients. * * @return the max number of socket clients allowed to connect this server. */ int get_max_clients () const; /** * @brief Set the max number of clients. * * @param max_clients the max number of socket clients allowed to connect this server. */ void set_max_clients (int max_clients); /** * @brief Insert an external socket into the main loop. * * If data is available on this socket, then the receive signal will be emitted. * * @param sock The external socket to be inserted. * @return true if the socket is valid. */ bool insert_external_socket (const Socket &sock); /** * @brief Remove an external socket which was inserted by insert_external_socket (). * * @param sock The external socket to be removed. * @return true if the socket is valid and has been removed successfully. */ bool remove_external_socket (const Socket &sock); public: /** * @brief Connect a slot to socket accept signal. * * Connect a slot to socket accept signal, if a client connection is accepted, * this signal will be emitted. * * @param slot the slot to be connected to this signal. * * @return the Connection object of this slot-signal connection, can be used * to disconnect the slot later. */ Connection signal_connect_accept (SocketServerSlotSocket *slot); /** * @brief Connect a slot to socket receive signal. * * Connect a slot to socket receive signal, if a client send data to this server, * this signal will be emitted. * * @param slot the slot to be connected to this signal. * * @return the Connection object of this slot-signal connection, can be used * to disconnect the slot later. */ Connection signal_connect_receive (SocketServerSlotSocket *slot); /** * @brief Connect a slot to socket exception signal. * * Connect a slot to socket exception signal, if an exception was occurred * to a client connection, this signal will be emitted. * * @param slot the slot to be connected to this signal. * * @return the Connection object of this slot-signal connection, can be used * to disconnect the slot later. */ Connection signal_connect_exception (SocketServerSlotSocket *slot); }; /** * @brief Socket client class. * * Class SocketClient provides basic operations to create a Socket Client, * such as connect, read, write, etc. */ class SocketClient : public Socket { bool m_connected; public: /** * @brief Constructor. */ SocketClient (); /** * @brief Constructor. * * @param address the server address to be connected. */ SocketClient (const SocketAddress &address); /** * @brief Destructor. */ ~SocketClient (); /** * @brief Check if the socket is connected. * * @return true if the socket client is connected to a server. */ bool is_connected () const; /** * @brief Connect to a server. * * @param address the server socket address to be connected to. * * @return true if connected successfully. */ bool connect (const SocketAddress &address); /** * @brief Close the client. */ void close (); }; /** * @brief Get the default socket address of SocketFrontEnd * * SocketFrontEnd should listen on this address by default. */ String scim_get_default_socket_frontend_address (); /** * @brief Get the default socket address of SocketIMEngine * * SocketIMEngine should connect to this address by default. */ String scim_get_default_socket_imengine_address (); /** * @brief Get the default socket address of SocketConfig * * SocketConfig should connect to this address by default. */ String scim_get_default_socket_config_address (); /** * @brief Get the default socket address of the Panel running on localhost. * * The panel running on local host should listen on this address by default. * All FrontEnds which need panel should connect to this address by default. */ String scim_get_default_panel_socket_address (const String &display); /** * @brief Get the default socket address of Helper Manager Server running on localhost. */ String scim_get_default_helper_manager_socket_address (); /** * @brief Get the default socket timeout value. * * All socket connection should use this timeout value. */ int scim_get_default_socket_timeout (); /** * @brief Helper function to open a connection to a socket server * with a standard hand shake protocol. * * This function is used by a socket client to establish a connection * between a socket server with a standard hand shake protocol. * * The communication between Panel and FrontEnd, SocketFrontEnd and SocketIMEngine, * SocketFrontEnd and SocketConfig all uses this hand shake protocol. * * @param key A random magic key sent from the socket server * to identify this client in later communications. * @param client_type The type of this socket client, for example: * "FrontEnd", "GUI", "SocketIMEngine", "SocketConfig" etc. * If the type is "ConnectionTester" then this call just * test if the connection can be established. The client * should close this socket just after the call. * @param server_type The request socket server type, for example: * "Panel", "SocketFrontEnd" etc. * @param socket The reference to the client socket which has been * connected to the socket server. * @param timeout The socket read timeout in millisecond, -1 means unlimited. * * @return true if the connection was established successfully, otherwise * return false, and the client should close the socket. */ bool scim_socket_open_connection (uint32 &key, const String &client_type, const String &server_type, const Socket &socket, int timeout = -1); /** * @brief Helper function to accept a connection request from a socket client * with a standard hand shake protocol. * * This function is used by a socket server to accept a connection request * from a socket client which is calling scim_socket_open_connection (). * * If a client with type "ConnectionTester" connected to this socket server, then * this function will return an empty string, but tell the client the connection * was established successfully. * * @param key A random magic key to identify the socket client in later * communications. * @param server_types The type of this server, for example: * "SocketFrontEnd", "Panel" etc. * One server can have multiple types, separated by comma. * @param client_types A list of acceptable client types, separated by comma. * The client type maybe: "FrontEnd", "GUI", "SocketIMEngine" etc. * @param socket The socket connected to the client. * @param timeout the socket read timeout in millisecond, -1 means unlimited. * * @return The type of the accepted socket client, or an empty string if the * connection could not be established. */ String scim_socket_accept_connection (uint32 &key, const String &server_types, const String &client_types, const Socket &socket, int timeout = -1); /** @} */ } // namespace scim #endif //__SCIM_SOCKET_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_socket.cpp0000644000175000017500000011363612422143415015747 0ustar tzhuantzhuan/** @file scim_socket.cpp * @brief Implementation of Socket related classes. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_socket.cpp,v 1.44 2005/12/01 08:27:36 suzhe Exp $ * */ #define Uses_SCIM_SOCKET #define Uses_SCIM_TRANSACTION #define Uses_SCIM_CONFIG_PATH #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "scim_private.h" #include "scim.h" #define SCIM_SOCKET_SERVER_MAX_CLIENTS 256 namespace scim { static struct in_addr __gethostname (const char *host) { struct in_addr addr = { 0 }; #if HAVE_GETHOSTBYNAME_R struct hostent hostbuf, *hp; size_t hstbuflen; char *tmphstbuf; int res; int herr; hstbuflen = 1024; /* Allocate buffer, remember to free it to avoid memory leakage. */ tmphstbuf = (char*) malloc (hstbuflen); while ((res = gethostbyname_r (host, &hostbuf, tmphstbuf, hstbuflen, &hp, &herr)) == ERANGE) { /* Enlarge the buffer. */ hstbuflen *= 2; tmphstbuf = (char*) realloc (tmphstbuf, hstbuflen); } /* Found the host */ if (!res && hp) { addr = * ((struct in_addr *)hp->h_addr_list [0]); } free (tmphstbuf); #else struct hostent *hostinfo; hostinfo = gethostbyname (host); if (hostinfo) addr = * ((struct in_addr *) hostinfo->h_addr_list [0]); #endif return addr; } class SocketAddress::SocketAddressImpl { struct sockaddr *m_data; SocketFamily m_family; String m_address; public: SocketAddressImpl (const String &addr = String ()) : m_data (0), m_family (SCIM_SOCKET_UNKNOWN) { if (addr.length ()) set_address (addr); } SocketAddressImpl (const SocketAddressImpl &other) : m_data (0), m_family (other.m_family), m_address (other.m_address) { if (other.m_data) { size_t len = 0; switch (m_family) { case SCIM_SOCKET_LOCAL: m_data = (struct sockaddr*) new struct sockaddr_un; len = sizeof (sockaddr_un); break; case SCIM_SOCKET_INET: m_data = (struct sockaddr*) new struct sockaddr_in; len = sizeof (sockaddr_in); break; } if (len && m_data) memcpy (m_data, other.m_data, len); } } ~SocketAddressImpl () { if (m_data) delete m_data; } void swap (SocketAddressImpl &other) { std::swap (m_data, other.m_data); std::swap (m_family, other.m_family); std::swap (m_address, other.m_address); } bool valid () const { if (m_address.length () && m_data && (m_family == SCIM_SOCKET_LOCAL || m_family == SCIM_SOCKET_INET)) return true; return false; } SocketFamily get_family () const { return m_family; } bool set_address (const String &addr); const String & get_address () const { return m_address; } const void * get_data () const { return (void *)m_data; } int get_data_length () const { if (m_data) { if (m_family == SCIM_SOCKET_LOCAL) return SUN_LEN ((struct sockaddr_un*)(m_data)); else if (m_family == SCIM_SOCKET_INET) return sizeof (struct sockaddr_in); } return 0; } }; bool SocketAddress::SocketAddressImpl::set_address (const String &addr) { std::vector varlist; struct sockaddr *new_data = 0; SocketFamily new_family = SCIM_SOCKET_UNKNOWN; scim_split_string_list (varlist, addr, ':'); if (varlist.size () < 2) return false; if (varlist [0] == "local" || varlist [0] == "unix" || varlist [0] == "file") { String real_addr = addr.substr (varlist [0].length ()+1) + String ("-") + scim_get_user_name (); struct sockaddr_un *un = new struct sockaddr_un; un->sun_family = AF_UNIX; memset (un->sun_path, 0, sizeof (un->sun_path)); strncpy (un->sun_path, real_addr.c_str (), sizeof (un->sun_path)); un->sun_path[sizeof (un->sun_path) - 1] = '\0'; SCIM_DEBUG_SOCKET(3) << " local:" << un->sun_path << "\n"; new_family = SCIM_SOCKET_LOCAL; new_data = (struct sockaddr *) un; } else if ((varlist [0] == "tcp" || varlist [0] == "inet") && varlist.size () == 3) { struct sockaddr_in *in = new struct sockaddr_in; in->sin_addr = __gethostname (varlist [1].c_str ()); if (in->sin_addr.s_addr) { in->sin_family = AF_INET; in->sin_port = htons (atoi (varlist [2].c_str ())); SCIM_DEBUG_SOCKET(3) << " inet:" << inet_ntoa (in->sin_addr) << ":" << ntohs (in->sin_port) << "\n"; new_family = SCIM_SOCKET_INET; new_data = (struct sockaddr *) in; } else { delete in; } } if (new_data) { if (m_data) delete m_data; m_data = new_data; m_family = new_family; m_address = addr; return valid (); } return false; } // Implementation of SocketAddress SocketAddress::SocketAddress (const String &addr) : m_impl (new SocketAddressImpl (addr)) { } SocketAddress::SocketAddress (const SocketAddress &addr) : m_impl (new SocketAddressImpl (*addr.m_impl)) { } SocketAddress::~SocketAddress () { delete m_impl; } const SocketAddress& SocketAddress::operator = (const SocketAddress &addr) { if (this != &addr) { SocketAddressImpl new_impl (*addr.m_impl); m_impl->swap (new_impl); } return *this; } bool SocketAddress::valid () const { return m_impl->valid (); } SocketFamily SocketAddress::get_family () const { return m_impl->get_family (); } bool SocketAddress::set_address (const String &addr) { SCIM_DEBUG_SOCKET(2) << " SocketAddress::set_address (" << addr << ")\n"; return m_impl->set_address (addr); } String SocketAddress::get_address () const { return m_impl->get_address (); } const void * SocketAddress::get_data () const { return m_impl->get_data (); } int SocketAddress::get_data_length () const { return m_impl->get_data_length (); } // Implementation of Socket class Socket::SocketImpl { int m_id; int m_err; bool m_binded; bool m_no_close; SocketFamily m_family; SocketAddress m_address; public: SocketImpl (int id = -1) : m_id (id), m_err (0), m_binded (false), m_no_close (true), m_family (SCIM_SOCKET_UNKNOWN) { } ~SocketImpl () { close (); } bool valid () const { return m_id >= 0; } int read (void *buf, size_t size) { if (!buf || !size) { m_err = EINVAL; return -1; } if (m_id < 0) { m_err = EBADF; return -1; } m_err = 0; int ret; while (1) { ret = ::read (m_id, buf, size); if (ret >= 0) break; if (errno == EINTR) continue; m_err = errno; } return ret; } int read_with_timeout (void *buf, size_t size, int timeout) { if (!buf || !size) { m_err = EINVAL; return -1; } if (m_id < 0) { m_err = EBADF; return -1; } if (timeout < 0) return read (buf, size); int ret; int nbytes = 0; char *cbuf = static_cast (buf); while (size > 0) { ret = wait_for_data_internal (&timeout); if (ret < 0) return ret; if (ret == 0) return nbytes; ret = read (cbuf, size); if (ret < 0) return ret; if (ret == 0) return nbytes; cbuf += ret; nbytes += ret; size -= ret; } return nbytes; } int write (const void *buf, size_t size) { if (!buf || !size) { m_err = EINVAL; return -1; } if (m_id < 0) { m_err = EBADF; return -1; } int ret = -1; typedef void (*_scim_sighandler_t)(int); _scim_sighandler_t orig_handler = signal (SIGPIPE, SIG_IGN); m_err = 0; const char *cbuf = static_cast (buf); while (size > 0) { ret = ::write (m_id, cbuf, size); if (ret > 0) { size -= (size_t) ret; cbuf += ret; continue; } if (errno == EINTR) continue; break; } m_err = errno; if (orig_handler != SIG_ERR) signal (SIGPIPE, orig_handler); else signal (SIGPIPE, SIG_DFL); return ret; } int wait_for_data (int timeout = -1) { if (m_id < 0) { m_err = EBADF; return -1; } return wait_for_data_internal (&timeout); } int get_error_number () const { return m_err; } String get_error_message () const { if (m_err > 0) return String (strerror (m_err)); return String (); } int get_id () const { return m_id; } bool connect (const SocketAddress &addr) { SCIM_DEBUG_SOCKET(1) << "Socket: Connect to server: " << addr.get_address () << " ...\n"; m_err = EBADF; if (m_binded) return false; if (addr.valid () && m_id >= 0 && m_family == addr.get_family ()) { struct sockaddr * data = (sockaddr *) addr.get_data (); int len = addr.get_data_length (); if (::connect (m_id, data, len) == 0) { m_address = addr; m_err = 0; return true; } m_err = errno; } return false; } bool bind (const SocketAddress &addr) { SCIM_DEBUG_SOCKET(1) << "Socket: Bind to address: " << addr.get_address () << " ...\n"; m_err = EBADF; if (m_binded) return false; if (addr.valid () && m_id >= 0 && m_family == addr.get_family ()) { const struct sockaddr_un * data_un = 0; const struct sockaddr * data = static_cast (addr.get_data ()); int len = addr.get_data_length (); // Unlink the broken socket file. if (m_family == SCIM_SOCKET_LOCAL) { data_un = static_cast (addr.get_data ()); // The file is already exist, check if it's broken // by connecting to it. SCIM_DEBUG_SOCKET(2) << "Try to remove the broken socket file: " << data_un->sun_path << "\n"; if (::access (data_un->sun_path, F_OK) == 0) { SocketClient tmp_socket (addr); if (!tmp_socket.is_connected ()) { struct stat statbuf; // If it's a socket file, then // delete it. if (::stat (data_un->sun_path, &statbuf) == 0 && S_ISSOCK (statbuf.st_mode)) { // TODO need to separate stat and S_ISSOCK here if (::unlink (data_un->sun_path) == -1) { std::cerr << _("Creating socket") << " " << data_un->sun_path << ": " << _("file exists and we were unable to delete it") << ": " << _("syscall") << " unlink " << _("failed") << ": " << strerror(errno) << ": " << _("exiting") << "" << std::endl; exit(-1); } } else { std::cerr << _("Creating socket") << " " << data_un->sun_path << ": " << _("file exists and is not a socket") << ", " << _("exiting") << " ..." << std::endl; exit(-1); } } else { // NOTE another instance of the server is running: we can't just keep running like this // if we attempt to bind anyway there may be more than one servers listening on this socket. // In addition on FreeBSD bind will get EADDRINUSE, not clear why Linux doesn;t produce this same error. std::cerr << _("Creating socket") << " " << data_un->sun_path << ": " << _("another instance of the server is already listening on this socket") << ", " << _("exiting") << " ..." << std::endl; exit(-1); } tmp_socket.close (); } } if (::bind (m_id, data, len) == 0) { m_address = addr; m_binded = true; m_err = 0; // Set correct permission for the socket file if (m_family == SCIM_SOCKET_LOCAL) { if (::chmod (data_un->sun_path, S_IRUSR | S_IWUSR) == -1) { std::cerr << _("Creating socket") << " " << data_un->sun_path << ": " << _("unable to change the mode of this file") << ": " << _("syscall") << " chmod " << _("failed") << ", " << _("continuing") << " ..." << std::endl; } } return true; } std::cerr << _("Error creating socket") << ": bind " << _("syscall failed") << ": " << strerror(errno) << std::endl; m_err = errno; } return false; } bool listen (int queue_length = 5) { if (m_id < 0) { m_err = EBADF; return -1; } SCIM_DEBUG_SOCKET(1) << "Socket: Listen: " << queue_length << " ...\n"; m_err = 0; int ret = ::listen (m_id, queue_length); if (ret == -1) { std::cerr << _("Error creating socket") << ": listen " << _("syscall failed") << ": " << strerror(errno) << std::endl; m_err = errno; return false; } return true; } int accept () { if (m_id < 0) { m_err = EBADF; return -1; } int ret = -1; int addrlen = 0; m_err = 0; if (m_family == SCIM_SOCKET_LOCAL) { struct sockaddr_un addr; addrlen = sizeof (addr); ret = ::accept (m_id, (struct sockaddr*) &addr, (socklen_t*) &addrlen); } else if (m_family == SCIM_SOCKET_INET) { struct sockaddr_in addr; addrlen = sizeof (addr); ret = ::accept (m_id, (struct sockaddr*) &addr, (socklen_t*) &addrlen); } if (ret < 0 && addrlen > 0) m_err = errno; SCIM_DEBUG_SOCKET(1) << "Socket: Accept connection, ret: " << ret << "\n"; return ret; } bool create (SocketFamily family) { int ret = -1; if (family == SCIM_SOCKET_LOCAL) ret = ::socket (PF_UNIX, SOCK_STREAM, 0); else if (family == SCIM_SOCKET_INET) ret = ::socket (PF_INET, SOCK_STREAM, 0); else { m_err = EINVAL; return false; } if (ret > 0) { if (m_id >= 0) close (); m_no_close = false; m_binded = false; m_err = 0; m_family = family; m_id = ret; } else { std::cerr << _("Error creating socket") << ": socket " << _("syscall failed") << ": " << strerror(errno) << std::endl; m_err = errno; } SCIM_DEBUG_SOCKET(1) << "Socket: Socket created, family: " << family << " ret: " << ret << "\n"; return ret >= 0; } void close () { if (m_id < 0) return; if (!m_no_close) { SCIM_DEBUG_SOCKET(2) << " Closing the socket: " << m_id << " ...\n"; ::close (m_id); // Unlink the socket file. if (m_binded && m_family == SCIM_SOCKET_LOCAL) { const struct sockaddr_un * data = static_cast (m_address.get_data ()); // FIXME: Don't unlink the socket file, because if the process is forked and child process exits // the socket file will be unlinked by child process. //SCIM_DEBUG_SOCKET(3) << " Unlinking socket file " << data->sun_path << "...\n"; ::unlink (data->sun_path); } } m_id = -1; m_err = 0; m_binded = false; m_no_close = false; m_family = SCIM_SOCKET_UNKNOWN; m_address = SocketAddress (); } private: int wait_for_data_internal (int *timeout) { fd_set fds; struct timeval tv; struct timeval begin_tv; int ret; if (*timeout >= 0) { gettimeofday(&begin_tv, 0); tv.tv_sec = *timeout / 1000; tv.tv_usec = (*timeout % 1000) * 1000; } m_err = 0; while (1) { FD_ZERO(&fds); FD_SET(m_id, &fds); ret = select(m_id + 1, &fds, NULL, NULL, (*timeout >= 0) ? &tv : NULL); if (*timeout > 0) { int elapsed; struct timeval cur_tv; gettimeofday (&cur_tv, 0); elapsed = (cur_tv.tv_sec - begin_tv.tv_sec) * 1000 + (cur_tv.tv_usec - begin_tv.tv_usec) / 1000; *timeout = *timeout - elapsed; if (*timeout > 0) { tv.tv_sec = *timeout / 1000; tv.tv_usec = (*timeout % 1000) * 1000; } else { tv.tv_sec = 0; tv.tv_usec = 0; *timeout = 0; } } if (ret > 0) { return ret; } else if (ret == 0) { if (*timeout == 0) return ret; else continue; } if (errno == EINTR) continue; m_err = errno; return ret; } } }; Socket::Socket (int id) : m_impl (new SocketImpl (id)) { } Socket::~Socket () { m_impl->close (); delete m_impl; } bool Socket::valid () const { return m_impl->valid (); } int Socket::read (void *buf, size_t size) const { return m_impl->read (buf, size); } int Socket::read_with_timeout (void *buf, size_t size, int timeout) const { return m_impl->read_with_timeout (buf, size, timeout); } int Socket::write (const void *buf, size_t size) const { return m_impl->write (buf, size); } int Socket::wait_for_data (int timeout) const { return m_impl->wait_for_data (timeout); } int Socket::get_error_number () const { return m_impl->get_error_number (); } String Socket::get_error_message () const { return m_impl->get_error_message (); } bool Socket::connect (const SocketAddress &addr) const { return m_impl->connect (addr); } bool Socket::bind (const SocketAddress &addr) const { return m_impl->bind (addr); } bool Socket::listen (int queue_length) const { return m_impl->listen (queue_length); } int Socket::accept () const { return m_impl->accept (); } int Socket::get_id () const { return m_impl->get_id (); } bool Socket::create (SocketFamily family) { return m_impl->create (family); } void Socket::close () { return m_impl->close (); } // Implementation of SocketServer struct SocketServer::SocketServerImpl { fd_set active_fds; int max_fd; int err; bool running; bool created; int num_clients; int max_clients; std::vector ext_fds; SocketServerSignalSocket accept_signal; SocketServerSignalSocket receive_signal; SocketServerSignalSocket exception_signal; SocketServerImpl (int mc) : max_fd (0), err (0), running (false), created (false), num_clients (0), max_clients (std::min (mc, SCIM_SOCKET_SERVER_MAX_CLIENTS)) { FD_ZERO (&active_fds); } }; SocketServer::SocketServer (int max_clients) : Socket (-1), m_impl (new SocketServerImpl (max_clients)) { } SocketServer::SocketServer (const SocketAddress &address, int max_clients) : Socket (-1), m_impl (new SocketServerImpl (max_clients)) { create (address); } SocketServer::~SocketServer () { delete m_impl; } bool SocketServer::valid () const { return m_impl->created; } bool SocketServer::create (const SocketAddress &address) { m_impl->err = EBUSY; if (!m_impl->created) { SocketFamily family = address.get_family (); SCIM_DEBUG_SOCKET (1) << "Creating Socket Server, family: " << family << "\n"; if (family != SCIM_SOCKET_UNKNOWN) { if (Socket::create (family) && Socket::bind (address) && Socket::listen ()) { m_impl->created = true; m_impl->max_fd = Socket::get_id (); FD_ZERO (&(m_impl->active_fds)); FD_SET (m_impl->max_fd, &(m_impl->active_fds)); m_impl->err = 0; return true; } m_impl->err = Socket::get_error_number (); Socket::close (); } else { m_impl->err = EBADF; } } return false; } bool SocketServer::run () { if (m_impl->created && !m_impl->running) { fd_set read_fds, exception_fds; int client; int i; m_impl->running = true; m_impl->err = 0; while (1) { read_fds = m_impl->active_fds; exception_fds = m_impl->active_fds; SCIM_DEBUG_SOCKET (2) << " SocketServer: Watching socket...\n"; if (select (m_impl->max_fd + 1, &read_fds, NULL, &exception_fds, NULL) < 0) { m_impl->err = errno; m_impl->running = false; SCIM_DEBUG_SOCKET (3) << " SocketServer: Error: " << get_error_message () << "\n"; return false; } //The server has been shut down. if (!m_impl->running) return true; for (i = 0; imax_fd + 1; i++) { if (FD_ISSET (i, &read_fds)) { //New connection if (i == Socket::get_id ()) { client = Socket::accept (); SCIM_DEBUG_SOCKET (3) << " SocketServer: Accept new connection:" << client << "\n"; if (client < 0) { m_impl->err = Socket::get_error_number (); m_impl->running = false; SCIM_DEBUG_SOCKET (4) << " SocketServer: Error occurred: " << Socket::get_error_message () << "\n"; return false; } if (m_impl->max_clients > 0 && m_impl->num_clients >= m_impl->max_clients) { SCIM_DEBUG_SOCKET (4) << " SocketServer: Too many clients.\n"; ::close (client); } else { m_impl->num_clients ++; //Store the new client FD_SET (client, &(m_impl->active_fds)); if (m_impl->max_fd < client) m_impl->max_fd = client; Socket client_socket (client); //emit the signal. m_impl->accept_signal.emit (this, client_socket); } //Client reading } else { SCIM_DEBUG_SOCKET (3) << " SocketServer: Accept client reading...\n"; Socket client_socket (i); //emit the signal. m_impl->receive_signal.emit (this, client_socket); } } if (FD_ISSET (i, &exception_fds)) { //The server got an exception, return. if (i == Socket::get_id ()) { SCIM_DEBUG_SOCKET (3) << " SocketServer: Server got an exception, exiting...\n"; shutdown (); return true; } else { SCIM_DEBUG_SOCKET (3) << " SocketServer: Client " << i << "got an exception, callbacking...\n"; Socket client_socket (i); m_impl->exception_signal.emit (this, client_socket); } } if (!m_impl->running) break; } //The server has been shut down. if (!m_impl->running) return true; } } m_impl->err = EBADF; return false; } bool SocketServer::is_running () const { return m_impl->running; } void SocketServer::shutdown () { if (m_impl->created) { SCIM_DEBUG_SOCKET (2) << " SocketServer: Shutting down the server...\n"; m_impl->running = false; for (int i = 0; iext_fds.size (); i++) FD_CLR (m_impl->ext_fds [i], &m_impl->active_fds); for (int i = 0; imax_fd + 1; i++) { //Close all client if (FD_ISSET (i, &(m_impl->active_fds)) && i != Socket::get_id ()) { SCIM_DEBUG_SOCKET (3) << " SocketServer: Closing client: " << i << "\n"; ::close (i); } } m_impl->max_fd = 0; m_impl->created = false; m_impl->err = 0; m_impl->num_clients = 0; m_impl->ext_fds.clear (); FD_ZERO (&(m_impl->active_fds)); Socket::close (); } } bool SocketServer::close_connection (const Socket &socket) { int id = socket.get_id (); if (m_impl->created && m_impl->running && id > 0 && FD_ISSET (id, &(m_impl->active_fds))) { SCIM_DEBUG_SOCKET (2) << " SocketServer: Closing the connection: " << id << "\n"; m_impl->num_clients --; FD_CLR (id, &(m_impl->active_fds)); std::vector ::iterator it = std::find (m_impl->ext_fds.begin (), m_impl->ext_fds.end (), id); if (it != m_impl->ext_fds.end ()) m_impl->ext_fds.erase (it); ::close (id); return true; } return false; } int SocketServer::get_error_number () const { if (m_impl->err) return m_impl->err; return Socket::get_error_number (); } String SocketServer::get_error_message () const { if (m_impl->err) return String (strerror (m_impl->err)); return Socket::get_error_message (); } int SocketServer::get_max_clients () const { return m_impl->max_clients; } void SocketServer::set_max_clients (int max_clients) { if (max_clients < SCIM_SOCKET_SERVER_MAX_CLIENTS) m_impl->max_clients = max_clients; } bool SocketServer::insert_external_socket (const Socket &sock) { int fd = sock.get_id (); if (valid () && sock.valid () && sock.wait_for_data (0) >= 0 && m_impl->num_clients < m_impl->max_clients && !FD_ISSET (fd, &m_impl->active_fds)) { m_impl->ext_fds.push_back (fd); FD_SET (fd, &m_impl->active_fds); if (m_impl->max_fd < fd) m_impl->max_fd = fd; m_impl->num_clients ++; return true; } return false; } bool SocketServer::remove_external_socket (const Socket &sock) { int fd = sock.get_id (); if (valid () && FD_ISSET (fd, &m_impl->active_fds)) { FD_CLR (fd, &m_impl->active_fds); std::vector ::iterator it = std::find (m_impl->ext_fds.begin (), m_impl->ext_fds.end (), fd); if (it != m_impl->ext_fds.end ()) m_impl->ext_fds.erase (it); m_impl->num_clients --; return true; } return false; } Connection SocketServer::signal_connect_accept (SocketServerSlotSocket *slot) { return m_impl->accept_signal.connect (slot); } Connection SocketServer::signal_connect_receive (SocketServerSlotSocket *slot) { return m_impl->receive_signal.connect (slot); } Connection SocketServer::signal_connect_exception (SocketServerSlotSocket *slot) { return m_impl->exception_signal.connect (slot); } //Implementation of SocketClient SocketClient::SocketClient () : Socket (-1), m_connected (false) { } SocketClient::SocketClient (const SocketAddress &address) : Socket (-1), m_connected (false) { connect (address); } SocketClient::~SocketClient () { } bool SocketClient::is_connected () const { return Socket::valid () && m_connected; } bool SocketClient::connect (const SocketAddress &address) { if (m_connected) close (); if (Socket::create (address.get_family ()) && Socket::connect (address)) { m_connected = true; return true; } else { close (); } return false; } void SocketClient::close () { Socket::close (); m_connected = false; } #define SCIM_DEFAULT_SOCKET_FRONTEND_ADDRESS "local:/tmp/scim-socket-frontend" #define SCIM_DEFAULT_PANEL_SOCKET_ADDRESS "local:/tmp/scim-panel-socket" #define SCIM_DEFAULT_HELPER_MANAGER_SOCKET_ADDRESS "local:/tmp/scim-helper-manager-socket" String scim_get_default_socket_frontend_address () { String address (SCIM_DEFAULT_SOCKET_FRONTEND_ADDRESS); address = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_FRONTEND_ADDRESS, address); const char *env = getenv ("SCIM_SOCKET_ADDRESS"); if (env && strlen (env) > 0) { address = String (env); } else { env = getenv ("SCIM_FRONTEND_SOCKET_ADDRESS"); if (env && strlen (env)) address = String (env); } if (address == "default") address = SCIM_DEFAULT_SOCKET_FRONTEND_ADDRESS; return address; } String scim_get_default_socket_imengine_address () { String address (SCIM_DEFAULT_SOCKET_FRONTEND_ADDRESS); address = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_IMENGINE_ADDRESS, address); const char *env = getenv ("SCIM_SOCKET_ADDRESS"); if (env && strlen (env) > 0) { address = String (env); } else { env = getenv ("SCIM_IMENGINE_SOCKET_ADDRESS"); if (env && strlen (env)) address = String (env); } if (address == "default") address = SCIM_DEFAULT_SOCKET_FRONTEND_ADDRESS; return address; } String scim_get_default_socket_config_address () { String address (SCIM_DEFAULT_SOCKET_FRONTEND_ADDRESS); address = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_CONFIG_ADDRESS, address); const char *env = getenv ("SCIM_SOCKET_ADDRESS"); if (env && strlen (env) > 0) { address = String (env); } else { env = getenv ("SCIM_CONFIG_SOCKET_ADDRESS"); if (env && strlen (env)) address = String (env); } if (address == "default") address = SCIM_DEFAULT_SOCKET_FRONTEND_ADDRESS; return address; } String scim_get_default_panel_socket_address (const String &display) { String address (SCIM_DEFAULT_PANEL_SOCKET_ADDRESS); address = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_PANEL_SOCKET_ADDRESS, address); const char *env = getenv ("SCIM_PANEL_SOCKET_ADDRESS"); if (env && strlen (env) > 0) { address = String (env); } if (address == "default") address = SCIM_DEFAULT_PANEL_SOCKET_ADDRESS; SocketAddress sockaddr (address); if (!sockaddr.valid ()) return String (); String::size_type colon_pos = display.rfind (':'); String disp_name = display; int disp_num = 0; // Maybe It's a X11 DISPLAY name if (colon_pos != String::npos) { String::size_type dot_pos = display.find ('.', colon_pos+1); // It has screen number if (dot_pos != String::npos) { disp_name = display.substr (0, dot_pos); } // FIXME: ignore remote X Server name. disp_num = atoi (display.substr (colon_pos + 1, String::npos).c_str()); } if (sockaddr.get_family () == SCIM_SOCKET_LOCAL) { for (size_t i = 0; i < disp_name.length(); ++i) { if (disp_name[i] == '/') disp_name[i] = '_'; } address = address + disp_name; } else if (sockaddr.get_family () == SCIM_SOCKET_INET) { std::vector varlist; scim_split_string_list (varlist, address, ':'); if (varlist.size () == 3) { int port = atoi (varlist [2].c_str ()) + disp_num; char buf [10]; snprintf (buf, 10, "%d", port); varlist [2] = String (buf); address = scim_combine_string_list (varlist, ':'); } } sockaddr.set_address (address); if (sockaddr.valid ()) return address; return String (); } String scim_get_default_helper_manager_socket_address () { String address (SCIM_DEFAULT_HELPER_MANAGER_SOCKET_ADDRESS); address = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_HELPER_MANAGER_SOCKET_ADDRESS, address); const char *env = getenv ("SCIM_HELPER_MANAGER_SOCKET_ADDRESS"); if (env && strlen (env) > 0) { address = String (env); } if (address == "default") address = SCIM_DEFAULT_HELPER_MANAGER_SOCKET_ADDRESS; return address; } int scim_get_default_socket_timeout () { int timeout = 5000; timeout = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_TIMEOUT, timeout); const char *env = getenv ("SCIM_SOCKET_TIMEOUT"); if (env && strlen (env)) timeout = atoi (env); if (timeout <= 0) timeout = -1; return timeout; } static bool scim_socket_check_type (const String &types, const String &atype) { std::vector type_list; scim_split_string_list (type_list, types, ','); return std::find (type_list.begin (), type_list.end (), atype) != type_list.end (); } bool scim_socket_open_connection (uint32 &key, const String &client_type, const String &server_type, const Socket &socket, int timeout) { if (!socket.valid () || !client_type.length () || !server_type.length ()) return false; Transaction trans; trans.put_command (SCIM_TRANS_CMD_REQUEST); trans.put_command (SCIM_TRANS_CMD_OPEN_CONNECTION); trans.put_data (String (SCIM_BINARY_VERSION)); trans.put_data (client_type); if (trans.write_to_socket (socket)) { int cmd; String server_types; if (trans.read_from_socket (socket, timeout) && trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && trans.get_data (server_types) && scim_socket_check_type (server_types, server_type) && trans.get_data (key)) { trans.clear (); trans.put_command (SCIM_TRANS_CMD_REPLY); trans.put_command (SCIM_TRANS_CMD_OK); if (trans.write_to_socket (socket)) return true; } else { trans.clear (); trans.put_command (SCIM_TRANS_CMD_REPLY); trans.put_command (SCIM_TRANS_CMD_FAIL); trans.write_to_socket (socket); } } return false; } String scim_socket_accept_connection (uint32 &key, const String &server_types, const String &client_types, const Socket &socket, int timeout) { if (!socket.valid () || !client_types.length () || !server_types.length ()) return String (""); Transaction trans; if (trans.read_from_socket (socket, timeout)) { int cmd; String version; String client_type; if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REQUEST && trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OPEN_CONNECTION && trans.get_data (version) && version == String (SCIM_BINARY_VERSION) && trans.get_data (client_type) && (scim_socket_check_type (client_types, client_type) || client_type == "ConnectionTester")) { key = (uint32) rand (); trans.clear (); trans.put_command (SCIM_TRANS_CMD_REPLY); trans.put_data (server_types); trans.put_data (key); if (trans.write_to_socket (socket) && trans.read_from_socket (socket, timeout) && trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) { // Client is ok, return the client type. return (client_type == "ConnectionTester") ? String ("") : client_type; } } } return String (""); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_slot.h0000644000175000017500000012021512422143415015074 0ustar tzhuantzhuan/** @file scim_slot.h * @brief C++ slot interface. * * Provides a set of slot class templates. Slots are callable objects that * can be used to connect functions, class methods and function objects to * scim::Signals. * * Most code of this file are came from Inti project. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * Copyright (c) 2002 The Inti Development Team. * Copyright (c) 2000 Red Hat, Inc. * Copyright 1999, Karl Einar Nelson * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_slot.h,v 1.8 2005/01/10 08:30:54 suzhe Exp $ */ #ifndef __SCIM_SLOT_H #define __SCIM_SLOT_H namespace scim { /** * @addtogroup SignalSlot * @{ */ //! @name Slot functions returning a new slot //! @{ //! @class Slot //! @brief Base class for slots that can connect to scim::Signals. class Slot : public ReferencedObject { Slot(const Slot&); Slot& operator=(const Slot&); protected: Slot(); //!< Constructor. virtual ~Slot() = 0; //!< Destructor. }; //! @class Slot0 //! @brief Base class template for slots passing no arguments and returning a value of type R. template class Slot0 : public Slot { protected: Slot0() {} //!< Constructor. public: virtual R call() const = 0; //!< Calls the signal handler connected to this slot. R operator()() const { return call(); } //!< Function operator; Calls call(). }; //! @class FunctionSlot0 //! @brief A slot template for static functions taking no arguments and returning a value of type R. template class FunctionSlot0 : public Slot0 { typedef R (*PF)(); PF pf; public: FunctionSlot0(PF function) : pf(function) {} //!< Construct a new function slot for a static function. //!< @param function - static function with the signature R (*PF)(). virtual R call() const { return (*pf)(); } //!< Calls the function connected to this slot. //!< @return a value of type R returned by the called function. }; //! Overloaded slot factory function. //! @param function - a static function with the signature R (*function)(). //! @return a new slot passing no arguments and returning a value of type R. //! //!
If the returned slot is connected to a signal it doesn't have to be //! unreferenced. The signal it's connected to will unreference the slot when //! it is destroyed. Otherwise the slot must be unreferenced by calling unref(). template inline Slot0* slot(R (*function)()) { return new FunctionSlot0(function); } //! @class MethodSlot0 //! @brief A slot template for methods in a class of type T taking no arguments and returning a value of type R. template class MethodSlot0 : public Slot0 { typedef R (T::*PMF)(); PMF pmf; T *t; public: MethodSlot0(T *object, PMF function) : pmf(function), t(object) {} //!< Construct a new method slot for a class member function. //!< @param object - a pointer to an object of type T. //!< @param function - a class method with the signature R (T::*PMF)(). virtual R call() const { return (t->*pmf)(); } //!< Calls the class method connected to this slot. //!< @return a value of type R returned by the called method. }; //! Overloaded slot factory function. //! @param object - a reference to a pointer to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(). //! @return a new slot passing no arguments and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot0* slot(T1* &object, R (T2::*function)()) { return new MethodSlot0(object, function); } //! Overloaded slot factory function. //! @param object - a reference to a const pointer to an object of type T1 (e.g. this). //! @param function - a class method with the signature R (T2::*function)(). //! @return a new slot passing no arguments and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot0* slot(T1* const &object, R (T2::*function)()) { return new MethodSlot0(object, function); } //! Overloaded slot factory function. //! @param object - a reference to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(). //! @return a new slot passing no arguments and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot0* slot(T1& object, R (T2::*function)()) { return new MethodSlot0(&object, function); } /* SignalSlot0 */ template class SignalSlot0 : public Slot0 { typedef R (*PF)(void*); PF pf; T *t; public: SignalSlot0(T *signal, PF function) : pf(function), t(signal) {} virtual R call() const { return (*pf)(t); } }; //! @class Slot1 //! @brief Base class template for slots passing one argument of type P1 and returning a value of type R. template class Slot1 : public Slot { protected: Slot1() {} //!< Constructor. public: virtual R call(P1 p1) const = 0; //!< Calls the signal handler connected to this slot. R operator()(P1 p1) const { return call(p1); } //!< Function operator; Calls call(). }; //! @class FunctionSlot1 //! @brief A slot template for static functions taking one argument of type P1 //! and returning a value of type R. template class FunctionSlot1 : public Slot1 { typedef R (*PF)(P1); PF pf; public: FunctionSlot1(PF function) : pf(function) {} //!< Construct a new function slot for a static function. //!< @param function - static function with the signature R (*PF)(P1). virtual R call(P1 p1) const { return (*pf)(p1); } //!< Calls the function connected to this slot passing it argument p1. //!< @return a value of type R returned by the called function. }; //! Overloaded slot factory function. //! @param function - a static function with the signature R (*function)(P1). //! @return a new slot passing one argument of type P1 and returning a value of type R. //! //!
If the returned slot is connected to a signal it doesn't have to be //! unreferenced. The signal it's connected to will unreference the slot when //! it is destroyed. Otherwise the slot must be unreferenced by calling unref(). template inline Slot1* slot(R (*function)(P1)) { return new FunctionSlot1(function); } //! @class MethodSlot1 //! @brief A slot template for methods in a class of type T taking one argument of type P1 //! and returning a value of type R. template class MethodSlot1 : public Slot1 { typedef R (T::*PMF)(P1); PMF pmf; T *t; public: MethodSlot1(T *object, PMF function) : pmf(function), t(object) {} //!< Construct a new method slot for a class member function. //!< @param object - a pointer to an object of type T. //!< @param function - a class method with the signature R (T::*PMF)(P1). virtual R call(P1 p1) const { return (t->*pmf)(p1); } //!< Calls the class method connected to this slot passing it argument p1. //!< @return a value of type R returned by the called method. }; //! Overloaded slot factory function. //! @param object - a reference to a pointer to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(P1). //! @return a new slot passing one argument of type P1 and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot1* slot(T1* &object, R (T2::*function)(P1)) { return new MethodSlot1(object, function); } //! Overloaded slot factory function. //! @param object - a reference to a const pointer to an object of type T1 (e.g. this). //! @param function - a class method with the signature R (T2::*function)(P1). //! @return a new slot passing one argument of type P1 and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot1* slot(T1* const &object, R (T2::*function)(P1)) { return new MethodSlot1(object, function); } //! Overloaded slot factory function. //! @param object - a reference to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(P1). //! @return a new slot passing one argument of type P1 and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot1* slot(T1& object, R (T2::*function)(P1)) { return new MethodSlot1(&object, function); } /* SignalSlot1 */ template class SignalSlot1 : public Slot1 { typedef R (*PF)(void*, P1); PF pf; T *t; public: SignalSlot1(T *signal, PF function) : pf(function), t(signal) {} virtual R call(P1 p1) const { return (*pf)(t, p1); } }; //! @class Slot2 //! @brief Base class template for slots passing two arguments of type P1 and P2, //! and returning a value of type R. template class Slot2 : public Slot { protected: Slot2() {} //!< Constructor. public: virtual R call(P1 p1, P2 p2) const = 0; //!< Calls the signal handler connected to this slot. R operator()(P1 p1, P2 p2) const { return call(p1, p2); } //!< Function operator; Calls call(). }; //! @class FunctionSlot2 //! @brief A slot template for static functions taking two arguments of type P1 and P2, //! and returning a value of type R. template class FunctionSlot2 : public Slot2 { typedef R (*PF)(P1, P2); PF pf; public: FunctionSlot2(PF function) : pf(function) {} //!< Construct a new function slot for a static function. //!< @param function - static function with the signature R (*PF)(P1, P2). virtual R call(P1 p1, P2 p2) const { return (*pf)(p1, p2); } //!< Calls the function connected to this slot passing it arguments p1 and p2. //!< @return a value of type R returned by the called function. }; //! Overloaded slot factory function. //! @param function - a static function with the signature R (*function)(P1, P2). //! @return a new slot passing two arguments of type P1 and P2, and returning a value of type R. //! //!
If the returned slot is connected to a signal it doesn't have to be //! unreferenced. The signal it's connected to will unreference the slot when //! it is destroyed. Otherwise the slot must be unreferenced by calling unref(). template inline Slot2* slot(R (*function)(P1, P2)) { return new FunctionSlot2(function); } //! @class MethodSlot2 //! @brief A slot template for methods in a class of type T taking two arguments of type P1 and P2, //! and returning a value of type R. template class MethodSlot2 : public Slot2 { typedef R (T::*PMF)(P1, P2); PMF pmf; T *t; public: MethodSlot2(T *object, PMF function) : pmf(function), t(object) {} //!< Construct a new method slot for a class member function. //!< @param object - a pointer to an object of type T. //!< @param function - a class method with the signature R (T::*PMF)(P1, P2). virtual R call(P1 p1, P2 p2) const { return (t->*pmf)(p1, p2); } //!< Calls the class method connected to this slot passing it arguments p1 and p2. //!< @return a value of type R returned by the called method. }; //! Overloaded slot factory function. //! @param object - a reference to a pointer to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(P1, P2). //! @return a new slot passing two arguments of type P1 and P2, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot2* slot(T1* &object, R (T2::*function)(P1, P2)) { return new MethodSlot2(object, function); } //! Overloaded slot factory function. //! @param object - a reference to a const pointer to an object of type T1 (e.g. this). //! @param function - a class method with the signature R (T2::*function)(P1, P2). //! @return a new slot passing two arguments of type P1 and P2, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot2* slot(T1* const &object, R (T2::*function)(P1, P2)) { return new MethodSlot2(object, function); } //! Overloaded slot factory function. //! @param object - a reference to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(P1, P2). //! @return a new slot passing two arguments of type P1 and P2, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot2* slot(T1& object, R (T2::*function)(P1, P2)) { return new MethodSlot2(&object, function); } /* SignalSlot2 */ template class SignalSlot2 : public Slot2 { typedef R (*PF)(void*, P1, P2); PF pf; T *t; public: SignalSlot2(T *signal, PF function) : pf(function), t(signal) {} virtual R call(P1 p1, P2 p2) const { return (*pf)(t, p1, p2); } }; //! @class Slot3 //! @brief Base class template for slots passing three arguments of type P1, P2 and P3, //! and returning a value of type R. template class Slot3 : public Slot { protected: Slot3() {} //!< Constructor. public: virtual R call(P1 p1, P2 p2, P3 p3) const = 0; //!< Calls the signal handler connected to this slot. R operator()(P1 p1, P2 p2, P3 p3) const { return call(p1, p2, p3); } //!< Function operator; Calls call(). }; //! @class FunctionSlot3 //! @brief A slot template for static functions taking three arguments of type P1, P2 and P3, //! and returning a value of type R. template class FunctionSlot3 : public Slot3 { typedef R (*PF)(P1, P2, P3); PF pf; public: FunctionSlot3(PF function) : pf(function) {} //!< Construct a new function slot for a static function. //!< @param function - static function with the signature R (*PF)(P1, P2, P3). virtual R call(P1 p1, P2 p2, P3 p3) const { return (*pf)(p1, p2, p3); } //!< Calls the function connected to this slot passing it arguments p1, p2 and p3. //!< @return a value of type R returned by the called function. }; //! Overloaded slot factory function. //! @param function - a static function with the signature R (*function)(P1, P2, P3). //! @return a new slot passing three arguments of type P1, P2 and P3, and returning a value of type R. //! //!
If the returned slot is connected to a signal it doesn't have to be //! unreferenced. The signal it's connected to will unreference the slot when //! it is destroyed. Otherwise the slot must be unreferenced by calling unref(). template inline Slot3* slot(R (*function)(P1, P2, P3)) { return new FunctionSlot3(function); } //! @class MethodSlot3 //! @brief A slot template for methods in a class of type T taking three arguments of type P1, P2 and P3, //! and returning a value of type R. template class MethodSlot3 : public Slot3 { typedef R (T::*PMF)(P1, P2, P3); PMF pmf; T *t; public: MethodSlot3(T *object, PMF function) : pmf(function), t(object) {} //!< Construct a new method slot for a class member function. //!< @param object - a pointer to an object of type T. //!< @param function - a class method with the signature R (T::*PMF)(P1, P2, P3). virtual R call(P1 p1, P2 p2, P3 p3) const { return (t->*pmf)(p1, p2, p3); } //!< Calls the class method connected to this slot passing it arguments p1, p2 and p3. //!< @return a value of type R returned by the called method. }; //! Overloaded slot factory function. //! @param object - a reference to a pointer to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(P1, P2, P3). //! @return a new slot passing three arguments of type P1, P2 and P3, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot3* slot(T1* &object, R (T2::*function)(P1, P2, P3)) { return new MethodSlot3(object, function); } //! Overloaded slot factory function. //! @param object - a reference to a const pointer to an object of type T1 (e.g. this). //! @param function - a class method with the signature R (T2::*function)(P1, P2, P3). //! @return a new slot passing three arguments of type P1, P2 and P3, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot3* slot(T1* const &object, R (T2::*function)(P1, P2, P3)) { return new MethodSlot3(object, function); } //! Overloaded slot factory function. //! @param object - a reference to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(P1, P2, P3). //! @return a new slot passing three arguments of type P1, P2 and P3, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot3* slot(T1& object, R (T2::*function)(P1, P2, P3)) { return new MethodSlot3(&object, function); } /* SignalSlot3 */ template class SignalSlot3 : public Slot3 { typedef R (*PF)(void*, P1, P2, P3); PF pf; T *t; public: SignalSlot3(T *signal, PF function) : pf(function), t(signal) {} virtual R call(P1 p1, P2 p2, P3 p3) const { return (*pf)(t, p1, p2, p3); } }; //! @class Slot4 //! @brief Base class template for slots passing four arguments of type P1, P2, P3 and P4, //! and returning a value of type R. template class Slot4 : public Slot { protected: Slot4() {} //!< Constructor. public: virtual R call(P1 p1, P2 p2, P3 p3, P4 p4) const = 0; //!< Calls the signal handler connected to this slot. R operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { return call(p1, p2, p3, p4); } //!< Function operator; Calls call(). }; //! @class FunctionSlot4 //! @brief A slot template for static functions taking four arguments of type P1, P2, P3 and P4, //! and returning a value of type R. template class FunctionSlot4 : public Slot4 { typedef R (*PF)(P1, P2, P3, P4); PF pf; public: FunctionSlot4(PF function) : pf(function) {} //!< Construct a new function slot for a static function. //!< @param function - static function with the signature R (*PF)(P1, P2, P3, P4). virtual R call(P1 p1, P2 p2, P3 p3, P4 p4) const { return (*pf)(p1, p2, p3, p4); } //!< Calls the function connected to this slot passing it arguments p1, p2, p3 and p4. //!< @return a value of type R returned by the called function. }; //! Overloaded slot factory function. //! @param function - a static function with the signature R (*function)(P1, P2, P3, P4). //! @return a new slot passing four arguments of type P1, P2, P3 and P4, and returning a value of type R. //! //!
If the returned slot is connected to a signal it doesn't have to be //! unreferenced. The signal it's connected to will unreference the slot when //! it is destroyed. Otherwise the slot must be unreferenced by calling unref(). template inline Slot4* slot(R (*function)(P1, P2, P3, P4)) { return new FunctionSlot4(function); } //! @class MethodSlot4 //! @brief A slot template for methods in a class of type T taking four arguments of type P1, P2, P3 and P4, //! and returning a value of type R. template class MethodSlot4 : public Slot4 { typedef R (T::*PMF)(P1, P2, P3, P4); PMF pmf; T *t; public: MethodSlot4(T *object, PMF function) : pmf(function), t(object) {} //!< Construct a new method slot for a class member function. //!< @param object - a pointer to an object of type T. //!< @param function - a class method with the signature R (T::*PMF)(P1, P2, P3, P4). virtual R call(P1 p1, P2 p2, P3 p3, P4 p4) const { return (t->*pmf)(p1, p2, p3, p4); } //!< Calls the class method connected to this slot passing it arguments p1, p2, p3 and p4. //!< @return a value of type R returned by the called method. }; //! Overloaded slot factory function. //! @param object - a reference to a pointer to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(P1, P2, P3, P4). //! @return a new slot passing four arguments of type P1, P2, P3 and P4, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot4* slot(T1* &object, R (T2::*function)(P1, P2, P3, P4)) { return new MethodSlot4(object, function); } //! Overloaded slot factory function. //! @param object - a reference to a const pointer to an object of type T1 (e.g. this). //! @param function - a class method with the signature R (T2::*function)(P1, P2, P3, P4). //! @return a new slot passing four arguments of type P1, P2, P3 and P4, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot4* slot(T1* const &object, R (T2::*function)(P1, P2, P3, P4)) { return new MethodSlot4(object, function); } //! Overloaded slot factory function. //! @param object - a reference to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(P1, P2, P3, P4). //! @return a new slot passing four arguments of type P1, P2, P3 and P4, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot4* slot(T1& object, R (T2::*function)(P1, P2, P3, P4)) { return new MethodSlot4(&object, function); } /* SignalSlot4 */ template class SignalSlot4 : public Slot4 { typedef R (*PF)(void*, P1, P2, P3, P4); PF pf; T *t; public: SignalSlot4(T *signal, PF function) : pf(function), t(signal) {} virtual R call(P1 p1, P2 p2, P3 p3, P4 p4) const { return (*pf)(t, p1, p2, p3, p4); } }; //! @class Slot5 //! @brief Base class template for slots passing five arguments of type P1, P2, P3, P4 and P5, //! and returning a value of type R. template class Slot5 : public Slot { protected: Slot5() {} public: virtual R call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const = 0; //!< Calls the signal handler connected to this slot. R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { return call(p1, p2, p3, p4, p5); } //!< Function operator; Calls call(). }; //! @class FunctionSlot5 //! @brief A slot template for static functions taking five arguments of type P1, P2, P3, P4 and P5, //! and returning a value of type R. template class FunctionSlot5 : public Slot5 { typedef R (*PF)(P1, P2, P3, P4, P5); PF pf; public: FunctionSlot5(PF function) : pf(function) {} //!< Construct a new function slot for a static function. //!< @param function - static function with the signature R (*PF)(P1, P2, P3, P4, P5). virtual R call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { return (*pf)(p1, p2, p3, p4, p5); } //!< Calls the function connected to this slot passing it arguments p1, p2, p3, p4 and p5. //!< @return a value of type R returned by the called function. }; //! Overloaded slot factory function. //! @param function - a static function with the signature R (*function)(P1, P2, P3, P4, P5). //! @return a new slot passing five arguments of type P1, P2, P3, P4 and P5, and returning a value of type R. //! //!
If the returned slot is connected to a signal it doesn't have to be //! unreferenced. The signal it's connected to will unreference the slot when //! it is destroyed. Otherwise the slot must be unreferenced by calling unref(). template inline Slot5* slot(R (*function)(P1, P2, P3, P4, P5)) { return new FunctionSlot5(function); } //! @class MethodSlot5 //! @brief A slot template for methods in a class of type T taking five arguments of type P1, P2, P3, P4 and P5, //! and returning a value of type R. template class MethodSlot5 : public Slot5 { typedef R (T::*PMF)(P1, P2, P3, P4, P5); PMF pmf; T *t; public: MethodSlot5(T *object, PMF function) : pmf(function), t(object) {} //!< Construct a new method slot for a class member function. //!< @param object - a pointer to an object of type T. //!< @param function - a class method with the signature R (T::*PMF)(P1, P2, P3, P4, P5). virtual R call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { return (t->*pmf)(p1, p2, p3, p4, p5); } //!< Calls the class method connected to this slot passing it arguments p1, p2, p3, p4 and p5. //!< @return a value of type R returned by the called method. }; //! Overloaded slot factory function. //! @param object - a reference to a pointer to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(P1, P2, P3, P4, P5). //! @return a new slot passing five arguments of type P1, P2, P3, P4 and P5, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot5* slot(T1* &object, R (T2::*function)(P1, P2, P3, P4, P5)) { return new MethodSlot5(object, function); } //! Overloaded slot factory function. //! @param object - a reference to a const pointer to an object of type T1 (e.g. this). //! @param function - a class method with the signature R (T2::*function)(P1, P2, P3, P4, P5). //! @return a new slot passing five arguments of type P1, P2, P3, P4 and P5, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot5* slot(T1* const &object, R (T2::*function)(P1, P2, P3, P4, P5)) { return new MethodSlot5(object, function); } //! Overloaded slot factory function. //! @param object - a reference to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(P1, P2, P3, P4, P5). //! @return a new slot passing five arguments of type P1, P2, P3, P4 and P5, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot5* slot(T1& object, R (T2::*function)(P1, P2, P3, P4, P5)) { return new MethodSlot5(&object, function); } /* SignalSlot5 */ template class SignalSlot5 : public Slot5 { typedef R (*PF)(void*, P1, P2, P3, P4, P5); PF pf; T *t; public: SignalSlot5(T *signal, PF function) : pf(function), t(signal) {} virtual R call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { return (*pf)(t, p1, p2, p3, p4, p5); } }; //! @class Slot6 //! @brief Base class template for slots passing six arguments of type P1, P2, P3, P4, P5 and P6, //! and returning a value of type R. template class Slot6 : public Slot { protected: Slot6() {} //!< Constructor. public: virtual R call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const = 0; //!< Calls the signal handler connected to this slot. R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const { return call(p1, p2, p3, p4, p5, p6); } //!< Function operator; Calls call(). }; //! @class FunctionSlot6 //! @brief A slot template for static functions taking six arguments of type P1, P2, P3, P4, P5 and P6, //! and returning a value of type R. template class FunctionSlot6 : public Slot6 { typedef R (*PF)(P1, P2, P3, P4, P5, P6); PF pf; public: FunctionSlot6(PF function) : pf(function) {} //!< Construct a new function slot for a static function. //!< @param function - static function with the signature R (*PF)(P1, P2, P3, P4, P5). virtual R call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const { return (*pf)(p1, p2, p3, p4, p5, p6); } //!< Calls the function connected to this slot passing it arguments p1, p2, p3, p4, p5 and p6. //!< @return a value of type R returned by the called function. }; //! Overloaded slot factory function. //! @param function - a static function with the signature R (*function)(P1, P2, P3, P4, P5, P6). //! @return a new slot passing six arguments of type P1, P2, P3, P4, P5 and P6, and returning a value of type R. //! //!
If the returned slot is connected to a signal it doesn't have to be //! unreferenced. The signal it's connected to will unreference the slot when //! it is destroyed. Otherwise the slot must be unreferenced by calling unref(). template inline Slot6* slot(R (*function)(P1, P2, P3, P4, P5, P6)) { return new FunctionSlot6(function); } //! @class MethodSlot6 //! @brief A slot template for methods in a class of type T taking six arguments of type P1, P2, P3, P4, P5 and P6, //! and returning a value of type R. template class MethodSlot6 : public Slot6 { typedef R (T::*PMF)(P1, P2, P3, P4, P5, P6); PMF pmf; T *t; public: MethodSlot6(T *object, PMF function) : pmf(function), t(object) {} //!< Construct a new method slot for a class member function. //!< @param object - a pointer to an object of type T. //!< @param function - a class method with the signature R (T::*PMF)(P1, P2, P3, P4, P5, P6). virtual R call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const { return (t->*pmf)(p1, p2, p3, p4, p5, p6); } //!< Calls the class method connected to this slot passing it arguments p1, p2, p3, p4, p5 and p6. //!< @return a value of type R returned by the called method. }; //! Overloaded slot factory function. //! @param object - a reference to a pointer to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(P1, P2, P3, P4, P5, P6). //! @return a new slot passing six arguments of type P1, P2, P3, P4, P5 and P6, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot6* slot(T1* &object, R (T2::*function)(P1, P2, P3, P4, P5, P6)) { return new MethodSlot6(object, function); } //! Overloaded slot factory function. //! @param object - a reference to a const pointer to an object of type T1 (e.g. this). //! @param function - a class method with the signature R (T2::*function)(P1, P2, P3, P4, P5, P6). //! @return a new slot passing six arguments of type P1, P2, P3, P4, P5 and P6, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot6* slot(T1* const &object, R (T2::*function)(P1, P2, P3, P4, P5, P6)) { return new MethodSlot6(object, function); } //! Overloaded slot factory function. //! @param object - a reference to an object of type T1. //! @param function - a class method with the signature R (T2::*function)(P1, P2, P3, P4, P5, P6). //! @return a new slot passing six arguments of type P1, P2, P3, P4, P5 and P6, and returning a value of type R. //! //!
T1 can be the same object type as T2. If the returned slot is connected //! to a signal it doesn't have to be unreferenced. The signal it's connected to //! will unreference the slot when it is destroyed. Otherwise the slot must be //! unreferenced by calling unref(). template inline Slot6* slot(T1& object, R (T2::*function)(P1, P2, P3, P4, P5, P6)) { return new MethodSlot6(&object, function); } /* SignalSlot6 */ template class SignalSlot6 : public Slot6 { typedef R (*PF)(void*, P1, P2, P3, P4, P5, P6); PF pf; T *t; public: SignalSlot6(T *signal, PF function) : pf(function), t(signal) {} virtual R call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const { return (*pf)(t, p1, p2, p3, p4, p5, p6); } }; //! @} /** @} */ } // namespace scim #endif //__SCIM_SLOT_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_slot.cpp0000644000175000017500000000236512422143415015434 0ustar tzhuantzhuan/* * Most code of this file are came from Inti project. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * Copyright (c) 2002 The Inti Development Team. * Copyright (c) 2000 Red Hat, Inc. * Copyright 1999, Karl Einar Nelson * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_slot.cpp,v 1.5 2005/01/10 08:30:54 suzhe Exp $ */ #define Uses_SCIM_SLOT #include "scim_private.h" #include "scim.h" namespace scim { Slot::Slot() { } Slot::~Slot() { } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_signals.h0000644000175000017500000006430112422143415015556 0ustar tzhuantzhuan/** * @file scim_signals.h * @brief C++ signal interface. * * Provides a set of signal class templates you can use to create signals * that can pass up to 6 arguments to signal handlers connected via the * slot interface (see scim_slot.h). The signal classes are named Signal0 * to Signal6, where 0 to 6 specifies the number of arguments that can be * passed to a slot. * * Most code of this file are came from Inti project. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * Copyright (c) 2002 The Inti Development Team. * Copyright (c) 2000 Red Hat, Inc. * Copyright 1999, Karl Einar Nelson * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_signals.h,v 1.12 2005/01/30 13:24:13 suzhe Exp $ */ #ifndef __SCIM_SIGNALS_H #define __SCIM_SIGNALS_H namespace scim { /** * @addtogroup SignalSlot * @{ */ class Signal; //! @class SlotNode //! @brief A node class for managing slots connected to scim::Signal's. class SlotNode : public Node { friend class Signal; SlotNode(Slot *slot); ~SlotNode(); bool is_blocked; public: bool blocked() const { return is_blocked; } //!< Returns true if the slot is blocked. virtual void block(); //!< Block signal emission to the slot until unblock is called. virtual void unblock(); //!< Unblock the slot so signal emmissions can be received. virtual void disconnect(); //!< Disconnect the slot. The slot will no longer receive signal emissions. }; // DefaultMarshal class (from marshal.h, libsigc++) template class DefaultMarshal { public: typedef R OutType; typedef R InType; private: OutType value_; public: DefaultMarshal() :value_() {} OutType& value() { return value_; } // Return true to stop emission. bool marshal(const InType & newval) { value_ = newval; return false; } }; // Marshal specialization template <> class DefaultMarshal { public: typedef bool OutType; typedef bool InType; private: OutType value_; public: DefaultMarshal() :value_(false) {} OutType& value() { return value_; } // Return true to stop emission. bool marshal(const InType & newval) { value_ = newval; return false; } }; //! @class Signal //! @brief Base class for the C++ signal interface. class Signal { Signal(const Signal&); Signal& operator=(const Signal&); protected: typedef std::vector< Pointer > ConnectionList; //!< ConnectionList type. ConnectionList connection_list; //!< A list of all the slots connected to the signal. public: Signal(); //!< Constructor. virtual ~Signal(); //!< Destructor. SlotNode* connect(Slot *slot); //!< Creates a new SlotNode for slot and adds it to the connection_list. }; //! @class Signal0 //! @brief A template for a signal passing no arguments and returning a value of type R. template > class Signal0 : public Signal { typedef Signal0 Self; static R callback(void *data) { Self *s = static_cast(data); return s->emit(); } public: typedef Slot0 SlotType; //!< Function signature for handlers connecting the signal. Connection connect(SlotType *slot) { return Signal::connect(slot); } //!< Connect a slot to the signal. //!< @param slot - a slot of type Slot0. //!< @return a connection object. //!< //!<
The returned connection object can be used alter or change the connection. SlotType* slot() { return new SignalSlot0(this, &callback); } //!< Returns a slot for this signal. //!< @return a new slot of type Slot0. //!< //!<
The returned slot can be passed to another signal allowing the //!< other signal to call this signal when it gets emitted. R emit() { Marshal m; ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot && m.marshal(slot->call())) break; } ++i; } return m.value(); } //!< Emit the signal. //!< @return the value returned by the signal handler. //!< //!<
Calls every slot connected to this signal, in order of connection. R operator()() { return emit(); } //!< Function operator; calls emit(). }; // Signal0 partially specialized for void return template class Signal0 : public Signal { typedef Signal0 Self; static void callback(void *data) { Self *s = static_cast(data); s->emit(); } public: typedef Slot0 SlotType; Connection connect(SlotType *slot) { return Signal::connect(slot); } SlotType* slot() { return new SignalSlot0(this, &callback); } void emit() { ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot) slot->call(); } ++i; } } void operator()() { emit(); } }; //! @class Signal1 //! @brief A template for a signal passing one argument of type P1 and returning a value of type R. template > class Signal1 : public Signal { typedef Signal1 Self; static R callback(void *data, P1 p1) { Self *s = static_cast(data); return s->emit(p1); } public: typedef Slot1 SlotType; //!< Function signature for handlers connecting to the signal. Connection connect(SlotType *slot) { return Signal::connect(slot); } //!< Connect a slot to the signal. //!< @param slot - a slot of type Slot1. //!< @return a connection object. //!< //!<
The returned connection object can be used alter or change the connection. SlotType* slot() { return new SignalSlot1(this, &callback); } //!< Returns a slot for this signal. //!< @return a new slot of type Slot1. //!< //!<
The returned slot can be passed to another signal allowing the //!< other signal to call this signal when it gets emitted. R emit(P1 p1) { Marshal m; ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot && m.marshal(slot->call(p1))) break; } ++i; } return m.value(); } //!< Emit the signal. //!< @param p1 - passes p1 to the signal handler. //!< @return the value returned by the signal handler. //!< //!<
Calls every slot connected to this signal, in order of connection. R operator()(P1 p1) { return emit(p1); } //!< Function operator; calls emit(). }; // Signal1 partially specialized for void return template class Signal1 : public Signal { typedef Signal1 Self; static void callback(void *data, P1 p1) { Self *s = static_cast(data); s->emit(p1); } public: typedef Slot1 SlotType; Connection connect(SlotType *slot) { return Signal::connect(slot); } SlotType* slot() { return new SignalSlot1(this, &callback); } void emit(P1 p1) { ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot) slot->call(p1); } ++i; } } void operator()(P1 p1) { emit(p1); } }; //! @class Signal2 //! @brief A template for a signal passing two arguments of type P1 and P2, //! and returning a value of type R. template > class Signal2 : public Signal { typedef Signal2 Self; static R callback(void *data, P1 p1, P2 p2) { Self *s = static_cast(data); return s->emit(p1, p2); } public: typedef Slot2 SlotType; //!< Function signature for handlers connecting to the signal. Connection connect(SlotType *slot) { return Signal::connect(slot); } //!< Connect a slot to the signal. //!< @param slot - a slot of type Slot2. //!< @return a connection object. //!< //!<
The returned connection object can be used alter or change the connection. SlotType* slot() { return new SignalSlot2(this, &callback); } //!< Returns a slot for this signal. //!< @return a new slot of type Slot2. //!< //!<
The returned slot can be passed to another signal allowing the //!< other signal to call this signal when it gets emitted. R emit(P1 p1, P2 p2) { Marshal m; ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot && m.marshal(slot->call(p1, p2))) break; } ++i; } return m.value(); } //!< Emit the signal. //!< @param p1 - passes p1 to the signal handler. //!< @param p2 - passes p2 to the signal handler. //!< @return the value returned by the signal handler. //!< //!<
Calls every slot connected to this signal, in order of connection. R operator()(P1 p1, P2 p2) { return emit(p1, p2); } //!< Function operator; calls emit(). }; // Signal2 partially specialized for void return template class Signal2 : public Signal { typedef Signal2 Self; static void callback(void *data, P1 p1, P2 p2) { Self *s = static_cast(data); s->emit(p1, p2); } public: typedef Slot2 SlotType; Connection connect(SlotType *slot) { return Signal::connect(slot); } SlotType* slot() { return new SignalSlot2(this, &callback); } void emit(P1 p1, P2 p2) { ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot) slot->call(p1, p2); } ++i; } } void operator()(P1 p1, P2 p2) { emit(p1, p2); } }; //! @class Signal3 //! @brief A template for a signal passing three arguments of type P1, P2 and P3, //! and returning a value of type R. template > class Signal3 : public Signal { typedef Signal3 Self; static R callback(void *data, P1 p1, P2 p2, P3 p3) { Self *s = static_cast(data); return s->emit(p1, p2, p3); } public: typedef Slot3 SlotType; //!< Function signature for handlers connecting to the signal. Connection connect(SlotType *slot) { return Signal::connect(slot); } //!< Connect a slot to the signal. //!< @param slot - a slot of type Slot3. //!< @return a connection object. //!< //!<
The returned connection object can be used alter or change the connection. SlotType* slot() { return new SignalSlot3(this, &callback); } //!< Returns a slot for this signal. //!< @return a new slot of type Slot3. //!< //!<
The returned slot can be passed to another signal allowing the //!< other signal to call this signal when it gets emitted. R emit(P1 p1, P2 p2, P3 p3) { Marshal m; ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot && m.marshal(slot->call(p1, p2, p3))) break; } ++i; } return m.value(); } //!< Emit the signal. //!< @param p1 - passes p1 to the signal handler. //!< @param p2 - passes p2 to the signal handler. //!< @param p3 - passes p3 to the signal handler. //!< @return the value returned by the signal handler. //!< //!<
Calls every slot connected to this signal, in order of connection. R operator()(P1 p1, P2 p2, P3 p3) { return emit(p1, p2, p3); } //!< Function operator; calls emit(). }; // Signal3 partially specialized for void return template class Signal3 : public Signal { typedef Signal3 Self; static void callback(void *data, P1 p1, P2 p2, P3 p3) { Self *s = static_cast(data); s->emit(p1, p2, p3); } public: typedef Slot3 SlotType; Connection connect(SlotType *slot) { return Signal::connect(slot); } SlotType* slot() { return new SignalSlot3(this, &callback); } void emit(P1 p1, P2 p2, P3 p3) { ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot) slot->call(p1, p2, p3); } ++i; } } void operator()(P1 p1, P2 p2, P3 p3) { emit(p1, p2, p3); } }; //! @class Signal4 //! @brief A template for a signal passing four arguments of type P1, P2, P3 and P4, //! and returning a value of type R. template > class Signal4 : public Signal { typedef Signal4 Self; static R callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4) { Self *s = static_cast(data); return s->emit(p1, p2, p3, p4); } public: typedef Slot4 SlotType; //!< Function signature for handlers connecting to the signal. Connection connect(SlotType *slot) { return Signal::connect(slot); } //!< Connect a slot to the signal. //!< @param slot - a slot of type Slot4. //!< @return a connection object. //!< //!<
The returned connection object can be used alter or change the connection. SlotType* slot() { return new SignalSlot4(this, &callback); } //!< Returns a slot for this signal. //!< @return a new slot of type Slot4. //!< //!<
The returned slot can be passed to another signal allowing the //!< other signal to call this signal when it gets emitted. R emit(P1 p1, P2 p2, P3 p3, P4 p4) { Marshal m; ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot && m.marshal(slot->call(p1, p2, p3, p4))) break; } ++i; } return m.value(); } //!< Emit the signal. //!< @param p1 - passes p1 to the signal handler. //!< @param p2 - passes p2 to the signal handler. //!< @param p3 - passes p3 to the signal handler. //!< @param p4 - passes p4 to the signal handler. //!< @return the value returned by the signal handler. //!< //!<
Calls every slot connected to this signal, in order of connection. R operator()(P1 p1, P2 p2, P3 p3, P4 p4) { return emit(p1, p2, p3, p4); } //!< Function operator; calls emit(). }; // Signal4 partially specialized for void return template class Signal4 : public Signal { typedef Signal4 Self; static void callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4) { Self *s = static_cast(data); s->emit(p1, p2, p3, p4); } public: typedef Slot4 SlotType; Connection connect(SlotType *slot) { return Signal::connect(slot); } SlotType* slot() { return new SignalSlot4(this, &callback); } void emit(P1 p1, P2 p2, P3 p3, P4 p4) { ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot) slot->call(p1, p2, p3, p4); } ++i; } } void operator()(P1 p1, P2 p2, P3 p3, P4 p4) { emit(p1, p2, p3, p4); } }; //! @class Signal5 //! @brief A template for a signal passing five arguments of type P1, P2, P3, P4 and P5, //! and returning a value of type R. template > class Signal5 : public Signal { typedef Signal5 Self; static R callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { Self *s = static_cast(data); return s->emit(p1, p2, p3, p4, p5); } public: typedef Slot5 SlotType; //!< Function signature for handlers connecting to the signal. Connection connect(SlotType *slot) { return Signal::connect(slot); } //!< Connect a slot to the signal. //!< @param slot - a slot of type Slot5. //!< @return a connection object. //!< //!<
The returned connection object can be used alter or change the connection. SlotType* slot() { return new SignalSlot5(this, &callback); } //!< Returns a slot for this signal. //!< @return a new slot of type Slot5. //!< //!<
The returned slot can be passed to another signal allowing the //!< other signal to call this signal when it gets emitted. R emit(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { Marshal m; ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot && m.marshal(slot->call(p1, p2, p3, p4, p5))) break; } ++i; } return m.value(); } //!< Emit the signal. //!< @param p1 - passes p1 to the signal handler. //!< @param p2 - passes p2 to the signal handler. //!< @param p3 - passes p3 to the signal handler. //!< @param p4 - passes p4 to the signal handler. //!< @param p5 - passes p5 to the signal handler. //!< @return the value returned by the signal handler. //!< //!<
Calls every slot connected to this signal, in order of connection. R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { return emit(p1, p2, p3, p4, p5); } //!< Function operator; calls emit(). }; // Signal5 partially specialized for void return template class Signal5 : public Signal { typedef Signal5 Self; static void callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { Self *s = static_cast(data); s->emit(p1, p2, p3, p4, p5); } public: typedef Slot5 SlotType; Connection connect(SlotType *slot) { return Signal::connect(slot); } SlotType* slot() { return new SignalSlot5(this, &callback); } void emit(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot) slot->call(p1, p2, p3, p4, p5); } ++i; } } void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { emit(p1, p2, p3, p4, p5); } }; //! @class Signal6 //! @brief A template for a signal passing six arguments of type P1, P2, P3, P4, P5 and P6, //! and returning a value of type R. template > class Signal6 : public Signal { typedef Signal6 Self; static R callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) { Self *s = static_cast(data); return s->emit(p1, p2, p3, p4, p5, p6); } public: typedef Slot6 SlotType; //!< Function signature for handlers connecting to the signal. Connection connect(SlotType *slot) { return Signal::connect(slot); } //!< Connect a slot to the signal. //!< @param slot - a slot of type Slot6. //!< @return a connection object. //!< //!<
The returned connection object can be used alter or change the connection. SlotType* slot() { return new SignalSlot6(this, &callback); } //!< Returns a slot for this signal. //!< @return a new slot of type Slot6. //!< //!<
The returned slot can be passed to another signal allowing the //!< other signal to call this signal when it gets emitted. R emit(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) { Marshal m; ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot && m.marshal(slot->call(p1, p2, p3, p4, p5, p6))) break; } ++i; } return m.value(); } //!< Emit the signal. //!< @param p1 - passes p1 to the signal handler. //!< @param p2 - passes p2 to the signal handler. //!< @param p3 - passes p3 to the signal handler. //!< @param p4 - passes p4 to the signal handler. //!< @param p5 - passes p5 to the signal handler. //!< @param p6 - passes p6 to the signal handler. //!< @return the value returned by the signal handler. //!< //!<
Calls every slot connected to this signal, in order of connection. R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) { return emit(p1, p2, p3, p4, p5, p6); } //!< Function operator; calls emit(). }; /* Signal6 partially specialized for void return */ template class Signal6 : public Signal { typedef Signal6 Self; static void callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) { Self *s = static_cast(data); s->emit(p1, p2, p3, p4, p5, p6); } public: typedef Slot6 SlotType; Connection connect(SlotType *slot) { return Signal::connect(slot); } SlotType* slot() { return new SignalSlot6(this, &callback); } void emit(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) { ConnectionList::iterator i = connection_list.begin(); while (i != connection_list.end()) { if (!(*i)->blocked()) { SlotType *slot = dynamic_cast((*i)->slot()); if (slot) slot->call(p1, p2, p3, p4, p5, p6); } ++i; } } void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) { emit(p1, p2, p3, p4, p5, p6); } }; /** @} */ } // namespace scim #endif //__SCIM_SIGNALS_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_signals.cpp0000644000175000017500000000345112422143415016110 0ustar tzhuantzhuan/* * Most code of this file are came from Inti project. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * Copyright (c) 2002 The Inti Development Team. * Copyright (c) 2000 Red Hat, Inc. * Copyright 1999, Karl Einar Nelson * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_signals.cpp,v 1.7 2005/01/10 08:30:54 suzhe Exp $ */ #define Uses_SCIM_OBJECT #define Uses_SCIM_SIGNALS #define Uses_SCIM_SLOT #define Uses_SCIM_CONNECTION #include "scim_private.h" #include "scim.h" namespace scim { /* SlotNode */ SlotNode::SlotNode(Slot *slot) : Node(slot), is_blocked(false) { } SlotNode::~SlotNode() { } void SlotNode::block() { is_blocked = true; } void SlotNode::unblock() { is_blocked = false; } void SlotNode::disconnect() { Node::disconnect (); is_blocked = true; } /* Signal; */ Signal::Signal() { } Signal::~Signal() { } SlotNode* Signal::connect(Slot *slot) { SlotNode *node = new SlotNode(slot); connection_list.push_back(node); return node; } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_property.h0000644000175000017500000001452112422143415016001 0ustar tzhuantzhuan/** @file scim_properties.h * @brief Definition of scim::Property and scim::PropertyList * * Provide class scim::Property to hold of a property * of a IMEngineInstance or a Panel GUI client. */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_property.h,v 1.7 2005/01/10 08:30:54 suzhe Exp $ */ #ifndef __SCIM_PROPERTY_H #define __SCIM_PROPERTY_H namespace scim { #define SCIM_PROPERTY_ACTIVE 0x01 #define SCIM_PROPERTY_VISIBLE 0x02 /** * @addtogroup Accessories * @{ */ /** * @brief Class to hold a property of a IMEngineInstance object or a Panel GUI client. * * A property has four elements: * - key * An unique identify key of the property, for example: * - /TableInstance * - /TableInstance/FullWidthLetter * In this case, the second property will be a leaf (maybe a submenu item) of the first property. * - label * A label of the property which should be displayed. * - icon * An icon file of the property which should be displayed along with label. * - tip * A string to descript what the property means. * * With path like keys, the properties can form a cascade structure, which may be displayed * like a cascading menu. * * But only the leaf properties can act as trigger commands * and give feedback to IMEngineInstance. * * All strings should be encoded into UTF-8. */ class Property { String m_key; String m_label; String m_icon; String m_tip; uint16 m_state; public: /** * @brief Default constructor */ Property () : m_state (0) { } /** * @brief Constructor */ Property (const String &key, const String &label, const String &icon = String (""), const String &tip = String ("")) : m_key (key), m_label (label), m_icon (icon), m_tip (tip), m_state (SCIM_PROPERTY_VISIBLE | SCIM_PROPERTY_ACTIVE) { } /** * @brief Test if this property is valid. * * @return true if this property is valid. */ bool valid () const { return m_key.length (); } /** * @brief If this property is visible. * * @return true if this property is visible. */ bool visible () const { return m_state & SCIM_PROPERTY_VISIBLE; } /** * @brief If this property is active. * * A active property can be clicked by users. * * @return true if this property is active. */ bool active () const { return m_state & SCIM_PROPERTY_ACTIVE; } /** * @brief Get the key of this property. */ const String & get_key () const { return m_key; } /** * @brief Get the label of this property. */ const String & get_label () const { return m_label; } /** * @brief Get the icon file of this property. */ const String & get_icon () const { return m_icon; } /** * @brief Get the tip of this property. */ const String & get_tip () const { return m_tip; } /** * @brief Set a new key for this property. */ void set_key (const String & key) { m_key = key; } /** * @brief Set a new label for this property. */ void set_label (const String & label) { m_label = label; } /** * @brief Set a new icon file for this property. */ void set_icon (const String & icon) { m_icon = icon; } /** * @brief Set a new tip for this property. */ void set_tip (const String & tip) { m_tip = tip; } /** * @brief Set if this property is active. * * @param active If this property is active. */ void set_active (bool active) { if (active) m_state |= SCIM_PROPERTY_ACTIVE; else m_state &= (~ SCIM_PROPERTY_ACTIVE); } void show (bool visible = true) { if (visible) m_state |= SCIM_PROPERTY_VISIBLE; else m_state &= ~SCIM_PROPERTY_VISIBLE; } void hide (bool hidden = true) { show (!hidden); } /** * @brief Test if this property is a leaf of another one. * * @return true if this property is a leaf of the node. */ bool is_a_leaf_of (const Property &node) const { if (m_key.length () > node.m_key.length () && m_key.substr (0, node.m_key.length ()) == node.m_key && m_key [node.m_key.length ()] == '/') return true; return false; } }; inline bool operator < (const Property &lhs, const Property &rhs) { return lhs.get_key () < rhs.get_key (); } inline bool operator < (const Property &lhs, const String &rhs) { return lhs.get_key () < rhs; } inline bool operator < (const String &lhs, const Property &rhs) { return lhs < rhs.get_key (); } inline bool operator == (const Property &lhs, const Property &rhs) { return lhs.get_key () == rhs.get_key (); } inline bool operator == (const Property &lhs, const String &rhs) { return lhs.get_key () == rhs; } inline bool operator == (const String &lhs, const Property &rhs) { return lhs == rhs.get_key (); } inline bool operator != (const Property &lhs, const Property &rhs) { return lhs.get_key () != rhs.get_key (); } inline bool operator != (const Property &lhs, const String &rhs) { return lhs.get_key () != rhs; } inline bool operator != (const String &lhs, const Property &rhs) { return lhs != rhs.get_key (); } /** * @typedef std::vector PropertyList; * @brief The container to store a set of Properties. * * You should use the STL container methods to manipulate its objects. */ typedef std::vector PropertyList; /** @} */ } // namespace scim #endif //__SCIM_PROPERTY_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_private.h0000644000175000017500000000301312422143415015561 0ustar tzhuantzhuan/** @file scim_private.h * private used headers are included in this header. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_private.h,v 1.11 2005/01/10 08:30:54 suzhe Exp $ */ #ifndef __SCIM_PRIVATE_H #define __SCIM_PRIVATE_H // Include scim configuration header #ifdef HAVE_CONFIG_H #include #endif #if defined(HAVE_LIBINTL_H) && defined(ENABLE_NLS) #include #define _(String) dgettext(GETTEXT_PACKAGE,String) #define N_(String) (String) #else #define _(String) (String) #define N_(String) (String) #define bindtextdomain(Package,Directory) #define textdomain(domain) #define bind_textdomain_codeset(domain,codeset) #endif #endif //__SCIM_PRIVATE_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_private.cpp0000644000175000017500000000430412422143415016120 0ustar tzhuantzhuan/** @file scim_private.cpp * @brief Do some library initialize work here. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_private.cpp,v 1.6.4.1 2007/03/11 12:35:10 suzhe Exp $ * */ #define Uses_C_STRING #define Uses_C_STRING #include "scim_private.h" #include "scim.h" #ifdef HAVE_LOCALE_H #include #endif #include #ifdef TIME_WITH_SYS_TIME #include #endif #include namespace scim { class TextdomainInitializer { public: TextdomainInitializer () { #ifdef HAVE_SETLOCALE char *locale = setlocale (LC_MESSAGES, 0); if (!locale || strcmp (locale, "C") == 0 || strcmp (locale, "POSIX") == 0) setlocale (LC_MESSAGES, ""); locale = setlocale (LC_CTYPE, 0); if (!locale || strcmp (locale, "C") == 0 || strcmp (locale, "POSIX") == 0) setlocale (LC_CTYPE, ""); #endif bindtextdomain (GETTEXT_PACKAGE, SCIM_LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); } }; class RandSeedInitializer { public: RandSeedInitializer () { #ifdef HAVE_GETTIMEOFDAY timeval cur_time; if (gettimeofday (&cur_time, 0) == 0) { srand (cur_time.tv_sec); } #else srand (time (0)); #endif } }; static TextdomainInitializer __textdomain_initializer; static RandSeedInitializer __rand_seed_initializer; } // namespace scim /* vi:ts=4:ai:nowrap:expandtab */ scim-1.4.15/src/scim_pointer.h0000644000175000017500000002010412422143415015567 0ustar tzhuantzhuan/** @file scim_pointer.h * @brief Smart pointer class interface. * * Provides a reference-counted-object aware smart pointer class. * * Most code of this file are came from Inti project. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * Copyright (c) 2002 The Inti Development Team. * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_pointer.h,v 1.11 2005/01/10 08:30:54 suzhe Exp $ */ #ifndef __SCIM_POINTER_H #define __SCIM_POINTER_H namespace scim { /** * @addtogroup Accessories * @{ */ /** * @class Pointer * @brief Smart pointer template class. * * Pointer is a standard auto_ptr-like smart pointer for managing heap * allocated reference counted objects. T must be a class derived from * scim::ReferencedObject. */ template class Pointer { T *t; void set(T *object) { if (object) { if (!object->is_referenced()) object->ref(); object->set_referenced(false); } if (t) t->unref(); t = object; } template friend bool operator == (const Pointer& t1, const Pointer& t2); public: //! @name Constructors //! @{ Pointer(T *object = 0) : t(0) { set(object); } //!< Construct a new smart pointer. //!< @param object - a pointer to an object allocated on the heap. //!< //!<
Initialize a new Pointer with any dumb pointer. Pointer(Pointer& src) : t(0) { set(src.get()); } //!< Copy constructor. //!< @param src - a reference to a smart pointer. //!< //!<
Initialize a new Pointer with any compatible Pointer. template Pointer(const Pointer& src) : t(0) { set(src.get()); } //!< Copy constructor. //!< @param src - a Pointer to type T1 where T1 is derived from T. //!< //!<
Initialize a new Pointer of type T from a Pointer of type T1, //!< only if T1 is derived from T. ~Pointer() { set(0); } //!< Destructor. //!< Decreases the object reference count. Pointer& operator=(T *object) { set(object); return *this; } //!< Assignment operator. //!< @param object - a pointer to an object allocated on the heap. //!< //!<
Releases the current dumb pointer, if any and assigns object //!< to this Pointer, incrementing its reference count. Pointer& operator=(const Pointer& src) { set(src.get()); return *this; } //!< Assignment operator. //!< @param src - a reference to a smart pointer. //!< //!<
Releases the current dumb pointer, if any and assigns the dumb pointer //!< managed by src to this Pointer, incrementing its reference count. template Pointer& operator=(const Pointer& src) { set(src.get()); return *this; } //!< Assignment operator. //!< @param src - a Pointer to type T1 where T1 is derived from T. //!< //!<
Releases the current dumb pointer, if any and assigns the dumb pointer //!< of type T1 managed by src to this Pointer as a dumb pointer of type T, //!< only if T1 is derived from T. The reference count is incremented. //! @} //! @name Accessors //! @{ T& operator*() const { return *get(); } //!< Dereference operator. //!< @return a reference to the object pointed to by the dumb pointer. T* operator->() const { return get(); } //!< Member selection operator. //!< @return the dumb pointer. operator T*() const { return get(); } //!< Conversion operator. //!< Converts a Pointer into its dumb pointer: the C pointer it manages. //!< Normally it is considered pretty evil to mix smart and regular pointers. //!< In scim you can safely if you just follow the reference counting rules //!< for each of them. You can never call delete on Pointer either because //!< you don't call delete on scim objects; you call unref(). T* get() const { return t; } //!< Returns the dumb pointer; the regular C pointer managed by the Pointer. //!< @return the dumb pointer. bool null() const { return t == 0; } //!< Returns true if the Pointer has no dumb pointer. //! @} //! @name Methods //! @{ T* release() { T *tmp = t; if (tmp) tmp->ref(); set(0); return tmp; } //!< Releases the dumb pointer. //!< @return the regular C pointer previously managed by the Pointer. //!< //!<
Before releasing the dumb pointer its reference count is incremented //!< to prevent it being destroyed. You must call unref() on the pointer to //!< prevent a memory leak. void reset(T *object = 0) { set(object); } //!< Sets a new dumb pointer for the Pointer to manage. //!< @param object - the new dumb pointer. //!< //!<
Releases the current dumb pointer, if any, and assigns object //!< to the Pointer, incrementing its reference count. //! @} }; //! @name Equality operators //! @{ template inline bool operator == (const Pointer& t1, const Pointer& t2) { return t1.t == t2.t; } //!< Compares two Pointers. //!< @return true if both Pointers manage to same dumb pointer. template inline bool operator != (const Pointer& t1, const Pointer& t2) { return !(t1 == t2); } //!< Compares two Pointers. //!< @return true if both Pointers manage a different dumb pointer. //! @} //! @name C++-style casting functions //! @{ template inline Pointer cast_const(const Pointer& from) { return Pointer(from ? const_cast(from.get()) : 0); } //!< Removes the const qualifier from a managed const dumb pointer. //!< @param from - a Pointer that manages a const dumb pointer. //!< @return a new Pointer that manages the non-const dumb pointer. //!< //!<
Calls const_cast on the dumb pointer and returns the non-const //!< pointer as a new Pointer. template inline Pointer cast_dynamic(const Pointer& from) { return Pointer(dynamic_cast(from.get())); } //!< Casts a managed polymophic dumb pointer down or across its inheritance heirarchy. //!< @param from - a Pointer managing a polymophic dumb pointer of type From. //!< @return a new Pointer managing the dumb pointer as a base or sibling pointer of type To. //!< //!<
Calls dynmaic_cast to safely cast a managed polymophic dumb pointer //!< of type From to a base, derived or sibling class pointer of type To. template inline Pointer cast_static(const Pointer& from) { return Pointer(from ? static_cast(from.get()) : 0); } //!< Casts a managed dumb pointer to a pointer to a related type. //!< @param from - a Pointer managing a dumb pointer of type From. //!< @return a new Pointer managing the dumb pointer as a pointer of type To. //!< //!<
Calls static_cast to cast a dumb pointer of type From to a //!< pointer of type To. //! @} /** @} */ } // namespace scim #endif //__SCIM_POINTER_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_panel_common.h0000644000175000017500000000357112422143415016567 0ustar tzhuantzhuan/** * @file scim_panel_common.h * @brief Defines some structures and types which are used by both scim::PanelAgent and scim::PanelClient. */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_panel_common.h,v 1.4 2005/05/13 04:21:29 suzhe Exp $ */ #ifndef __SCIM_PANEL_COMMON_H #define __SCIM_PANEL_COMMON_H namespace scim { /** * @addtogroup Panel * The accessory classes to help develop Panel daemons and FrontEnds * which need to communicate with Panel daemons. * @{ */ class PanelError: public Exception { public: PanelError (const String& what_arg) : Exception (String("scim::Panel: ") + what_arg) { } }; /** * @brief Structure to hold factory information. It's used by PanelAgent and PanelClient classes. */ struct PanelFactoryInfo { String uuid; String name; String lang; String icon; PanelFactoryInfo () { } PanelFactoryInfo (const String &u, const String &n, const String &l, const String &i) : uuid (u), name (n), lang (l), icon (i) { } }; /** @} */ } // namespace scim #endif //__SCIM_PANEL_COMMON_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_panel_client.h0000644000175000017500000002564012422143415016556 0ustar tzhuantzhuan/** * @file scim_panel_client.h * @brief Defines scim::PanelClient and it's related types. * * scim::PanelClient is a class used to connect with a Panel daemon. * It acts like a Socket Client and handles all socket communication * issues. */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_panel_client.h,v 1.4 2005/06/26 16:35:33 suzhe Exp $ */ #ifndef __SCIM_PANEL_CLIENT_H #define __SCIM_PANEL_CLIENT_H #include namespace scim { /** * @addtogroup Panel * @{ */ typedef Slot1 PanelClientSlotVoid; typedef Slot2 PanelClientSlotInt; typedef Slot2 PanelClientSlotString; typedef Slot2 PanelClientSlotWideString; typedef Slot4 PanelClientSlotStringStringTransaction; typedef Slot2 PanelClientSlotKeyEvent; /** * @brief PanelClient is used by FrontEnd to communicate with Panel daemon. * * All socket communication between FrontEnd and Panel is handled by this class. * FrontEnd may just register some slots to the corresponding signals to handle * the events sent from Panel. */ class PanelClient { class PanelClientImpl; PanelClientImpl *m_impl; PanelClient (const PanelClient &); const PanelClient & operator = (const PanelClient &); public: PanelClient (); ~PanelClient (); /** * @brief Open socket connection to the Panel. * * FrontEnd and Panel communicate with each other via the Socket created by Panel. * * FrontEnd can select/poll on the connection id returned by this method to see * if there are any data available to be read. If any data are available, * PanelClient::filter_event() should be called to process the data. * * If PanelClient::filter_event() returns false, then it means that the connection * is broken and should be re-established by calling PanelClient::close_connection() * and PanelClient::open_connection() again. * * This method would try to launch the panel daemon and make connection again, * if the connection could not be established successfully. * So this method should always success, unless the panel could not be started on * the certain display. * * @param config The config module name which should be used by launching the panel daemon. * @param display The display name which the panel daemon should run on. * @return The id of the socket connection, -1 means connection is failed. */ int open_connection (const String &config, const String &display); /** * @brief Close the connection to Panel. */ void close_connection (); /** * @brief Return the connection id, which was returned by PanelClient::open_connection(). */ int get_connection_number () const; /** * @brief Return whether this PanelClient has been connected to a Panel. */ bool is_connected () const; /** * @brief Check if there are any events available to be processed. * * If it returns true then FrontEnd should call * PanelClient::filter_event() to process them. * * @return true if there are any events available. */ bool has_pending_event () const; /** * @brief Filter the events sent from Panel daemon. * * Corresponding signal will be emitted in this method. * * @return false if the connection is broken, otherwise return true. */ bool filter_event (); /** * @brief Prepare the send transation for an IC. * * This method should be called before any events would be sent to Panel. * * @param icid The id of the IC which has events to be sent to Panel. * @return true if the preparation is ok. */ bool prepare (int icid); /** * @brief Send the transaction to Panel. * @return true if sent successfully. */ bool send (); public: /** * @name Action methods to send events to Panel. * @{ */ void turn_on (int icid); void turn_off (int icid); void update_screen (int icid, int screen); void show_help (int icid, const String &help); void show_factory_menu (int icid, const std::vector &menu); void focus_in (int icid, const String &uuid); void focus_out (int icid); void update_factory_info (int icid, const PanelFactoryInfo &info); void update_spot_location (int icid, int x, int y); void show_preedit_string (int icid); void show_aux_string (int icid); void show_lookup_table (int icid); void hide_preedit_string (int icid); void hide_aux_string (int icid); void hide_lookup_table (int icid); void update_preedit_string (int icid, const WideString &str, const AttributeList &attrs); void update_preedit_caret (int icid, int caret); void update_aux_string (int icid, const WideString &str, const AttributeList &attrs); void update_lookup_table (int icid, const LookupTable &table); void register_properties (int icid, const PropertyList &properties); void update_property (int icid, const Property &property); void start_helper (int icid, const String &helper_uuid); void stop_helper (int icid, const String &helper_uuid); void send_helper_event (int icid, const String &helper_uuid, const Transaction &trans); void register_input_context (int icid, const String &uuid); void remove_input_context (int icid); /** @} */ public: /** * @name Signal connection functions. * * These functions are used by FrontEnds to connect their corresponding slots to * this PanelClient's signals. * * The first parameter of each slot method is always "int context", which is the * id of the input method context. * * @{ */ /** * @brief Signal: reload configuration. * * slot prototype: void reload_config (int context); * * The context parameter is useless here. */ Connection signal_connect_reload_config (PanelClientSlotVoid *slot); /** * @brief Signal: exit the FrontEnd * * slot prototype: void exit (int context); * * The context parameter is useless here. */ Connection signal_connect_exit (PanelClientSlotVoid *slot); /** * @brief Signal: update lookup table page size * * slot prototype: void update_lookup_table_page_size (int context, int page_size); */ Connection signal_connect_update_lookup_table_page_size (PanelClientSlotInt *slot); /** * @brief Signal: lookup table page up * * slot prototype: void lookup_table_page_up (int context); */ Connection signal_connect_lookup_table_page_up (PanelClientSlotVoid *slot); /** * @brief Signal: lookup table page down * * slot prototype: void lookup_table_page_down (int context); */ Connection signal_connect_lookup_table_page_down (PanelClientSlotVoid *slot); /** * @brief Signal: trigger property * * slot prototype: void trigger_property (int context, const String &property); */ Connection signal_connect_trigger_property (PanelClientSlotString *slot); /** * @brief Signal: process helper event * * slot prototype: void process_helper_event (int context, const String &target_uuid, const String &helper_uuid, const Transaction &trans); * * - target_uuid is UUID of the IMEngineInstance object which should handle the events. * - helper_uuid is UUID of the Helper which sent the events. * - trans contains the events. */ Connection signal_connect_process_helper_event (PanelClientSlotStringStringTransaction *slot); /** * @brief Signal: move preedit caret * * slot prototype: void move_preedit_caret (int context, int caret_pos); */ Connection signal_connect_move_preedit_caret (PanelClientSlotInt *slot); /** * @brief Signal: select candidate * * slot prototype: void select_candidate (int context, int cand_index); */ Connection signal_connect_select_candidate (PanelClientSlotInt *slot); /** * @brief Signal: process key event * * slot prototype: void process_key_event (int context, const KeyEvent &key); */ Connection signal_connect_process_key_event (PanelClientSlotKeyEvent *slot); /** * @brief Signal: commit string * * slot prototype: void commit_string (int context, const WideString &wstr); */ Connection signal_connect_commit_string (PanelClientSlotWideString *slot); /** * @brief Signal: forward key event * * slot prototype: void forward_key_event (int context, const KeyEvent &key); */ Connection signal_connect_forward_key_event (PanelClientSlotKeyEvent *slot); /** * @brief Signal: request help * * slot prototype: void request_help (int context); */ Connection signal_connect_request_help (PanelClientSlotVoid *slot); /** * @brief Signal: request factory menu * * slot prototype: void request_factory_menu (int context); */ Connection signal_connect_request_factory_menu (PanelClientSlotVoid *slot); /** * @brief Signal: change factory * * slot prototype: void change_factory (int context, const String &uuid); */ Connection signal_connect_change_factory (PanelClientSlotString *slot); /** @} */ }; /** @} */ } // namespace scim #endif //__SCIM_PANEL_CLIENT_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_panel_client.cpp0000644000175000017500000006523712422143415017117 0ustar tzhuantzhuan/** @file scim_panel_client.cpp * @brief Implementation of class PanelClient. */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_panel_client.cpp,v 1.6 2005/06/26 16:35:33 suzhe Exp $ * */ #define Uses_SCIM_TRANSACTION #define Uses_SCIM_TRANS_COMMANDS #define Uses_SCIM_PANEL_CLIENT #define Uses_SCIM_SOCKET #define Uses_SCIM_EVENT #include "scim_private.h" #include "scim.h" namespace scim { typedef Signal1 PanelClientSignalVoid; typedef Signal2 PanelClientSignalInt; typedef Signal2 PanelClientSignalString; typedef Signal2 PanelClientSignalWideString; typedef Signal4 PanelClientSignalStringStringTransaction; typedef Signal2 PanelClientSignalKeyEvent; class PanelClient::PanelClientImpl { SocketClient m_socket; int m_socket_timeout; uint32 m_socket_magic_key; Transaction m_send_trans; int m_current_icid; int m_send_refcount; PanelClientSignalVoid m_signal_reload_config; PanelClientSignalVoid m_signal_exit; PanelClientSignalInt m_signal_update_lookup_table_page_size; PanelClientSignalVoid m_signal_lookup_table_page_up; PanelClientSignalVoid m_signal_lookup_table_page_down; PanelClientSignalString m_signal_trigger_property; PanelClientSignalStringStringTransaction m_signal_process_helper_event; PanelClientSignalInt m_signal_move_preedit_caret; PanelClientSignalInt m_signal_select_candidate; PanelClientSignalKeyEvent m_signal_process_key_event; PanelClientSignalWideString m_signal_commit_string; PanelClientSignalKeyEvent m_signal_forward_key_event; PanelClientSignalVoid m_signal_request_help; PanelClientSignalVoid m_signal_request_factory_menu; PanelClientSignalString m_signal_change_factory; public: PanelClientImpl () : m_socket_timeout (scim_get_default_socket_timeout ()), m_socket_magic_key (0), m_current_icid (-1), m_send_refcount (0) { } int open_connection (const String &config, const String &display) { SocketAddress addr (scim_get_default_panel_socket_address (display)); if (m_socket.is_connected ()) close_connection (); bool ret; int count = 0; // Try three times. while (1) { if ((ret = m_socket.connect (addr)) == false) { scim_usleep (100000); launch_panel (config, display); for (int i = 0; i < 200; ++i) { if (m_socket.connect (addr)) { ret = true; break; } scim_usleep (100000); } } if (ret && scim_socket_open_connection (m_socket_magic_key, String ("FrontEnd"), String ("Panel"), m_socket, m_socket_timeout)) break; m_socket.close (); if (count++ >= 3) break; scim_usleep (100000); } return m_socket.get_id (); } void close_connection () { m_socket.close (); m_socket_magic_key = 0; } int get_connection_number () const { return m_socket.get_id (); } bool is_connected () const { return m_socket.is_connected (); } bool has_pending_event () const { return m_socket.is_connected () && m_socket.wait_for_data (0) > 0; } bool filter_event () { Transaction recv; if (!m_socket.is_connected () || !recv.read_from_socket (m_socket, m_socket_timeout)) return false; int cmd; uint32 context = (uint32)(-1); if (!recv.get_command (cmd) || cmd != SCIM_TRANS_CMD_REPLY) return true; // No context id available, so there will be some global command. if (recv.get_data_type () == SCIM_TRANS_DATA_COMMAND) { while (recv.get_command (cmd)) { switch (cmd) { case SCIM_TRANS_CMD_RELOAD_CONFIG: m_signal_reload_config ((int)context); break; case SCIM_TRANS_CMD_EXIT: m_signal_exit ((int)context); break; default: break; } } return true; } // Now for context related command. if (!recv.get_data (context)) return true; while (recv.get_command (cmd)) { switch (cmd) { case SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE: { uint32 size; if (recv.get_data (size)) m_signal_update_lookup_table_page_size ((int) context, (int) size); } break; case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP: { m_signal_lookup_table_page_up ((int) context); } break; case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN: { m_signal_lookup_table_page_down ((int) context); } break; case SCIM_TRANS_CMD_TRIGGER_PROPERTY: { String property; if (recv.get_data (property)) m_signal_trigger_property ((int) context, property); } break; case SCIM_TRANS_CMD_PROCESS_HELPER_EVENT: { String target_uuid; String helper_uuid; Transaction trans; if (recv.get_data (target_uuid) && recv.get_data (helper_uuid) && recv.get_data (trans)) m_signal_process_helper_event ((int) context, target_uuid, helper_uuid, trans); } break; case SCIM_TRANS_CMD_MOVE_PREEDIT_CARET: { uint32 caret; if (recv.get_data (caret)) m_signal_move_preedit_caret ((int) context, (int) caret); } break; case SCIM_TRANS_CMD_SELECT_CANDIDATE: { uint32 item; if (recv.get_data (item)) m_signal_select_candidate ((int) context, (int) item); } break; case SCIM_TRANS_CMD_PROCESS_KEY_EVENT: { KeyEvent key; if (recv.get_data (key)) m_signal_process_key_event ((int) context, key); } break; case SCIM_TRANS_CMD_COMMIT_STRING: { WideString wstr; if (recv.get_data (wstr)) m_signal_commit_string ((int) context, wstr); } break; case SCIM_TRANS_CMD_FORWARD_KEY_EVENT: { KeyEvent key; if (recv.get_data (key)) m_signal_forward_key_event ((int) context, key); } break; case SCIM_TRANS_CMD_PANEL_REQUEST_HELP: { m_signal_request_help ((int) context); } break; case SCIM_TRANS_CMD_PANEL_REQUEST_FACTORY_MENU: { m_signal_request_factory_menu ((int) context); } break; case SCIM_TRANS_CMD_PANEL_CHANGE_FACTORY: { String sfid; if (recv.get_data (sfid)) m_signal_change_factory ((int) context, sfid); } break; default: break; } } return true; } bool prepare (int icid) { if (!m_socket.is_connected ()) return false; int cmd; uint32 data; if (m_send_refcount <= 0) { m_current_icid = icid; m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REQUEST); m_send_trans.put_data (m_socket_magic_key); m_send_trans.put_data ((uint32) icid); m_send_trans.get_command (cmd); m_send_trans.get_data (data); m_send_trans.get_data (data); m_send_refcount = 0; } if (m_current_icid == icid) { m_send_refcount ++; return true; } return false; } bool send () { if (!m_socket.is_connected ()) return false; if (m_send_refcount <= 0) return false; m_send_refcount --; if (m_send_refcount > 0) return false; if (m_send_trans.get_data_type () != SCIM_TRANS_DATA_UNKNOWN) return m_send_trans.write_to_socket (m_socket, 0x4d494353); return false; } public: void turn_on (int icid) { if (m_send_refcount > 0 && m_current_icid == icid) m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_TURN_ON); } void turn_off (int icid) { if (m_send_refcount > 0 && m_current_icid == icid) m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_TURN_OFF); } void update_screen (int icid, int screen) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_SCREEN); m_send_trans.put_data ((uint32) screen); } } void show_help (int icid, const String &help) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_SHOW_HELP); m_send_trans.put_data (help); } } void show_factory_menu (int icid, const std::vector &menu) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_SHOW_FACTORY_MENU); for (size_t i = 0; i < menu.size (); ++ i) { m_send_trans.put_data (menu [i].uuid); m_send_trans.put_data (menu [i].name); m_send_trans.put_data (menu [i].lang); m_send_trans.put_data (menu [i].icon); } } } void focus_in (int icid, const String &uuid) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_FOCUS_IN); m_send_trans.put_data (uuid); } } void focus_out (int icid) { if (m_send_refcount > 0 && m_current_icid == icid) m_send_trans.put_command (SCIM_TRANS_CMD_FOCUS_OUT); } void update_factory_info (int icid, const PanelFactoryInfo &info) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_UPDATE_FACTORY_INFO); m_send_trans.put_data (info.uuid); m_send_trans.put_data (info.name); m_send_trans.put_data (info.lang); m_send_trans.put_data (info.icon); } } void update_spot_location (int icid, int x, int y) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION); m_send_trans.put_data ((uint32) x); m_send_trans.put_data ((uint32) y); } } void show_preedit_string (int icid) { if (m_send_refcount > 0 && m_current_icid == icid) m_send_trans.put_command (SCIM_TRANS_CMD_SHOW_PREEDIT_STRING); } void show_aux_string (int icid) { if (m_send_refcount > 0 && m_current_icid == icid) m_send_trans.put_command (SCIM_TRANS_CMD_SHOW_AUX_STRING); } void show_lookup_table (int icid) { if (m_send_refcount > 0 && m_current_icid == icid) m_send_trans.put_command (SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE); } void hide_preedit_string (int icid) { if (m_send_refcount > 0 && m_current_icid == icid) m_send_trans.put_command (SCIM_TRANS_CMD_HIDE_PREEDIT_STRING); } void hide_aux_string (int icid) { if (m_send_refcount > 0 && m_current_icid == icid) m_send_trans.put_command (SCIM_TRANS_CMD_HIDE_AUX_STRING); } void hide_lookup_table (int icid) { if (m_send_refcount > 0 && m_current_icid == icid) m_send_trans.put_command (SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE); } void update_preedit_string (int icid, const WideString &str, const AttributeList &attrs) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING); m_send_trans.put_data (utf8_wcstombs (str)); m_send_trans.put_data (attrs); } } void update_preedit_caret (int icid, int caret) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET); m_send_trans.put_data ((uint32) caret); } } void update_aux_string (int icid, const WideString &str, const AttributeList &attrs) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_AUX_STRING); m_send_trans.put_data (utf8_wcstombs (str)); m_send_trans.put_data (attrs); } } void update_lookup_table (int icid, const LookupTable &table) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE); m_send_trans.put_data (table); } } void register_properties (int icid, const PropertyList &properties) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_REGISTER_PROPERTIES); m_send_trans.put_data (properties); } } void update_property (int icid, const Property &property) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_PROPERTY); m_send_trans.put_data (property); } } void start_helper (int icid, const String &helper_uuid) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_START_HELPER); m_send_trans.put_data (helper_uuid); } } void stop_helper (int icid, const String &helper_uuid) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_STOP_HELPER); m_send_trans.put_data (helper_uuid); } } void send_helper_event (int icid, const String &helper_uuid, const Transaction &trans) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_SEND_HELPER_EVENT); m_send_trans.put_data (helper_uuid); m_send_trans.put_data (trans); } } void register_input_context (int icid, const String &uuid) { if (m_send_refcount > 0 && m_current_icid == icid) { m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_REGISTER_INPUT_CONTEXT); m_send_trans.put_data (uuid); } } void remove_input_context (int icid) { if (m_send_refcount > 0 && m_current_icid == icid) m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_REMOVE_INPUT_CONTEXT); } public: Connection signal_connect_reload_config (PanelClientSlotVoid *slot) { return m_signal_reload_config.connect (slot); } Connection signal_connect_exit (PanelClientSlotVoid *slot) { return m_signal_exit.connect (slot); } Connection signal_connect_update_lookup_table_page_size (PanelClientSlotInt *slot) { return m_signal_update_lookup_table_page_size.connect (slot); } Connection signal_connect_lookup_table_page_up (PanelClientSlotVoid *slot) { return m_signal_lookup_table_page_up.connect (slot); } Connection signal_connect_lookup_table_page_down (PanelClientSlotVoid *slot) { return m_signal_lookup_table_page_down.connect (slot); } Connection signal_connect_trigger_property (PanelClientSlotString *slot) { return m_signal_trigger_property.connect (slot); } Connection signal_connect_process_helper_event (PanelClientSlotStringStringTransaction *slot) { return m_signal_process_helper_event.connect (slot); } Connection signal_connect_move_preedit_caret (PanelClientSlotInt *slot) { return m_signal_move_preedit_caret.connect (slot); } Connection signal_connect_select_candidate (PanelClientSlotInt *slot) { return m_signal_select_candidate.connect (slot); } Connection signal_connect_process_key_event (PanelClientSlotKeyEvent *slot) { return m_signal_process_key_event.connect (slot); } Connection signal_connect_commit_string (PanelClientSlotWideString *slot) { return m_signal_commit_string.connect (slot); } Connection signal_connect_forward_key_event (PanelClientSlotKeyEvent *slot) { return m_signal_forward_key_event.connect (slot); } Connection signal_connect_request_help (PanelClientSlotVoid *slot) { return m_signal_request_help.connect (slot); } Connection signal_connect_request_factory_menu (PanelClientSlotVoid *slot) { return m_signal_request_factory_menu.connect (slot); } Connection signal_connect_change_factory (PanelClientSlotString *slot) { return m_signal_change_factory.connect (slot); } private: void launch_panel (const String &config, const String &display) const { char * my_argv [2] = {const_cast ("--no-stay"), 0}; scim_launch_panel (true, config, display, my_argv); } }; PanelClient::PanelClient () : m_impl (new PanelClientImpl ()) { } PanelClient::~PanelClient () { delete m_impl; } int PanelClient::open_connection (const String &config, const String &display) { return m_impl->open_connection (config, display); } void PanelClient::close_connection () { m_impl->close_connection (); } int PanelClient::get_connection_number () const { return m_impl->get_connection_number (); } bool PanelClient::is_connected () const { return m_impl->is_connected (); } bool PanelClient::has_pending_event () const { return m_impl->has_pending_event (); } bool PanelClient::filter_event () { return m_impl->filter_event (); } bool PanelClient::prepare (int icid) { return m_impl->prepare (icid); } bool PanelClient::send () { return m_impl->send (); } void PanelClient::turn_on (int icid) { m_impl->turn_on (icid); } void PanelClient::turn_off (int icid) { m_impl->turn_off (icid); } void PanelClient::update_screen (int icid, int screen) { m_impl->update_screen (icid, screen); } void PanelClient::show_help (int icid, const String &help) { m_impl->show_help (icid, help); } void PanelClient::show_factory_menu (int icid, const std::vector &menu) { m_impl->show_factory_menu (icid, menu); } void PanelClient::focus_in (int icid, const String &uuid) { m_impl->focus_in (icid, uuid); } void PanelClient::focus_out (int icid) { m_impl->focus_out (icid); } void PanelClient::update_factory_info (int icid, const PanelFactoryInfo &info) { m_impl->update_factory_info (icid, info); } void PanelClient::update_spot_location (int icid, int x, int y) { m_impl->update_spot_location (icid, x, y); } void PanelClient::show_preedit_string (int icid) { m_impl->show_preedit_string (icid); } void PanelClient::show_aux_string (int icid) { m_impl->show_aux_string (icid); } void PanelClient::show_lookup_table (int icid) { m_impl->show_lookup_table (icid); } void PanelClient::hide_preedit_string (int icid) { m_impl->hide_preedit_string (icid); } void PanelClient::hide_aux_string (int icid) { m_impl->hide_aux_string (icid); } void PanelClient::hide_lookup_table (int icid) { m_impl->hide_lookup_table (icid); } void PanelClient::update_preedit_string (int icid, const WideString &str, const AttributeList &attrs) { m_impl->update_preedit_string (icid, str, attrs); } void PanelClient::update_preedit_caret (int icid, int caret) { m_impl->update_preedit_caret (icid, caret); } void PanelClient::update_aux_string (int icid, const WideString &str, const AttributeList &attrs) { m_impl->update_aux_string (icid, str, attrs); } void PanelClient::update_lookup_table (int icid, const LookupTable &table) { m_impl->update_lookup_table (icid, table); } void PanelClient::register_properties (int icid, const PropertyList &properties) { m_impl->register_properties (icid, properties); } void PanelClient::update_property (int icid, const Property &property) { m_impl->update_property (icid, property); } void PanelClient::start_helper (int icid, const String &helper_uuid) { m_impl->start_helper (icid, helper_uuid); } void PanelClient::stop_helper (int icid, const String &helper_uuid) { m_impl->stop_helper (icid, helper_uuid); } void PanelClient::send_helper_event (int icid, const String &helper_uuid, const Transaction &trans) { m_impl->send_helper_event (icid, helper_uuid, trans); } void PanelClient::register_input_context (int icid, const String &uuid) { m_impl->register_input_context (icid, uuid); } void PanelClient::remove_input_context (int icid) { m_impl->remove_input_context (icid); } Connection PanelClient::signal_connect_reload_config (PanelClientSlotVoid *slot) { return m_impl->signal_connect_reload_config (slot); } Connection PanelClient::signal_connect_exit (PanelClientSlotVoid *slot) { return m_impl->signal_connect_exit (slot); } Connection PanelClient::signal_connect_update_lookup_table_page_size (PanelClientSlotInt *slot) { return m_impl->signal_connect_update_lookup_table_page_size (slot); } Connection PanelClient::signal_connect_lookup_table_page_up (PanelClientSlotVoid *slot) { return m_impl->signal_connect_lookup_table_page_up (slot); } Connection PanelClient::signal_connect_lookup_table_page_down (PanelClientSlotVoid *slot) { return m_impl->signal_connect_lookup_table_page_down (slot); } Connection PanelClient::signal_connect_trigger_property (PanelClientSlotString *slot) { return m_impl->signal_connect_trigger_property (slot); } Connection PanelClient::signal_connect_process_helper_event (PanelClientSlotStringStringTransaction *slot) { return m_impl->signal_connect_process_helper_event (slot); } Connection PanelClient::signal_connect_move_preedit_caret (PanelClientSlotInt *slot) { return m_impl->signal_connect_move_preedit_caret (slot); } Connection PanelClient::signal_connect_select_candidate (PanelClientSlotInt *slot) { return m_impl->signal_connect_select_candidate (slot); } Connection PanelClient::signal_connect_process_key_event (PanelClientSlotKeyEvent *slot) { return m_impl->signal_connect_process_key_event (slot); } Connection PanelClient::signal_connect_commit_string (PanelClientSlotWideString *slot) { return m_impl->signal_connect_commit_string (slot); } Connection PanelClient::signal_connect_forward_key_event (PanelClientSlotKeyEvent *slot) { return m_impl->signal_connect_forward_key_event (slot); } Connection PanelClient::signal_connect_request_help (PanelClientSlotVoid *slot) { return m_impl->signal_connect_request_help (slot); } Connection PanelClient::signal_connect_request_factory_menu (PanelClientSlotVoid *slot) { return m_impl->signal_connect_request_factory_menu (slot); } Connection PanelClient::signal_connect_change_factory (PanelClientSlotString *slot) { return m_impl->signal_connect_change_factory (slot); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_panel_agent.h0000644000175000017500000004011612422143415016371 0ustar tzhuantzhuan/** * @file scim_panel_agent.h * @brief Defines scim::PanelAgent and their related types. * * scim::PanelAgent is a class used to write Panel daemons. * It acts like a Socket Server and handles all socket clients * issues. */ /* * Smart Common Input Method * * Copyright (c) 2004-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_panel_agent.h,v 1.2 2005/06/11 14:50:31 suzhe Exp $ */ #ifndef __SCIM_PANEL_AGENT_H #define __SCIM_PANEL_AGENT_H #include namespace scim { /** * @addtogroup Panel * The accessory classes to help develop Panel daemons and FrontEnds * which need to communicate with Panel daemons. * @{ */ typedef Slot0 PanelAgentSlotVoid; typedef Slot1 PanelAgentSlotInt; typedef Slot1 PanelAgentSlotString; typedef Slot1 PanelAgentSlotFactoryInfo; typedef Slot1 &> PanelAgentSlotFactoryInfoVector; typedef Slot1 PanelAgentSlotLookupTable; typedef Slot1 PanelAgentSlotProperty; typedef Slot1 PanelAgentSlotPropertyList; typedef Slot2 PanelAgentSlotIntInt; typedef Slot2 PanelAgentSlotIntProperty; typedef Slot2 PanelAgentSlotIntPropertyList; typedef Slot2 PanelAgentSlotIntHelperInfo; typedef Slot2 PanelAgentSlotAttributeString; /** * @brief The class to implement all socket protocol in Panel. * * This class acts like a stand alone SocketServer. * It has its own dedicated main loop, and will be blocked when run () is called. * So run () must be called within a separated thread, in order to not block * the main loop of the Panel program itself. * * Before calling run (), the panel must hook the callback functions to the * corresponding signals. * * Note that, there are two special signals: lock(void) and unlock(void). These * two signals are used to provide a thread lock to PanelAgent, so that PanelAgent * can run correctly within a multi-threading Panel program. */ class PanelAgent { class PanelAgentImpl; PanelAgentImpl *m_impl; PanelAgent (const HelperAgent &); const PanelAgent & operator = (const HelperAgent &); public: PanelAgent (); ~PanelAgent (); /** * @brief Initialize this PanelAgent. * * @param config The name of the config module to be used by Helpers. * @param display The name of display, on which the Panel should run. * @param resident If this is true then this PanelAgent will keep running * even if there is no more client connected. * * @return true if the PanelAgent is initialized correctly and ready to run. */ bool initialize (const String &config, const String &display, bool resident = false); /** * @brief Check if this PanelAgent is initialized correctly and ready to run. * * @return true if this PanelAgent is ready to run. */ bool valid (void) const; /** * @brief Run this PanelAgent. * * This method has its own dedicated main loop, * so it should be run in a separated thread. * * @return false if the Panel SocketServer encountered an error when running. * Otherwise, it won't return until the server exits. */ bool run (void); /** * @brief Stop this PanelAgent. */ void stop (void); public: /** * @brief Get the list of all helpers. * * Panel program should provide a menu which contains * all stand alone but not auto start Helpers, so that users can activate * the Helpers by clicking in the menu. * * All auto start Helpers should be started by Panel after running PanelAgent * by calling PanelAgent::start_helper(). * * @param helpers A list contains information of all Helpers. */ int get_helper_list (std::vector & helpers) const; public: /** * @brief Let the focused IMEngineInstance object move the preedit caret. * * @param position The new preedit caret position. * @return true if the command was sent correctly. */ bool move_preedit_caret (uint32 position); /** * @brief Request help information from the focused IMEngineInstance object. * @return true if the command was sent correctly. */ bool request_help (void); /** * @brief Request factory menu from the focused FrontEnd. * @return true if the command was sent correctly. */ bool request_factory_menu (void); /** * @brief Change the factory used by the focused IMEngineInstance object. * * @param uuid The uuid of the new factory. * @return true if the command was sent correctly. */ bool change_factory (const String &uuid); /** * @brief Let the focused IMEngineInstance object * select a candidate in current lookup table. * * @param item The index of the selected candidate. * @return true if the command was sent correctly. */ bool select_candidate (uint32 item); /** * @brief Let the focused IMEngineInstance object * flip the LookupTable to previous page. * @return true if the command was sent correctly. */ bool lookup_table_page_up (void); /** * @brief Let the focused IMEngineInstance object * flip the LookupTable to next page. * @return true if the command was sent correctly. */ bool lookup_table_page_down (void); /** * @brief Let the focused IMEngineInstance object * update the page size of the LookupTable. * * @param size The new page size. * @return true if the command was sent correctly. */ bool update_lookup_table_page_size (uint32 size); /** * @brief Trigger a property of the focused IMEngineInstance object. * * @param property The property key to be triggered. * @return true if the command was sent correctly. */ bool trigger_property (const String &property); /** * @brief Trigger a property of a Helper object. * * @param client The client id of the Helper object. * @param property The property key to be triggered. * @return true if the command was sent correctly. */ bool trigger_helper_property (int client, const String &property); /** * @brief Start a stand alone helper. * * @param uuid The uuid of the Helper object to be started. * @return true if the command was sent correctly. */ bool start_helper (const String &uuid); /** * @brief Let all FrontEnds and Helpers reload configuration. * @return true if the command was sent correctly. */ bool reload_config (void); /** * @brief Let all FrontEnds, Helpers and this Panel exit. * @return true if the command was sent correctly. */ bool exit (void); public: /** * @brief Signal: Reload configuration. * * When a Helper object send a RELOAD_CONFIG event to this Panel, * this signal will be emitted. Panel should reload all configuration here. */ Connection signal_connect_reload_config (PanelAgentSlotVoid *slot); /** * @brief Signal: Turn on. * * slot prototype: void turn_on (void); */ Connection signal_connect_turn_on (PanelAgentSlotVoid *slot); /** * @brief Signal: Turn off. * * slot prototype: void turn_off (void); */ Connection signal_connect_turn_off (PanelAgentSlotVoid *slot); /** * @brief Signal: Update screen. * * slot prototype: void update_screen (int screen); */ Connection signal_connect_update_screen (PanelAgentSlotInt *slot); /** * @brief Signal: Update spot location. * * slot prototype: void update_spot_location (int x, int y); */ Connection signal_connect_update_spot_location (PanelAgentSlotIntInt *slot); /** * @brief Signal: Update factory information. * * slot prototype: void update_factory_info (const PanelFactoryInfo &info); */ Connection signal_connect_update_factory_info (PanelAgentSlotFactoryInfo *slot); /** * @brief Signal: Show help. * * slot prototype: void show_help (const String &help); */ Connection signal_connect_show_help (PanelAgentSlotString *slot); /** * @brief Signal: Show factory menu. * * slot prototype: void show_factory_menu (const std::vector &menu); */ Connection signal_connect_show_factory_menu (PanelAgentSlotFactoryInfoVector *slot); /** * @brief Signal: Show preedit string. * * slot prototype: void show_preedit_string (void): */ Connection signal_connect_show_preedit_string (PanelAgentSlotVoid *slot); /** * @brief Signal: Show aux string. * * slot prototype: void show_aux_string (void): */ Connection signal_connect_show_aux_string (PanelAgentSlotVoid *slot); /** * @brief Signal: Show lookup table. * * slot prototype: void show_lookup_table (void): */ Connection signal_connect_show_lookup_table (PanelAgentSlotVoid *slot); /** * @brief Signal: Hide preedit string. * * slot prototype: void hide_preedit_string (void); */ Connection signal_connect_hide_preedit_string (PanelAgentSlotVoid *slot); /** * @brief Signal: Hide aux string. * * slot prototype: void hide_aux_string (void); */ Connection signal_connect_hide_aux_string (PanelAgentSlotVoid *slot); /** * @brief Signal: Hide lookup table. * * slot prototype: void hide_lookup_table (void); */ Connection signal_connect_hide_lookup_table (PanelAgentSlotVoid *slot); /** * @brief Signal: Update preedit string. * * slot prototype: void update_preedit_string (const String &str, const AttributeList &attrs); * - str -- The UTF-8 encoded string to be displayed in preedit area. * - attrs -- The attributes of the string. */ Connection signal_connect_update_preedit_string (PanelAgentSlotAttributeString *slot); /** * @brief Signal: Update preedit caret. * * slot prototype: void update_preedit_caret (int caret); */ Connection signal_connect_update_preedit_caret (PanelAgentSlotInt *slot); /** * @brief Signal: Update aux string. * * slot prototype: void update_aux_string (const String &str, const AttributeList &attrs); * - str -- The UTF-8 encoded string to be displayed in aux area. * - attrs -- The attributes of the string. */ Connection signal_connect_update_aux_string (PanelAgentSlotAttributeString *slot); /** * @brief Signal: Update lookup table. * * slot prototype: void update_lookup_table (const LookupTable &table); * - table -- The new LookupTable object. */ Connection signal_connect_update_lookup_table (PanelAgentSlotLookupTable *slot); /** * @brief Signal: Register properties. * * Register properties of the focused instance. * * slot prototype: void register_properties (const PropertyList &props); * - props -- The properties to be registered. */ Connection signal_connect_register_properties (PanelAgentSlotPropertyList *slot); /** * @brief Signal: Update property. * * Update a property of the focused instance. * * slot prototype: void update_property (const Property &prop); * - prop -- The property to be updated. */ Connection signal_connect_update_property (PanelAgentSlotProperty *slot); /** * @brief Signal: Register properties of a helper. * * slot prototype: void register_helper_properties (int id, const PropertyList &props); * - id -- The client id of the helper object. * - props -- The properties to be registered. */ Connection signal_connect_register_helper_properties (PanelAgentSlotIntPropertyList *slot); /** * @brief Signal: Update helper property. * * slot prototype: void update_helper_property (int id, const Property &prop); * - id -- The client id of the helper object. * - prop -- The property to be updated. */ Connection signal_connect_update_helper_property (PanelAgentSlotIntProperty *slot); /** * @brief Signal: Register a helper object. * * A newly started helper object will send this event to Panel. * * slot prototype: register_helper (int id, const HelperInfo &helper); * - id -- The client id of the helper object. * - helper -- The information of the helper object. */ Connection signal_connect_register_helper (PanelAgentSlotIntHelperInfo *slot); /** * @brief Signal: Remove a helper object. * * If a running helper close its connection to Panel, then this signal will be triggered to * tell Panel to remove all data associated to this helper. * * slot prototype: void remove_helper (int id); * - id -- The client id of the helper object to be removed. */ Connection signal_connect_remove_helper (PanelAgentSlotInt *slot); /** * @brief Signal: A transaction is started. * * This signal infers that the Panel should disable update before this transaction finishes. * * slot prototype: void signal_connect_transaction_start (void); */ Connection signal_connect_transaction_start (PanelAgentSlotVoid *slot); /** * @brief Signal: A transaction is finished. * * This signal will get emitted when a transaction is finished. This implys to re-enable * panel GUI update * * slot prototype: void signal_connect_transaction_end (void); */ Connection signal_connect_transaction_end (PanelAgentSlotVoid *slot); /** * @brief Signal: Lock the exclusive lock for this PanelAgent. * * The panel program should provide a thread lock and hook a slot into this signal to lock it. * PanelAgent will use this lock to ensure the data integrity. * * slot prototype: void lock (void); */ Connection signal_connect_lock (PanelAgentSlotVoid *slot); /** * @brief Signal: Unlock the exclusive lock for this PanelAgent. * * slot prototype: void unlock (void); */ Connection signal_connect_unlock (PanelAgentSlotVoid *slot); }; /** @} */ } // namespace scim #endif //__SCIM_PANEL_AGENT_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_panel_agent.cpp0000644000175000017500000023107612422143415016733 0ustar tzhuantzhuan/** @file scim_panel.cpp * @brief Implementation of class PanelAgent. */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_panel_agent.cpp,v 1.8.2.1 2006/01/09 14:32:18 suzhe Exp $ * */ #define Uses_SCIM_TRANSACTION #define Uses_SCIM_TRANS_COMMANDS #define Uses_SCIM_PANEL_AGENT #define Uses_SCIM_HELPER #define Uses_SCIM_SOCKET #define Uses_SCIM_EVENT #define SCIM_KEYBOARD_ICON_FILE (SCIM_ICONDIR "/keyboard.png") #include "scim_private.h" #include "scim.h" #include "scim_stl_map.h" namespace scim { typedef Signal0 PanelAgentSignalVoid; typedef Signal1 PanelAgentSignalInt; typedef Signal1 PanelAgentSignalString; typedef Signal1 PanelAgentSignalFactoryInfo; typedef Signal1 &> PanelAgentSignalFactoryInfoVector; typedef Signal1 PanelAgentSignalLookupTable; typedef Signal1 PanelAgentSignalProperty; typedef Signal1 PanelAgentSignalPropertyList; typedef Signal2 PanelAgentSignalIntInt; typedef Signal2 PanelAgentSignalIntProperty; typedef Signal2 PanelAgentSignalIntPropertyList; typedef Signal2 PanelAgentSignalIntHelperInfo; typedef Signal2 PanelAgentSignalAttributeString; enum ClientType { UNKNOWN_CLIENT, FRONTEND_CLIENT, HELPER_CLIENT, PANELCONTROL_CLIENT }; struct ClientInfo { uint32 key; ClientType type; int awaitedTransCommand; }; struct HelperClientStub { int id; int ref; HelperClientStub (int i = 0, int r = 0) : id (i), ref (r) { } }; #if SCIM_USE_STL_EXT_HASH_MAP typedef __gnu_cxx::hash_map > ClientRepository; typedef __gnu_cxx::hash_map > HelperInfoRepository; typedef __gnu_cxx::hash_map > ClientContextUUIDRepository; typedef __gnu_cxx::hash_map HelperClientIndex; typedef __gnu_cxx::hash_map >, scim_hash_string> StartHelperICIndex; #elif SCIM_USE_STL_HASH_MAP typedef std::hash_map > ClientRepository; typedef std::hash_map > HelperInfoRepository; typedef std::hash_map > ClientContextUUIDRepository; typedef std::hash_map HelperClientIndex; typedef std::hash_map >, scim_hash_string> StartHelperICIndex; #else typedef std::map ClientRepository; typedef std::map HelperInfoRepository; typedef std::map ClientContextUUIDRepository; typedef std::map HelperClientIndex; typedef std::map > > StartHelperICIndex; #endif static uint32 get_helper_ic (int client, uint32 context) { return (uint32) (client & 0xFFFF) | ((context & 0x7FFF) << 16); } static void get_imengine_client_context (uint32 helper_ic, int &client, uint32 &context) { client = (int) (helper_ic & 0xFFFF); context = ((helper_ic >> 16) & 0x7FFF); } //==================================== PanelAgent =========================== class PanelAgent::PanelAgentImpl { bool m_should_exit; bool m_should_resident; int m_current_screen; String m_config_name; String m_display_name; int m_socket_timeout; String m_socket_address; SocketServer m_socket_server; Transaction m_send_trans; Transaction m_recv_trans; Transaction m_nest_trans; int m_current_socket_client; uint32 m_current_client_context; String m_current_context_uuid; int m_last_socket_client; uint32 m_last_client_context; String m_last_context_uuid; ClientRepository m_client_repository; HelperInfoRepository m_helper_info_repository; HelperClientIndex m_helper_client_index; StartHelperICIndex m_start_helper_ic_index; ClientContextUUIDRepository m_client_context_uuids; PanelFactoryInfo m_currentFactoryInfo; PanelFactoryInfo m_defaultFactoryInfo; HelperManager m_helper_manager; PanelAgentSignalVoid m_signal_reload_config; PanelAgentSignalVoid m_signal_turn_on; PanelAgentSignalVoid m_signal_turn_off; PanelAgentSignalInt m_signal_update_screen; PanelAgentSignalIntInt m_signal_update_spot_location; PanelAgentSignalFactoryInfo m_signal_update_factory_info; PanelAgentSignalString m_signal_show_help; PanelAgentSignalFactoryInfoVector m_signal_show_factory_menu; PanelAgentSignalVoid m_signal_show_preedit_string; PanelAgentSignalVoid m_signal_show_aux_string; PanelAgentSignalVoid m_signal_show_lookup_table; PanelAgentSignalVoid m_signal_hide_preedit_string; PanelAgentSignalVoid m_signal_hide_aux_string; PanelAgentSignalVoid m_signal_hide_lookup_table; PanelAgentSignalAttributeString m_signal_update_preedit_string; PanelAgentSignalInt m_signal_update_preedit_caret; PanelAgentSignalAttributeString m_signal_update_aux_string; PanelAgentSignalLookupTable m_signal_update_lookup_table; PanelAgentSignalPropertyList m_signal_register_properties; PanelAgentSignalProperty m_signal_update_property; PanelAgentSignalIntPropertyList m_signal_register_helper_properties; PanelAgentSignalIntProperty m_signal_update_helper_property; PanelAgentSignalIntHelperInfo m_signal_register_helper; PanelAgentSignalInt m_signal_remove_helper; PanelAgentSignalVoid m_signal_transaction_start; PanelAgentSignalVoid m_signal_transaction_end; PanelAgentSignalVoid m_signal_lock; PanelAgentSignalVoid m_signal_unlock; public: PanelAgentImpl () : m_should_exit (false), m_should_resident (false), m_current_screen (0), m_socket_timeout (scim_get_default_socket_timeout ()), m_current_socket_client (-1), m_current_client_context (0), m_last_socket_client (-1), m_last_client_context (0), m_defaultFactoryInfo (PanelFactoryInfo (String (""), String (_("English/Keyboard")), String ("C"), String (SCIM_KEYBOARD_ICON_FILE))), m_currentFactoryInfo (PanelFactoryInfo (String (""), String (_("English/Keyboard")), String ("C"), String (SCIM_KEYBOARD_ICON_FILE))) { m_socket_server.signal_connect_accept (slot (this, &PanelAgentImpl::socket_accept_callback)); m_socket_server.signal_connect_receive (slot (this, &PanelAgentImpl::socket_receive_callback)); m_socket_server.signal_connect_exception (slot (this, &PanelAgentImpl::socket_exception_callback)); } bool initialize (const String &config, const String &display, bool resident) { m_config_name = config; m_display_name = display; m_should_resident = resident; m_socket_address = scim_get_default_panel_socket_address (display); m_socket_server.shutdown (); return m_socket_server.create (SocketAddress (m_socket_address)); } bool valid (void) const { return m_socket_server.valid (); } public: bool run (void) { SCIM_DEBUG_MAIN (1) << "PanelAgent::run ()\n"; return m_socket_server.run (); } void stop (void) { SCIM_DEBUG_MAIN(1) << "PanelAgent::stop ()\n"; lock (); m_should_exit = true; unlock (); SocketClient client; if (client.connect (SocketAddress (m_socket_address))) { client.close (); } } int get_helper_list (std::vector & helpers) const { SCIM_DEBUG_MAIN (1) << "PanelAgent::get_helper_list ()\n"; helpers.clear (); unsigned int num = m_helper_manager.number_of_helpers (); HelperInfo info; SCIM_DEBUG_MAIN (2) << "Found " << num << " Helper objects\n"; for (unsigned int i = 0; i < num; ++i) { SCIM_DEBUG_MAIN (3) << "Helper " << i << " : " << info.uuid << " : " << info.name << " : " << ((info.option & SCIM_HELPER_STAND_ALONE) ? "SA " : "") << ((info.option & SCIM_HELPER_AUTO_START) ? "AS " : "") << ((info.option & SCIM_HELPER_AUTO_RESTART) ? "AR " : "") << "\n"; if (m_helper_manager.get_helper_info (i, info) && info.uuid.length () && (info.option & SCIM_HELPER_STAND_ALONE)) helpers.push_back (info); } return helpers.size (); } bool move_preedit_caret (uint32 position) { SCIM_DEBUG_MAIN(1) << "PanelAgent::move_preedit_caret (" << position << ")\n"; int client; uint32 context; lock (); get_focused_context (client, context); if (client >= 0) { Socket client_socket (client); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); m_send_trans.put_command (SCIM_TRANS_CMD_MOVE_PREEDIT_CARET); m_send_trans.put_data ((uint32) position); m_send_trans.write_to_socket (client_socket); } unlock (); return client >= 0; } bool request_help (void) { SCIM_DEBUG_MAIN(1) << "PanelAgent::request_help ()\n"; int client; uint32 context; lock (); get_focused_context (client, context); if (client >= 0) { Socket client_socket (client); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_REQUEST_HELP); m_send_trans.write_to_socket (client_socket); } unlock (); return client >= 0; } bool request_factory_menu (void) { SCIM_DEBUG_MAIN(1) << "PanelAgent::request_factory_menu ()\n"; int client; uint32 context; lock (); get_focused_context (client, context); if (client >= 0) { Socket client_socket (client); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_REQUEST_FACTORY_MENU); m_send_trans.write_to_socket (client_socket); } unlock (); return client >= 0; } bool change_factory (const String &uuid) { SCIM_DEBUG_MAIN(1) << "PanelAgent::change_factory (" << uuid << ")\n"; int client; uint32 context; lock (); get_focused_context (client, context); if (client >= 0) { Socket client_socket (client); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_CHANGE_FACTORY); m_send_trans.put_data (uuid); m_send_trans.write_to_socket (client_socket); } unlock (); return client >= 0; } bool select_candidate (uint32 item) { SCIM_DEBUG_MAIN(1) << "PanelAgent::select_candidate (" << item << ")\n"; int client; uint32 context; lock (); get_focused_context (client, context); if (client >= 0) { Socket client_socket (client); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); m_send_trans.put_command (SCIM_TRANS_CMD_SELECT_CANDIDATE); m_send_trans.put_data ((uint32)item); m_send_trans.write_to_socket (client_socket); } unlock (); return client >= 0; } bool lookup_table_page_up (void) { SCIM_DEBUG_MAIN(1) << "PanelAgent::lookup_table_page_up ()\n"; int client; uint32 context; lock (); get_focused_context (client, context); if (client >= 0) { Socket client_socket (client); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); m_send_trans.put_command (SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP); m_send_trans.write_to_socket (client_socket); } unlock (); return client >= 0; } bool lookup_table_page_down (void) { SCIM_DEBUG_MAIN(1) << "PanelAgent::lookup_table_page_down ()\n"; int client; uint32 context; lock (); get_focused_context (client, context); if (client >= 0) { Socket client_socket (client); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); m_send_trans.put_command (SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN); m_send_trans.write_to_socket (client_socket); } unlock (); return client >= 0; } bool update_lookup_table_page_size (uint32 size) { SCIM_DEBUG_MAIN(1) << "PanelAgent::update_lookup_table_page_size (" << size << ")\n"; int client; uint32 context; lock (); get_focused_context (client, context); if (client >= 0) { Socket client_socket (client); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE); m_send_trans.put_data (size); m_send_trans.write_to_socket (client_socket); } unlock (); return client >= 0; } bool trigger_property (const String &property) { SCIM_DEBUG_MAIN(1) << "PanelAgent::trigger_property (" << property << ")\n"; int client; uint32 context; lock (); get_focused_context (client, context); if (client >= 0) { Socket client_socket (client); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); m_send_trans.put_command (SCIM_TRANS_CMD_TRIGGER_PROPERTY); m_send_trans.put_data (property); m_send_trans.write_to_socket (client_socket); } unlock (); return client >= 0; } bool trigger_helper_property (int client, const String &property) { SCIM_DEBUG_MAIN(1) << "PanelAgent::trigger_helper_property (" << client << "," << property << ")\n"; lock (); ClientInfo info = socket_get_client_info (client); if (client >= 0 && info.type == HELPER_CLIENT) { int fe_client; uint32 fe_context; String fe_uuid; fe_uuid = get_focused_context (fe_client, fe_context); Socket client_socket (client); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); // FIXME: We presume that client and context are both less than 65536. // Hopefully, it should be true in any UNIXs. // So it's ok to combine client and context into one uint32. m_send_trans.put_data (get_helper_ic (fe_client, fe_context)); m_send_trans.put_data (fe_uuid); m_send_trans.put_command (SCIM_TRANS_CMD_TRIGGER_PROPERTY); m_send_trans.put_data (property); m_send_trans.write_to_socket (client_socket); } unlock (); return client >= 0 && info.type == HELPER_CLIENT; } bool start_helper (const String &uuid) { SCIM_DEBUG_MAIN(1) << "PanelAgent::start_helper (" << uuid << ")\n"; lock (); HelperClientIndex::iterator it = m_helper_client_index.find (uuid); if (it == m_helper_client_index.end ()) m_helper_manager.run_helper (uuid, m_config_name, m_display_name); unlock (); return true; } bool reload_config (void) { SCIM_DEBUG_MAIN(1) << "PanelAgent::reload_config ()\n"; lock (); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_command (SCIM_TRANS_CMD_RELOAD_CONFIG); for (ClientRepository::iterator it = m_client_repository.begin (); it != m_client_repository.end (); ++it) { Socket client_socket (it->first); m_send_trans.write_to_socket (client_socket); } unlock (); return true; } bool exit (void) { SCIM_DEBUG_MAIN(1) << "PanelAgent::exit ()\n"; lock (); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_command (SCIM_TRANS_CMD_EXIT); for (ClientRepository::iterator it = m_client_repository.begin (); it != m_client_repository.end (); ++it) { Socket client_socket (it->first); m_send_trans.write_to_socket (client_socket); } unlock (); stop (); return true; } Connection signal_connect_reload_config (PanelAgentSlotVoid *slot) { return m_signal_reload_config.connect (slot); } Connection signal_connect_turn_on (PanelAgentSlotVoid *slot) { return m_signal_turn_on.connect (slot); } Connection signal_connect_turn_off (PanelAgentSlotVoid *slot) { return m_signal_turn_off.connect (slot); } Connection signal_connect_update_screen (PanelAgentSlotInt *slot) { return m_signal_update_screen.connect (slot); } Connection signal_connect_update_spot_location (PanelAgentSlotIntInt *slot) { return m_signal_update_spot_location.connect (slot); } Connection signal_connect_update_factory_info (PanelAgentSlotFactoryInfo *slot) { return m_signal_update_factory_info.connect (slot); } Connection signal_connect_show_help (PanelAgentSlotString *slot) { return m_signal_show_help.connect (slot); } Connection signal_connect_show_factory_menu (PanelAgentSlotFactoryInfoVector *slot) { return m_signal_show_factory_menu.connect (slot); } Connection signal_connect_show_preedit_string (PanelAgentSlotVoid *slot) { return m_signal_show_preedit_string.connect (slot); } Connection signal_connect_show_aux_string (PanelAgentSlotVoid *slot) { return m_signal_show_aux_string.connect (slot); } Connection signal_connect_show_lookup_table (PanelAgentSlotVoid *slot) { return m_signal_show_lookup_table.connect (slot); } Connection signal_connect_hide_preedit_string (PanelAgentSlotVoid *slot) { return m_signal_hide_preedit_string.connect (slot); } Connection signal_connect_hide_aux_string (PanelAgentSlotVoid *slot) { return m_signal_hide_aux_string.connect (slot); } Connection signal_connect_hide_lookup_table (PanelAgentSlotVoid *slot) { return m_signal_hide_lookup_table.connect (slot); } Connection signal_connect_update_preedit_string (PanelAgentSlotAttributeString *slot) { return m_signal_update_preedit_string.connect (slot); } Connection signal_connect_update_preedit_caret (PanelAgentSlotInt *slot) { return m_signal_update_preedit_caret.connect (slot); } Connection signal_connect_update_aux_string (PanelAgentSlotAttributeString *slot) { return m_signal_update_aux_string.connect (slot); } Connection signal_connect_update_lookup_table (PanelAgentSlotLookupTable *slot) { return m_signal_update_lookup_table.connect (slot); } Connection signal_connect_register_properties (PanelAgentSlotPropertyList *slot) { return m_signal_register_properties.connect (slot); } Connection signal_connect_update_property (PanelAgentSlotProperty *slot) { return m_signal_update_property.connect (slot); } Connection signal_connect_register_helper_properties (PanelAgentSlotIntPropertyList *slot) { return m_signal_register_helper_properties.connect (slot); } Connection signal_connect_update_helper_property (PanelAgentSlotIntProperty *slot) { return m_signal_update_helper_property.connect (slot); } Connection signal_connect_register_helper (PanelAgentSlotIntHelperInfo *slot) { return m_signal_register_helper.connect (slot); } Connection signal_connect_remove_helper (PanelAgentSlotInt *slot) { return m_signal_remove_helper.connect (slot); } Connection signal_connect_transaction_start (PanelAgentSlotVoid *slot) { return m_signal_transaction_start.connect (slot); } Connection signal_connect_transaction_end (PanelAgentSlotVoid *slot) { return m_signal_transaction_end.connect (slot); } Connection signal_connect_lock (PanelAgentSlotVoid *slot) { return m_signal_lock.connect (slot); } Connection signal_connect_unlock (PanelAgentSlotVoid *slot) { return m_signal_unlock.connect (slot); } private: bool socket_check_client_connection (const Socket &client) { SCIM_DEBUG_MAIN (3) << "PanelAgent::socket_check_client_connection (" << client.get_id () << ")\n"; unsigned char buf [sizeof(uint32)]; int nbytes = client.read_with_timeout (buf, sizeof(uint32), m_socket_timeout); if (nbytes == sizeof (uint32)) return true; if (nbytes < 0) { SCIM_DEBUG_MAIN (4) << "Error occurred when reading socket: " << client.get_error_message () << ".\n"; } else { SCIM_DEBUG_MAIN (4) << "Timeout when reading socket.\n"; } return false; } void socket_accept_callback (SocketServer *server, const Socket &client) { SCIM_DEBUG_MAIN (2) << "PanelAgent::socket_accept_callback (" << client.get_id () << ")\n"; lock (); if (m_should_exit) { SCIM_DEBUG_MAIN (3) << "Exit Socket Server Thread.\n"; server->shutdown (); } unlock (); } void socket_receive_callback (SocketServer *server, const Socket &client) { int client_id = client.get_id (); int cmd = 0; uint32 key = 0; uint32 context = 0; String uuid; bool current = false; bool last = false; ClientInfo client_info; SCIM_DEBUG_MAIN (1) << "PanelAgent::socket_receive_callback (" << client_id << ")\n"; // If the connection is closed then close this client. if (!socket_check_client_connection (client)) { socket_close_connection (server, client); return; } client_info = socket_get_client_info (client_id); // If it's a new client, then request to open the connection first. if (client_info.type == UNKNOWN_CLIENT) { socket_open_connection (server, client); return; } // If can not read the transaction, // or the transaction is not started with SCIM_TRANS_CMD_REQUEST, // or the key is mismatch, // just return. if (!m_recv_trans.read_from_socket (client, m_socket_timeout) || !m_recv_trans.get_command (cmd) || cmd != SCIM_TRANS_CMD_REQUEST || !m_recv_trans.get_data (key) || key != (uint32) client_info.key) return; if (client_info.type == FRONTEND_CLIENT) { if (m_recv_trans.get_data (context)) { SCIM_DEBUG_MAIN (1) << "PanelAgent::FrontEnd Client, context = " << context << "\n"; socket_transaction_start(); while (m_recv_trans.get_command (cmd)) { SCIM_DEBUG_MAIN (3) << "PanelAgent::cmd = " << cmd << "\n"; if (cmd == SCIM_TRANS_CMD_PANEL_REGISTER_INPUT_CONTEXT) { if (m_recv_trans.get_data (uuid)) { SCIM_DEBUG_MAIN (2) << "PanelAgent::register_input_context (" << client_id << "," << "," << context << "," << uuid << ")\n"; uint32 ctx = get_helper_ic (client_id, context); m_client_context_uuids [ctx] = uuid; } continue; } if (cmd == SCIM_TRANS_CMD_PANEL_REMOVE_INPUT_CONTEXT) { uint32 ctx = get_helper_ic (client_id, context); m_client_context_uuids.erase (ctx); continue; } if (cmd == SCIM_TRANS_CMD_FOCUS_IN) { if (m_recv_trans.get_data (uuid)) { SCIM_DEBUG_MAIN (2) << "PanelAgent::focus_in (" << client_id << "," << "," << context << "," << uuid << ")\n"; lock (); if (m_current_socket_client >= 0) { m_last_socket_client = m_current_socket_client; m_last_client_context = m_current_client_context; m_last_context_uuid = m_current_context_uuid; } m_current_socket_client = client_id; m_current_client_context = context; m_current_context_uuid = uuid; unlock (); } continue; } current = last = false; uuid.clear (); // Get the context uuid from the client context registration table. { ClientContextUUIDRepository::iterator it = m_client_context_uuids.find (get_helper_ic (client_id, context)); if (it != m_client_context_uuids.end ()) uuid = it->second; } if (m_current_socket_client == client_id && m_current_client_context == context) { current = true; if (!uuid.length ()) uuid = m_current_context_uuid; } else if (m_last_socket_client == client_id && m_last_client_context == context) { last = true; if (!uuid.length ()) uuid = m_last_context_uuid; } // Skip to the next command and continue, if it's not current or last focused. if (!uuid.length ()) { SCIM_DEBUG_MAIN (3) << "PanelAgent:: Couldn't find context uuid.\n"; while (m_recv_trans.get_data_type () != SCIM_TRANS_DATA_COMMAND && m_recv_trans.get_data_type () != SCIM_TRANS_DATA_UNKNOWN) m_recv_trans.skip_data (); continue; } if (cmd == SCIM_TRANS_CMD_START_HELPER) { socket_start_helper (client_id, context, uuid); continue; } if (cmd == SCIM_TRANS_CMD_SEND_HELPER_EVENT) { socket_send_helper_event (client_id, context, uuid); continue; } if (cmd == SCIM_TRANS_CMD_STOP_HELPER) { socket_stop_helper (client_id, context, uuid); continue; } if (cmd == SCIM_TRANS_CMD_PANEL_SHOW_FACTORY_MENU) socket_show_factory_menu (); // If it's not focused, just continue. if ((!current && !last) || (last && m_current_socket_client >= 0)) { SCIM_DEBUG_MAIN (3) << "PanelAgent::Not current focused.\n"; while (m_recv_trans.get_data_type () != SCIM_TRANS_DATA_COMMAND && m_recv_trans.get_data_type () != SCIM_TRANS_DATA_UNKNOWN) m_recv_trans.skip_data (); continue; } // Client must focus in before do any other things. if (cmd == SCIM_TRANS_CMD_PANEL_TURN_ON) socket_turn_on (); else if (cmd == SCIM_TRANS_CMD_PANEL_TURN_OFF) socket_turn_off (); else if (cmd == SCIM_TRANS_CMD_UPDATE_SCREEN) socket_update_screen (); else if (cmd == SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION) socket_update_spot_location (); else if (cmd == SCIM_TRANS_CMD_PANEL_UPDATE_FACTORY_INFO) socket_update_factory_info (); else if (cmd == SCIM_TRANS_CMD_SHOW_PREEDIT_STRING) socket_show_preedit_string (); else if (cmd == SCIM_TRANS_CMD_SHOW_AUX_STRING) socket_show_aux_string (); else if (cmd == SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE) socket_show_lookup_table (); else if (cmd == SCIM_TRANS_CMD_HIDE_PREEDIT_STRING) socket_hide_preedit_string (); else if (cmd == SCIM_TRANS_CMD_HIDE_AUX_STRING) socket_hide_aux_string (); else if (cmd == SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE) socket_hide_lookup_table (); else if (cmd == SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING) socket_update_preedit_string (); else if (cmd == SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET) socket_update_preedit_caret (); else if (cmd == SCIM_TRANS_CMD_UPDATE_AUX_STRING) socket_update_aux_string (); else if (cmd == SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE) socket_update_lookup_table (); else if (cmd == SCIM_TRANS_CMD_REGISTER_PROPERTIES) socket_register_properties (); else if (cmd == SCIM_TRANS_CMD_UPDATE_PROPERTY) socket_update_property (); else if (cmd == SCIM_TRANS_CMD_PANEL_SHOW_HELP) socket_show_help (); else if (cmd == SCIM_TRANS_CMD_FOCUS_OUT) { SCIM_DEBUG_MAIN (2) << "PanelAgent::focus_out (" << client_id << "," << "," << context << ")\n"; lock (); if (m_current_socket_client >= 0) { m_last_socket_client = m_current_socket_client; m_last_client_context = m_current_client_context; m_last_context_uuid = m_current_context_uuid; } m_current_socket_client = -1; m_current_client_context = 0; m_current_context_uuid = String (""); unlock (); socket_turn_off (); } } socket_transaction_end(); } } else if (client_info.type == HELPER_CLIENT) { socket_transaction_start(); while (m_recv_trans.get_command (cmd)) { if (cmd == SCIM_TRANS_CMD_PANEL_REGISTER_HELPER) { socket_helper_register_helper (client_id); } else if (cmd == SCIM_TRANS_CMD_COMMIT_STRING) { socket_helper_commit_string (client_id); } else if (cmd == SCIM_TRANS_CMD_PROCESS_KEY_EVENT || cmd == SCIM_TRANS_CMD_PANEL_SEND_KEY_EVENT) { socket_helper_send_key_event (client_id); } else if (cmd == SCIM_TRANS_CMD_FORWARD_KEY_EVENT) { socket_helper_forward_key_event (client_id); } else if (cmd == SCIM_TRANS_CMD_PANEL_SEND_IMENGINE_EVENT) { socket_helper_send_imengine_event (client_id); } else if (cmd == SCIM_TRANS_CMD_REGISTER_PROPERTIES) { socket_helper_register_properties (client_id); } else if (cmd == SCIM_TRANS_CMD_UPDATE_PROPERTY) { socket_helper_update_property (client_id); } else if (cmd == SCIM_TRANS_CMD_RELOAD_CONFIG) { reload_config (); m_signal_reload_config (); } } socket_transaction_end(); } else if (client_info.type == PANELCONTROL_CLIENT) { SCIM_DEBUG_MAIN (1) << "PanelAgent::PanelController Client\n"; socket_transaction_start(); while (m_recv_trans.get_command (cmd)) { SCIM_DEBUG_MAIN (3) << "PanelAgent::cmd = " << cmd << "\n"; if(previous_command_is_outstanding_for_client(client_id)) return; //if the response to a previous command is outstanding we ignore the current command if (cmd == SCIM_TRANS_CMD_CONTROLLER_REQUEST_FACTORY_MENU) { register_awaited_command_for_client(client_id, SCIM_TRANS_CMD_PANEL_SHOW_FACTORY_MENU); socket_panelcontroller_request_factory_menu (); } if (cmd == SCIM_TRANS_CMD_CONTROLLER_CHANGE_FACTORY) { register_awaited_command_for_client(client_id, SCIM_TRANS_CMD_PANEL_UPDATE_FACTORY_INFO); socket_panelcontroller_change_factory (); } if (cmd == SCIM_TRANS_CMD_CONTROLLER_GET_CURRENT_FACTORY) { register_awaited_command_for_client(client_id, SCIM_TRANS_CMD_PANEL_RETURN_CURRENT_FACTORY_INFO); socket_panelcontroller_get_current_factory (client_id); } if (cmd == SCIM_TRANS_CMD_CONTROLLER_GET_CURRENT_CONTEXT) { register_awaited_command_for_client(client_id, SCIM_TRANS_CMD_PANEL_RETURN_CURRENT_CONTEXT); socket_panelcontroller_get_current_frontend_client_and_context (client_id); } } socket_transaction_end(); } } bool previous_command_is_outstanding_for_client(int client_id){ ClientRepository::iterator it = m_client_repository.find (client_id); return (it->second.awaitedTransCommand != 0); } void register_awaited_command_for_client(int client_id, int cmd){ ClientRepository::iterator it = m_client_repository.find (client_id); it->second.awaitedTransCommand = cmd; } int expected_command_for_client(int client_id){ ClientRepository::iterator it = m_client_repository.find (client_id); return it->second.awaitedTransCommand; } void socket_panelcontroller_get_current_frontend_client_and_context(int client_id) { SCIM_DEBUG_MAIN (2) << "PanelAgent::socket_panelcontroller_get_current_frontend_client_and_context ()\n"; inform_waiting_client_of_current_context(client_id); } void socket_panelcontroller_request_factory_menu() { SCIM_DEBUG_MAIN (2) << "PanelAgent::socket_panelcontroller_request_factory_menu ()\n"; request_factory_menu(); } void socket_panelcontroller_change_factory () { String requested_uuid; m_recv_trans.get_data(requested_uuid); SCIM_DEBUG_MAIN (2) << "PanelAgent::socket_panelcontroller_change_factory ()" << requested_uuid << "\n"; change_factory(requested_uuid); } void socket_panelcontroller_get_current_factory (int client_id) { SCIM_DEBUG_MAIN (2) << "PanelAgent::socket_panelcontroller_get_current_factory ()\n"; inform_waiting_client_of_current_factory(client_id); } void socket_exception_callback (SocketServer *server, const Socket &client) { SCIM_DEBUG_MAIN (2) << "PanelAgent::socket_exception_callback (" << client.get_id () << ")\n"; socket_close_connection (server, client); } bool socket_open_connection (SocketServer *server, const Socket &client) { SCIM_DEBUG_MAIN (3) << "PanelAgent::socket_open_connection (" << client.get_id () << ")\n"; uint32 key; String type = scim_socket_accept_connection (key, String ("Panel"), String ("FrontEnd,Helper,PanelController"), client, m_socket_timeout); if (type.length ()) { ClientInfo info; info.key = key; info.awaitedTransCommand = 0; if (type=="FrontEnd") {info.type = FRONTEND_CLIENT;} else if (type=="Helper") {info.type = HELPER_CLIENT;} else {info.type = PANELCONTROL_CLIENT;} SCIM_DEBUG_MAIN (4) << "Add client to repository. Type=" << type << " key=" << key << "\n"; lock (); m_client_repository [client.get_id ()] = info; unlock (); return true; } SCIM_DEBUG_MAIN (4) << "Close client connection " << client.get_id () << "\n"; server->close_connection (client); return false; } void socket_close_connection (SocketServer *server, const Socket &client) { SCIM_DEBUG_MAIN (3) << "PanelAgent::socket_close_connection (" << client.get_id () << ")\n"; lock (); ClientInfo client_info = socket_get_client_info (client.get_id ()); m_client_repository.erase (client.get_id ()); server->close_connection (client); // Exit panel if there is no connected client anymore. if (client_info.type != UNKNOWN_CLIENT && m_client_repository.size () == 0 && !m_should_resident) { SCIM_DEBUG_MAIN (4) << "Exit Socket Server Thread.\n"; server->shutdown (); } unlock (); if (client_info.type == FRONTEND_CLIENT) { SCIM_DEBUG_MAIN(4) << "It's a FrontEnd client.\n"; // The focused client is closed. if (m_current_socket_client == client.get_id ()) { lock (); m_current_socket_client = -1; m_current_client_context = 0; m_current_context_uuid = String (""); unlock (); socket_transaction_start (); socket_turn_off (); socket_transaction_end (); } if (m_last_socket_client == client.get_id ()) { lock (); m_last_socket_client = -1; m_last_client_context = 0; m_last_context_uuid = String (""); unlock (); } // Erase all associated Client Context UUIDs. std::vector ctx_list; ClientContextUUIDRepository::iterator it = m_client_context_uuids.begin (); for (; it != m_client_context_uuids.end (); ++it) { if ((it->first & 0xFFFF) == (client.get_id () & 0xFFFF)) ctx_list.push_back (it->first); } for (size_t i = 0; i < ctx_list.size (); ++i) m_client_context_uuids.erase (ctx_list [i]); } else if (client_info.type == HELPER_CLIENT) { SCIM_DEBUG_MAIN(4) << "It's a Helper client.\n"; lock (); HelperInfoRepository::iterator hiit = m_helper_info_repository.find (client.get_id ()); if (hiit != m_helper_info_repository.end ()) { bool restart = false; String uuid = hiit->second.uuid; HelperClientIndex::iterator it = m_helper_client_index.find (uuid); if ((hiit->second.option & SCIM_HELPER_AUTO_RESTART) && it->second.ref > 0) restart = true; m_helper_client_index.erase (uuid); m_helper_info_repository.erase (hiit); if (restart) m_helper_manager.run_helper (uuid, m_config_name, m_display_name); } unlock (); socket_transaction_start (); m_signal_remove_helper (client.get_id ()); socket_transaction_end (); } } const ClientInfo & socket_get_client_info (int client) { static ClientInfo null_client = { 0, UNKNOWN_CLIENT }; ClientRepository::iterator it = m_client_repository.find (client); if (it != m_client_repository.end ()) return it->second; return null_client; } private: void socket_turn_on (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_turn_on ()\n"; m_signal_turn_on (); } void socket_turn_off (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_turn_off ()\n"; //inform_waiting_clients_of_factory_update(m_defaultFactoryInfo); m_signal_turn_off (); } void socket_update_screen (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_screen ()\n"; uint32 num; if (m_recv_trans.get_data (num) && ((int) num) != m_current_screen) { SCIM_DEBUG_MAIN(4) << "New Screen number = " << num << "\n"; m_signal_update_screen ((int) num); helper_all_update_screen ((int) num); m_current_screen = (num); } } void socket_update_spot_location (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_spot_location ()\n"; uint32 x, y; if (m_recv_trans.get_data (x) && m_recv_trans.get_data (y)) { SCIM_DEBUG_MAIN(4) << "New Spot location x=" << x << " y=" << y << "\n"; m_signal_update_spot_location ((int)x, (int)y); helper_all_update_spot_location ((int)x, (int)y); } } void socket_update_factory_info (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_factory_info ()\n"; PanelFactoryInfo info; if (m_recv_trans.get_data (info.uuid) && m_recv_trans.get_data (info.name) && m_recv_trans.get_data (info.lang) && m_recv_trans.get_data (info.icon)) { SCIM_DEBUG_MAIN(4) << "New Factory info uuid=" << info.uuid << " name=" << info.name << "\n"; info.lang = scim_get_normalized_language (info.lang); m_currentFactoryInfo = info; m_signal_update_factory_info (info); inform_waiting_clients_of_factory_update(info); } } bool inform_waiting_clients_of_factory_update(PanelFactoryInfo info){ bool message_was_forwarded = false; SCIM_DEBUG_MAIN (1) << "PanelAgent::Checking if message needs forwarding\n"; for(ClientRepository::iterator it = m_client_repository.begin (); it != m_client_repository.end (); ++it){ if(it->second.awaitedTransCommand == SCIM_TRANS_CMD_PANEL_UPDATE_FACTORY_INFO){ uint32 context = m_current_client_context; Socket client_socket (it->first); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); //this is the REAL context. i.e. it is 0 when the desktop is focused m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_UPDATE_FACTORY_INFO); m_send_trans.put_data (info.uuid); m_send_trans.put_data (info.name); m_send_trans.put_data (info.lang); m_send_trans.put_data (info.icon); m_send_trans.write_to_socket (client_socket); SCIM_DEBUG_MAIN (2) << "Forwarded message " << "SCIM_TRANS_CMD_PANEL_UPDATE_FACTORY_INFO" << "to " << it->first << "\n"; it->second.awaitedTransCommand = 0; message_was_forwarded = true; break; //client iteration } } return message_was_forwarded; } void inform_waiting_client_of_current_context(int client_id){ SCIM_DEBUG_MAIN (1) << "PanelAgent::Checking if message needs forwarding\n"; uint32 context = m_current_client_context; Socket client_socket (client_id); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); //this is the REAL context. i.e. it is 0 when the desktop is focused m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_RETURN_CURRENT_CONTEXT); m_send_trans.put_data ((uint32) m_current_socket_client); //this is the REAL client. i.e. it is -1 when the desktop is focused m_send_trans.put_data ((uint32) m_current_client_context); //this is the REAL context. i.e. it is 0 when the desktop is focused m_send_trans.write_to_socket (client_socket); m_client_repository[client_id].awaitedTransCommand = 0; SCIM_DEBUG_MAIN (2) << "Forwarded message " << "SCIM_TRANS_CMD_PANEL_RETURN_CURRENT_CONTEXT\n"; } void inform_waiting_client_of_current_factory(int client_id){ SCIM_DEBUG_MAIN (1) << "PanelAgent::Checking if message needs forwarding\n"; uint32 context = m_current_client_context; Socket client_socket (client_id); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); //this is the REAL context. i.e. it is 0 when the desktop is focused m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_RETURN_CURRENT_FACTORY_INFO); m_send_trans.put_data (m_currentFactoryInfo.uuid); m_send_trans.put_data (m_currentFactoryInfo.name); m_send_trans.put_data (m_currentFactoryInfo.lang); m_send_trans.put_data (m_currentFactoryInfo.icon); m_send_trans.write_to_socket (client_socket); m_client_repository[client_id].awaitedTransCommand = 0; SCIM_DEBUG_MAIN (2) << "Forwarded message " << "SCIM_TRANS_CMD_PANEL_RETURN_CURRENT_FACTORY_INFO\n"; } void socket_show_help (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_show_help ()\n"; String help; if (m_recv_trans.get_data (help)) m_signal_show_help (help); } void socket_show_factory_menu (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_show_factory_menu ()\n"; PanelFactoryInfo info; std::vector vec; while (m_recv_trans.get_data (info.uuid) && m_recv_trans.get_data (info.name) && m_recv_trans.get_data (info.lang) && m_recv_trans.get_data (info.icon)) { info.lang = scim_get_normalized_language (info.lang); vec.push_back (info); } if (vec.size ()){ if(!inform_waiting_clients_of_factory_menu(vec)) m_signal_show_factory_menu (vec); } } bool inform_waiting_clients_of_factory_menu(std::vector menu){ bool message_was_forwarded = false; SCIM_DEBUG_MAIN (1) << "PanelAgent::Checking if message needs forwarding\n"; menu.push_back(m_defaultFactoryInfo); for(ClientRepository::iterator it = m_client_repository.begin (); it != m_client_repository.end (); ++it){ if(it->second.awaitedTransCommand == SCIM_TRANS_CMD_PANEL_SHOW_FACTORY_MENU){ uint32 context = m_current_client_context; Socket client_socket (it->first); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data ((uint32) context); //this is the REAL context. i.e. it is 0 when the desktop is focused m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_SHOW_FACTORY_MENU); for (size_t i = 0; i < menu.size (); ++ i) { m_send_trans.put_data (menu [i].uuid); m_send_trans.put_data (menu [i].name); m_send_trans.put_data (menu [i].lang); m_send_trans.put_data (menu [i].icon); } m_send_trans.write_to_socket (client_socket); SCIM_DEBUG_MAIN (2) << "Forwarded message " << "SCIM_TRANS_CMD_PANEL_SHOW_FACTORY_MENU" << "to " << it->first << "\n"; it->second.awaitedTransCommand = 0; message_was_forwarded = true; break; //client iteration } } return message_was_forwarded; } void socket_show_preedit_string (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_show_preedit_string ()\n"; m_signal_show_preedit_string (); } void socket_show_aux_string (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_show_aux_string ()\n"; m_signal_show_aux_string (); } void socket_show_lookup_table (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_show_lookup_table ()\n"; m_signal_show_lookup_table (); } void socket_hide_preedit_string (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_hide_preedit_string ()\n"; m_signal_hide_preedit_string (); } void socket_hide_aux_string (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_hide_aux_string ()\n"; m_signal_hide_aux_string (); } void socket_hide_lookup_table (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_hide_lookup_table ()\n"; m_signal_hide_lookup_table (); } void socket_update_preedit_string (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_preedit_string ()\n"; String str; AttributeList attrs; if (m_recv_trans.get_data (str) && m_recv_trans.get_data (attrs)) m_signal_update_preedit_string (str, attrs); } void socket_update_preedit_caret (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_preedit_caret ()\n"; uint32 caret; if (m_recv_trans.get_data (caret)) m_signal_update_preedit_caret ((int) caret); } void socket_update_aux_string (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_aux_string ()\n"; String str; AttributeList attrs; if (m_recv_trans.get_data (str) && m_recv_trans.get_data (attrs)) m_signal_update_aux_string (str, attrs); } void socket_update_lookup_table (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_lookup_table ()\n"; CommonLookupTable table; if (m_recv_trans.get_data (table)) m_signal_update_lookup_table (table); } void socket_register_properties (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_register_properties ()\n"; PropertyList properties; if (m_recv_trans.get_data (properties)) m_signal_register_properties (properties); } void socket_update_property (void) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_property ()\n"; Property property; if (m_recv_trans.get_data (property)) m_signal_update_property (property); } void socket_start_helper (int client, uint32 context, const String &ic_uuid) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_start_helper ()\n"; String uuid; if (m_recv_trans.get_data (uuid) && uuid.length ()) { HelperClientIndex::iterator it = m_helper_client_index.find (uuid); uint32 ic; lock (); ic = get_helper_ic (client, context); SCIM_DEBUG_MAIN(5) << "Helper UUID =" << uuid << " IC UUID =" << ic_uuid <<"\n"; if (it == m_helper_client_index.end ()) { SCIM_DEBUG_MAIN(5) << "Run this Helper.\n"; m_start_helper_ic_index [uuid].push_back (std::make_pair (ic, ic_uuid)); m_helper_manager.run_helper (uuid, m_config_name, m_display_name); } else { SCIM_DEBUG_MAIN(5) << "Increase the Reference count.\n"; Socket client_socket (it->second.id); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data (ic); m_send_trans.put_data (ic_uuid); m_send_trans.put_command (SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT); m_send_trans.write_to_socket (client_socket); ++ it->second.ref; } unlock (); } } void socket_stop_helper (int client, uint32 context, const String &ic_uuid) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_stop_helper ()\n"; String uuid; if (m_recv_trans.get_data (uuid) && uuid.length ()) { HelperClientIndex::iterator it = m_helper_client_index.find (uuid); uint32 ic; lock (); ic = get_helper_ic (client, context); SCIM_DEBUG_MAIN(5) << "Helper UUID =" << uuid << " IC UUID =" << ic_uuid <<"\n"; if (it != m_helper_client_index.end ()) { SCIM_DEBUG_MAIN(5) << "Decrase the Reference count.\n"; -- it->second.ref; Socket client_socket (it->second.id); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data (ic); m_send_trans.put_data (ic_uuid); m_send_trans.put_command (SCIM_TRANS_CMD_HELPER_DETACH_INPUT_CONTEXT); if (it->second.ref <= 0) m_send_trans.put_command (SCIM_TRANS_CMD_EXIT); m_send_trans.write_to_socket (client_socket); } unlock (); } } void socket_send_helper_event (int client, uint32 context, const String &ic_uuid) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_send_helper_event ()\n"; String uuid; if (m_recv_trans.get_data (uuid) && m_recv_trans.get_data (m_nest_trans) && uuid.length () && m_nest_trans.valid ()) { HelperClientIndex::iterator it = m_helper_client_index.find (uuid); if (it != m_helper_client_index.end ()) { Socket client_socket (it->second.id); lock (); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); // FIXME: We presume that client and context are both less than 65536. // Hopefully, it should be true in any UNIXs. // So it's ok to combine client and context into one uint32. m_send_trans.put_data (get_helper_ic (client, context)); m_send_trans.put_data (ic_uuid); m_send_trans.put_command (SCIM_TRANS_CMD_HELPER_PROCESS_IMENGINE_EVENT); m_send_trans.put_data (m_nest_trans); m_send_trans.write_to_socket (client_socket); unlock (); } } } void socket_helper_register_properties (int client) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_register_properties (" << client << ")\n"; PropertyList properties; if (m_recv_trans.get_data (properties)) m_signal_register_helper_properties (client, properties); } void socket_helper_update_property (int client) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_update_property (" << client << ")\n"; Property property; if (m_recv_trans.get_data (property)) m_signal_update_helper_property (client, property); } void socket_helper_send_imengine_event (int client) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_send_imengine_event (" << client << ")\n"; uint32 target_ic; String target_uuid; HelperInfoRepository::iterator hiit = m_helper_info_repository.find (client); if (m_recv_trans.get_data (target_ic) && m_recv_trans.get_data (target_uuid) && m_recv_trans.get_data (m_nest_trans) && m_nest_trans.valid () && hiit != m_helper_info_repository.end ()) { int target_client; uint32 target_context; get_imengine_client_context (target_ic, target_client, target_context); int focused_client; uint32 focused_context; String focused_uuid; focused_uuid = get_focused_context (focused_client, focused_context); if (target_ic == (uint32) (-1)) { target_client = focused_client; target_context = focused_context; } if (target_uuid.length () == 0) target_uuid = focused_uuid; ClientInfo client_info = socket_get_client_info (target_client); SCIM_DEBUG_MAIN(5) << "Target UUID = " << target_uuid << " Focused UUId = " << focused_uuid << "\nTarget Client = " << target_client << "\n"; if (client_info.type == FRONTEND_CLIENT) { Socket socket_client (target_client); lock (); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data (target_context); m_send_trans.put_command (SCIM_TRANS_CMD_PROCESS_HELPER_EVENT); m_send_trans.put_data (target_uuid); m_send_trans.put_data (hiit->second.uuid); m_send_trans.put_data (m_nest_trans); m_send_trans.write_to_socket (socket_client); unlock (); } } } void socket_helper_key_event_op (int client, int cmd) { uint32 target_ic; String target_uuid; KeyEvent key; if (m_recv_trans.get_data (target_ic) && m_recv_trans.get_data (target_uuid) && m_recv_trans.get_data (key) && !key.empty ()) { int target_client; uint32 target_context; get_imengine_client_context (target_ic, target_client, target_context); int focused_client; uint32 focused_context; String focused_uuid; focused_uuid = get_focused_context (focused_client, focused_context); if (target_ic == (uint32) (-1)) { target_client = focused_client; target_context = focused_context; } if (target_uuid.length () == 0) target_uuid = focused_uuid; if (target_client == focused_client && target_context == focused_context && target_uuid == focused_uuid) { ClientInfo client_info = socket_get_client_info (target_client); if (client_info.type == FRONTEND_CLIENT) { Socket socket_client (target_client); lock (); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data (target_context); m_send_trans.put_command (cmd); m_send_trans.put_data (key); m_send_trans.write_to_socket (socket_client); unlock (); } } } } void socket_helper_send_key_event (int client) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_send_key_event (" << client << ")\n"; socket_helper_key_event_op (client, SCIM_TRANS_CMD_PROCESS_KEY_EVENT); } void socket_helper_forward_key_event (int client) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_forward_key_event (" << client << ")\n"; socket_helper_key_event_op (client, SCIM_TRANS_CMD_FORWARD_KEY_EVENT); } void socket_helper_commit_string (int client) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_commit_string (" << client << ")\n"; uint32 target_ic; String target_uuid; WideString wstr; if (m_recv_trans.get_data (target_ic) && m_recv_trans.get_data (target_uuid) && m_recv_trans.get_data (wstr) && wstr.length ()) { int target_client; uint32 target_context; get_imengine_client_context (target_ic, target_client, target_context); int focused_client; uint32 focused_context; String focused_uuid; focused_uuid = get_focused_context (focused_client, focused_context); if (target_ic == (uint32) (-1)) { target_client = focused_client; target_context = focused_context; } if (target_uuid.length () == 0) target_uuid = focused_uuid; if (target_client == focused_client && target_context == focused_context && target_uuid == focused_uuid) { ClientInfo client_info = socket_get_client_info (target_client); if (client_info.type == FRONTEND_CLIENT) { Socket socket_client (target_client); lock (); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); m_send_trans.put_data (target_context); m_send_trans.put_command (SCIM_TRANS_CMD_COMMIT_STRING); m_send_trans.put_data (wstr); m_send_trans.write_to_socket (socket_client); unlock (); } } } } void socket_helper_register_helper (int client) { SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_register_helper (" << client << ")\n"; HelperInfo info; bool result = false; lock (); Socket socket_client (client); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); if (m_recv_trans.get_data (info.uuid) && m_recv_trans.get_data (info.name) && m_recv_trans.get_data (info.icon) && m_recv_trans.get_data (info.description) && m_recv_trans.get_data (info.option) && info.uuid.length () && info.name.length ()) { SCIM_DEBUG_MAIN(4) << "New Helper uuid=" << info.uuid << " name=" << info.name << "\n"; HelperClientIndex::iterator it = m_helper_client_index.find (info.uuid); if (it == m_helper_client_index.end ()) { m_helper_info_repository [client] = info; m_helper_client_index [info.uuid] = HelperClientStub (client, 1); m_send_trans.put_command (SCIM_TRANS_CMD_OK); StartHelperICIndex::iterator icit = m_start_helper_ic_index.find (info.uuid); if (icit != m_start_helper_ic_index.end ()) { m_send_trans.put_command (SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT); for (size_t i = 0; i < icit->second.size (); ++i) { m_send_trans.put_data (icit->second [i].first); m_send_trans.put_data (icit->second [i].second); } m_start_helper_ic_index.erase (icit); } m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_SCREEN); m_send_trans.put_data ((uint32)m_current_screen); result = true; } else { m_send_trans.put_command (SCIM_TRANS_CMD_FAIL); } } m_send_trans.write_to_socket (socket_client); unlock (); if (result) m_signal_register_helper (client, info); } void helper_all_update_spot_location (int x, int y) { SCIM_DEBUG_MAIN (5) << "PanelAgent::helper_all_update_spot_location (" << x << "," << y << ")\n"; HelperInfoRepository::iterator hiit = m_helper_info_repository.begin (); int client; uint32 context; String uuid; uuid = get_focused_context (client, context); lock (); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); // FIXME: We presume that client and context are both less than 65536. // Hopefully, it should be true in any UNIXs. // So it's ok to combine client and context into one uint32. m_send_trans.put_data (get_helper_ic (client, context)); m_send_trans.put_data (uuid); m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION); m_send_trans.put_data ((uint32) x); m_send_trans.put_data ((uint32) y); for (; hiit != m_helper_info_repository.end (); ++ hiit) { if (hiit->second.option & SCIM_HELPER_NEED_SPOT_LOCATION_INFO) { Socket client_socket (hiit->first); m_send_trans.write_to_socket (client_socket); } } unlock (); } void helper_all_update_screen (int screen) { SCIM_DEBUG_MAIN (5) << "PanelAgent::helper_all_update_screen (" << screen << ")\n"; HelperInfoRepository::iterator hiit = m_helper_info_repository.begin (); int client; uint32 context; String uuid; lock (); uuid = get_focused_context (client, context); m_send_trans.clear (); m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); // FIXME: We presume that client and context are both less than 65536. // Hopefully, it should be true in any UNIXs. // So it's ok to combine client and context into one uint32. m_send_trans.put_data (get_helper_ic (client, context)); m_send_trans.put_data (uuid); m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_SCREEN); m_send_trans.put_data ((uint32) screen); for (; hiit != m_helper_info_repository.end (); ++ hiit) { if (hiit->second.option & SCIM_HELPER_NEED_SCREEN_INFO) { Socket client_socket (hiit->first); m_send_trans.write_to_socket (client_socket); } } unlock (); } const String & get_focused_context (int &client, uint32 &context, bool force_last_context = false) const { if (m_current_socket_client >= 0) { client = m_current_socket_client; context = m_current_client_context; return m_current_context_uuid; } else { client = m_last_socket_client; context = m_last_client_context; return m_last_context_uuid; } } private: void socket_transaction_start (void) { m_signal_transaction_start(); } void socket_transaction_end (void) { m_signal_transaction_end(); } void lock (void) { m_signal_lock (); } void unlock (void) { m_signal_unlock (); } }; PanelAgent::PanelAgent () : m_impl (new PanelAgentImpl ()) { } PanelAgent::~PanelAgent () { delete m_impl; } bool PanelAgent::initialize (const String &config, const String &display, bool resident) { return m_impl->initialize (config, display, resident); } bool PanelAgent::valid (void) const { return m_impl->valid (); } bool PanelAgent::run (void) { return m_impl->run (); } void PanelAgent::stop (void) { m_impl->stop (); } int PanelAgent::get_helper_list (std::vector & helpers) const { return m_impl->get_helper_list (helpers); } bool PanelAgent::move_preedit_caret (uint32 position) { return m_impl->move_preedit_caret (position); } bool PanelAgent::request_help (void) { return m_impl->request_help (); } bool PanelAgent::request_factory_menu (void) { return m_impl->request_factory_menu (); } bool PanelAgent::change_factory (const String &uuid) { return m_impl->change_factory (uuid); } bool PanelAgent::select_candidate (uint32 item) { return m_impl->select_candidate (item); } bool PanelAgent::lookup_table_page_up (void) { return m_impl->lookup_table_page_up (); } bool PanelAgent::lookup_table_page_down (void) { return m_impl->lookup_table_page_down (); } bool PanelAgent::update_lookup_table_page_size (uint32 size) { return m_impl->update_lookup_table_page_size (size); } bool PanelAgent::trigger_property (const String &property) { return m_impl->trigger_property (property); } bool PanelAgent::trigger_helper_property (int client, const String &property) { return m_impl->trigger_helper_property (client, property); } bool PanelAgent::start_helper (const String &uuid) { return m_impl->start_helper (uuid); } bool PanelAgent::reload_config (void) { return m_impl->reload_config (); } bool PanelAgent::exit (void) { return m_impl->exit (); } Connection PanelAgent::signal_connect_reload_config (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_reload_config (slot); } Connection PanelAgent::signal_connect_turn_on (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_turn_on (slot); } Connection PanelAgent::signal_connect_turn_off (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_turn_off (slot); } Connection PanelAgent::signal_connect_update_screen (PanelAgentSlotInt *slot) { return m_impl->signal_connect_update_screen (slot); } Connection PanelAgent::signal_connect_update_spot_location (PanelAgentSlotIntInt *slot) { return m_impl->signal_connect_update_spot_location (slot); } Connection PanelAgent::signal_connect_update_factory_info (PanelAgentSlotFactoryInfo *slot) { return m_impl->signal_connect_update_factory_info (slot); } Connection PanelAgent::signal_connect_show_help (PanelAgentSlotString *slot) { return m_impl->signal_connect_show_help (slot); } Connection PanelAgent::signal_connect_show_factory_menu (PanelAgentSlotFactoryInfoVector *slot) { return m_impl->signal_connect_show_factory_menu (slot); } Connection PanelAgent::signal_connect_show_preedit_string (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_show_preedit_string (slot); } Connection PanelAgent::signal_connect_show_aux_string (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_show_aux_string (slot); } Connection PanelAgent::signal_connect_show_lookup_table (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_show_lookup_table (slot); } Connection PanelAgent::signal_connect_hide_preedit_string (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_hide_preedit_string (slot); } Connection PanelAgent::signal_connect_hide_aux_string (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_hide_aux_string (slot); } Connection PanelAgent::signal_connect_hide_lookup_table (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_hide_lookup_table (slot); } Connection PanelAgent::signal_connect_update_preedit_string (PanelAgentSlotAttributeString *slot) { return m_impl->signal_connect_update_preedit_string (slot); } Connection PanelAgent::signal_connect_update_preedit_caret (PanelAgentSlotInt *slot) { return m_impl->signal_connect_update_preedit_caret (slot); } Connection PanelAgent::signal_connect_update_aux_string (PanelAgentSlotAttributeString *slot) { return m_impl->signal_connect_update_aux_string (slot); } Connection PanelAgent::signal_connect_update_lookup_table (PanelAgentSlotLookupTable *slot) { return m_impl->signal_connect_update_lookup_table (slot); } Connection PanelAgent::signal_connect_register_properties (PanelAgentSlotPropertyList *slot) { return m_impl->signal_connect_register_properties (slot); } Connection PanelAgent::signal_connect_update_property (PanelAgentSlotProperty *slot) { return m_impl->signal_connect_update_property (slot); } Connection PanelAgent::signal_connect_register_helper_properties (PanelAgentSlotIntPropertyList *slot) { return m_impl->signal_connect_register_helper_properties (slot); } Connection PanelAgent::signal_connect_update_helper_property (PanelAgentSlotIntProperty *slot) { return m_impl->signal_connect_update_helper_property (slot); } Connection PanelAgent::signal_connect_register_helper (PanelAgentSlotIntHelperInfo *slot) { return m_impl->signal_connect_register_helper (slot); } Connection PanelAgent::signal_connect_remove_helper (PanelAgentSlotInt *slot) { return m_impl->signal_connect_remove_helper (slot); } Connection PanelAgent::signal_connect_transaction_start (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_transaction_start (slot); } Connection PanelAgent::signal_connect_transaction_end (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_transaction_end (slot); } Connection PanelAgent::signal_connect_lock (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_lock (slot); } Connection PanelAgent::signal_connect_unlock (PanelAgentSlotVoid *slot) { return m_impl->signal_connect_unlock (slot); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_object.h0000644000175000017500000000606012422143415015362 0ustar tzhuantzhuan/** @file scim_object.h * @brief Reference counted base class interface. * * Provides a reference counted base class * for dynamic objects handled the scim smart pointer. * * Most code of this file are came from Inti project. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * Copyright (c) 2002 The Inti Development Team. * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_object.h,v 1.9 2005/01/10 08:30:54 suzhe Exp $ */ #ifndef __SCIM_OBJECT_H #define __SCIM_OBJECT_H namespace scim { /** * @addtogroup Accessories * @{ */ /** * @class ReferencedObject * @brief Reference counted base class. * * ReferencedObject is a reference counting base class. * it has an integer reference counter so that dynamic objects * can have their memory allocation handled by the scim * smart pointer: Pointer<>. This keeps the memory management * in scim consistent across all classes. * If you derive a class from ReferencedObject and allocate it * on the heap, you free the memory and destroy the object by * calling unref(), not delete. */ class ReferencedObject { template friend class Pointer; ReferencedObject(const ReferencedObject&); ReferencedObject& operator=(const ReferencedObject&); bool m_referenced; int m_ref_count; protected: ReferencedObject(); //!< Constructor. virtual ~ReferencedObject() = 0; //!< Destructor. void set_referenced(bool reference); //!< Set the internal referenced flag. //!< @param reference - true if the initial reference count must be removed by owner. //!< //!<
Called by derived classes to set the referenced flag. A object sets this flag //!< to true , indicating that it owns the initial reference count and unref() must be called. public: bool is_referenced() const; //!< The referenced flag setting. //!< @return true if unref() must be explicitly called on this object. void ref(); //!< Increase an object's reference count by one. void unref(); //!< Decrease an object's reference count by one. //!< When the reference count becomes zero delete is called. Remember, with ReferencedObject //!< you must call unref() on dynmaically allocated objects, not delete. }; /** @} */ } // namespace scim #endif //__SCIM_OBJECT_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_object.cpp0000644000175000017500000000312612422143415015715 0ustar tzhuantzhuan/* * Most code of this file are came from Inti project. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * Copyright (c) 2002 The Inti Development Team. * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_object.cpp,v 1.9 2005/01/10 08:30:54 suzhe Exp $ */ #define Uses_SCIM_OBJECT #include "scim_private.h" #include "scim.h" namespace scim { /* ReferencedObject */ ReferencedObject::ReferencedObject () : m_referenced (true), m_ref_count (1) { } ReferencedObject::~ReferencedObject () { } void ReferencedObject::set_referenced (bool reference) { m_referenced = reference; } bool ReferencedObject::is_referenced() const { return m_referenced; } void ReferencedObject::ref() { ++m_ref_count; } void ReferencedObject::unref() { if (--m_ref_count == 0) delete this; } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_module.h0000644000175000017500000000361212422143415015401 0ustar tzhuantzhuan/** @file scim_module.h * @brief definition of Module related classes. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_module.h,v 1.19 2005/01/10 08:30:54 suzhe Exp $ */ #ifndef __SCIM_MODULE_H #define __SCIM_MODULE_H namespace scim { /** * @addtogroup Accessories * @{ */ class ModuleError: public Exception { public: ModuleError (const String& what_arg) : Exception (String("scim::Module: ") + what_arg) { } }; class Module { class ModuleImpl; ModuleImpl *m_impl; Module (const Module &); Module & operator= (const Module &); public: Module (); Module (const String &name, const String &type); ~Module (); bool load (const String &name, const String &type); bool unload (); bool valid () const; bool is_resident () const; bool make_resident () const; String get_path () const; void * symbol (const String & sym) const; protected: void init(); }; int scim_get_module_list (std::vector & mod_list, const String& type = ""); /** @} */ } // namespace scim #endif //__SCIM_MODULE_H /* vi:ts=4:ai:nowrap:expandtab */ scim-1.4.15/src/scim_module.cpp0000644000175000017500000002162512422143415015740 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_module.cpp,v 1.26 2005/05/24 12:22:51 suzhe Exp $ * */ #define Uses_SCIM_MODULE #define Uses_STL_ALGORITHM #include "scim_private.h" #include "scim.h" extern "C" { #include } #include #include #include #include namespace scim { typedef void (*ModuleInitFunc) (void); typedef void (*ModuleExitFunc) (void); struct Module::ModuleImpl { #if SCIM_LTDLADVISE lt_dladvise advise; #endif lt_dlhandle handle; ModuleInitFunc init; ModuleExitFunc exit; String path; String name; ModuleImpl () : handle (0), init (0), exit (0) { } }; static std::vector _scim_modules; static void _scim_get_module_paths (std::vector &paths, const String &type) { const char *module_path_env; std::vector module_paths; std::vector ::iterator it; paths.clear (); module_path_env = getenv ("SCIM_MODULE_PATH"); if (module_path_env) module_paths.push_back (String (module_path_env)); module_paths.push_back (String (SCIM_MODULE_PATH)); // append version to the end of the paths for (it = module_paths.begin (); it != module_paths.end (); ++it) { String tmp_dir; tmp_dir = *it + String (SCIM_PATH_DELIM_STRING) + String (SCIM_BINARY_VERSION) + String (SCIM_PATH_DELIM_STRING) + type; paths.push_back (tmp_dir); tmp_dir = *it + String (SCIM_PATH_DELIM_STRING) + type; paths.push_back (tmp_dir); } } int scim_get_module_list (std::vector & mod_list, const String& type) { std::vector paths; _scim_get_module_paths (paths, type); mod_list.clear (); for (std::vector::iterator i = paths.begin (); i!= paths.end (); ++i) { DIR *dir = opendir (i->c_str ()); if (dir) { struct dirent *file = readdir (dir); while (file) { struct stat filestat; String absfn = *i + String (SCIM_PATH_DELIM_STRING) + file->d_name; stat (absfn.c_str (), &filestat); if (S_ISREG (filestat.st_mode)) { std::vector vec; scim_split_string_list (vec, String (file->d_name), '.'); mod_list.push_back (vec [0]); } file = readdir (dir); } closedir (dir); } } std::sort (mod_list.begin (), mod_list.end ()); mod_list.erase (std::unique (mod_list.begin(), mod_list.end()), mod_list.end()); return mod_list.size (); } Module::Module () : m_impl (new ModuleImpl) { init (); } Module::Module (const String &name, const String &type) : m_impl (new ModuleImpl) { init (); load (name, type); } void Module::init () { lt_dlinit (); #if SCIM_LTDLADVISE lt_dladvise_init (&(m_impl->advise)); lt_dladvise_ext (&(m_impl->advise)); lt_dladvise_global (&(m_impl->advise)); #endif } Module::~Module () { unload (); #if SCIM_LTDLADVISE lt_dladvise_destroy (&(m_impl->advise)); #endif lt_dlexit (); delete m_impl; } static String _concatenate_ltdl_prefix (const String &name, const String &symbol) { String prefix (name); for (size_t i=0; i paths; std::vector ::iterator it; String module_path; lt_dlhandle new_handle = 0; ModuleInitFunc new_init; ModuleExitFunc new_exit; _scim_get_module_paths (paths, type); for (it = paths.begin (); it != paths.end (); ++it) { module_path = *it + String (SCIM_PATH_DELIM_STRING) + name; #if SCIM_LTDLADVISE new_handle = lt_dlopenadvise (module_path.c_str (), m_impl->advise); #else new_handle = lt_dlopenext (module_path.c_str ()); #endif if (new_handle) break; } if (!new_handle) { #if SCIM_LTDLADVISE new_handle = lt_dlopenadvise (name.c_str (), m_impl->advise); #else new_handle = lt_dlopenext (name.c_str ()); #endif } if (!new_handle) return false; String symbol; // Try to load the symbol scim_module_init symbol = "scim_module_init"; new_init = (ModuleInitFunc) lt_dlsym (new_handle, symbol.c_str ()); // If symbol load failed, try to add LTX prefix and load again. // This will occurred when name.la is missing. if (!new_init) { symbol = _concatenate_ltdl_prefix (name, symbol); new_init = (ModuleInitFunc) lt_dlsym (new_handle, symbol.c_str ()); // Failed again? Try to prepend a under score to the symbol name. if (!new_init) { symbol.insert (symbol.begin (),'_'); new_init = (ModuleInitFunc) lt_dlsym (new_handle, symbol.c_str ()); } } // Could not load the module! if (!new_init) { lt_dlclose (new_handle); return false; } // Try to load the symbol scim_module_exit symbol = "scim_module_exit"; new_exit = (ModuleExitFunc) lt_dlsym (new_handle, symbol.c_str ()); // If symbol load failed, try to add LTX prefix and load again. // This will occurred when name.la is missing. if (!new_exit) { symbol = _concatenate_ltdl_prefix (name, symbol); new_exit = (ModuleExitFunc) lt_dlsym (new_handle, symbol.c_str ()); // Failed again? Try to prepend a under score to the symbol name. if (!new_exit) { symbol.insert (symbol.begin (),'_'); new_exit = (ModuleExitFunc) lt_dlsym (new_handle, symbol.c_str ()); } } //Check if the module is already loaded. if (std::find (_scim_modules.begin (), _scim_modules.end (), new_init) != _scim_modules.end ()) { lt_dlclose (new_handle); return false; } if (unload ()) { _scim_modules.push_back (new_init); const lt_dlinfo *info = lt_dlgetinfo (new_handle); m_impl->handle = new_handle; m_impl->init = new_init; m_impl->exit = new_exit; m_impl->path = String (info->filename); m_impl->name = name; try { m_impl->init (); return true; } catch (...) { unload (); } } else { lt_dlclose (new_handle); } return false; } bool Module::unload () { if (!m_impl->handle) return true; if (is_resident ()) return false; if (m_impl->exit) { try { m_impl->exit (); } catch (...) { } } lt_dlclose (m_impl->handle); std::vector ::iterator it = std::find (_scim_modules.begin (), _scim_modules.end (), m_impl->init); if (it != _scim_modules.end ()) _scim_modules.erase (it); m_impl->handle = 0; m_impl->init = 0; m_impl->exit = 0; m_impl->path = String (); m_impl->name = String (); return true; } bool Module::make_resident () const { if (m_impl->handle) { return lt_dlmakeresident (m_impl->handle) == 0; } return false; } bool Module::is_resident () const { if (m_impl->handle) { return lt_dlisresident (m_impl->handle) == 1; } return false; } bool Module::valid () const { return (m_impl->handle && m_impl->init); } String Module::get_path () const { return m_impl->path; } void * Module::symbol (const String & sym) const { void * func = 0; if (m_impl->handle) { String symbol = sym; func = lt_dlsym (m_impl->handle, symbol.c_str ()); if (!func) { symbol = _concatenate_ltdl_prefix (m_impl->name, symbol); func = lt_dlsym (m_impl->handle, symbol.c_str ()); if (!func) { symbol.insert (symbol.begin (), '_'); func = lt_dlsym (m_impl->handle, symbol.c_str ()); } } } return func; } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_lookup_table.h0000644000175000017500000002105712422143415016577 0ustar tzhuantzhuan/** @file scim_lookup_table.h * @brief definition of LookupTable classes. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_lookup_table.h,v 1.32 2005/05/13 04:21:29 suzhe Exp $ */ #ifndef __SCIM_LOOKUP_TABLE_H #define __SCIM_LOOKUP_TABLE_H namespace scim { /** * @addtogroup Accessories * @{ */ #define SCIM_LOOKUP_TABLE_MAX_PAGESIZE 16 /** * @brief The base class of lookup table. * * LookupTable is used to store the candidate phrases, it provides a easy way * to manage the content of candidates and flip between multiple pages. * * It also can manage the attributes for each candidate string. * * This is abstract class and cannot store data. * IMEngine should use its derivation class. * This class is the interface that uses within FrontEnd class. */ class LookupTable { class LookupTableImpl; LookupTableImpl * m_impl; LookupTable (const LookupTable &); const LookupTable & operator= (const LookupTable &); public: /** * @brief Constructor * @param page_size - the maximum page size, can be set by set_page_size() later. */ LookupTable (int page_size = 10); /** * @brief Virtual destructor. */ virtual ~LookupTable (); /** * @brief Set the strings to label the candidates in one page. * @param labels - the strings to label the candidates in one page. */ void set_candidate_labels (const std::vector &labels); /** * @brief Get the label string of a candidate in a page. * @param page_index - the index in a page, 0 to (max page size - 1). * @return the corresponding label of the index. */ WideString get_candidate_label (int page_index) const; /** * @brief Set the maximum page size. * @param page_size - the max page size of the table. */ void set_page_size (int page_size); /** * @brief Get the maximum page size. * @return the max page size of the table. */ int get_page_size () const; /** * @brief Get current page size, * @return the page size of current page.It can be less than the max page size. */ int get_current_page_size () const; /** * @brief Get the start index of current page. * @return the start item index of current page, starting from 0. */ int get_current_page_start () const; /** * @brief Check if the cursor is visible. * @return true if the cursor should be shown. */ bool is_cursor_visible () const; /** * @brief Check if the page size is fixed, aka. couldn't reduced by FrontEnd. * @return true if the page size shouldn't be reduced by FrontEnd. */ bool is_page_size_fixed () const; /** * @brief Get current cursor position. * @return the cursor position in the table, starting from 0. */ int get_cursor_pos () const; /** * @brief Get the cursor position in current page. * @return the cursor position in current page, * equals to get_cursor_pos () - get_current_page_start (). */ int get_cursor_pos_in_current_page () const; /** * @brief Flip to the previous page. * @return true if success, false if it's already in the first page. */ bool page_up (); /** * @brief Flip to the next page. * @return true if success, false if it's already in the last page. */ bool page_down (); /** * @brief Move cursor position to the previous entry. * @return true if success, false if it's already at the first entry. */ bool cursor_up (); /** * @brief Move cursor position to the next entry. * @return true if success. false if it's already at the last entry. */ bool cursor_down (); /** * @brief Set the cursor visibility. * @param show - true to show the cursor. */ void show_cursor (bool show=true); /** * @brief Set the page size to be fixed, aka. prevent from being changed by FrontEnd. */ void fix_page_size (bool fixed=true); /** * @brief Set the cursor position. * @param pos - the absolute position of the cursor. */ void set_cursor_pos (int pos); /** * @brief Set the cursor position in current page. * @param pos - the relative position of the cursor in current page. */ void set_cursor_pos_in_current_page (int pos); /** * @brief Get a candidate in current page. * * @param page_index - the candidate index in current page. * @return the content of this candidate. * * @sa get_candidate */ WideString get_candidate_in_current_page (int page_index) const; /** * @brief Get the display attributes of a candidate in current page. * * @param page_index - the index in current page. * @return the AttributeList object holding the attributes of this candidate. * * @sa get_attributes */ AttributeList get_attributes_in_current_page (int page_index) const; public: /** * @name Pure Virtual functions. * These functions should be implemented in derivation classes. * * @{ */ /** * @brief Get a candidate. * @param index - the candidate index in the lookup table. * @return the content of this candidate. */ virtual WideString get_candidate (int index) const = 0; /** * @brief Get the attributes of a candidate. * @param index - the index in the lookup table. * @return the AttributeList object holding the attributes of this candidate. */ virtual AttributeList get_attributes (int index) const = 0; /** * @brief Return the number of candidates in this table. * @return the number of entries currently in this table. */ virtual uint32 number_of_candidates () const = 0; /** * @brief Clear the table. */ virtual void clear () = 0; /** * @} */ }; /** * @brief A common lookup table class. * * This class implements the LookupTable interface in a common way. * */ class CommonLookupTable : public LookupTable { class CommonLookupTableImpl; CommonLookupTableImpl *m_impl; CommonLookupTable (const CommonLookupTable &); const CommonLookupTable & operator= (const CommonLookupTable &); public: CommonLookupTable (int page_size = 10); /** * @brief Constructor * * @param page_size - the maximum page size, can be set by set_page_size () later. * @param labels - the strings to label the candidates in one page. */ CommonLookupTable (int page_size, const std::vector &labels); ~CommonLookupTable (); virtual WideString get_candidate (int index) const; virtual AttributeList get_attributes (int index) const; virtual uint32 number_of_candidates () const; virtual void clear (); public: /** * @brief Append a candidate string into the table. * * @param cand - a candidate string to be added into the table. * @param attrs - the attributes to control the display effect of this entry. * It can be omitted if no attribute. * * @return true if success. */ bool append_candidate (const WideString &cand, const AttributeList &attrs = AttributeList ()); /** * @brief Append a candidate char into the table. * * @param cand - a candidate char to be added into the table. * @param attrs - the attributes to control the display effect of this entry. * It can be omitted if no attribute. * * @return true if success. */ bool append_candidate (ucs4_t cand, const AttributeList &attrs = AttributeList ()); }; /** @} */ } // namespace scim #endif //__SCIM_LOOKUP_TABLE_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_lookup_table.cpp0000644000175000017500000002532712422143415017136 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_lookup_table.cpp,v 1.32 2005/05/13 04:21:29 suzhe Exp $ * */ #define Uses_SCIM_LOOKUP_TABLE #include "scim_private.h" #include "scim.h" namespace scim { struct LookupTable::LookupTableImpl { std::vector m_page_history; int m_page_size; int m_current_page_start; int m_cursor_pos; bool m_cursor_visible; bool m_page_size_fixed; std::vector m_candidate_labels; LookupTableImpl (int page_size) : m_page_size (page_size), m_current_page_start (0), m_cursor_pos (0), m_cursor_visible (false), m_page_size_fixed (false) { if (m_page_size <= 0 || m_page_size > SCIM_LOOKUP_TABLE_MAX_PAGESIZE) m_page_size = SCIM_LOOKUP_TABLE_MAX_PAGESIZE; } }; //implementation of class LookupTable LookupTable::LookupTable (int page_size) : m_impl (new LookupTableImpl (page_size)) { } LookupTable::~LookupTable () { delete m_impl; } void LookupTable::set_candidate_labels (const std::vector &labels) { if (labels.size ()) m_impl->m_candidate_labels = labels; } void LookupTable::set_page_size (int page_size) { if (page_size > 0 && page_size <= SCIM_LOOKUP_TABLE_MAX_PAGESIZE) { m_impl->m_page_size = page_size; if (m_impl->m_cursor_pos >= m_impl->m_current_page_start + get_current_page_size ()) m_impl->m_cursor_pos = m_impl->m_current_page_start + get_current_page_size () - 1; if (m_impl->m_cursor_pos < 0) m_impl->m_cursor_pos = 0; } } int LookupTable::get_page_size () const { return m_impl->m_page_size; } int LookupTable::get_current_page_start () const { return m_impl->m_current_page_start; } int LookupTable::get_cursor_pos() const { return m_impl->m_cursor_pos; } int LookupTable::get_cursor_pos_in_current_page () const { return m_impl->m_cursor_pos - m_impl->m_current_page_start; } int LookupTable::get_current_page_size () const { return std::min ((uint32) m_impl->m_page_size, (uint32)(number_of_candidates () - m_impl->m_current_page_start)); } bool LookupTable::page_up () { if (m_impl->m_current_page_start <= 0) return false; if (m_impl->m_page_history.size ()) { m_impl->m_page_size = m_impl->m_page_history.back (); m_impl->m_page_history.pop_back (); } if (m_impl->m_current_page_start >= m_impl->m_page_size) m_impl->m_current_page_start -= m_impl->m_page_size; else m_impl->m_current_page_start = 0; if (m_impl->m_cursor_pos >= m_impl->m_page_size) m_impl->m_cursor_pos -= m_impl->m_page_size; else m_impl->m_cursor_pos = 0; if (m_impl->m_cursor_pos < m_impl->m_current_page_start) m_impl->m_cursor_pos = m_impl->m_current_page_start; else if (m_impl->m_cursor_pos >= m_impl->m_current_page_start + get_current_page_size ()) m_impl->m_cursor_pos = m_impl->m_current_page_start + get_current_page_size () - 1; return true; } bool LookupTable::page_down () { if (m_impl->m_current_page_start + m_impl->m_page_size >= number_of_candidates ()) return false; m_impl->m_current_page_start += m_impl->m_page_size; m_impl->m_page_history.push_back (m_impl->m_page_size); m_impl->m_cursor_pos += m_impl->m_page_size; if (m_impl->m_cursor_pos < m_impl->m_current_page_start) m_impl->m_cursor_pos = m_impl->m_current_page_start; else if (m_impl->m_cursor_pos >= m_impl->m_current_page_start + get_current_page_size ()) m_impl->m_cursor_pos = m_impl->m_current_page_start + get_current_page_size () - 1; return true; } bool LookupTable::cursor_up () { if (m_impl->m_cursor_pos <= 0) return false; if (!m_impl->m_cursor_visible) m_impl->m_cursor_visible = true; m_impl->m_cursor_pos --; if (m_impl->m_cursor_pos < m_impl->m_current_page_start) { page_up (); m_impl->m_cursor_pos = m_impl->m_current_page_start + get_current_page_size () - 1; } return true; } bool LookupTable::cursor_down () { if (m_impl->m_cursor_pos + 1 >= number_of_candidates ()) return false; if (!m_impl->m_cursor_visible) m_impl->m_cursor_visible = true; ++m_impl->m_cursor_pos; if (m_impl->m_cursor_pos >= m_impl->m_current_page_start + get_current_page_size ()) { page_down (); m_impl->m_cursor_pos = m_impl->m_current_page_start; } return true; } void LookupTable::show_cursor (bool show) { m_impl->m_cursor_visible = show; } bool LookupTable::is_cursor_visible () const { return m_impl->m_cursor_visible; } void LookupTable::fix_page_size (bool fixed) { m_impl->m_page_size_fixed = fixed; } bool LookupTable::is_page_size_fixed () const { return m_impl->m_page_size_fixed; } void LookupTable::set_cursor_pos (int pos) { if (pos < 0 || pos >= number_of_candidates ()) return; if (!m_impl->m_cursor_visible) m_impl->m_cursor_visible = true; if (pos >= get_current_page_start () && pos < get_current_page_start () + get_current_page_size ()) { m_impl->m_cursor_pos = pos; } else if (pos < get_cursor_pos ()) { while (pos < get_cursor_pos ()) cursor_up (); } else if (pos > get_cursor_pos ()) { while (pos > get_cursor_pos ()) cursor_down (); } } void LookupTable::set_cursor_pos_in_current_page (int pos) { if (pos < 0 || pos >= get_current_page_size ()) return; if (!m_impl->m_cursor_visible) m_impl->m_cursor_visible = true; m_impl->m_cursor_pos = pos + get_current_page_start (); } WideString LookupTable::get_candidate_label (int page_index) const { if (page_index >= 0 && page_index < get_current_page_size () && page_index < m_impl->m_candidate_labels.size ()) return m_impl->m_candidate_labels [page_index]; return WideString (); } WideString LookupTable::get_candidate_in_current_page (int page_index) const { if (page_index >= 0 && page_index < get_current_page_size ()) return get_candidate (page_index + m_impl->m_current_page_start); return WideString (); } AttributeList LookupTable::get_attributes_in_current_page (int page_index) const { if (page_index >= 0 && page_index < get_current_page_size ()) return get_attributes (page_index + m_impl->m_current_page_start); return AttributeList (); } void LookupTable::clear () { m_impl->m_current_page_start = 0; m_impl->m_cursor_pos = 0; std::vector ().swap (m_impl->m_page_history); } class CommonLookupTable::CommonLookupTableImpl { public: std::vector m_buffer; std::vector m_index; AttributeList m_attributes; std::vector m_attrs_index; }; //implementation of CommonLookupTable CommonLookupTable::CommonLookupTable (int page_size) : LookupTable (page_size), m_impl (new CommonLookupTableImpl ()) { std::vector labels; char buf [2] = { 0, 0 }; for (int i = 0; i < 9; ++i) { buf [0] = '1' + i; labels.push_back (utf8_mbstowcs (buf)); } labels.push_back (utf8_mbstowcs ("0")); set_candidate_labels (labels); } CommonLookupTable::CommonLookupTable (int page_size, const std::vector &labels) : LookupTable (page_size), m_impl (new CommonLookupTableImpl ()) { set_candidate_labels (labels); } CommonLookupTable::~CommonLookupTable () { delete m_impl; } uint32 CommonLookupTable::number_of_candidates () const { return m_impl->m_index.size (); } bool CommonLookupTable::append_candidate (const WideString &cand, const AttributeList &attrs) { if (cand.length () == 0) return false; m_impl->m_index.push_back (m_impl->m_buffer.size ()); m_impl->m_buffer.insert (m_impl->m_buffer.end (), cand.begin (), cand.end ()); m_impl->m_attrs_index.push_back (m_impl->m_attributes.size ()); if (attrs.size ()) m_impl->m_attributes.insert (m_impl->m_attributes.end (), attrs.begin (), attrs.end ()); return true; } bool CommonLookupTable::append_candidate (ucs4_t cand, const AttributeList &attrs) { if (cand == 0) return false; m_impl->m_index.push_back (m_impl->m_buffer.size ()); m_impl->m_buffer.push_back (cand); m_impl->m_attrs_index.push_back (m_impl->m_attributes.size ()); if (attrs.size ()) m_impl->m_attributes.insert (m_impl->m_attributes.end (), attrs.begin (), attrs.end ()); return true; } WideString CommonLookupTable::get_candidate (int index) const { if (index < 0 || index >= number_of_candidates ()) return WideString (); std::vector ::const_iterator start, end; start = m_impl->m_buffer.begin () + m_impl->m_index [index]; if (index < number_of_candidates () - 1) end = m_impl->m_buffer.begin () + m_impl->m_index [index+1]; else end = m_impl->m_buffer.end (); return WideString (start, end); } AttributeList CommonLookupTable::get_attributes (int index) const { if (index < 0 || index >= number_of_candidates ()) return AttributeList (); AttributeList::const_iterator start, end; start = m_impl->m_attributes.begin () + m_impl->m_attrs_index [index]; if (index < number_of_candidates () - 1) end = m_impl->m_attributes.begin () + m_impl->m_attrs_index [index+1]; else end = m_impl->m_attributes.end (); if (start < end) return AttributeList (start, end); return AttributeList (); } void CommonLookupTable::clear () { LookupTable::clear (); std::vector ().swap (m_impl->m_buffer); std::vector ().swap (m_impl->m_index); AttributeList ().swap (m_impl->m_attributes); std::vector ().swap (m_impl->m_attrs_index); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_launcher.cpp0000644000175000017500000001576012422143415016257 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_launcher.cpp,v 1.9 2005/06/15 00:19:08 suzhe Exp $ * */ #define Uses_SCIM_FRONTEND_MODULE #define Uses_SCIM_IMENGINE_MODULE #define Uses_SCIM_BACKEND #define Uses_SCIM_CONFIG_PATH #define Uses_SCIM_CONFIG #define Uses_C_LOCALE #include "scim_private.h" #include "scim.h" #include #include #include using namespace scim; FrontEndModule *frontend_module = 0; ConfigModule *config_module = 0; ConfigPointer config; void signalhandler(int sig) { if (config != NULL) { config->flush (); } std::cerr << "SCIM successfully exited.\n"; exit (0); } int main (int argc, char *argv []) { BackEndPointer backend; std::vector engine_list; String config_name ("simple"); String frontend_name ("socket"); int new_argc = 0; char *new_argv [40]; int i = 0; bool daemon = false; new_argv [new_argc ++] = argv [0]; while (i= argc) break; if (String ("-f") == argv [i] || String ("--frontend") == argv [i]) { if (++i >= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; return -1; } frontend_name = argv [i]; continue; } if (String ("-c") == argv [i] || String ("--config") == argv [i]) { if (++i >= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; return -1; } config_name = argv [i]; continue; } if (String ("-d") == argv [i] || String ("--daemon") == argv [i]) { daemon = true; continue; } if (String ("-e") == argv [i] || String ("--engines") == argv [i]) { if (++i >= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; return -1; } if (String (argv [i]) == "all") { scim_get_imengine_module_list (engine_list); for (size_t j = 0; j < engine_list.size (); ++j) { if (engine_list [j] == "socket") { engine_list.erase (engine_list.begin () + j); break; } } } else if (String (argv [i]) != "none") { scim_split_string_list (engine_list, String (argv [i]), ','); } continue; } if (String ("-v") == argv [i] || String ("--verbose") == argv [i]) { if (++i >= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; return -1; } DebugOutput::set_verbose_level (atoi (argv [i])); continue; } if (String ("-m") == argv [i] || String ("--mask") == argv [i]) { if (++i >= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; return -1; } if (String (argv [i]) != "none") { std::vector debug_mask_list; scim_split_string_list (debug_mask_list, argv [i], ','); DebugOutput::disable_debug (SCIM_DEBUG_AllMask); for (size_t j=0; j= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; return -1; } DebugOutput::set_output (String (argv [i])); continue; } if (String ("--") == argv [i]) break; new_argv [new_argc ++] = argv [i]; } //End of command line parsing. // Construct new argv array for FrontEnd. new_argv [new_argc ++] = const_cast ("-c"); new_argv [new_argc ++] = const_cast (config_name.c_str ()); // Store the rest argvs into new_argv. for (++i; i < argc && new_argc < 40; ++i) { new_argv [new_argc ++] = argv [i]; } new_argv [new_argc] = 0; try { // Try to load config module std::cerr << "Loading " << config_name << " Config module ...\n"; if (config_name != "dummy") { //load config module config_module = new ConfigModule (config_name); if (!config_module->valid ()) { std::cerr << "Can not load " << config_name << " Config module. Using dummy module instead.\n"; delete config_module; config_module = 0; } } if (config_module) { config = config_module->create_config (); } else { config = new DummyConfig (); } if (config.null ()) { std::cerr << "Can not create Config Object!\n"; return 1; } // create backend std::cerr << "Creating backend ...\n"; backend = new CommonBackEnd (config, engine_list); //load FrontEnd module std::cerr << "Loading " << frontend_name << " FrontEnd module ...\n"; frontend_module = new FrontEndModule (frontend_name, backend, config, new_argc, new_argv); if (!frontend_module || !frontend_module->valid ()) { std::cerr << "Failed to load " << frontend_name << " FrontEnd module.\n"; return 1; } //reset backend pointer, in order to destroy backend automatically. backend.reset (); signal(SIGQUIT, signalhandler); signal(SIGTERM, signalhandler); signal(SIGINT, signalhandler); signal(SIGHUP, signalhandler); if (daemon) { std::cerr << "Starting SCIM as daemon ...\n"; scim_daemon (); } else { std::cerr << "Starting SCIM ...\n"; } frontend_module->run (); } catch (const std::exception & err) { std::cerr << err.what () << "\n"; return 1; } return 0; } /* vi:ts=4:ai:nowrap:expandtab */ scim-1.4.15/src/scim_keyevent_data.h0000644000175000017500000042265612422143415016754 0ustar tzhuantzhuan/* Thanks to Markus G. Kuhn for the ksysym<->Unicode * mapping functions, from the xterm sources. */ /* These tables could be compressed by contiguous ranges, but the benefit of doing so * is smallish. It would save about ~1000 bytes total. */ static __Uint16Pair __scim_key_to_unicode_tab [] = { { 0x01a1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */ { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ { 0x01a3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */ { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ { 0x01a6, 0x015a }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */ { 0x01a9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */ { 0x01aa, 0x015e }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */ { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ { 0x01af, 0x017b }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */ { 0x01b1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */ { 0x01b2, 0x02db }, /* ogonek ˛ OGONEK */ { 0x01b3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */ { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ { 0x01b6, 0x015b }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */ { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ { 0x01b9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */ { 0x01ba, 0x015f }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */ { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */ { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ { 0x01bd, 0x02dd }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */ { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ { 0x01c0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */ { 0x01c3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */ { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */ { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ { 0x01cc, 0x011a }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */ { 0x01cf, 0x010e }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */ { 0x01d0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */ { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ { 0x01d5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ { 0x01d9, 0x016e }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */ { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */ { 0x01e0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */ { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ { 0x01e8, 0x010d }, /* ccaron č LATIN SMALL LETTER C WITH CARON */ { 0x01ea, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */ { 0x01ec, 0x011b }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */ { 0x01ef, 0x010f }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */ { 0x01f0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */ { 0x01f1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */ { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ { 0x01f5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */ { 0x01f8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */ { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */ { 0x01ff, 0x02d9 }, /* abovedot ˙ DOT ABOVE */ { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ { 0x02ab, 0x011e }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */ { 0x02ac, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ { 0x02bb, 0x011f }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */ { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ { 0x02c5, 0x010a }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */ { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ { 0x02d5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */ { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ { 0x02e5, 0x010b }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */ { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ { 0x02f5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */ { 0x02f8, 0x011d }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */ { 0x02fd, 0x016d }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */ { 0x02fe, 0x015d }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */ { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ { 0x03a3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */ { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ { 0x03a6, 0x013b }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */ { 0x03aa, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */ { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */ { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ { 0x03b3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */ { 0x03b5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */ { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ { 0x03ba, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */ { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */ { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ { 0x03bd, 0x014a }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */ { 0x03bf, 0x014b }, /* eng ŋ LATIN SMALL LETTER ENG */ { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */ { 0x03c7, 0x012e }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */ { 0x03cc, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */ { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ { 0x03d1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */ { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */ { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ { 0x03e0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */ { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ { 0x03ec, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */ { 0x03ef, 0x012b }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */ { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ { 0x03f2, 0x014d }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */ { 0x03f3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */ { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ { 0x03fd, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */ { 0x03fe, 0x016b }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */ { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ { 0x04a3, 0x300d }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */ { 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */ { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ { 0x04a7, 0x30a1 }, /* kana_a ァ KATAKANA LETTER SMALL A */ { 0x04a8, 0x30a3 }, /* kana_i ィ KATAKANA LETTER SMALL I */ { 0x04a9, 0x30a5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */ { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ { 0x04ab, 0x30a9 }, /* kana_o ォ KATAKANA LETTER SMALL O */ { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ { 0x04b1, 0x30a2 }, /* kana_A ア KATAKANA LETTER A */ { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ { 0x04b6, 0x30ab }, /* kana_KA カ KATAKANA LETTER KA */ { 0x04b7, 0x30ad }, /* kana_KI キ KATAKANA LETTER KI */ { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ { 0x04bc, 0x30b7 }, /* kana_SHI シ KATAKANA LETTER SI */ { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ { 0x04be, 0x30bb }, /* kana_SE セ KATAKANA LETTER SE */ { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ { 0x04c0, 0x30bf }, /* kana_TA タ KATAKANA LETTER TA */ { 0x04c1, 0x30c1 }, /* kana_CHI チ KATAKANA LETTER TI */ { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ { 0x04c8, 0x30cd }, /* kana_NE ネ KATAKANA LETTER NE */ { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ { 0x04ca, 0x30cf }, /* kana_HA ハ KATAKANA LETTER HA */ { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ { 0x04de, 0x309b }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */ { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */ { 0x05bb, 0x061b }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */ { 0x05bf, 0x061f }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */ { 0x05c1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */ { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */ { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */ { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */ { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */ { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ { 0x05cb, 0x062b }, /* Arabic_theh ث ARABIC LETTER THEH */ { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ { 0x05cd, 0x062d }, /* Arabic_hah ح ARABIC LETTER HAH */ { 0x05ce, 0x062e }, /* Arabic_khah خ ARABIC LETTER KHAH */ { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ { 0x05d4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */ { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ { 0x05d7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */ { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ { 0x05e0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */ { 0x05e1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */ { 0x05e2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */ { 0x05e3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */ { 0x05e4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */ { 0x05e5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */ { 0x05e6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */ { 0x05e7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */ { 0x05e8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */ { 0x05e9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */ { 0x05ea, 0x064a }, /* Arabic_yeh ي ARABIC LETTER YEH */ { 0x05eb, 0x064b }, /* Arabic_fathatan ً ARABIC FATHATAN */ { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */ { 0x05ed, 0x064d }, /* Arabic_kasratan ٍ ARABIC KASRATAN */ { 0x05ee, 0x064e }, /* Arabic_fatha َ ARABIC FATHA */ { 0x05ef, 0x064f }, /* Arabic_damma ُ ARABIC DAMMA */ { 0x05f0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */ { 0x05f1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */ { 0x05f2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */ { 0x06a1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */ { 0x06a2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */ { 0x06a3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */ { 0x06a4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */ { 0x06a5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */ { 0x06a6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ { 0x06a7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */ { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ { 0x06a9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */ { 0x06aa, 0x045a }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */ { 0x06ab, 0x045b }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */ { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */ { 0x06ae, 0x045e }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */ { 0x06af, 0x045f }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */ { 0x06b0, 0x2116 }, /* numerosign № NUMERO SIGN */ { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ { 0x06b3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */ { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ { 0x06b5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */ { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */ { 0x06be, 0x040e }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */ { 0x06bf, 0x040f }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */ { 0x06c0, 0x044e }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */ { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ { 0x06c6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */ { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ { 0x06c8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */ { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ { 0x06d1, 0x044f }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */ { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */ { 0x06d3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */ { 0x06d4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */ { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */ { 0x06d9, 0x044b }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */ { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ { 0x06dc, 0x044d }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */ { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ { 0x06df, 0x044a }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */ { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ { 0x06e1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */ { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */ { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ { 0x06ee, 0x041d }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */ { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ { 0x06f7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */ { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */ { 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */ { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */ { 0x07ae, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */ { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ { 0x07b5, 0x03ca }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */ { 0x07b8, 0x03cd }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */ { 0x07b9, 0x03cb }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ { 0x07bb, 0x03ce }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */ { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ { 0x07c2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */ { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ { 0x07cd, 0x039d }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */ { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */ { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */ { 0x07f1, 0x03c1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */ { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */ { 0x07f4, 0x03c4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */ { 0x07f5, 0x03c5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */ { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ /* 0x08a1 leftradical ? ??? */ /* 0x08a2 topleftradical ? ??? */ /* 0x08a3 horizconnector ? ??? */ { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ /* 0x08a7 topleftsqbracket ? ??? */ /* 0x08a8 botleftsqbracket ? ??? */ /* 0x08a9 toprightsqbracket ? ??? */ /* 0x08aa botrightsqbracket ? ??? */ /* 0x08ab topleftparens ? ??? */ /* 0x08ac botleftparens ? ??? */ /* 0x08ad toprightparens ? ??? */ /* 0x08ae botrightparens ? ??? */ /* 0x08af leftmiddlecurlybrace ? ??? */ /* 0x08b0 rightmiddlecurlybrace ? ??? */ /* 0x08b1 topleftsummation ? ??? */ /* 0x08b2 botleftsummation ? ??? */ /* 0x08b3 topvertsummationconnector ? ??? */ /* 0x08b4 botvertsummationconnector ? ??? */ /* 0x08b5 toprightsummation ? ??? */ /* 0x08b6 botrightsummation ? ??? */ /* 0x08b7 rightmiddlesummation ? ??? */ { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ { 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */ { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */ /* 0x08c9 similarequal ? ??? */ { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ { 0x08dd, 0x222a }, /* union ∪ UNION */ { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ { 0x08f6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */ { 0x08fb, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */ { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ { 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */ { 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */ { 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */ { 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */ { 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */ { 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */ { 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */ { 0x09e8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */ { 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */ { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ { 0x09eb, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ { 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */ { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ /* 0x09ef horizlinescan1 ? ??? */ /* 0x09f0 horizlinescan3 ? ??? */ { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ /* 0x09f2 horizlinescan7 ? ??? */ /* 0x09f3 horizlinescan9 ? ??? */ { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ { 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ { 0x0aaa, 0x2013 }, /* endash – EN DASH */ /* 0x0aac signifblank ? ??? */ { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ /* 0x0aaf doubbaselinedot ? ??? */ { 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */ { 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */ { 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */ { 0x0ab3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */ { 0x0ab4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */ { 0x0ab5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */ { 0x0ab6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */ { 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */ { 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */ { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ /* 0x0abf marker ? ??? */ { 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */ { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */ { 0x0ac5, 0x215d }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */ { 0x0ac6, 0x215e }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */ { 0x0ac9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */ { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ /* 0x0acb trademarkincircle ? ??? */ { 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */ { 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */ { 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */ { 0x0acf, 0x25a1 }, /* emopenrectangle □ WHITE SQUARE */ { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ { 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */ { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ { 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */ /* 0x0ada hexagram ? ??? */ { 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */ { 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */ { 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */ { 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */ { 0x0adf, 0x25a0 }, /* emfilledrect ■ BLACK SQUARE */ { 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */ { 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */ { 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */ { 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */ { 0x0ae4, 0x25bd }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */ { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ { 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */ { 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */ { 0x0ae9, 0x25bc }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */ { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ { 0x0af1, 0x2020 }, /* dagger † DAGGER */ { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ { 0x0af6, 0x266d }, /* musicalflat ♭ MUSIC FLAT SIGN */ { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ { 0x0afb, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */ { 0x0afc, 0x2038 }, /* caret ‸ CARET */ { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ /* 0x0aff cursor ? ??? */ { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */ { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */ { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */ { 0x0bcf, 0x25cb }, /* circle ○ WHITE CIRCLE */ { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */ { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */ { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ { 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */ { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ { 0x0ce2, 0x05d2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */ { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ { 0x0ce4, 0x05d4 }, /* hebrew_he ה HEBREW LETTER HE */ { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ { 0x0ce6, 0x05d6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */ { 0x0ce7, 0x05d7 }, /* hebrew_chet ח HEBREW LETTER HET */ { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ { 0x0ce9, 0x05d9 }, /* hebrew_yod י HEBREW LETTER YOD */ { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ { 0x0ceb, 0x05db }, /* hebrew_kaph כ HEBREW LETTER KAF */ { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ { 0x0ced, 0x05dd }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */ { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ { 0x0cf0, 0x05e0 }, /* hebrew_nun נ HEBREW LETTER NUN */ { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ { 0x0cf2, 0x05e2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */ { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */ { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */ { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ { 0x0da1, 0x0e01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */ { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ { 0x0dad, 0x0e0d }, /* Thai_yoying ญ THAI CHARACTER YO YING */ { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ { 0x0daf, 0x0e0f }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */ { 0x0db0, 0x0e10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */ { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ { 0x0dbd, 0x0e1d }, /* Thai_fofa ฝ THAI CHARACTER FO FA */ { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */ { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ { 0x0de1, 0x0e41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */ { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ { 0x0ded, 0x0e4d }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */ { 0x0df0, 0x0e50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */ { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ { 0x0ea4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */ { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */ { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ { 0x0eab, 0x313b }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */ { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */ { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */ { 0x0eb1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */ { 0x0eb2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */ { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */ { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */ { 0x0eb5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */ { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */ { 0x0eb7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */ { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */ { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */ { 0x0eba, 0x314a }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */ { 0x0ebb, 0x314b }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */ { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */ { 0x0ebd, 0x314d }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */ { 0x0ebe, 0x314e }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */ { 0x0ebf, 0x314f }, /* Hangul_A ㅏ HANGUL LETTER A */ { 0x0ec0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */ { 0x0ec1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */ { 0x0ec2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */ { 0x0ec3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */ { 0x0ec4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */ { 0x0ec5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */ { 0x0ec6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */ { 0x0ec7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */ { 0x0ec8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */ { 0x0ec9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */ { 0x0eca, 0x315a }, /* Hangul_OE ㅚ HANGUL LETTER OE */ { 0x0ecb, 0x315b }, /* Hangul_YO ㅛ HANGUL LETTER YO */ { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */ { 0x0ecd, 0x315d }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */ { 0x0ece, 0x315e }, /* Hangul_WE ㅞ HANGUL LETTER WE */ { 0x0ecf, 0x315f }, /* Hangul_WI ㅟ HANGUL LETTER WI */ { 0x0ed0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */ { 0x0ed1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */ { 0x0ed2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */ { 0x0ed3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */ { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */ { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */ { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */ { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */ { 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */ /* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */ { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */ { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ /* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */ { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ { 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */ { 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */ { 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */ { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ { 0x20a0, 0x20a0 }, /* EcuSign ₠ EURO-CURRENCY SIGN */ { 0x20a1, 0x20a1 }, /* ColonSign ₡ COLON SIGN */ { 0x20a2, 0x20a2 }, /* CruzeiroSign ₢ CRUZEIRO SIGN */ { 0x20a3, 0x20a3 }, /* FFrancSign ₣ FRENCH FRANC SIGN */ { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */ { 0x20a5, 0x20a5 }, /* MillSign ₥ MILL SIGN */ { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */ { 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */ { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */ { 0x20a9, 0x20a9 }, /* WonSign ₩ WON SIGN */ { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */ { 0x20ab, 0x20ab }, /* DongSign ₫ DONG SIGN */ { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ /* Following items added to SCIM, not in the xterm table */ /* Function keys */ { 0xFF09, 0x0009 }, { 0xFF0A, 0x000a }, { 0xFF0D, 0x000d }, /* Numeric keypad */ { 0xFF80 /* Space */, ' ' }, { 0xFF89 /* Space */, 0x09 }, { 0xFF8D /* Enter */, 0x0d }, { 0xFFAA /* Multiply */, '*' }, { 0xFFAB /* Add */, '+' }, { 0xFFAD /* Subtract */, '-' }, { 0xFFAE /* Decimal */, '.' }, { 0xFFAF /* Divide */, '/' }, { 0xFFB0 /* 0 */, '0' }, { 0xFFB1 /* 1 */, '1' }, { 0xFFB2 /* 2 */, '2' }, { 0xFFB3 /* 3 */, '3' }, { 0xFFB4 /* 4 */, '4' }, { 0xFFB5 /* 5 */, '5' }, { 0xFFB6 /* 6 */, '6' }, { 0xFFB7 /* 7 */, '7' }, { 0xFFB8 /* 8 */, '8' }, { 0xFFB9 /* 9 */, '9' }, { 0xFFBD /* Equal */, '=' }, /* End numeric keypad */ }; static __KeyName __scim_keys_by_code [] = { { 0x0020, "space" }, { 0x0021, "exclam" }, { 0x0022, "quotedbl" }, { 0x0023, "numbersign" }, { 0x0024, "dollar" }, { 0x0025, "percent" }, { 0x0026, "ampersand" }, { 0x0027, "apostrophe" }, { 0x0027, "quoteright" }, { 0x0028, "parenleft" }, { 0x0029, "parenright" }, { 0x002a, "asterisk" }, { 0x002b, "plus" }, { 0x002c, "comma" }, { 0x002d, "minus" }, { 0x002e, "period" }, { 0x002f, "slash" }, { 0x0030, "0" }, { 0x0031, "1" }, { 0x0032, "2" }, { 0x0033, "3" }, { 0x0034, "4" }, { 0x0035, "5" }, { 0x0036, "6" }, { 0x0037, "7" }, { 0x0038, "8" }, { 0x0039, "9" }, { 0x003a, "colon" }, { 0x003b, "semicolon" }, { 0x003c, "less" }, { 0x003d, "equal" }, { 0x003e, "greater" }, { 0x003f, "question" }, { 0x0040, "at" }, { 0x0041, "A" }, { 0x0042, "B" }, { 0x0043, "C" }, { 0x0044, "D" }, { 0x0045, "E" }, { 0x0046, "F" }, { 0x0047, "G" }, { 0x0048, "H" }, { 0x0049, "I" }, { 0x004a, "J" }, { 0x004b, "K" }, { 0x004c, "L" }, { 0x004d, "M" }, { 0x004e, "N" }, { 0x004f, "O" }, { 0x0050, "P" }, { 0x0051, "Q" }, { 0x0052, "R" }, { 0x0053, "S" }, { 0x0054, "T" }, { 0x0055, "U" }, { 0x0056, "V" }, { 0x0057, "W" }, { 0x0058, "X" }, { 0x0059, "Y" }, { 0x005a, "Z" }, { 0x005b, "bracketleft" }, { 0x005c, "backslash" }, { 0x005d, "bracketright" }, { 0x005e, "asciicircum" }, { 0x005f, "underscore" }, { 0x0060, "grave" }, { 0x0060, "quoteleft" }, { 0x0061, "a" }, { 0x0062, "b" }, { 0x0063, "c" }, { 0x0064, "d" }, { 0x0065, "e" }, { 0x0066, "f" }, { 0x0067, "g" }, { 0x0068, "h" }, { 0x0069, "i" }, { 0x006a, "j" }, { 0x006b, "k" }, { 0x006c, "l" }, { 0x006d, "m" }, { 0x006e, "n" }, { 0x006f, "o" }, { 0x0070, "p" }, { 0x0071, "q" }, { 0x0072, "r" }, { 0x0073, "s" }, { 0x0074, "t" }, { 0x0075, "u" }, { 0x0076, "v" }, { 0x0077, "w" }, { 0x0078, "x" }, { 0x0079, "y" }, { 0x007a, "z" }, { 0x007b, "braceleft" }, { 0x007c, "bar" }, { 0x007d, "braceright" }, { 0x007e, "asciitilde" }, { 0x00a0, "nobreakspace" }, { 0x00a1, "exclamdown" }, { 0x00a2, "cent" }, { 0x00a3, "sterling" }, { 0x00a4, "currency" }, { 0x00a5, "yen" }, { 0x00a6, "brokenbar" }, { 0x00a7, "section" }, { 0x00a8, "diaeresis" }, { 0x00a9, "copyright" }, { 0x00aa, "ordfeminine" }, { 0x00ab, "guillemotleft" }, { 0x00ac, "notsign" }, { 0x00ad, "hyphen" }, { 0x00ae, "registered" }, { 0x00af, "macron" }, { 0x00b0, "degree" }, { 0x00b1, "plusminus" }, { 0x00b2, "twosuperior" }, { 0x00b3, "threesuperior" }, { 0x00b4, "acute" }, { 0x00b5, "mu" }, { 0x00b6, "paragraph" }, { 0x00b7, "periodcentered" }, { 0x00b8, "cedilla" }, { 0x00b9, "onesuperior" }, { 0x00ba, "masculine" }, { 0x00bb, "guillemotright" }, { 0x00bc, "onequarter" }, { 0x00bd, "onehalf" }, { 0x00be, "threequarters" }, { 0x00bf, "questiondown" }, { 0x00c0, "Agrave" }, { 0x00c1, "Aacute" }, { 0x00c2, "Acircumflex" }, { 0x00c3, "Atilde" }, { 0x00c4, "Adiaeresis" }, { 0x00c5, "Aring" }, { 0x00c6, "AE" }, { 0x00c7, "Ccedilla" }, { 0x00c8, "Egrave" }, { 0x00c9, "Eacute" }, { 0x00ca, "Ecircumflex" }, { 0x00cb, "Ediaeresis" }, { 0x00cc, "Igrave" }, { 0x00cd, "Iacute" }, { 0x00ce, "Icircumflex" }, { 0x00cf, "Idiaeresis" }, { 0x00d0, "ETH" }, { 0x00d0, "Eth" }, { 0x00d1, "Ntilde" }, { 0x00d2, "Ograve" }, { 0x00d3, "Oacute" }, { 0x00d4, "Ocircumflex" }, { 0x00d5, "Otilde" }, { 0x00d6, "Odiaeresis" }, { 0x00d7, "multiply" }, { 0x00d8, "Ooblique" }, { 0x00d9, "Ugrave" }, { 0x00da, "Uacute" }, { 0x00db, "Ucircumflex" }, { 0x00dc, "Udiaeresis" }, { 0x00dd, "Yacute" }, { 0x00de, "THORN" }, { 0x00de, "Thorn" }, { 0x00df, "ssharp" }, { 0x00e0, "agrave" }, { 0x00e1, "aacute" }, { 0x00e2, "acircumflex" }, { 0x00e3, "atilde" }, { 0x00e4, "adiaeresis" }, { 0x00e5, "aring" }, { 0x00e6, "ae" }, { 0x00e7, "ccedilla" }, { 0x00e8, "egrave" }, { 0x00e9, "eacute" }, { 0x00ea, "ecircumflex" }, { 0x00eb, "ediaeresis" }, { 0x00ec, "igrave" }, { 0x00ed, "iacute" }, { 0x00ee, "icircumflex" }, { 0x00ef, "idiaeresis" }, { 0x00f0, "eth" }, { 0x00f1, "ntilde" }, { 0x00f2, "ograve" }, { 0x00f3, "oacute" }, { 0x00f4, "ocircumflex" }, { 0x00f5, "otilde" }, { 0x00f6, "odiaeresis" }, { 0x00f7, "division" }, { 0x00f8, "oslash" }, { 0x00f9, "ugrave" }, { 0x00fa, "uacute" }, { 0x00fb, "ucircumflex" }, { 0x00fc, "udiaeresis" }, { 0x00fd, "yacute" }, { 0x00fe, "thorn" }, { 0x00ff, "ydiaeresis" }, { 0x01a1, "Aogonek" }, { 0x01a2, "breve" }, { 0x01a3, "Lstroke" }, { 0x01a5, "Lcaron" }, { 0x01a6, "Sacute" }, { 0x01a9, "Scaron" }, { 0x01aa, "Scedilla" }, { 0x01ab, "Tcaron" }, { 0x01ac, "Zacute" }, { 0x01ae, "Zcaron" }, { 0x01af, "Zabovedot" }, { 0x01b1, "aogonek" }, { 0x01b2, "ogonek" }, { 0x01b3, "lstroke" }, { 0x01b5, "lcaron" }, { 0x01b6, "sacute" }, { 0x01b7, "caron" }, { 0x01b9, "scaron" }, { 0x01ba, "scedilla" }, { 0x01bb, "tcaron" }, { 0x01bc, "zacute" }, { 0x01bd, "doubleacute" }, { 0x01be, "zcaron" }, { 0x01bf, "zabovedot" }, { 0x01c0, "Racute" }, { 0x01c3, "Abreve" }, { 0x01c5, "Lacute" }, { 0x01c6, "Cacute" }, { 0x01c8, "Ccaron" }, { 0x01ca, "Eogonek" }, { 0x01cc, "Ecaron" }, { 0x01cf, "Dcaron" }, { 0x01d0, "Dstroke" }, { 0x01d1, "Nacute" }, { 0x01d2, "Ncaron" }, { 0x01d5, "Odoubleacute" }, { 0x01d8, "Rcaron" }, { 0x01d9, "Uring" }, { 0x01db, "Udoubleacute" }, { 0x01de, "Tcedilla" }, { 0x01e0, "racute" }, { 0x01e3, "abreve" }, { 0x01e5, "lacute" }, { 0x01e6, "cacute" }, { 0x01e8, "ccaron" }, { 0x01ea, "eogonek" }, { 0x01ec, "ecaron" }, { 0x01ef, "dcaron" }, { 0x01f0, "dstroke" }, { 0x01f1, "nacute" }, { 0x01f2, "ncaron" }, { 0x01f5, "odoubleacute" }, { 0x01f8, "rcaron" }, { 0x01f9, "uring" }, { 0x01fb, "udoubleacute" }, { 0x01fe, "tcedilla" }, { 0x01ff, "abovedot" }, { 0x02a1, "Hstroke" }, { 0x02a6, "Hcircumflex" }, { 0x02a9, "Iabovedot" }, { 0x02ab, "Gbreve" }, { 0x02ac, "Jcircumflex" }, { 0x02b1, "hstroke" }, { 0x02b6, "hcircumflex" }, { 0x02b9, "idotless" }, { 0x02bb, "gbreve" }, { 0x02bc, "jcircumflex" }, { 0x02c5, "Cabovedot" }, { 0x02c6, "Ccircumflex" }, { 0x02d5, "Gabovedot" }, { 0x02d8, "Gcircumflex" }, { 0x02dd, "Ubreve" }, { 0x02de, "Scircumflex" }, { 0x02e5, "cabovedot" }, { 0x02e6, "ccircumflex" }, { 0x02f5, "gabovedot" }, { 0x02f8, "gcircumflex" }, { 0x02fd, "ubreve" }, { 0x02fe, "scircumflex" }, { 0x03a2, "kappa" }, { 0x03a2, "kra" }, { 0x03a3, "Rcedilla" }, { 0x03a5, "Itilde" }, { 0x03a6, "Lcedilla" }, { 0x03aa, "Emacron" }, { 0x03ab, "Gcedilla" }, { 0x03ac, "Tslash" }, { 0x03b3, "rcedilla" }, { 0x03b5, "itilde" }, { 0x03b6, "lcedilla" }, { 0x03ba, "emacron" }, { 0x03bb, "gcedilla" }, { 0x03bc, "tslash" }, { 0x03bd, "ENG" }, { 0x03bf, "eng" }, { 0x03c0, "Amacron" }, { 0x03c7, "Iogonek" }, { 0x03cc, "Eabovedot" }, { 0x03cf, "Imacron" }, { 0x03d1, "Ncedilla" }, { 0x03d2, "Omacron" }, { 0x03d3, "Kcedilla" }, { 0x03d9, "Uogonek" }, { 0x03dd, "Utilde" }, { 0x03de, "Umacron" }, { 0x03e0, "amacron" }, { 0x03e7, "iogonek" }, { 0x03ec, "eabovedot" }, { 0x03ef, "imacron" }, { 0x03f1, "ncedilla" }, { 0x03f2, "omacron" }, { 0x03f3, "kcedilla" }, { 0x03f9, "uogonek" }, { 0x03fd, "utilde" }, { 0x03fe, "umacron" }, { 0x047e, "overline" }, { 0x04a1, "kana_fullstop" }, { 0x04a2, "kana_openingbracket" }, { 0x04a3, "kana_closingbracket" }, { 0x04a4, "kana_comma" }, { 0x04a5, "kana_conjunctive" }, { 0x04a5, "kana_middledot" }, { 0x04a6, "kana_WO" }, { 0x04a7, "kana_a" }, { 0x04a8, "kana_i" }, { 0x04a9, "kana_u" }, { 0x04aa, "kana_e" }, { 0x04ab, "kana_o" }, { 0x04ac, "kana_ya" }, { 0x04ad, "kana_yu" }, { 0x04ae, "kana_yo" }, { 0x04af, "kana_tsu" }, { 0x04af, "kana_tu" }, { 0x04b0, "prolongedsound" }, { 0x04b1, "kana_A" }, { 0x04b2, "kana_I" }, { 0x04b3, "kana_U" }, { 0x04b4, "kana_E" }, { 0x04b5, "kana_O" }, { 0x04b6, "kana_KA" }, { 0x04b7, "kana_KI" }, { 0x04b8, "kana_KU" }, { 0x04b9, "kana_KE" }, { 0x04ba, "kana_KO" }, { 0x04bb, "kana_SA" }, { 0x04bc, "kana_SHI" }, { 0x04bd, "kana_SU" }, { 0x04be, "kana_SE" }, { 0x04bf, "kana_SO" }, { 0x04c0, "kana_TA" }, { 0x04c1, "kana_CHI" }, { 0x04c1, "kana_TI" }, { 0x04c2, "kana_TSU" }, { 0x04c2, "kana_TU" }, { 0x04c3, "kana_TE" }, { 0x04c4, "kana_TO" }, { 0x04c5, "kana_NA" }, { 0x04c6, "kana_NI" }, { 0x04c7, "kana_NU" }, { 0x04c8, "kana_NE" }, { 0x04c9, "kana_NO" }, { 0x04ca, "kana_HA" }, { 0x04cb, "kana_HI" }, { 0x04cc, "kana_FU" }, { 0x04cc, "kana_HU" }, { 0x04cd, "kana_HE" }, { 0x04ce, "kana_HO" }, { 0x04cf, "kana_MA" }, { 0x04d0, "kana_MI" }, { 0x04d1, "kana_MU" }, { 0x04d2, "kana_ME" }, { 0x04d3, "kana_MO" }, { 0x04d4, "kana_YA" }, { 0x04d5, "kana_YU" }, { 0x04d6, "kana_YO" }, { 0x04d7, "kana_RA" }, { 0x04d8, "kana_RI" }, { 0x04d9, "kana_RU" }, { 0x04da, "kana_RE" }, { 0x04db, "kana_RO" }, { 0x04dc, "kana_WA" }, { 0x04dd, "kana_N" }, { 0x04de, "voicedsound" }, { 0x04df, "semivoicedsound" }, { 0x05ac, "Arabic_comma" }, { 0x05bb, "Arabic_semicolon" }, { 0x05bf, "Arabic_question_mark" }, { 0x05c1, "Arabic_hamza" }, { 0x05c2, "Arabic_maddaonalef" }, { 0x05c3, "Arabic_hamzaonalef" }, { 0x05c4, "Arabic_hamzaonwaw" }, { 0x05c5, "Arabic_hamzaunderalef" }, { 0x05c6, "Arabic_hamzaonyeh" }, { 0x05c7, "Arabic_alef" }, { 0x05c8, "Arabic_beh" }, { 0x05c9, "Arabic_tehmarbuta" }, { 0x05ca, "Arabic_teh" }, { 0x05cb, "Arabic_theh" }, { 0x05cc, "Arabic_jeem" }, { 0x05cd, "Arabic_hah" }, { 0x05ce, "Arabic_khah" }, { 0x05cf, "Arabic_dal" }, { 0x05d0, "Arabic_thal" }, { 0x05d1, "Arabic_ra" }, { 0x05d2, "Arabic_zain" }, { 0x05d3, "Arabic_seen" }, { 0x05d4, "Arabic_sheen" }, { 0x05d5, "Arabic_sad" }, { 0x05d6, "Arabic_dad" }, { 0x05d7, "Arabic_tah" }, { 0x05d8, "Arabic_zah" }, { 0x05d9, "Arabic_ain" }, { 0x05da, "Arabic_ghain" }, { 0x05e0, "Arabic_tatweel" }, { 0x05e1, "Arabic_feh" }, { 0x05e2, "Arabic_qaf" }, { 0x05e3, "Arabic_kaf" }, { 0x05e4, "Arabic_lam" }, { 0x05e5, "Arabic_meem" }, { 0x05e6, "Arabic_noon" }, { 0x05e7, "Arabic_ha" }, { 0x05e7, "Arabic_heh" }, { 0x05e8, "Arabic_waw" }, { 0x05e9, "Arabic_alefmaksura" }, { 0x05ea, "Arabic_yeh" }, { 0x05eb, "Arabic_fathatan" }, { 0x05ec, "Arabic_dammatan" }, { 0x05ed, "Arabic_kasratan" }, { 0x05ee, "Arabic_fatha" }, { 0x05ef, "Arabic_damma" }, { 0x05f0, "Arabic_kasra" }, { 0x05f1, "Arabic_shadda" }, { 0x05f2, "Arabic_sukun" }, { 0x06a1, "Serbian_dje" }, { 0x06a2, "Macedonia_gje" }, { 0x06a3, "Cyrillic_io" }, { 0x06a4, "Ukrainian_ie" }, { 0x06a4, "Ukranian_je" }, { 0x06a5, "Macedonia_dse" }, { 0x06a6, "Ukrainian_i" }, { 0x06a6, "Ukranian_i" }, { 0x06a7, "Ukrainian_yi" }, { 0x06a7, "Ukranian_yi" }, { 0x06a8, "Cyrillic_je" }, { 0x06a8, "Serbian_je" }, { 0x06a9, "Cyrillic_lje" }, { 0x06a9, "Serbian_lje" }, { 0x06aa, "Cyrillic_nje" }, { 0x06aa, "Serbian_nje" }, { 0x06ab, "Serbian_tshe" }, { 0x06ac, "Macedonia_kje" }, { 0x06ae, "Byelorussian_shortu" }, { 0x06af, "Cyrillic_dzhe" }, { 0x06af, "Serbian_dze" }, { 0x06b0, "numerosign" }, { 0x06b1, "Serbian_DJE" }, { 0x06b2, "Macedonia_GJE" }, { 0x06b3, "Cyrillic_IO" }, { 0x06b4, "Ukrainian_IE" }, { 0x06b4, "Ukranian_JE" }, { 0x06b5, "Macedonia_DSE" }, { 0x06b6, "Ukrainian_I" }, { 0x06b6, "Ukranian_I" }, { 0x06b7, "Ukrainian_YI" }, { 0x06b7, "Ukranian_YI" }, { 0x06b8, "Cyrillic_JE" }, { 0x06b8, "Serbian_JE" }, { 0x06b9, "Cyrillic_LJE" }, { 0x06b9, "Serbian_LJE" }, { 0x06ba, "Cyrillic_NJE" }, { 0x06ba, "Serbian_NJE" }, { 0x06bb, "Serbian_TSHE" }, { 0x06bc, "Macedonia_KJE" }, { 0x06be, "Byelorussian_SHORTU" }, { 0x06bf, "Cyrillic_DZHE" }, { 0x06bf, "Serbian_DZE" }, { 0x06c0, "Cyrillic_yu" }, { 0x06c1, "Cyrillic_a" }, { 0x06c2, "Cyrillic_be" }, { 0x06c3, "Cyrillic_tse" }, { 0x06c4, "Cyrillic_de" }, { 0x06c5, "Cyrillic_ie" }, { 0x06c6, "Cyrillic_ef" }, { 0x06c7, "Cyrillic_ghe" }, { 0x06c8, "Cyrillic_ha" }, { 0x06c9, "Cyrillic_i" }, { 0x06ca, "Cyrillic_shorti" }, { 0x06cb, "Cyrillic_ka" }, { 0x06cc, "Cyrillic_el" }, { 0x06cd, "Cyrillic_em" }, { 0x06ce, "Cyrillic_en" }, { 0x06cf, "Cyrillic_o" }, { 0x06d0, "Cyrillic_pe" }, { 0x06d1, "Cyrillic_ya" }, { 0x06d2, "Cyrillic_er" }, { 0x06d3, "Cyrillic_es" }, { 0x06d4, "Cyrillic_te" }, { 0x06d5, "Cyrillic_u" }, { 0x06d6, "Cyrillic_zhe" }, { 0x06d7, "Cyrillic_ve" }, { 0x06d8, "Cyrillic_softsign" }, { 0x06d9, "Cyrillic_yeru" }, { 0x06da, "Cyrillic_ze" }, { 0x06db, "Cyrillic_sha" }, { 0x06dc, "Cyrillic_e" }, { 0x06dd, "Cyrillic_shcha" }, { 0x06de, "Cyrillic_che" }, { 0x06df, "Cyrillic_hardsign" }, { 0x06e0, "Cyrillic_YU" }, { 0x06e1, "Cyrillic_A" }, { 0x06e2, "Cyrillic_BE" }, { 0x06e3, "Cyrillic_TSE" }, { 0x06e4, "Cyrillic_DE" }, { 0x06e5, "Cyrillic_IE" }, { 0x06e6, "Cyrillic_EF" }, { 0x06e7, "Cyrillic_GHE" }, { 0x06e8, "Cyrillic_HA" }, { 0x06e9, "Cyrillic_I" }, { 0x06ea, "Cyrillic_SHORTI" }, { 0x06eb, "Cyrillic_KA" }, { 0x06ec, "Cyrillic_EL" }, { 0x06ed, "Cyrillic_EM" }, { 0x06ee, "Cyrillic_EN" }, { 0x06ef, "Cyrillic_O" }, { 0x06f0, "Cyrillic_PE" }, { 0x06f1, "Cyrillic_YA" }, { 0x06f2, "Cyrillic_ER" }, { 0x06f3, "Cyrillic_ES" }, { 0x06f4, "Cyrillic_TE" }, { 0x06f5, "Cyrillic_U" }, { 0x06f6, "Cyrillic_ZHE" }, { 0x06f7, "Cyrillic_VE" }, { 0x06f8, "Cyrillic_SOFTSIGN" }, { 0x06f9, "Cyrillic_YERU" }, { 0x06fa, "Cyrillic_ZE" }, { 0x06fb, "Cyrillic_SHA" }, { 0x06fc, "Cyrillic_E" }, { 0x06fd, "Cyrillic_SHCHA" }, { 0x06fe, "Cyrillic_CHE" }, { 0x06ff, "Cyrillic_HARDSIGN" }, { 0x07a1, "Greek_ALPHAaccent" }, { 0x07a2, "Greek_EPSILONaccent" }, { 0x07a3, "Greek_ETAaccent" }, { 0x07a4, "Greek_IOTAaccent" }, { 0x07a5, "Greek_IOTAdiaeresis" }, { 0x07a7, "Greek_OMICRONaccent" }, { 0x07a8, "Greek_UPSILONaccent" }, { 0x07a9, "Greek_UPSILONdieresis" }, { 0x07ab, "Greek_OMEGAaccent" }, { 0x07ae, "Greek_accentdieresis" }, { 0x07af, "Greek_horizbar" }, { 0x07b1, "Greek_alphaaccent" }, { 0x07b2, "Greek_epsilonaccent" }, { 0x07b3, "Greek_etaaccent" }, { 0x07b4, "Greek_iotaaccent" }, { 0x07b5, "Greek_iotadieresis" }, { 0x07b6, "Greek_iotaaccentdieresis" }, { 0x07b7, "Greek_omicronaccent" }, { 0x07b8, "Greek_upsilonaccent" }, { 0x07b9, "Greek_upsilondieresis" }, { 0x07ba, "Greek_upsilonaccentdieresis" }, { 0x07bb, "Greek_omegaaccent" }, { 0x07c1, "Greek_ALPHA" }, { 0x07c2, "Greek_BETA" }, { 0x07c3, "Greek_GAMMA" }, { 0x07c4, "Greek_DELTA" }, { 0x07c5, "Greek_EPSILON" }, { 0x07c6, "Greek_ZETA" }, { 0x07c7, "Greek_ETA" }, { 0x07c8, "Greek_THETA" }, { 0x07c9, "Greek_IOTA" }, { 0x07ca, "Greek_KAPPA" }, { 0x07cb, "Greek_LAMBDA" }, { 0x07cb, "Greek_LAMDA" }, { 0x07cc, "Greek_MU" }, { 0x07cd, "Greek_NU" }, { 0x07ce, "Greek_XI" }, { 0x07cf, "Greek_OMICRON" }, { 0x07d0, "Greek_PI" }, { 0x07d1, "Greek_RHO" }, { 0x07d2, "Greek_SIGMA" }, { 0x07d4, "Greek_TAU" }, { 0x07d5, "Greek_UPSILON" }, { 0x07d6, "Greek_PHI" }, { 0x07d7, "Greek_CHI" }, { 0x07d8, "Greek_PSI" }, { 0x07d9, "Greek_OMEGA" }, { 0x07e1, "Greek_alpha" }, { 0x07e2, "Greek_beta" }, { 0x07e3, "Greek_gamma" }, { 0x07e4, "Greek_delta" }, { 0x07e5, "Greek_epsilon" }, { 0x07e6, "Greek_zeta" }, { 0x07e7, "Greek_eta" }, { 0x07e8, "Greek_theta" }, { 0x07e9, "Greek_iota" }, { 0x07ea, "Greek_kappa" }, { 0x07eb, "Greek_lambda" }, { 0x07eb, "Greek_lamda" }, { 0x07ec, "Greek_mu" }, { 0x07ed, "Greek_nu" }, { 0x07ee, "Greek_xi" }, { 0x07ef, "Greek_omicron" }, { 0x07f0, "Greek_pi" }, { 0x07f1, "Greek_rho" }, { 0x07f2, "Greek_sigma" }, { 0x07f3, "Greek_finalsmallsigma" }, { 0x07f4, "Greek_tau" }, { 0x07f5, "Greek_upsilon" }, { 0x07f6, "Greek_phi" }, { 0x07f7, "Greek_chi" }, { 0x07f8, "Greek_psi" }, { 0x07f9, "Greek_omega" }, { 0x08a1, "leftradical" }, { 0x08a2, "topleftradical" }, { 0x08a3, "horizconnector" }, { 0x08a4, "topintegral" }, { 0x08a5, "botintegral" }, { 0x08a6, "vertconnector" }, { 0x08a7, "topleftsqbracket" }, { 0x08a8, "botleftsqbracket" }, { 0x08a9, "toprightsqbracket" }, { 0x08aa, "botrightsqbracket" }, { 0x08ab, "topleftparens" }, { 0x08ac, "botleftparens" }, { 0x08ad, "toprightparens" }, { 0x08ae, "botrightparens" }, { 0x08af, "leftmiddlecurlybrace" }, { 0x08b0, "rightmiddlecurlybrace" }, { 0x08b1, "topleftsummation" }, { 0x08b2, "botleftsummation" }, { 0x08b3, "topvertsummationconnector" }, { 0x08b4, "botvertsummationconnector" }, { 0x08b5, "toprightsummation" }, { 0x08b6, "botrightsummation" }, { 0x08b7, "rightmiddlesummation" }, { 0x08bc, "lessthanequal" }, { 0x08bd, "notequal" }, { 0x08be, "greaterthanequal" }, { 0x08bf, "integral" }, { 0x08c0, "therefore" }, { 0x08c1, "variation" }, { 0x08c2, "infinity" }, { 0x08c5, "nabla" }, { 0x08c8, "approximate" }, { 0x08c9, "similarequal" }, { 0x08cd, "ifonlyif" }, { 0x08ce, "implies" }, { 0x08cf, "identical" }, { 0x08d6, "radical" }, { 0x08da, "includedin" }, { 0x08db, "includes" }, { 0x08dc, "intersection" }, { 0x08dd, "union" }, { 0x08de, "logicaland" }, { 0x08df, "logicalor" }, { 0x08ef, "partialderivative" }, { 0x08f6, "function" }, { 0x08fb, "leftarrow" }, { 0x08fc, "uparrow" }, { 0x08fd, "rightarrow" }, { 0x08fe, "downarrow" }, { 0x09df, "blank" }, { 0x09e0, "soliddiamond" }, { 0x09e1, "checkerboard" }, { 0x09e2, "ht" }, { 0x09e3, "ff" }, { 0x09e4, "cr" }, { 0x09e5, "lf" }, { 0x09e8, "nl" }, { 0x09e9, "vt" }, { 0x09ea, "lowrightcorner" }, { 0x09eb, "uprightcorner" }, { 0x09ec, "upleftcorner" }, { 0x09ed, "lowleftcorner" }, { 0x09ee, "crossinglines" }, { 0x09ef, "horizlinescan1" }, { 0x09f0, "horizlinescan3" }, { 0x09f1, "horizlinescan5" }, { 0x09f2, "horizlinescan7" }, { 0x09f3, "horizlinescan9" }, { 0x09f4, "leftt" }, { 0x09f5, "rightt" }, { 0x09f6, "bott" }, { 0x09f7, "topt" }, { 0x09f8, "vertbar" }, { 0x0aa1, "emspace" }, { 0x0aa2, "enspace" }, { 0x0aa3, "em3space" }, { 0x0aa4, "em4space" }, { 0x0aa5, "digitspace" }, { 0x0aa6, "punctspace" }, { 0x0aa7, "thinspace" }, { 0x0aa8, "hairspace" }, { 0x0aa9, "emdash" }, { 0x0aaa, "endash" }, { 0x0aac, "signifblank" }, { 0x0aae, "ellipsis" }, { 0x0aaf, "doubbaselinedot" }, { 0x0ab0, "onethird" }, { 0x0ab1, "twothirds" }, { 0x0ab2, "onefifth" }, { 0x0ab3, "twofifths" }, { 0x0ab4, "threefifths" }, { 0x0ab5, "fourfifths" }, { 0x0ab6, "onesixth" }, { 0x0ab7, "fivesixths" }, { 0x0ab8, "careof" }, { 0x0abb, "figdash" }, { 0x0abc, "leftanglebracket" }, { 0x0abd, "decimalpoint" }, { 0x0abe, "rightanglebracket" }, { 0x0abf, "marker" }, { 0x0ac3, "oneeighth" }, { 0x0ac4, "threeeighths" }, { 0x0ac5, "fiveeighths" }, { 0x0ac6, "seveneighths" }, { 0x0ac9, "trademark" }, { 0x0aca, "signaturemark" }, { 0x0acb, "trademarkincircle" }, { 0x0acc, "leftopentriangle" }, { 0x0acd, "rightopentriangle" }, { 0x0ace, "emopencircle" }, { 0x0acf, "emopenrectangle" }, { 0x0ad0, "leftsinglequotemark" }, { 0x0ad1, "rightsinglequotemark" }, { 0x0ad2, "leftdoublequotemark" }, { 0x0ad3, "rightdoublequotemark" }, { 0x0ad4, "prescription" }, { 0x0ad6, "minutes" }, { 0x0ad7, "seconds" }, { 0x0ad9, "latincross" }, { 0x0ada, "hexagram" }, { 0x0adb, "filledrectbullet" }, { 0x0adc, "filledlefttribullet" }, { 0x0add, "filledrighttribullet" }, { 0x0ade, "emfilledcircle" }, { 0x0adf, "emfilledrect" }, { 0x0ae0, "enopencircbullet" }, { 0x0ae1, "enopensquarebullet" }, { 0x0ae2, "openrectbullet" }, { 0x0ae3, "opentribulletup" }, { 0x0ae4, "opentribulletdown" }, { 0x0ae5, "openstar" }, { 0x0ae6, "enfilledcircbullet" }, { 0x0ae7, "enfilledsqbullet" }, { 0x0ae8, "filledtribulletup" }, { 0x0ae9, "filledtribulletdown" }, { 0x0aea, "leftpointer" }, { 0x0aeb, "rightpointer" }, { 0x0aec, "club" }, { 0x0aed, "diamond" }, { 0x0aee, "heart" }, { 0x0af0, "maltesecross" }, { 0x0af1, "dagger" }, { 0x0af2, "doubledagger" }, { 0x0af3, "checkmark" }, { 0x0af4, "ballotcross" }, { 0x0af5, "musicalsharp" }, { 0x0af6, "musicalflat" }, { 0x0af7, "malesymbol" }, { 0x0af8, "femalesymbol" }, { 0x0af9, "telephone" }, { 0x0afa, "telephonerecorder" }, { 0x0afb, "phonographcopyright" }, { 0x0afc, "caret" }, { 0x0afd, "singlelowquotemark" }, { 0x0afe, "doublelowquotemark" }, { 0x0aff, "cursor" }, { 0x0ba3, "leftcaret" }, { 0x0ba6, "rightcaret" }, { 0x0ba8, "downcaret" }, { 0x0ba9, "upcaret" }, { 0x0bc0, "overbar" }, { 0x0bc2, "downtack" }, { 0x0bc3, "upshoe" }, { 0x0bc4, "downstile" }, { 0x0bc6, "underbar" }, { 0x0bca, "jot" }, { 0x0bcc, "quad" }, { 0x0bce, "uptack" }, { 0x0bcf, "circle" }, { 0x0bd3, "upstile" }, { 0x0bd6, "downshoe" }, { 0x0bd8, "rightshoe" }, { 0x0bda, "leftshoe" }, { 0x0bdc, "lefttack" }, { 0x0bfc, "righttack" }, { 0x0cdf, "hebrew_doublelowline" }, { 0x0ce0, "hebrew_aleph" }, { 0x0ce1, "hebrew_bet" }, { 0x0ce1, "hebrew_beth" }, { 0x0ce2, "hebrew_gimel" }, { 0x0ce2, "hebrew_gimmel" }, { 0x0ce3, "hebrew_dalet" }, { 0x0ce3, "hebrew_daleth" }, { 0x0ce4, "hebrew_he" }, { 0x0ce5, "hebrew_waw" }, { 0x0ce6, "hebrew_zain" }, { 0x0ce6, "hebrew_zayin" }, { 0x0ce7, "hebrew_chet" }, { 0x0ce7, "hebrew_het" }, { 0x0ce8, "hebrew_tet" }, { 0x0ce8, "hebrew_teth" }, { 0x0ce9, "hebrew_yod" }, { 0x0cea, "hebrew_finalkaph" }, { 0x0ceb, "hebrew_kaph" }, { 0x0cec, "hebrew_lamed" }, { 0x0ced, "hebrew_finalmem" }, { 0x0cee, "hebrew_mem" }, { 0x0cef, "hebrew_finalnun" }, { 0x0cf0, "hebrew_nun" }, { 0x0cf1, "hebrew_samech" }, { 0x0cf1, "hebrew_samekh" }, { 0x0cf2, "hebrew_ayin" }, { 0x0cf3, "hebrew_finalpe" }, { 0x0cf4, "hebrew_pe" }, { 0x0cf5, "hebrew_finalzade" }, { 0x0cf5, "hebrew_finalzadi" }, { 0x0cf6, "hebrew_zade" }, { 0x0cf6, "hebrew_zadi" }, { 0x0cf7, "hebrew_kuf" }, { 0x0cf7, "hebrew_qoph" }, { 0x0cf8, "hebrew_resh" }, { 0x0cf9, "hebrew_shin" }, { 0x0cfa, "hebrew_taf" }, { 0x0cfa, "hebrew_taw" }, { 0x0da1, "Thai_kokai" }, { 0x0da2, "Thai_khokhai" }, { 0x0da3, "Thai_khokhuat" }, { 0x0da4, "Thai_khokhwai" }, { 0x0da5, "Thai_khokhon" }, { 0x0da6, "Thai_khorakhang" }, { 0x0da7, "Thai_ngongu" }, { 0x0da8, "Thai_chochan" }, { 0x0da9, "Thai_choching" }, { 0x0daa, "Thai_chochang" }, { 0x0dab, "Thai_soso" }, { 0x0dac, "Thai_chochoe" }, { 0x0dad, "Thai_yoying" }, { 0x0dae, "Thai_dochada" }, { 0x0daf, "Thai_topatak" }, { 0x0db0, "Thai_thothan" }, { 0x0db1, "Thai_thonangmontho" }, { 0x0db2, "Thai_thophuthao" }, { 0x0db3, "Thai_nonen" }, { 0x0db4, "Thai_dodek" }, { 0x0db5, "Thai_totao" }, { 0x0db6, "Thai_thothung" }, { 0x0db7, "Thai_thothahan" }, { 0x0db8, "Thai_thothong" }, { 0x0db9, "Thai_nonu" }, { 0x0dba, "Thai_bobaimai" }, { 0x0dbb, "Thai_popla" }, { 0x0dbc, "Thai_phophung" }, { 0x0dbd, "Thai_fofa" }, { 0x0dbe, "Thai_phophan" }, { 0x0dbf, "Thai_fofan" }, { 0x0dc0, "Thai_phosamphao" }, { 0x0dc1, "Thai_moma" }, { 0x0dc2, "Thai_yoyak" }, { 0x0dc3, "Thai_rorua" }, { 0x0dc4, "Thai_ru" }, { 0x0dc5, "Thai_loling" }, { 0x0dc6, "Thai_lu" }, { 0x0dc7, "Thai_wowaen" }, { 0x0dc8, "Thai_sosala" }, { 0x0dc9, "Thai_sorusi" }, { 0x0dca, "Thai_sosua" }, { 0x0dcb, "Thai_hohip" }, { 0x0dcc, "Thai_lochula" }, { 0x0dcd, "Thai_oang" }, { 0x0dce, "Thai_honokhuk" }, { 0x0dcf, "Thai_paiyannoi" }, { 0x0dd0, "Thai_saraa" }, { 0x0dd1, "Thai_maihanakat" }, { 0x0dd2, "Thai_saraaa" }, { 0x0dd3, "Thai_saraam" }, { 0x0dd4, "Thai_sarai" }, { 0x0dd5, "Thai_saraii" }, { 0x0dd6, "Thai_saraue" }, { 0x0dd7, "Thai_sarauee" }, { 0x0dd8, "Thai_sarau" }, { 0x0dd9, "Thai_sarauu" }, { 0x0dda, "Thai_phinthu" }, { 0x0dde, "Thai_maihanakat_maitho" }, { 0x0ddf, "Thai_baht" }, { 0x0de0, "Thai_sarae" }, { 0x0de1, "Thai_saraae" }, { 0x0de2, "Thai_sarao" }, { 0x0de3, "Thai_saraaimaimuan" }, { 0x0de4, "Thai_saraaimaimalai" }, { 0x0de5, "Thai_lakkhangyao" }, { 0x0de6, "Thai_maiyamok" }, { 0x0de7, "Thai_maitaikhu" }, { 0x0de8, "Thai_maiek" }, { 0x0de9, "Thai_maitho" }, { 0x0dea, "Thai_maitri" }, { 0x0deb, "Thai_maichattawa" }, { 0x0dec, "Thai_thanthakhat" }, { 0x0ded, "Thai_nikhahit" }, { 0x0df0, "Thai_leksun" }, { 0x0df1, "Thai_leknung" }, { 0x0df2, "Thai_leksong" }, { 0x0df3, "Thai_leksam" }, { 0x0df4, "Thai_leksi" }, { 0x0df5, "Thai_lekha" }, { 0x0df6, "Thai_lekhok" }, { 0x0df7, "Thai_lekchet" }, { 0x0df8, "Thai_lekpaet" }, { 0x0df9, "Thai_lekkao" }, { 0x0ea1, "Hangul_Kiyeog" }, { 0x0ea2, "Hangul_SsangKiyeog" }, { 0x0ea3, "Hangul_KiyeogSios" }, { 0x0ea4, "Hangul_Nieun" }, { 0x0ea5, "Hangul_NieunJieuj" }, { 0x0ea6, "Hangul_NieunHieuh" }, { 0x0ea7, "Hangul_Dikeud" }, { 0x0ea8, "Hangul_SsangDikeud" }, { 0x0ea9, "Hangul_Rieul" }, { 0x0eaa, "Hangul_RieulKiyeog" }, { 0x0eab, "Hangul_RieulMieum" }, { 0x0eac, "Hangul_RieulPieub" }, { 0x0ead, "Hangul_RieulSios" }, { 0x0eae, "Hangul_RieulTieut" }, { 0x0eaf, "Hangul_RieulPhieuf" }, { 0x0eb0, "Hangul_RieulHieuh" }, { 0x0eb1, "Hangul_Mieum" }, { 0x0eb2, "Hangul_Pieub" }, { 0x0eb3, "Hangul_SsangPieub" }, { 0x0eb4, "Hangul_PieubSios" }, { 0x0eb5, "Hangul_Sios" }, { 0x0eb6, "Hangul_SsangSios" }, { 0x0eb7, "Hangul_Ieung" }, { 0x0eb8, "Hangul_Jieuj" }, { 0x0eb9, "Hangul_SsangJieuj" }, { 0x0eba, "Hangul_Cieuc" }, { 0x0ebb, "Hangul_Khieuq" }, { 0x0ebc, "Hangul_Tieut" }, { 0x0ebd, "Hangul_Phieuf" }, { 0x0ebe, "Hangul_Hieuh" }, { 0x0ebf, "Hangul_A" }, { 0x0ec0, "Hangul_AE" }, { 0x0ec1, "Hangul_YA" }, { 0x0ec2, "Hangul_YAE" }, { 0x0ec3, "Hangul_EO" }, { 0x0ec4, "Hangul_E" }, { 0x0ec5, "Hangul_YEO" }, { 0x0ec6, "Hangul_YE" }, { 0x0ec7, "Hangul_O" }, { 0x0ec8, "Hangul_WA" }, { 0x0ec9, "Hangul_WAE" }, { 0x0eca, "Hangul_OE" }, { 0x0ecb, "Hangul_YO" }, { 0x0ecc, "Hangul_U" }, { 0x0ecd, "Hangul_WEO" }, { 0x0ece, "Hangul_WE" }, { 0x0ecf, "Hangul_WI" }, { 0x0ed0, "Hangul_YU" }, { 0x0ed1, "Hangul_EU" }, { 0x0ed2, "Hangul_YI" }, { 0x0ed3, "Hangul_I" }, { 0x0ed4, "Hangul_J_Kiyeog" }, { 0x0ed5, "Hangul_J_SsangKiyeog" }, { 0x0ed6, "Hangul_J_KiyeogSios" }, { 0x0ed7, "Hangul_J_Nieun" }, { 0x0ed8, "Hangul_J_NieunJieuj" }, { 0x0ed9, "Hangul_J_NieunHieuh" }, { 0x0eda, "Hangul_J_Dikeud" }, { 0x0edb, "Hangul_J_Rieul" }, { 0x0edc, "Hangul_J_RieulKiyeog" }, { 0x0edd, "Hangul_J_RieulMieum" }, { 0x0ede, "Hangul_J_RieulPieub" }, { 0x0edf, "Hangul_J_RieulSios" }, { 0x0ee0, "Hangul_J_RieulTieut" }, { 0x0ee1, "Hangul_J_RieulPhieuf" }, { 0x0ee2, "Hangul_J_RieulHieuh" }, { 0x0ee3, "Hangul_J_Mieum" }, { 0x0ee4, "Hangul_J_Pieub" }, { 0x0ee5, "Hangul_J_PieubSios" }, { 0x0ee6, "Hangul_J_Sios" }, { 0x0ee7, "Hangul_J_SsangSios" }, { 0x0ee8, "Hangul_J_Ieung" }, { 0x0ee9, "Hangul_J_Jieuj" }, { 0x0eea, "Hangul_J_Cieuc" }, { 0x0eeb, "Hangul_J_Khieuq" }, { 0x0eec, "Hangul_J_Tieut" }, { 0x0eed, "Hangul_J_Phieuf" }, { 0x0eee, "Hangul_J_Hieuh" }, { 0x0eef, "Hangul_RieulYeorinHieuh" }, { 0x0ef0, "Hangul_SunkyeongeumMieum" }, { 0x0ef1, "Hangul_SunkyeongeumPieub" }, { 0x0ef2, "Hangul_PanSios" }, { 0x0ef3, "Hangul_KkogjiDalrinIeung" }, { 0x0ef4, "Hangul_SunkyeongeumPhieuf" }, { 0x0ef5, "Hangul_YeorinHieuh" }, { 0x0ef6, "Hangul_AraeA" }, { 0x0ef7, "Hangul_AraeAE" }, { 0x0ef8, "Hangul_J_PanSios" }, { 0x0ef9, "Hangul_J_KkogjiDalrinIeung" }, { 0x0efa, "Hangul_J_YeorinHieuh" }, { 0x0eff, "Korean_Won" }, { 0x13bc, "OE" }, { 0x13bd, "oe" }, { 0x13be, "Ydiaeresis" }, { 0x1e9f, "combining_tilde" }, { 0x1ef2, "combining_grave" }, { 0x1ef3, "combining_acute" }, { 0x1efa, "Ohorn" }, { 0x1efb, "ohorn" }, { 0x1efc, "Uhorn" }, { 0x1efd, "uhorn" }, { 0x1efe, "combining_hook" }, { 0x1eff, "combining_belowdot" }, { 0x20a0, "EcuSign" }, { 0x20a1, "ColonSign" }, { 0x20a2, "CruzeiroSign" }, { 0x20a3, "FFrancSign" }, { 0x20a4, "LiraSign" }, { 0x20a5, "MillSign" }, { 0x20a6, "NairaSign" }, { 0x20a7, "PesetaSign" }, { 0x20a8, "RupeeSign" }, { 0x20a9, "WonSign" }, { 0x20aa, "NewSheqelSign" }, { 0x20ab, "DongSign" }, { 0x20ac, "EuroSign" }, { 0xfd01, "3270_Duplicate" }, { 0xfd02, "3270_FieldMark" }, { 0xfd03, "3270_Right2" }, { 0xfd04, "3270_Left2" }, { 0xfd05, "3270_BackTab" }, { 0xfd06, "3270_EraseEOF" }, { 0xfd07, "3270_EraseInput" }, { 0xfd08, "3270_Reset" }, { 0xfd09, "3270_Quit" }, { 0xfd0a, "3270_PA1" }, { 0xfd0b, "3270_PA2" }, { 0xfd0c, "3270_PA3" }, { 0xfd0d, "3270_Test" }, { 0xfd0e, "3270_Attn" }, { 0xfd0f, "3270_CursorBlink" }, { 0xfd10, "3270_AltCursor" }, { 0xfd11, "3270_KeyClick" }, { 0xfd12, "3270_Jump" }, { 0xfd13, "3270_Ident" }, { 0xfd14, "3270_Rule" }, { 0xfd15, "3270_Copy" }, { 0xfd16, "3270_Play" }, { 0xfd17, "3270_Setup" }, { 0xfd18, "3270_Record" }, { 0xfd19, "3270_ChangeScreen" }, { 0xfd1a, "3270_DeleteWord" }, { 0xfd1b, "3270_ExSelect" }, { 0xfd1c, "3270_CursorSelect" }, { 0xfd1d, "3270_PrintScreen" }, { 0xfd1e, "3270_Enter" }, { 0xfe01, "ISO_Lock" }, { 0xfe02, "ISO_Level2_Latch" }, { 0xfe03, "ISO_Level3_Shift" }, { 0xfe04, "ISO_Level3_Latch" }, { 0xfe05, "ISO_Level3_Lock" }, { 0xfe06, "ISO_Group_Latch" }, { 0xfe07, "ISO_Group_Lock" }, { 0xfe08, "ISO_Next_Group" }, { 0xfe09, "ISO_Next_Group_Lock" }, { 0xfe0a, "ISO_Prev_Group" }, { 0xfe0b, "ISO_Prev_Group_Lock" }, { 0xfe0c, "ISO_First_Group" }, { 0xfe0d, "ISO_First_Group_Lock" }, { 0xfe0e, "ISO_Last_Group" }, { 0xfe0f, "ISO_Last_Group_Lock" }, { 0xfe20, "ISO_Left_Tab" }, { 0xfe21, "ISO_Move_Line_Up" }, { 0xfe22, "ISO_Move_Line_Down" }, { 0xfe23, "ISO_Partial_Line_Up" }, { 0xfe24, "ISO_Partial_Line_Down" }, { 0xfe25, "ISO_Partial_Space_Left" }, { 0xfe26, "ISO_Partial_Space_Right" }, { 0xfe27, "ISO_Set_Margin_Left" }, { 0xfe28, "ISO_Set_Margin_Right" }, { 0xfe29, "ISO_Release_Margin_Left" }, { 0xfe2a, "ISO_Release_Margin_Right" }, { 0xfe2b, "ISO_Release_Both_Margins" }, { 0xfe2c, "ISO_Fast_Cursor_Left" }, { 0xfe2d, "ISO_Fast_Cursor_Right" }, { 0xfe2e, "ISO_Fast_Cursor_Up" }, { 0xfe2f, "ISO_Fast_Cursor_Down" }, { 0xfe30, "ISO_Continuous_Underline" }, { 0xfe31, "ISO_Discontinuous_Underline" }, { 0xfe32, "ISO_Emphasize" }, { 0xfe33, "ISO_Center_Object" }, { 0xfe34, "ISO_Enter" }, { 0xfe50, "dead_grave" }, { 0xfe51, "dead_acute" }, { 0xfe52, "dead_circumflex" }, { 0xfe53, "dead_tilde" }, { 0xfe54, "dead_macron" }, { 0xfe55, "dead_breve" }, { 0xfe56, "dead_abovedot" }, { 0xfe57, "dead_diaeresis" }, { 0xfe58, "dead_abovering" }, { 0xfe59, "dead_doubleacute" }, { 0xfe5a, "dead_caron" }, { 0xfe5b, "dead_cedilla" }, { 0xfe5c, "dead_ogonek" }, { 0xfe5d, "dead_iota" }, { 0xfe5e, "dead_voiced_sound" }, { 0xfe5f, "dead_semivoiced_sound" }, { 0xfe60, "dead_belowdot" }, { 0xfe61, "dead_hook" }, { 0xfe62, "dead_horn" }, { 0xfe70, "AccessX_Enable" }, { 0xfe71, "AccessX_Feedback_Enable" }, { 0xfe72, "RepeatKeys_Enable" }, { 0xfe73, "SlowKeys_Enable" }, { 0xfe74, "BounceKeys_Enable" }, { 0xfe75, "StickyKeys_Enable" }, { 0xfe76, "MouseKeys_Enable" }, { 0xfe77, "MouseKeys_Accel_Enable" }, { 0xfe78, "Overlay1_Enable" }, { 0xfe79, "Overlay2_Enable" }, { 0xfe7a, "AudibleBell_Enable" }, { 0xfed0, "First_Virtual_Screen" }, { 0xfed1, "Prev_Virtual_Screen" }, { 0xfed2, "Next_Virtual_Screen" }, { 0xfed4, "Last_Virtual_Screen" }, { 0xfed5, "Terminate_Server" }, { 0xfee0, "Pointer_Left" }, { 0xfee1, "Pointer_Right" }, { 0xfee2, "Pointer_Up" }, { 0xfee3, "Pointer_Down" }, { 0xfee4, "Pointer_UpLeft" }, { 0xfee5, "Pointer_UpRight" }, { 0xfee6, "Pointer_DownLeft" }, { 0xfee7, "Pointer_DownRight" }, { 0xfee8, "Pointer_Button_Dflt" }, { 0xfee9, "Pointer_Button1" }, { 0xfeea, "Pointer_Button2" }, { 0xfeeb, "Pointer_Button3" }, { 0xfeec, "Pointer_Button4" }, { 0xfeed, "Pointer_Button5" }, { 0xfeee, "Pointer_DblClick_Dflt" }, { 0xfeef, "Pointer_DblClick1" }, { 0xfef0, "Pointer_DblClick2" }, { 0xfef1, "Pointer_DblClick3" }, { 0xfef2, "Pointer_DblClick4" }, { 0xfef3, "Pointer_DblClick5" }, { 0xfef4, "Pointer_Drag_Dflt" }, { 0xfef5, "Pointer_Drag1" }, { 0xfef6, "Pointer_Drag2" }, { 0xfef7, "Pointer_Drag3" }, { 0xfef8, "Pointer_Drag4" }, { 0xfef9, "Pointer_EnableKeys" }, { 0xfefa, "Pointer_Accelerate" }, { 0xfefb, "Pointer_DfltBtnNext" }, { 0xfefc, "Pointer_DfltBtnPrev" }, { 0xfefd, "Pointer_Drag5" }, { 0xff08, "BackSpace" }, { 0xff09, "Tab" }, { 0xff0a, "Linefeed" }, { 0xff0b, "Clear" }, { 0xff0d, "Return" }, { 0xff13, "Pause" }, { 0xff14, "Scroll_Lock" }, { 0xff15, "Sys_Req" }, { 0xff1b, "Escape" }, { 0xff20, "Multi_key" }, { 0xff21, "Kanji" }, { 0xff22, "Muhenkan" }, { 0xff23, "Henkan" }, { 0xff23, "Henkan_Mode" }, { 0xff24, "Romaji" }, { 0xff25, "Hiragana" }, { 0xff26, "Katakana" }, { 0xff27, "Hiragana_Katakana" }, { 0xff28, "Zenkaku" }, { 0xff29, "Hankaku" }, { 0xff2a, "Zenkaku_Hankaku" }, { 0xff2b, "Touroku" }, { 0xff2c, "Massyo" }, { 0xff2d, "Kana_Lock" }, { 0xff2e, "Kana_Shift" }, { 0xff2f, "Eisu_Shift" }, { 0xff30, "Eisu_toggle" }, { 0xff31, "Hangul" }, { 0xff32, "Hangul_Start" }, { 0xff33, "Hangul_End" }, { 0xff34, "Hangul_Hanja" }, { 0xff35, "Hangul_Jamo" }, { 0xff36, "Hangul_Romaja" }, { 0xff37, "Codeinput" }, { 0xff38, "Hangul_Jeonja" }, { 0xff39, "Hangul_Banja" }, { 0xff3a, "Hangul_PreHanja" }, { 0xff3b, "Hangul_PostHanja" }, { 0xff3c, "SingleCandidate" }, { 0xff3d, "MultipleCandidate" }, { 0xff3e, "PreviousCandidate" }, { 0xff3f, "Hangul_Special" }, { 0xff50, "Home" }, { 0xff51, "Left" }, { 0xff52, "Up" }, { 0xff53, "Right" }, { 0xff54, "Down" }, { 0xff55, "Page_Up" }, { 0xff55, "Prior" }, { 0xff56, "Page_Down" }, { 0xff56, "Next" }, { 0xff57, "End" }, { 0xff58, "Begin" }, { 0xff60, "Select" }, { 0xff61, "Print" }, { 0xff62, "Execute" }, { 0xff63, "Insert" }, { 0xff65, "Undo" }, { 0xff66, "Redo" }, { 0xff67, "Menu" }, { 0xff68, "Find" }, { 0xff69, "Cancel" }, { 0xff6a, "Help" }, { 0xff6b, "Break" }, { 0xff7e, "Mode_switch" }, { 0xff7e, "Arabic_switch" }, { 0xff7e, "Greek_switch" }, { 0xff7e, "Hangul_switch" }, { 0xff7e, "Hebrew_switch" }, { 0xff7e, "ISO_Group_Shift" }, { 0xff7e, "kana_switch" }, { 0xff7e, "script_switch" }, { 0xff7f, "Num_Lock" }, { 0xff80, "KP_Space" }, { 0xff89, "KP_Tab" }, { 0xff8d, "KP_Enter" }, { 0xff91, "KP_F1" }, { 0xff92, "KP_F2" }, { 0xff93, "KP_F3" }, { 0xff94, "KP_F4" }, { 0xff95, "KP_Home" }, { 0xff96, "KP_Left" }, { 0xff97, "KP_Up" }, { 0xff98, "KP_Right" }, { 0xff99, "KP_Down" }, { 0xff9a, "KP_Page_Up" }, { 0xff9a, "KP_Prior" }, { 0xff9b, "KP_Page_Down" }, { 0xff9b, "KP_Next" }, { 0xff9c, "KP_End" }, { 0xff9d, "KP_Begin" }, { 0xff9e, "KP_Insert" }, { 0xff9f, "KP_Delete" }, { 0xffaa, "KP_Multiply" }, { 0xffab, "KP_Add" }, { 0xffac, "KP_Separator" }, { 0xffad, "KP_Subtract" }, { 0xffae, "KP_Decimal" }, { 0xffaf, "KP_Divide" }, { 0xffb0, "KP_0" }, { 0xffb1, "KP_1" }, { 0xffb2, "KP_2" }, { 0xffb3, "KP_3" }, { 0xffb4, "KP_4" }, { 0xffb5, "KP_5" }, { 0xffb6, "KP_6" }, { 0xffb7, "KP_7" }, { 0xffb8, "KP_8" }, { 0xffb9, "KP_9" }, { 0xffbd, "KP_Equal" }, { 0xffbe, "F1" }, { 0xffbf, "F2" }, { 0xffc0, "F3" }, { 0xffc1, "F4" }, { 0xffc2, "F5" }, { 0xffc3, "F6" }, { 0xffc4, "F7" }, { 0xffc5, "F8" }, { 0xffc6, "F9" }, { 0xffc7, "F10" }, { 0xffc8, "F11" }, { 0xffc9, "F12" }, { 0xffca, "F13" }, { 0xffcb, "F14" }, { 0xffcc, "F15" }, { 0xffcd, "F16" }, { 0xffce, "F17" }, { 0xffcf, "F18" }, { 0xffd0, "F19" }, { 0xffd1, "F20" }, { 0xffd2, "F21" }, { 0xffd3, "F22" }, { 0xffd4, "F23" }, { 0xffd5, "F24" }, { 0xffd6, "F25" }, { 0xffd7, "F26" }, { 0xffd8, "F27" }, { 0xffd9, "F28" }, { 0xffda, "F29" }, { 0xffdb, "F30" }, { 0xffdc, "F31" }, { 0xffdd, "F32" }, { 0xffde, "F33" }, { 0xffdf, "F34" }, { 0xffe0, "F35" }, { 0xffe1, "Shift_L" }, { 0xffe2, "Shift_R" }, { 0xffe3, "Control_L" }, { 0xffe4, "Control_R" }, { 0xffe5, "Caps_Lock" }, { 0xffe6, "Shift_Lock" }, { 0xffe7, "Meta_L" }, { 0xffe8, "Meta_R" }, { 0xffe9, "Alt_L" }, { 0xffea, "Alt_R" }, { 0xffeb, "Super_L" }, { 0xffec, "Super_R" }, { 0xffed, "Hyper_L" }, { 0xffee, "Hyper_R" }, { 0xffff, "Delete" } }; static __KeyName __scim_keys_by_name [] = { { 0x0030, "0" }, { 0x0031, "1" }, { 0x0032, "2" }, { 0x0033, "3" }, { 0xFD10, "3270_AltCursor" }, { 0xFD0E, "3270_Attn" }, { 0xFD05, "3270_BackTab" }, { 0xFD19, "3270_ChangeScreen" }, { 0xFD15, "3270_Copy" }, { 0xFD0F, "3270_CursorBlink" }, { 0xFD1C, "3270_CursorSelect" }, { 0xFD1A, "3270_DeleteWord" }, { 0xFD01, "3270_Duplicate" }, { 0xFD1E, "3270_Enter" }, { 0xFD06, "3270_EraseEOF" }, { 0xFD07, "3270_EraseInput" }, { 0xFD1B, "3270_ExSelect" }, { 0xFD02, "3270_FieldMark" }, { 0xFD13, "3270_Ident" }, { 0xFD12, "3270_Jump" }, { 0xFD11, "3270_KeyClick" }, { 0xFD04, "3270_Left2" }, { 0xFD0A, "3270_PA1" }, { 0xFD0B, "3270_PA2" }, { 0xFD0C, "3270_PA3" }, { 0xFD16, "3270_Play" }, { 0xFD1D, "3270_PrintScreen" }, { 0xFD09, "3270_Quit" }, { 0xFD18, "3270_Record" }, { 0xFD08, "3270_Reset" }, { 0xFD03, "3270_Right2" }, { 0xFD14, "3270_Rule" }, { 0xFD17, "3270_Setup" }, { 0xFD0D, "3270_Test" }, { 0x0034, "4" }, { 0x0035, "5" }, { 0x0036, "6" }, { 0x0037, "7" }, { 0x0038, "8" }, { 0x0039, "9" }, { 0x0041, "A" }, { 0x00C6, "AE" }, { 0x00C1, "Aacute" }, { 0x01C3, "Abreve" }, { 0xFE70, "AccessX_Enable" }, { 0xFE71, "AccessX_Feedback_Enable" }, { 0x00C2, "Acircumflex" }, { 0x00C4, "Adiaeresis" }, { 0x00C0, "Agrave" }, { 0xFFE9, "Alt_L" }, { 0xFFEA, "Alt_R" }, { 0x03C0, "Amacron" }, { 0x01A1, "Aogonek" }, { 0x05D9, "Arabic_ain" }, { 0x05C7, "Arabic_alef" }, { 0x05E9, "Arabic_alefmaksura" }, { 0x05C8, "Arabic_beh" }, { 0x05AC, "Arabic_comma" }, { 0x05D6, "Arabic_dad" }, { 0x05CF, "Arabic_dal" }, { 0x05EF, "Arabic_damma" }, { 0x05EC, "Arabic_dammatan" }, { 0x05EE, "Arabic_fatha" }, { 0x05EB, "Arabic_fathatan" }, { 0x05E1, "Arabic_feh" }, { 0x05DA, "Arabic_ghain" }, { 0x05E7, "Arabic_ha" }, { 0x05CD, "Arabic_hah" }, { 0x05C1, "Arabic_hamza" }, { 0x05C3, "Arabic_hamzaonalef" }, { 0x05C4, "Arabic_hamzaonwaw" }, { 0x05C6, "Arabic_hamzaonyeh" }, { 0x05C5, "Arabic_hamzaunderalef" }, { 0x05E7, "Arabic_heh" }, { 0x05CC, "Arabic_jeem" }, { 0x05E3, "Arabic_kaf" }, { 0x05F0, "Arabic_kasra" }, { 0x05ED, "Arabic_kasratan" }, { 0x05CE, "Arabic_khah" }, { 0x05E4, "Arabic_lam" }, { 0x05C2, "Arabic_maddaonalef" }, { 0x05E5, "Arabic_meem" }, { 0x05E6, "Arabic_noon" }, { 0x05E2, "Arabic_qaf" }, { 0x05BF, "Arabic_question_mark" }, { 0x05D1, "Arabic_ra" }, { 0x05D5, "Arabic_sad" }, { 0x05D3, "Arabic_seen" }, { 0x05BB, "Arabic_semicolon" }, { 0x05F1, "Arabic_shadda" }, { 0x05D4, "Arabic_sheen" }, { 0x05F2, "Arabic_sukun" }, { 0xFF7E, "Arabic_switch" }, { 0x05D7, "Arabic_tah" }, { 0x05E0, "Arabic_tatweel" }, { 0x05CA, "Arabic_teh" }, { 0x05C9, "Arabic_tehmarbuta" }, { 0x05D0, "Arabic_thal" }, { 0x05CB, "Arabic_theh" }, { 0x05E8, "Arabic_waw" }, { 0x05EA, "Arabic_yeh" }, { 0x05D8, "Arabic_zah" }, { 0x05D2, "Arabic_zain" }, { 0x00C5, "Aring" }, { 0x00C3, "Atilde" }, { 0xFE7A, "AudibleBell_Enable" }, { 0x0042, "B" }, { 0xFF08, "BackSpace" }, { 0xFF58, "Begin" }, { 0xFE74, "BounceKeys_Enable" }, { 0xFF6B, "Break" }, { 0x06BE, "Byelorussian_SHORTU" }, { 0x06AE, "Byelorussian_shortu" }, { 0x0043, "C" }, { 0x02C5, "Cabovedot" }, { 0x01C6, "Cacute" }, { 0xFF69, "Cancel" }, { 0xFFE5, "Caps_Lock" }, { 0x01C8, "Ccaron" }, { 0x00C7, "Ccedilla" }, { 0x02C6, "Ccircumflex" }, { 0xFF0B, "Clear" }, { 0xFF37, "Codeinput" }, { 0x20A1, "ColonSign" }, { 0xFFE3, "Control_L" }, { 0xFFE4, "Control_R" }, { 0x20A2, "CruzeiroSign" }, { 0x06E1, "Cyrillic_A" }, { 0x06E2, "Cyrillic_BE" }, { 0x06FE, "Cyrillic_CHE" }, { 0x06E4, "Cyrillic_DE" }, { 0x06BF, "Cyrillic_DZHE" }, { 0x06FC, "Cyrillic_E" }, { 0x06E6, "Cyrillic_EF" }, { 0x06EC, "Cyrillic_EL" }, { 0x06ED, "Cyrillic_EM" }, { 0x06EE, "Cyrillic_EN" }, { 0x06F2, "Cyrillic_ER" }, { 0x06F3, "Cyrillic_ES" }, { 0x06E7, "Cyrillic_GHE" }, { 0x06E8, "Cyrillic_HA" }, { 0x06FF, "Cyrillic_HARDSIGN" }, { 0x06E9, "Cyrillic_I" }, { 0x06E5, "Cyrillic_IE" }, { 0x06B3, "Cyrillic_IO" }, { 0x06B8, "Cyrillic_JE" }, { 0x06EB, "Cyrillic_KA" }, { 0x06B9, "Cyrillic_LJE" }, { 0x06BA, "Cyrillic_NJE" }, { 0x06EF, "Cyrillic_O" }, { 0x06F0, "Cyrillic_PE" }, { 0x06FB, "Cyrillic_SHA" }, { 0x06FD, "Cyrillic_SHCHA" }, { 0x06EA, "Cyrillic_SHORTI" }, { 0x06F8, "Cyrillic_SOFTSIGN" }, { 0x06F4, "Cyrillic_TE" }, { 0x06E3, "Cyrillic_TSE" }, { 0x06F5, "Cyrillic_U" }, { 0x06F7, "Cyrillic_VE" }, { 0x06F1, "Cyrillic_YA" }, { 0x06F9, "Cyrillic_YERU" }, { 0x06E0, "Cyrillic_YU" }, { 0x06FA, "Cyrillic_ZE" }, { 0x06F6, "Cyrillic_ZHE" }, { 0x06C1, "Cyrillic_a" }, { 0x06C2, "Cyrillic_be" }, { 0x06DE, "Cyrillic_che" }, { 0x06C4, "Cyrillic_de" }, { 0x06AF, "Cyrillic_dzhe" }, { 0x06DC, "Cyrillic_e" }, { 0x06C6, "Cyrillic_ef" }, { 0x06CC, "Cyrillic_el" }, { 0x06CD, "Cyrillic_em" }, { 0x06CE, "Cyrillic_en" }, { 0x06D2, "Cyrillic_er" }, { 0x06D3, "Cyrillic_es" }, { 0x06C7, "Cyrillic_ghe" }, { 0x06C8, "Cyrillic_ha" }, { 0x06DF, "Cyrillic_hardsign" }, { 0x06C9, "Cyrillic_i" }, { 0x06C5, "Cyrillic_ie" }, { 0x06A3, "Cyrillic_io" }, { 0x06A8, "Cyrillic_je" }, { 0x06CB, "Cyrillic_ka" }, { 0x06A9, "Cyrillic_lje" }, { 0x06AA, "Cyrillic_nje" }, { 0x06CF, "Cyrillic_o" }, { 0x06D0, "Cyrillic_pe" }, { 0x06DB, "Cyrillic_sha" }, { 0x06DD, "Cyrillic_shcha" }, { 0x06CA, "Cyrillic_shorti" }, { 0x06D8, "Cyrillic_softsign" }, { 0x06D4, "Cyrillic_te" }, { 0x06C3, "Cyrillic_tse" }, { 0x06D5, "Cyrillic_u" }, { 0x06D7, "Cyrillic_ve" }, { 0x06D1, "Cyrillic_ya" }, { 0x06D9, "Cyrillic_yeru" }, { 0x06C0, "Cyrillic_yu" }, { 0x06DA, "Cyrillic_ze" }, { 0x06D6, "Cyrillic_zhe" }, { 0x0044, "D" }, { 0x01CF, "Dcaron" }, { 0xFFFF, "Delete" }, { 0x20AB, "DongSign" }, { 0xFF54, "Down" }, { 0x01D0, "Dstroke" }, { 0x0045, "E" }, { 0x03BD, "ENG" }, { 0x00D0, "ETH" }, { 0x03CC, "Eabovedot" }, { 0x00C9, "Eacute" }, { 0x01CC, "Ecaron" }, { 0x00CA, "Ecircumflex" }, { 0x20A0, "EcuSign" }, { 0x00CB, "Ediaeresis" }, { 0x00C8, "Egrave" }, { 0xFF2F, "Eisu_Shift" }, { 0xFF30, "Eisu_toggle" }, { 0x03AA, "Emacron" }, { 0xFF57, "End" }, { 0x01CA, "Eogonek" }, { 0xFF1B, "Escape" }, { 0x00D0, "Eth" }, { 0x20AC, "EuroSign" }, { 0xFF62, "Execute" }, { 0x0046, "F" }, { 0xFFBE, "F1" }, { 0xFFC7, "F10" }, { 0xFFC8, "F11" }, { 0xFFC9, "F12" }, { 0xFFCA, "F13" }, { 0xFFCB, "F14" }, { 0xFFCC, "F15" }, { 0xFFCD, "F16" }, { 0xFFCE, "F17" }, { 0xFFCF, "F18" }, { 0xFFD0, "F19" }, { 0xFFBF, "F2" }, { 0xFFD1, "F20" }, { 0xFFD2, "F21" }, { 0xFFD3, "F22" }, { 0xFFD4, "F23" }, { 0xFFD5, "F24" }, { 0xFFD6, "F25" }, { 0xFFD7, "F26" }, { 0xFFD8, "F27" }, { 0xFFD9, "F28" }, { 0xFFDA, "F29" }, { 0xFFC0, "F3" }, { 0xFFDB, "F30" }, { 0xFFDC, "F31" }, { 0xFFDD, "F32" }, { 0xFFDE, "F33" }, { 0xFFDF, "F34" }, { 0xFFE0, "F35" }, { 0xFFC1, "F4" }, { 0xFFC2, "F5" }, { 0xFFC3, "F6" }, { 0xFFC4, "F7" }, { 0xFFC5, "F8" }, { 0xFFC6, "F9" }, { 0x20A3, "FFrancSign" }, { 0xFF68, "Find" }, { 0xFED0, "First_Virtual_Screen" }, { 0x0047, "G" }, { 0x02D5, "Gabovedot" }, { 0x02AB, "Gbreve" }, { 0x03AB, "Gcedilla" }, { 0x02D8, "Gcircumflex" }, { 0x07C1, "Greek_ALPHA" }, { 0x07A1, "Greek_ALPHAaccent" }, { 0x07C2, "Greek_BETA" }, { 0x07D7, "Greek_CHI" }, { 0x07C4, "Greek_DELTA" }, { 0x07C5, "Greek_EPSILON" }, { 0x07A2, "Greek_EPSILONaccent" }, { 0x07C7, "Greek_ETA" }, { 0x07A3, "Greek_ETAaccent" }, { 0x07C3, "Greek_GAMMA" }, { 0x07C9, "Greek_IOTA" }, { 0x07A4, "Greek_IOTAaccent" }, { 0x07A5, "Greek_IOTAdiaeresis" }, { 0x07CA, "Greek_KAPPA" }, { 0x07CB, "Greek_LAMBDA" }, { 0x07CB, "Greek_LAMDA" }, { 0x07CC, "Greek_MU" }, { 0x07CD, "Greek_NU" }, { 0x07D9, "Greek_OMEGA" }, { 0x07AB, "Greek_OMEGAaccent" }, { 0x07CF, "Greek_OMICRON" }, { 0x07A7, "Greek_OMICRONaccent" }, { 0x07D6, "Greek_PHI" }, { 0x07D0, "Greek_PI" }, { 0x07D8, "Greek_PSI" }, { 0x07D1, "Greek_RHO" }, { 0x07D2, "Greek_SIGMA" }, { 0x07D4, "Greek_TAU" }, { 0x07C8, "Greek_THETA" }, { 0x07D5, "Greek_UPSILON" }, { 0x07A8, "Greek_UPSILONaccent" }, { 0x07A9, "Greek_UPSILONdieresis" }, { 0x07CE, "Greek_XI" }, { 0x07C6, "Greek_ZETA" }, { 0x07AE, "Greek_accentdieresis" }, { 0x07E1, "Greek_alpha" }, { 0x07B1, "Greek_alphaaccent" }, { 0x07E2, "Greek_beta" }, { 0x07F7, "Greek_chi" }, { 0x07E4, "Greek_delta" }, { 0x07E5, "Greek_epsilon" }, { 0x07B2, "Greek_epsilonaccent" }, { 0x07E7, "Greek_eta" }, { 0x07B3, "Greek_etaaccent" }, { 0x07F3, "Greek_finalsmallsigma" }, { 0x07E3, "Greek_gamma" }, { 0x07AF, "Greek_horizbar" }, { 0x07E9, "Greek_iota" }, { 0x07B4, "Greek_iotaaccent" }, { 0x07B6, "Greek_iotaaccentdieresis" }, { 0x07B5, "Greek_iotadieresis" }, { 0x07EA, "Greek_kappa" }, { 0x07EB, "Greek_lambda" }, { 0x07EB, "Greek_lamda" }, { 0x07EC, "Greek_mu" }, { 0x07ED, "Greek_nu" }, { 0x07F9, "Greek_omega" }, { 0x07BB, "Greek_omegaaccent" }, { 0x07EF, "Greek_omicron" }, { 0x07B7, "Greek_omicronaccent" }, { 0x07F6, "Greek_phi" }, { 0x07F0, "Greek_pi" }, { 0x07F8, "Greek_psi" }, { 0x07F1, "Greek_rho" }, { 0x07F2, "Greek_sigma" }, { 0xFF7E, "Greek_switch" }, { 0x07F4, "Greek_tau" }, { 0x07E8, "Greek_theta" }, { 0x07F5, "Greek_upsilon" }, { 0x07B8, "Greek_upsilonaccent" }, { 0x07BA, "Greek_upsilonaccentdieresis" }, { 0x07B9, "Greek_upsilondieresis" }, { 0x07EE, "Greek_xi" }, { 0x07E6, "Greek_zeta" }, { 0x0048, "H" }, { 0xFF31, "Hangul" }, { 0x0EBF, "Hangul_A" }, { 0x0EC0, "Hangul_AE" }, { 0x0EF6, "Hangul_AraeA" }, { 0x0EF7, "Hangul_AraeAE" }, { 0xFF39, "Hangul_Banja" }, { 0x0EBA, "Hangul_Cieuc" }, { 0x0EA7, "Hangul_Dikeud" }, { 0x0EC4, "Hangul_E" }, { 0x0EC3, "Hangul_EO" }, { 0x0ED1, "Hangul_EU" }, { 0xFF33, "Hangul_End" }, { 0xFF34, "Hangul_Hanja" }, { 0x0EBE, "Hangul_Hieuh" }, { 0x0ED3, "Hangul_I" }, { 0x0EB7, "Hangul_Ieung" }, { 0x0EEA, "Hangul_J_Cieuc" }, { 0x0EDA, "Hangul_J_Dikeud" }, { 0x0EEE, "Hangul_J_Hieuh" }, { 0x0EE8, "Hangul_J_Ieung" }, { 0x0EE9, "Hangul_J_Jieuj" }, { 0x0EEB, "Hangul_J_Khieuq" }, { 0x0ED4, "Hangul_J_Kiyeog" }, { 0x0ED6, "Hangul_J_KiyeogSios" }, { 0x0EF9, "Hangul_J_KkogjiDalrinIeung" }, { 0x0EE3, "Hangul_J_Mieum" }, { 0x0ED7, "Hangul_J_Nieun" }, { 0x0ED9, "Hangul_J_NieunHieuh" }, { 0x0ED8, "Hangul_J_NieunJieuj" }, { 0x0EF8, "Hangul_J_PanSios" }, { 0x0EED, "Hangul_J_Phieuf" }, { 0x0EE4, "Hangul_J_Pieub" }, { 0x0EE5, "Hangul_J_PieubSios" }, { 0x0EDB, "Hangul_J_Rieul" }, { 0x0EE2, "Hangul_J_RieulHieuh" }, { 0x0EDC, "Hangul_J_RieulKiyeog" }, { 0x0EDD, "Hangul_J_RieulMieum" }, { 0x0EE1, "Hangul_J_RieulPhieuf" }, { 0x0EDE, "Hangul_J_RieulPieub" }, { 0x0EDF, "Hangul_J_RieulSios" }, { 0x0EE0, "Hangul_J_RieulTieut" }, { 0x0EE6, "Hangul_J_Sios" }, { 0x0ED5, "Hangul_J_SsangKiyeog" }, { 0x0EE7, "Hangul_J_SsangSios" }, { 0x0EEC, "Hangul_J_Tieut" }, { 0x0EFA, "Hangul_J_YeorinHieuh" }, { 0xFF35, "Hangul_Jamo" }, { 0xFF38, "Hangul_Jeonja" }, { 0x0EB8, "Hangul_Jieuj" }, { 0x0EBB, "Hangul_Khieuq" }, { 0x0EA1, "Hangul_Kiyeog" }, { 0x0EA3, "Hangul_KiyeogSios" }, { 0x0EF3, "Hangul_KkogjiDalrinIeung" }, { 0x0EB1, "Hangul_Mieum" }, { 0x0EA4, "Hangul_Nieun" }, { 0x0EA6, "Hangul_NieunHieuh" }, { 0x0EA5, "Hangul_NieunJieuj" }, { 0x0EC7, "Hangul_O" }, { 0x0ECA, "Hangul_OE" }, { 0x0EF2, "Hangul_PanSios" }, { 0x0EBD, "Hangul_Phieuf" }, { 0x0EB2, "Hangul_Pieub" }, { 0x0EB4, "Hangul_PieubSios" }, { 0xFF3B, "Hangul_PostHanja" }, { 0xFF3A, "Hangul_PreHanja" }, { 0x0EA9, "Hangul_Rieul" }, { 0x0EB0, "Hangul_RieulHieuh" }, { 0x0EAA, "Hangul_RieulKiyeog" }, { 0x0EAB, "Hangul_RieulMieum" }, { 0x0EAF, "Hangul_RieulPhieuf" }, { 0x0EAC, "Hangul_RieulPieub" }, { 0x0EAD, "Hangul_RieulSios" }, { 0x0EAE, "Hangul_RieulTieut" }, { 0x0EEF, "Hangul_RieulYeorinHieuh" }, { 0xFF36, "Hangul_Romaja" }, { 0x0EB5, "Hangul_Sios" }, { 0xFF3F, "Hangul_Special" }, { 0x0EA8, "Hangul_SsangDikeud" }, { 0x0EB9, "Hangul_SsangJieuj" }, { 0x0EA2, "Hangul_SsangKiyeog" }, { 0x0EB3, "Hangul_SsangPieub" }, { 0x0EB6, "Hangul_SsangSios" }, { 0xFF32, "Hangul_Start" }, { 0x0EF0, "Hangul_SunkyeongeumMieum" }, { 0x0EF4, "Hangul_SunkyeongeumPhieuf" }, { 0x0EF1, "Hangul_SunkyeongeumPieub" }, { 0x0EBC, "Hangul_Tieut" }, { 0x0ECC, "Hangul_U" }, { 0x0EC8, "Hangul_WA" }, { 0x0EC9, "Hangul_WAE" }, { 0x0ECE, "Hangul_WE" }, { 0x0ECD, "Hangul_WEO" }, { 0x0ECF, "Hangul_WI" }, { 0x0EC1, "Hangul_YA" }, { 0x0EC2, "Hangul_YAE" }, { 0x0EC6, "Hangul_YE" }, { 0x0EC5, "Hangul_YEO" }, { 0x0ED2, "Hangul_YI" }, { 0x0ECB, "Hangul_YO" }, { 0x0ED0, "Hangul_YU" }, { 0x0EF5, "Hangul_YeorinHieuh" }, { 0xFF7E, "Hangul_switch" }, { 0xFF29, "Hankaku" }, { 0x02A6, "Hcircumflex" }, { 0xFF7E, "Hebrew_switch" }, { 0xFF6A, "Help" }, { 0xFF23, "Henkan" }, { 0xFF23, "Henkan_Mode" }, { 0xFF25, "Hiragana" }, { 0xFF27, "Hiragana_Katakana" }, { 0xFF50, "Home" }, { 0x02A1, "Hstroke" }, { 0xFFED, "Hyper_L" }, { 0xFFEE, "Hyper_R" }, { 0x0049, "I" }, { 0xFE33, "ISO_Center_Object" }, { 0xFE30, "ISO_Continuous_Underline" }, { 0xFE31, "ISO_Discontinuous_Underline" }, { 0xFE32, "ISO_Emphasize" }, { 0xFE34, "ISO_Enter" }, { 0xFE2F, "ISO_Fast_Cursor_Down" }, { 0xFE2C, "ISO_Fast_Cursor_Left" }, { 0xFE2D, "ISO_Fast_Cursor_Right" }, { 0xFE2E, "ISO_Fast_Cursor_Up" }, { 0xFE0C, "ISO_First_Group" }, { 0xFE0D, "ISO_First_Group_Lock" }, { 0xFE06, "ISO_Group_Latch" }, { 0xFE07, "ISO_Group_Lock" }, { 0xFF7E, "ISO_Group_Shift" }, { 0xFE0E, "ISO_Last_Group" }, { 0xFE0F, "ISO_Last_Group_Lock" }, { 0xFE20, "ISO_Left_Tab" }, { 0xFE02, "ISO_Level2_Latch" }, { 0xFE04, "ISO_Level3_Latch" }, { 0xFE05, "ISO_Level3_Lock" }, { 0xFE03, "ISO_Level3_Shift" }, { 0xFE01, "ISO_Lock" }, { 0xFE22, "ISO_Move_Line_Down" }, { 0xFE21, "ISO_Move_Line_Up" }, { 0xFE08, "ISO_Next_Group" }, { 0xFE09, "ISO_Next_Group_Lock" }, { 0xFE24, "ISO_Partial_Line_Down" }, { 0xFE23, "ISO_Partial_Line_Up" }, { 0xFE25, "ISO_Partial_Space_Left" }, { 0xFE26, "ISO_Partial_Space_Right" }, { 0xFE0A, "ISO_Prev_Group" }, { 0xFE0B, "ISO_Prev_Group_Lock" }, { 0xFE2B, "ISO_Release_Both_Margins" }, { 0xFE29, "ISO_Release_Margin_Left" }, { 0xFE2A, "ISO_Release_Margin_Right" }, { 0xFE27, "ISO_Set_Margin_Left" }, { 0xFE28, "ISO_Set_Margin_Right" }, { 0x02A9, "Iabovedot" }, { 0x00CD, "Iacute" }, { 0x00CE, "Icircumflex" }, { 0x00CF, "Idiaeresis" }, { 0x00CC, "Igrave" }, { 0x03CF, "Imacron" }, { 0xFF63, "Insert" }, { 0x03C7, "Iogonek" }, { 0x03A5, "Itilde" }, { 0x004A, "J" }, { 0x02AC, "Jcircumflex" }, { 0x004B, "K" }, { 0xFFB0, "KP_0" }, { 0xFFB1, "KP_1" }, { 0xFFB2, "KP_2" }, { 0xFFB3, "KP_3" }, { 0xFFB4, "KP_4" }, { 0xFFB5, "KP_5" }, { 0xFFB6, "KP_6" }, { 0xFFB7, "KP_7" }, { 0xFFB8, "KP_8" }, { 0xFFB9, "KP_9" }, { 0xFFAB, "KP_Add" }, { 0xFF9D, "KP_Begin" }, { 0xFFAE, "KP_Decimal" }, { 0xFF9F, "KP_Delete" }, { 0xFFAF, "KP_Divide" }, { 0xFF99, "KP_Down" }, { 0xFF9C, "KP_End" }, { 0xFF8D, "KP_Enter" }, { 0xFFBD, "KP_Equal" }, { 0xFF91, "KP_F1" }, { 0xFF92, "KP_F2" }, { 0xFF93, "KP_F3" }, { 0xFF94, "KP_F4" }, { 0xFF95, "KP_Home" }, { 0xFF9E, "KP_Insert" }, { 0xFF96, "KP_Left" }, { 0xFFAA, "KP_Multiply" }, { 0xFF9B, "KP_Next" }, { 0xFF9B, "KP_Page_Down" }, { 0xFF9A, "KP_Page_Up" }, { 0xFF9A, "KP_Prior" }, { 0xFF98, "KP_Right" }, { 0xFFAC, "KP_Separator" }, { 0xFF80, "KP_Space" }, { 0xFFAD, "KP_Subtract" }, { 0xFF89, "KP_Tab" }, { 0xFF97, "KP_Up" }, { 0xFF2D, "Kana_Lock" }, { 0xFF2E, "Kana_Shift" }, { 0xFF21, "Kanji" }, { 0xFF26, "Katakana" }, { 0x03D3, "Kcedilla" }, { 0x0EFF, "Korean_Won" }, { 0x004C, "L" }, { 0x01C5, "Lacute" }, { 0xFED4, "Last_Virtual_Screen" }, { 0x01A5, "Lcaron" }, { 0x03A6, "Lcedilla" }, { 0xFF51, "Left" }, { 0xFF0A, "Linefeed" }, { 0x20A4, "LiraSign" }, { 0x01A3, "Lstroke" }, { 0x004D, "M" }, { 0x06B5, "Macedonia_DSE" }, { 0x06B2, "Macedonia_GJE" }, { 0x06BC, "Macedonia_KJE" }, { 0x06A5, "Macedonia_dse" }, { 0x06A2, "Macedonia_gje" }, { 0x06AC, "Macedonia_kje" }, { 0xFF2C, "Massyo" }, { 0xFF67, "Menu" }, { 0xFFE7, "Meta_L" }, { 0xFFE8, "Meta_R" }, { 0x20A5, "MillSign" }, { 0xFF7E, "Mode_switch" }, { 0xFE77, "MouseKeys_Accel_Enable" }, { 0xFE76, "MouseKeys_Enable" }, { 0xFF22, "Muhenkan" }, { 0xFF20, "Multi_key" }, { 0xFF3D, "MultipleCandidate" }, { 0x004E, "N" }, { 0x01D1, "Nacute" }, { 0x20A6, "NairaSign" }, { 0x01D2, "Ncaron" }, { 0x03D1, "Ncedilla" }, { 0x20AA, "NewSheqelSign" }, { 0xFF56, "Next" }, { 0xFED2, "Next_Virtual_Screen" }, { 0x00D1, "Ntilde" }, { 0xFF7F, "Num_Lock" }, { 0x004F, "O" }, { 0x13BC, "OE" }, { 0x00D3, "Oacute" }, { 0x00D4, "Ocircumflex" }, { 0x00D6, "Odiaeresis" }, { 0x01D5, "Odoubleacute" }, { 0x00D2, "Ograve" }, { 0x1EFA, "Ohorn" }, { 0x03D2, "Omacron" }, { 0x00D8, "Ooblique" }, { 0x00D5, "Otilde" }, { 0xFE78, "Overlay1_Enable" }, { 0xFE79, "Overlay2_Enable" }, { 0x0050, "P" }, { 0xFF56, "Page_Down" }, { 0xFF55, "Page_Up" }, { 0xFF13, "Pause" }, { 0x20A7, "PesetaSign" }, { 0xFEFA, "Pointer_Accelerate" }, { 0xFEE9, "Pointer_Button1" }, { 0xFEEA, "Pointer_Button2" }, { 0xFEEB, "Pointer_Button3" }, { 0xFEEC, "Pointer_Button4" }, { 0xFEED, "Pointer_Button5" }, { 0xFEE8, "Pointer_Button_Dflt" }, { 0xFEEF, "Pointer_DblClick1" }, { 0xFEF0, "Pointer_DblClick2" }, { 0xFEF1, "Pointer_DblClick3" }, { 0xFEF2, "Pointer_DblClick4" }, { 0xFEF3, "Pointer_DblClick5" }, { 0xFEEE, "Pointer_DblClick_Dflt" }, { 0xFEFB, "Pointer_DfltBtnNext" }, { 0xFEFC, "Pointer_DfltBtnPrev" }, { 0xFEE3, "Pointer_Down" }, { 0xFEE6, "Pointer_DownLeft" }, { 0xFEE7, "Pointer_DownRight" }, { 0xFEF5, "Pointer_Drag1" }, { 0xFEF6, "Pointer_Drag2" }, { 0xFEF7, "Pointer_Drag3" }, { 0xFEF8, "Pointer_Drag4" }, { 0xFEFD, "Pointer_Drag5" }, { 0xFEF4, "Pointer_Drag_Dflt" }, { 0xFEF9, "Pointer_EnableKeys" }, { 0xFEE0, "Pointer_Left" }, { 0xFEE1, "Pointer_Right" }, { 0xFEE2, "Pointer_Up" }, { 0xFEE4, "Pointer_UpLeft" }, { 0xFEE5, "Pointer_UpRight" }, { 0xFED1, "Prev_Virtual_Screen" }, { 0xFF3E, "PreviousCandidate" }, { 0xFF61, "Print" }, { 0xFF55, "Prior" }, { 0x0051, "Q" }, { 0x0052, "R" }, { 0x01C0, "Racute" }, { 0x01D8, "Rcaron" }, { 0x03A3, "Rcedilla" }, { 0xFF66, "Redo" }, { 0xFE72, "RepeatKeys_Enable" }, { 0xFF0D, "Return" }, { 0xFF53, "Right" }, { 0xFF24, "Romaji" }, { 0x20A8, "RupeeSign" }, { 0x0053, "S" }, { 0x01A6, "Sacute" }, { 0x01A9, "Scaron" }, { 0x01AA, "Scedilla" }, { 0x02DE, "Scircumflex" }, { 0xFF14, "Scroll_Lock" }, { 0xFF60, "Select" }, { 0x06B1, "Serbian_DJE" }, { 0x06BF, "Serbian_DZE" }, { 0x06B8, "Serbian_JE" }, { 0x06B9, "Serbian_LJE" }, { 0x06BA, "Serbian_NJE" }, { 0x06BB, "Serbian_TSHE" }, { 0x06A1, "Serbian_dje" }, { 0x06AF, "Serbian_dze" }, { 0x06A8, "Serbian_je" }, { 0x06A9, "Serbian_lje" }, { 0x06AA, "Serbian_nje" }, { 0x06AB, "Serbian_tshe" }, { 0xFFE1, "Shift_L" }, { 0xFFE6, "Shift_Lock" }, { 0xFFE2, "Shift_R" }, { 0xFF3C, "SingleCandidate" }, { 0xFE73, "SlowKeys_Enable" }, { 0xFE75, "StickyKeys_Enable" }, { 0xFFEB, "Super_L" }, { 0xFFEC, "Super_R" }, { 0xFF15, "Sys_Req" }, { 0x0054, "T" }, { 0x00DE, "THORN" }, { 0xFF09, "Tab" }, { 0x01AB, "Tcaron" }, { 0x01DE, "Tcedilla" }, { 0xFED5, "Terminate_Server" }, { 0x0DDF, "Thai_baht" }, { 0x0DBA, "Thai_bobaimai" }, { 0x0DA8, "Thai_chochan" }, { 0x0DAA, "Thai_chochang" }, { 0x0DA9, "Thai_choching" }, { 0x0DAC, "Thai_chochoe" }, { 0x0DAE, "Thai_dochada" }, { 0x0DB4, "Thai_dodek" }, { 0x0DBD, "Thai_fofa" }, { 0x0DBF, "Thai_fofan" }, { 0x0DCB, "Thai_hohip" }, { 0x0DCE, "Thai_honokhuk" }, { 0x0DA2, "Thai_khokhai" }, { 0x0DA5, "Thai_khokhon" }, { 0x0DA3, "Thai_khokhuat" }, { 0x0DA4, "Thai_khokhwai" }, { 0x0DA6, "Thai_khorakhang" }, { 0x0DA1, "Thai_kokai" }, { 0x0DE5, "Thai_lakkhangyao" }, { 0x0DF7, "Thai_lekchet" }, { 0x0DF5, "Thai_lekha" }, { 0x0DF6, "Thai_lekhok" }, { 0x0DF9, "Thai_lekkao" }, { 0x0DF1, "Thai_leknung" }, { 0x0DF8, "Thai_lekpaet" }, { 0x0DF3, "Thai_leksam" }, { 0x0DF4, "Thai_leksi" }, { 0x0DF2, "Thai_leksong" }, { 0x0DF0, "Thai_leksun" }, { 0x0DCC, "Thai_lochula" }, { 0x0DC5, "Thai_loling" }, { 0x0DC6, "Thai_lu" }, { 0x0DEB, "Thai_maichattawa" }, { 0x0DE8, "Thai_maiek" }, { 0x0DD1, "Thai_maihanakat" }, { 0x0DDE, "Thai_maihanakat_maitho" }, { 0x0DE7, "Thai_maitaikhu" }, { 0x0DE9, "Thai_maitho" }, { 0x0DEA, "Thai_maitri" }, { 0x0DE6, "Thai_maiyamok" }, { 0x0DC1, "Thai_moma" }, { 0x0DA7, "Thai_ngongu" }, { 0x0DED, "Thai_nikhahit" }, { 0x0DB3, "Thai_nonen" }, { 0x0DB9, "Thai_nonu" }, { 0x0DCD, "Thai_oang" }, { 0x0DCF, "Thai_paiyannoi" }, { 0x0DDA, "Thai_phinthu" }, { 0x0DBE, "Thai_phophan" }, { 0x0DBC, "Thai_phophung" }, { 0x0DC0, "Thai_phosamphao" }, { 0x0DBB, "Thai_popla" }, { 0x0DC3, "Thai_rorua" }, { 0x0DC4, "Thai_ru" }, { 0x0DD0, "Thai_saraa" }, { 0x0DD2, "Thai_saraaa" }, { 0x0DE1, "Thai_saraae" }, { 0x0DE4, "Thai_saraaimaimalai" }, { 0x0DE3, "Thai_saraaimaimuan" }, { 0x0DD3, "Thai_saraam" }, { 0x0DE0, "Thai_sarae" }, { 0x0DD4, "Thai_sarai" }, { 0x0DD5, "Thai_saraii" }, { 0x0DE2, "Thai_sarao" }, { 0x0DD8, "Thai_sarau" }, { 0x0DD6, "Thai_saraue" }, { 0x0DD7, "Thai_sarauee" }, { 0x0DD9, "Thai_sarauu" }, { 0x0DC9, "Thai_sorusi" }, { 0x0DC8, "Thai_sosala" }, { 0x0DAB, "Thai_soso" }, { 0x0DCA, "Thai_sosua" }, { 0x0DEC, "Thai_thanthakhat" }, { 0x0DB1, "Thai_thonangmontho" }, { 0x0DB2, "Thai_thophuthao" }, { 0x0DB7, "Thai_thothahan" }, { 0x0DB0, "Thai_thothan" }, { 0x0DB8, "Thai_thothong" }, { 0x0DB6, "Thai_thothung" }, { 0x0DAF, "Thai_topatak" }, { 0x0DB5, "Thai_totao" }, { 0x0DC7, "Thai_wowaen" }, { 0x0DC2, "Thai_yoyak" }, { 0x0DAD, "Thai_yoying" }, { 0x00DE, "Thorn" }, { 0xFF2B, "Touroku" }, { 0x03AC, "Tslash" }, { 0x0055, "U" }, { 0x00DA, "Uacute" }, { 0x02DD, "Ubreve" }, { 0x00DB, "Ucircumflex" }, { 0x00DC, "Udiaeresis" }, { 0x01DB, "Udoubleacute" }, { 0x00D9, "Ugrave" }, { 0x1EFC, "Uhorn" }, { 0x06B6, "Ukrainian_I" }, { 0x06B4, "Ukrainian_IE" }, { 0x06B7, "Ukrainian_YI" }, { 0x06A6, "Ukrainian_i" }, { 0x06A4, "Ukrainian_ie" }, { 0x06A7, "Ukrainian_yi" }, { 0x06B6, "Ukranian_I" }, { 0x06B4, "Ukranian_JE" }, { 0x06B7, "Ukranian_YI" }, { 0x06A6, "Ukranian_i" }, { 0x06A4, "Ukranian_je" }, { 0x06A7, "Ukranian_yi" }, { 0x03DE, "Umacron" }, { 0xFF65, "Undo" }, { 0x03D9, "Uogonek" }, { 0xFF52, "Up" }, { 0x01D9, "Uring" }, { 0x03DD, "Utilde" }, { 0x0056, "V" }, { 0x0057, "W" }, { 0x20A9, "WonSign" }, { 0x0058, "X" }, { 0x0059, "Y" }, { 0x00DD, "Yacute" }, { 0x13BE, "Ydiaeresis" }, { 0x005A, "Z" }, { 0x01AF, "Zabovedot" }, { 0x01AC, "Zacute" }, { 0x01AE, "Zcaron" }, { 0xFF28, "Zenkaku" }, { 0xFF2A, "Zenkaku_Hankaku" }, { 0x0061, "a" }, { 0x00E1, "aacute" }, { 0x01FF, "abovedot" }, { 0x01E3, "abreve" }, { 0x00E2, "acircumflex" }, { 0x00B4, "acute" }, { 0x00E4, "adiaeresis" }, { 0x00E6, "ae" }, { 0x00E0, "agrave" }, { 0x03E0, "amacron" }, { 0x0026, "ampersand" }, { 0x01B1, "aogonek" }, { 0x0027, "apostrophe" }, { 0x08C8, "approximate" }, { 0x00E5, "aring" }, { 0x005E, "asciicircum" }, { 0x007E, "asciitilde" }, { 0x002A, "asterisk" }, { 0x0040, "at" }, { 0x00E3, "atilde" }, { 0x0062, "b" }, { 0x005C, "backslash" }, { 0x0AF4, "ballotcross" }, { 0x007C, "bar" }, { 0x09DF, "blank" }, { 0x08A5, "botintegral" }, { 0x08AC, "botleftparens" }, { 0x08A8, "botleftsqbracket" }, { 0x08B2, "botleftsummation" }, { 0x08AE, "botrightparens" }, { 0x08AA, "botrightsqbracket" }, { 0x08B6, "botrightsummation" }, { 0x09F6, "bott" }, { 0x08B4, "botvertsummationconnector" }, { 0x007B, "braceleft" }, { 0x007D, "braceright" }, { 0x005B, "bracketleft" }, { 0x005D, "bracketright" }, { 0x01A2, "breve" }, { 0x00A6, "brokenbar" }, { 0x0063, "c" }, { 0x02E5, "cabovedot" }, { 0x01E6, "cacute" }, { 0x0AB8, "careof" }, { 0x0AFC, "caret" }, { 0x01B7, "caron" }, { 0x01E8, "ccaron" }, { 0x00E7, "ccedilla" }, { 0x02E6, "ccircumflex" }, { 0x00B8, "cedilla" }, { 0x00A2, "cent" }, { 0x09E1, "checkerboard" }, { 0x0AF3, "checkmark" }, { 0x0BCF, "circle" }, { 0x0AEC, "club" }, { 0x003A, "colon" }, { 0x1EF3, "combining_acute" }, { 0x1EFF, "combining_belowdot" }, { 0x1EF2, "combining_grave" }, { 0x1EFE, "combining_hook" }, { 0x1E9F, "combining_tilde" }, { 0x002C, "comma" }, { 0x00A9, "copyright" }, { 0x09E4, "cr" }, { 0x09EE, "crossinglines" }, { 0x00A4, "currency" }, { 0x0AFF, "cursor" }, { 0x0064, "d" }, { 0x0AF1, "dagger" }, { 0x01EF, "dcaron" }, { 0xFE56, "dead_abovedot" }, { 0xFE58, "dead_abovering" }, { 0xFE51, "dead_acute" }, { 0xFE60, "dead_belowdot" }, { 0xFE55, "dead_breve" }, { 0xFE5A, "dead_caron" }, { 0xFE5B, "dead_cedilla" }, { 0xFE52, "dead_circumflex" }, { 0xFE57, "dead_diaeresis" }, { 0xFE59, "dead_doubleacute" }, { 0xFE50, "dead_grave" }, { 0xFE61, "dead_hook" }, { 0xFE62, "dead_horn" }, { 0xFE5D, "dead_iota" }, { 0xFE54, "dead_macron" }, { 0xFE5C, "dead_ogonek" }, { 0xFE5F, "dead_semivoiced_sound" }, { 0xFE53, "dead_tilde" }, { 0xFE5E, "dead_voiced_sound" }, { 0x0ABD, "decimalpoint" }, { 0x00B0, "degree" }, { 0x00A8, "diaeresis" }, { 0x0AED, "diamond" }, { 0x0AA5, "digitspace" }, { 0x00F7, "division" }, { 0x0024, "dollar" }, { 0x0AAF, "doubbaselinedot" }, { 0x01BD, "doubleacute" }, { 0x0AF2, "doubledagger" }, { 0x0AFE, "doublelowquotemark" }, { 0x08FE, "downarrow" }, { 0x0BA8, "downcaret" }, { 0x0BD6, "downshoe" }, { 0x0BC4, "downstile" }, { 0x0BC2, "downtack" }, { 0x01F0, "dstroke" }, { 0x0065, "e" }, { 0x03EC, "eabovedot" }, { 0x00E9, "eacute" }, { 0x01EC, "ecaron" }, { 0x00EA, "ecircumflex" }, { 0x00EB, "ediaeresis" }, { 0x00E8, "egrave" }, { 0x0AAE, "ellipsis" }, { 0x0AA3, "em3space" }, { 0x0AA4, "em4space" }, { 0x03BA, "emacron" }, { 0x0AA9, "emdash" }, { 0x0ADE, "emfilledcircle" }, { 0x0ADF, "emfilledrect" }, { 0x0ACE, "emopencircle" }, { 0x0ACF, "emopenrectangle" }, { 0x0AA1, "emspace" }, { 0x0AAA, "endash" }, { 0x0AE6, "enfilledcircbullet" }, { 0x0AE7, "enfilledsqbullet" }, { 0x03BF, "eng" }, { 0x0AE0, "enopencircbullet" }, { 0x0AE1, "enopensquarebullet" }, { 0x0AA2, "enspace" }, { 0x01EA, "eogonek" }, { 0x003D, "equal" }, { 0x00F0, "eth" }, { 0x0021, "exclam" }, { 0x00A1, "exclamdown" }, { 0x0066, "f" }, { 0x0AF8, "femalesymbol" }, { 0x09E3, "ff" }, { 0x0ABB, "figdash" }, { 0x0ADC, "filledlefttribullet" }, { 0x0ADB, "filledrectbullet" }, { 0x0ADD, "filledrighttribullet" }, { 0x0AE9, "filledtribulletdown" }, { 0x0AE8, "filledtribulletup" }, { 0x0AC5, "fiveeighths" }, { 0x0AB7, "fivesixths" }, { 0x0AB5, "fourfifths" }, { 0x08F6, "function" }, { 0x0067, "g" }, { 0x02F5, "gabovedot" }, { 0x02BB, "gbreve" }, { 0x03BB, "gcedilla" }, { 0x02F8, "gcircumflex" }, { 0x0060, "grave" }, { 0x003E, "greater" }, { 0x08BE, "greaterthanequal" }, { 0x00AB, "guillemotleft" }, { 0x00BB, "guillemotright" }, { 0x0068, "h" }, { 0x0AA8, "hairspace" }, { 0x02B6, "hcircumflex" }, { 0x0AEE, "heart" }, { 0x0CE0, "hebrew_aleph" }, { 0x0CF2, "hebrew_ayin" }, { 0x0CE1, "hebrew_bet" }, { 0x0CE1, "hebrew_beth" }, { 0x0CE7, "hebrew_chet" }, { 0x0CE3, "hebrew_dalet" }, { 0x0CE3, "hebrew_daleth" }, { 0x0CDF, "hebrew_doublelowline" }, { 0x0CEA, "hebrew_finalkaph" }, { 0x0CED, "hebrew_finalmem" }, { 0x0CEF, "hebrew_finalnun" }, { 0x0CF3, "hebrew_finalpe" }, { 0x0CF5, "hebrew_finalzade" }, { 0x0CF5, "hebrew_finalzadi" }, { 0x0CE2, "hebrew_gimel" }, { 0x0CE2, "hebrew_gimmel" }, { 0x0CE4, "hebrew_he" }, { 0x0CE7, "hebrew_het" }, { 0x0CEB, "hebrew_kaph" }, { 0x0CF7, "hebrew_kuf" }, { 0x0CEC, "hebrew_lamed" }, { 0x0CEE, "hebrew_mem" }, { 0x0CF0, "hebrew_nun" }, { 0x0CF4, "hebrew_pe" }, { 0x0CF7, "hebrew_qoph" }, { 0x0CF8, "hebrew_resh" }, { 0x0CF1, "hebrew_samech" }, { 0x0CF1, "hebrew_samekh" }, { 0x0CF9, "hebrew_shin" }, { 0x0CFA, "hebrew_taf" }, { 0x0CFA, "hebrew_taw" }, { 0x0CE8, "hebrew_tet" }, { 0x0CE8, "hebrew_teth" }, { 0x0CE5, "hebrew_waw" }, { 0x0CE9, "hebrew_yod" }, { 0x0CF6, "hebrew_zade" }, { 0x0CF6, "hebrew_zadi" }, { 0x0CE6, "hebrew_zain" }, { 0x0CE6, "hebrew_zayin" }, { 0x0ADA, "hexagram" }, { 0x08A3, "horizconnector" }, { 0x09EF, "horizlinescan1" }, { 0x09F0, "horizlinescan3" }, { 0x09F1, "horizlinescan5" }, { 0x09F2, "horizlinescan7" }, { 0x09F3, "horizlinescan9" }, { 0x02B1, "hstroke" }, { 0x09E2, "ht" }, { 0x00AD, "hyphen" }, { 0x0069, "i" }, { 0x00ED, "iacute" }, { 0x00EE, "icircumflex" }, { 0x08CF, "identical" }, { 0x00EF, "idiaeresis" }, { 0x02B9, "idotless" }, { 0x08CD, "ifonlyif" }, { 0x00EC, "igrave" }, { 0x03EF, "imacron" }, { 0x08CE, "implies" }, { 0x08DA, "includedin" }, { 0x08DB, "includes" }, { 0x08C2, "infinity" }, { 0x08BF, "integral" }, { 0x08DC, "intersection" }, { 0x03E7, "iogonek" }, { 0x03B5, "itilde" }, { 0x006A, "j" }, { 0x02BC, "jcircumflex" }, { 0x0BCA, "jot" }, { 0x006B, "k" }, { 0x04B1, "kana_A" }, { 0x04C1, "kana_CHI" }, { 0x04B4, "kana_E" }, { 0x04CC, "kana_FU" }, { 0x04CA, "kana_HA" }, { 0x04CD, "kana_HE" }, { 0x04CB, "kana_HI" }, { 0x04CE, "kana_HO" }, { 0x04CC, "kana_HU" }, { 0x04B2, "kana_I" }, { 0x04B6, "kana_KA" }, { 0x04B9, "kana_KE" }, { 0x04B7, "kana_KI" }, { 0x04BA, "kana_KO" }, { 0x04B8, "kana_KU" }, { 0x04CF, "kana_MA" }, { 0x04D2, "kana_ME" }, { 0x04D0, "kana_MI" }, { 0x04D3, "kana_MO" }, { 0x04D1, "kana_MU" }, { 0x04DD, "kana_N" }, { 0x04C5, "kana_NA" }, { 0x04C8, "kana_NE" }, { 0x04C6, "kana_NI" }, { 0x04C9, "kana_NO" }, { 0x04C7, "kana_NU" }, { 0x04B5, "kana_O" }, { 0x04D7, "kana_RA" }, { 0x04DA, "kana_RE" }, { 0x04D8, "kana_RI" }, { 0x04DB, "kana_RO" }, { 0x04D9, "kana_RU" }, { 0x04BB, "kana_SA" }, { 0x04BE, "kana_SE" }, { 0x04BC, "kana_SHI" }, { 0x04BF, "kana_SO" }, { 0x04BD, "kana_SU" }, { 0x04C0, "kana_TA" }, { 0x04C3, "kana_TE" }, { 0x04C1, "kana_TI" }, { 0x04C4, "kana_TO" }, { 0x04C2, "kana_TSU" }, { 0x04C2, "kana_TU" }, { 0x04B3, "kana_U" }, { 0x04DC, "kana_WA" }, { 0x04A6, "kana_WO" }, { 0x04D4, "kana_YA" }, { 0x04D6, "kana_YO" }, { 0x04D5, "kana_YU" }, { 0x04A7, "kana_a" }, { 0x04A3, "kana_closingbracket" }, { 0x04A4, "kana_comma" }, { 0x04A5, "kana_conjunctive" }, { 0x04AA, "kana_e" }, { 0x04A1, "kana_fullstop" }, { 0x04A8, "kana_i" }, { 0x04A5, "kana_middledot" }, { 0x04AB, "kana_o" }, { 0x04A2, "kana_openingbracket" }, { 0xFF7E, "kana_switch" }, { 0x04AF, "kana_tsu" }, { 0x04AF, "kana_tu" }, { 0x04A9, "kana_u" }, { 0x04AC, "kana_ya" }, { 0x04AE, "kana_yo" }, { 0x04AD, "kana_yu" }, { 0x03A2, "kappa" }, { 0x03F3, "kcedilla" }, { 0x03A2, "kra" }, { 0x006C, "l" }, { 0x01E5, "lacute" }, { 0x0AD9, "latincross" }, { 0x01B5, "lcaron" }, { 0x03B6, "lcedilla" }, { 0x0ABC, "leftanglebracket" }, { 0x08FB, "leftarrow" }, { 0x0BA3, "leftcaret" }, { 0x0AD2, "leftdoublequotemark" }, { 0x08AF, "leftmiddlecurlybrace" }, { 0x0ACC, "leftopentriangle" }, { 0x0AEA, "leftpointer" }, { 0x08A1, "leftradical" }, { 0x0BDA, "leftshoe" }, { 0x0AD0, "leftsinglequotemark" }, { 0x09F4, "leftt" }, { 0x0BDC, "lefttack" }, { 0x003C, "less" }, { 0x08BC, "lessthanequal" }, { 0x09E5, "lf" }, { 0x08DE, "logicaland" }, { 0x08DF, "logicalor" }, { 0x09ED, "lowleftcorner" }, { 0x09EA, "lowrightcorner" }, { 0x01B3, "lstroke" }, { 0x006D, "m" }, { 0x00AF, "macron" }, { 0x0AF7, "malesymbol" }, { 0x0AF0, "maltesecross" }, { 0x0ABF, "marker" }, { 0x00BA, "masculine" }, { 0x002D, "minus" }, { 0x0AD6, "minutes" }, { 0x00B5, "mu" }, { 0x00D7, "multiply" }, { 0x0AF6, "musicalflat" }, { 0x0AF5, "musicalsharp" }, { 0x006E, "n" }, { 0x08C5, "nabla" }, { 0x01F1, "nacute" }, { 0x01F2, "ncaron" }, { 0x03F1, "ncedilla" }, { 0x09E8, "nl" }, { 0x00A0, "nobreakspace" }, { 0x08BD, "notequal" }, { 0x00AC, "notsign" }, { 0x00F1, "ntilde" }, { 0x0023, "numbersign" }, { 0x06B0, "numerosign" }, { 0x006F, "o" }, { 0x00F3, "oacute" }, { 0x00F4, "ocircumflex" }, { 0x00F6, "odiaeresis" }, { 0x01F5, "odoubleacute" }, { 0x13BD, "oe" }, { 0x01B2, "ogonek" }, { 0x00F2, "ograve" }, { 0x1EFB, "ohorn" }, { 0x03F2, "omacron" }, { 0x0AC3, "oneeighth" }, { 0x0AB2, "onefifth" }, { 0x00BD, "onehalf" }, { 0x00BC, "onequarter" }, { 0x0AB6, "onesixth" }, { 0x00B9, "onesuperior" }, { 0x0AB0, "onethird" }, { 0x0AE2, "openrectbullet" }, { 0x0AE5, "openstar" }, { 0x0AE4, "opentribulletdown" }, { 0x0AE3, "opentribulletup" }, { 0x00AA, "ordfeminine" }, { 0x00F8, "oslash" }, { 0x00F5, "otilde" }, { 0x0BC0, "overbar" }, { 0x047E, "overline" }, { 0x0070, "p" }, { 0x00B6, "paragraph" }, { 0x0028, "parenleft" }, { 0x0029, "parenright" }, { 0x08EF, "partialderivative" }, { 0x0025, "percent" }, { 0x002E, "period" }, { 0x00B7, "periodcentered" }, { 0x0AFB, "phonographcopyright" }, { 0x002B, "plus" }, { 0x00B1, "plusminus" }, { 0x0AD4, "prescription" }, { 0x04B0, "prolongedsound" }, { 0x0AA6, "punctspace" }, { 0x0071, "q" }, { 0x0BCC, "quad" }, { 0x003F, "question" }, { 0x00BF, "questiondown" }, { 0x0022, "quotedbl" }, { 0x0060, "quoteleft" }, { 0x0027, "quoteright" }, { 0x0072, "r" }, { 0x01E0, "racute" }, { 0x08D6, "radical" }, { 0x01F8, "rcaron" }, { 0x03B3, "rcedilla" }, { 0x00AE, "registered" }, { 0x0ABE, "rightanglebracket" }, { 0x08FD, "rightarrow" }, { 0x0BA6, "rightcaret" }, { 0x0AD3, "rightdoublequotemark" }, { 0x08B0, "rightmiddlecurlybrace" }, { 0x08B7, "rightmiddlesummation" }, { 0x0ACD, "rightopentriangle" }, { 0x0AEB, "rightpointer" }, { 0x0BD8, "rightshoe" }, { 0x0AD1, "rightsinglequotemark" }, { 0x09F5, "rightt" }, { 0x0BFC, "righttack" }, { 0x0073, "s" }, { 0x01B6, "sacute" }, { 0x01B9, "scaron" }, { 0x01BA, "scedilla" }, { 0x02FE, "scircumflex" }, { 0xFF7E, "script_switch" }, { 0x0AD7, "seconds" }, { 0x00A7, "section" }, { 0x003B, "semicolon" }, { 0x04DF, "semivoicedsound" }, { 0x0AC6, "seveneighths" }, { 0x0ACA, "signaturemark" }, { 0x0AAC, "signifblank" }, { 0x08C9, "similarequal" }, { 0x0AFD, "singlelowquotemark" }, { 0x002F, "slash" }, { 0x09E0, "soliddiamond" }, { 0x0020, "space" }, { 0x00DF, "ssharp" }, { 0x00A3, "sterling" }, { 0x0074, "t" }, { 0x01BB, "tcaron" }, { 0x01FE, "tcedilla" }, { 0x0AF9, "telephone" }, { 0x0AFA, "telephonerecorder" }, { 0x08C0, "therefore" }, { 0x0AA7, "thinspace" }, { 0x00FE, "thorn" }, { 0x0AC4, "threeeighths" }, { 0x0AB4, "threefifths" }, { 0x00BE, "threequarters" }, { 0x00B3, "threesuperior" }, { 0x08A4, "topintegral" }, { 0x08AB, "topleftparens" }, { 0x08A2, "topleftradical" }, { 0x08A7, "topleftsqbracket" }, { 0x08B1, "topleftsummation" }, { 0x08AD, "toprightparens" }, { 0x08A9, "toprightsqbracket" }, { 0x08B5, "toprightsummation" }, { 0x09F7, "topt" }, { 0x08B3, "topvertsummationconnector" }, { 0x0AC9, "trademark" }, { 0x0ACB, "trademarkincircle" }, { 0x03BC, "tslash" }, { 0x0AB3, "twofifths" }, { 0x00B2, "twosuperior" }, { 0x0AB1, "twothirds" }, { 0x0075, "u" }, { 0x00FA, "uacute" }, { 0x02FD, "ubreve" }, { 0x00FB, "ucircumflex" }, { 0x00FC, "udiaeresis" }, { 0x01FB, "udoubleacute" }, { 0x00F9, "ugrave" }, { 0x1EFD, "uhorn" }, { 0x03FE, "umacron" }, { 0x0BC6, "underbar" }, { 0x005F, "underscore" }, { 0x08DD, "union" }, { 0x03F9, "uogonek" }, { 0x08FC, "uparrow" }, { 0x0BA9, "upcaret" }, { 0x09EC, "upleftcorner" }, { 0x09EB, "uprightcorner" }, { 0x0BC3, "upshoe" }, { 0x0BD3, "upstile" }, { 0x0BCE, "uptack" }, { 0x01F9, "uring" }, { 0x03FD, "utilde" }, { 0x0076, "v" }, { 0x08C1, "variation" }, { 0x09F8, "vertbar" }, { 0x08A6, "vertconnector" }, { 0x04DE, "voicedsound" }, { 0x09E9, "vt" }, { 0x0077, "w" }, { 0x0078, "x" }, { 0x0079, "y" }, { 0x00FD, "yacute" }, { 0x00FF, "ydiaeresis" }, { 0x00A5, "yen" }, { 0x007A, "z" }, { 0x01BF, "zabovedot" }, { 0x01BC, "zacute" }, { 0x01BE, "zcaron" } }; static __KeyName __scim_key_mask_names [] = { {SCIM_KEY_ShiftMask, "Shift"}, {SCIM_KEY_CapsLockMask, "CapsLock"}, {SCIM_KEY_ControlMask, "Control"}, {SCIM_KEY_AltMask, "Alt"}, {SCIM_KEY_MetaMask, "Meta"}, {SCIM_KEY_SuperMask, "Super"}, {SCIM_KEY_HyperMask, "Hyper"}, {SCIM_KEY_NumLockMask, "NumLock"}, {SCIM_KEY_QuirkKanaRoMask, "QuirkKanaRo"}, {SCIM_KEY_ReleaseMask, "KeyRelease"} }; #define SCIM_NUM_KEY_UNICODES (sizeof (__scim_key_to_unicode_tab) / sizeof (__scim_key_to_unicode_tab[0])) #define SCIM_NUM_KEY_NAMES (sizeof (__scim_keys_by_code) / sizeof (__scim_keys_by_code [0])) #define SCIM_NUM_KEY_MASKS (sizeof (__scim_key_mask_names) / sizeof (__scim_key_mask_names[0])) /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_keyboard_layout_data.h0000644000175000017500000067723612422143415020325 0ustar tzhuantzhuan// KeyEvent code mapping pairs. // From To static __Uint16Pair __belgian_to_us_normal [] = { { SCIM_KEY_exclam, SCIM_KEY_8 }, { SCIM_KEY_quotedbl, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_bracketright }, { SCIM_KEY_ampersand, SCIM_KEY_1 }, { SCIM_KEY_apostrophe, SCIM_KEY_4 }, { SCIM_KEY_parenleft, SCIM_KEY_5 }, { SCIM_KEY_parenright, SCIM_KEY_minus }, { SCIM_KEY_comma, SCIM_KEY_m }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_colon, SCIM_KEY_period }, { SCIM_KEY_semicolon, SCIM_KEY_comma }, { SCIM_KEY_equal, SCIM_KEY_slash }, { SCIM_KEY_a, SCIM_KEY_q }, { SCIM_KEY_m, SCIM_KEY_semicolon }, { SCIM_KEY_q, SCIM_KEY_a }, { SCIM_KEY_w, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_w }, { SCIM_KEY_section, SCIM_KEY_6 }, { SCIM_KEY_twosuperior, SCIM_KEY_grave }, { SCIM_KEY_mu, SCIM_KEY_backslash }, { SCIM_KEY_agrave, SCIM_KEY_0 }, { SCIM_KEY_ccedilla, SCIM_KEY_9 }, { SCIM_KEY_egrave, SCIM_KEY_7 }, { SCIM_KEY_eacute, SCIM_KEY_2 }, { SCIM_KEY_ugrave, SCIM_KEY_apostrophe }, { SCIM_KEY_dead_circumflex, SCIM_KEY_bracketleft }, }; static __Uint16Pair __us_to_belgian_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_ugrave }, { SCIM_KEY_comma, SCIM_KEY_semicolon }, { SCIM_KEY_minus, SCIM_KEY_parenright }, { SCIM_KEY_period, SCIM_KEY_colon }, { SCIM_KEY_slash, SCIM_KEY_equal }, { SCIM_KEY_0, SCIM_KEY_agrave }, { SCIM_KEY_1, SCIM_KEY_ampersand }, { SCIM_KEY_2, SCIM_KEY_eacute }, { SCIM_KEY_3, SCIM_KEY_quotedbl }, { SCIM_KEY_4, SCIM_KEY_apostrophe }, { SCIM_KEY_5, SCIM_KEY_parenleft }, { SCIM_KEY_6, SCIM_KEY_section }, { SCIM_KEY_7, SCIM_KEY_egrave }, { SCIM_KEY_8, SCIM_KEY_exclam }, { SCIM_KEY_9, SCIM_KEY_ccedilla }, { SCIM_KEY_semicolon, SCIM_KEY_m }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_bracketleft, SCIM_KEY_dead_circumflex }, { SCIM_KEY_backslash, SCIM_KEY_mu }, { SCIM_KEY_bracketright, SCIM_KEY_dollar }, { SCIM_KEY_grave, SCIM_KEY_twosuperior }, { SCIM_KEY_a, SCIM_KEY_q }, { SCIM_KEY_m, SCIM_KEY_comma }, { SCIM_KEY_q, SCIM_KEY_a }, { SCIM_KEY_w, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_w }, }; static __Uint16Pair __belgian_to_us_caps [] = { { SCIM_KEY_exclam, SCIM_KEY_8 }, { SCIM_KEY_quotedbl, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_bracketright }, { SCIM_KEY_ampersand, SCIM_KEY_1 }, { SCIM_KEY_apostrophe, SCIM_KEY_4 }, { SCIM_KEY_parenleft, SCIM_KEY_5 }, { SCIM_KEY_parenright, SCIM_KEY_minus }, { SCIM_KEY_comma, SCIM_KEY_M }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_colon, SCIM_KEY_period }, { SCIM_KEY_semicolon, SCIM_KEY_comma }, { SCIM_KEY_equal, SCIM_KEY_slash }, { SCIM_KEY_A, SCIM_KEY_Q }, { SCIM_KEY_M, SCIM_KEY_semicolon }, { SCIM_KEY_Q, SCIM_KEY_A }, { SCIM_KEY_W, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_W }, { SCIM_KEY_section, SCIM_KEY_6 }, { SCIM_KEY_twosuperior, SCIM_KEY_grave }, { SCIM_KEY_mu, SCIM_KEY_backslash }, { SCIM_KEY_Agrave, SCIM_KEY_0 }, { SCIM_KEY_Ccedilla, SCIM_KEY_9 }, { SCIM_KEY_Egrave, SCIM_KEY_7 }, { SCIM_KEY_Eacute, SCIM_KEY_2 }, { SCIM_KEY_Ugrave, SCIM_KEY_apostrophe }, { SCIM_KEY_dead_circumflex, SCIM_KEY_bracketleft }, }; static __Uint16Pair __us_to_belgian_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Ugrave }, { SCIM_KEY_comma, SCIM_KEY_semicolon }, { SCIM_KEY_minus, SCIM_KEY_parenright }, { SCIM_KEY_period, SCIM_KEY_colon }, { SCIM_KEY_slash, SCIM_KEY_equal }, { SCIM_KEY_0, SCIM_KEY_Agrave }, { SCIM_KEY_1, SCIM_KEY_ampersand }, { SCIM_KEY_2, SCIM_KEY_Eacute }, { SCIM_KEY_3, SCIM_KEY_quotedbl }, { SCIM_KEY_4, SCIM_KEY_apostrophe }, { SCIM_KEY_5, SCIM_KEY_parenleft }, { SCIM_KEY_6, SCIM_KEY_section }, { SCIM_KEY_7, SCIM_KEY_Egrave }, { SCIM_KEY_8, SCIM_KEY_exclam }, { SCIM_KEY_9, SCIM_KEY_Ccedilla }, { SCIM_KEY_semicolon, SCIM_KEY_M }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_A, SCIM_KEY_Q }, { SCIM_KEY_M, SCIM_KEY_comma }, { SCIM_KEY_Q, SCIM_KEY_A }, { SCIM_KEY_W, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_W }, { SCIM_KEY_bracketleft, SCIM_KEY_dead_circumflex }, { SCIM_KEY_backslash, SCIM_KEY_mu }, { SCIM_KEY_bracketright, SCIM_KEY_dollar }, { SCIM_KEY_grave, SCIM_KEY_twosuperior }, }; static __Uint16Pair __belgian_to_us_shift [] = { { SCIM_KEY_percent, SCIM_KEY_quotedbl }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_plus, SCIM_KEY_question }, { SCIM_KEY_period, SCIM_KEY_less }, { SCIM_KEY_slash, SCIM_KEY_greater }, { SCIM_KEY_0, SCIM_KEY_parenright }, { SCIM_KEY_1, SCIM_KEY_exclam }, { SCIM_KEY_2, SCIM_KEY_at }, { SCIM_KEY_3, SCIM_KEY_numbersign }, { SCIM_KEY_4, SCIM_KEY_dollar }, { SCIM_KEY_5, SCIM_KEY_percent }, { SCIM_KEY_6, SCIM_KEY_asciicircum }, { SCIM_KEY_7, SCIM_KEY_ampersand }, { SCIM_KEY_8, SCIM_KEY_asterisk }, { SCIM_KEY_9, SCIM_KEY_parenleft }, { SCIM_KEY_question, SCIM_KEY_M }, { SCIM_KEY_A, SCIM_KEY_Q }, { SCIM_KEY_M, SCIM_KEY_colon }, { SCIM_KEY_Q, SCIM_KEY_A }, { SCIM_KEY_W, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_W }, { SCIM_KEY_underscore, SCIM_KEY_plus }, { SCIM_KEY_sterling, SCIM_KEY_bar }, { SCIM_KEY_degree, SCIM_KEY_underscore }, { SCIM_KEY_threesuperior, SCIM_KEY_asciitilde }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_braceleft }, }; static __Uint16Pair __us_to_belgian_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_1 }, { SCIM_KEY_quotedbl, SCIM_KEY_percent }, { SCIM_KEY_numbersign, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_4 }, { SCIM_KEY_percent, SCIM_KEY_5 }, { SCIM_KEY_ampersand, SCIM_KEY_7 }, { SCIM_KEY_parenleft, SCIM_KEY_9 }, { SCIM_KEY_parenright, SCIM_KEY_0 }, { SCIM_KEY_asterisk, SCIM_KEY_8 }, { SCIM_KEY_plus, SCIM_KEY_underscore }, { SCIM_KEY_colon, SCIM_KEY_M }, { SCIM_KEY_less, SCIM_KEY_period }, { SCIM_KEY_greater, SCIM_KEY_slash }, { SCIM_KEY_question, SCIM_KEY_plus }, { SCIM_KEY_at, SCIM_KEY_2 }, { SCIM_KEY_A, SCIM_KEY_Q }, { SCIM_KEY_M, SCIM_KEY_question }, { SCIM_KEY_Q, SCIM_KEY_A }, { SCIM_KEY_W, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_W }, { SCIM_KEY_asciicircum, SCIM_KEY_6 }, { SCIM_KEY_underscore, SCIM_KEY_degree }, { SCIM_KEY_braceleft, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_bar, SCIM_KEY_sterling }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_threesuperior }, }; static __Uint16Pair __belgian_to_us_caps_shift [] = { { SCIM_KEY_percent, SCIM_KEY_quotedbl }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_plus, SCIM_KEY_question }, { SCIM_KEY_period, SCIM_KEY_less }, { SCIM_KEY_slash, SCIM_KEY_greater }, { SCIM_KEY_0, SCIM_KEY_parenright }, { SCIM_KEY_1, SCIM_KEY_exclam }, { SCIM_KEY_2, SCIM_KEY_at }, { SCIM_KEY_3, SCIM_KEY_numbersign }, { SCIM_KEY_4, SCIM_KEY_dollar }, { SCIM_KEY_5, SCIM_KEY_percent }, { SCIM_KEY_6, SCIM_KEY_asciicircum }, { SCIM_KEY_7, SCIM_KEY_ampersand }, { SCIM_KEY_8, SCIM_KEY_asterisk }, { SCIM_KEY_9, SCIM_KEY_parenleft }, { SCIM_KEY_question, SCIM_KEY_m }, { SCIM_KEY_underscore, SCIM_KEY_plus }, { SCIM_KEY_a, SCIM_KEY_q }, { SCIM_KEY_m, SCIM_KEY_colon }, { SCIM_KEY_q, SCIM_KEY_a }, { SCIM_KEY_w, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_w }, { SCIM_KEY_sterling, SCIM_KEY_bar }, { SCIM_KEY_degree, SCIM_KEY_underscore }, { SCIM_KEY_threesuperior, SCIM_KEY_asciitilde }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_braceleft }, }; static __Uint16Pair __us_to_belgian_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_1 }, { SCIM_KEY_quotedbl, SCIM_KEY_percent }, { SCIM_KEY_numbersign, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_4 }, { SCIM_KEY_percent, SCIM_KEY_5 }, { SCIM_KEY_ampersand, SCIM_KEY_7 }, { SCIM_KEY_parenleft, SCIM_KEY_9 }, { SCIM_KEY_parenright, SCIM_KEY_0 }, { SCIM_KEY_asterisk, SCIM_KEY_8 }, { SCIM_KEY_plus, SCIM_KEY_underscore }, { SCIM_KEY_colon, SCIM_KEY_m }, { SCIM_KEY_less, SCIM_KEY_period }, { SCIM_KEY_greater, SCIM_KEY_slash }, { SCIM_KEY_question, SCIM_KEY_plus }, { SCIM_KEY_at, SCIM_KEY_2 }, { SCIM_KEY_asciicircum, SCIM_KEY_6 }, { SCIM_KEY_underscore, SCIM_KEY_degree }, { SCIM_KEY_a, SCIM_KEY_q }, { SCIM_KEY_m, SCIM_KEY_question }, { SCIM_KEY_q, SCIM_KEY_a }, { SCIM_KEY_w, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_w }, { SCIM_KEY_braceleft, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_bar, SCIM_KEY_sterling }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_threesuperior }, }; static __Uint16Pair __czech_to_us_normal [] = { { SCIM_KEY_parenright, SCIM_KEY_bracketright }, { SCIM_KEY_plus, SCIM_KEY_1 }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_semicolon, SCIM_KEY_grave }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_section, SCIM_KEY_apostrophe }, { SCIM_KEY_aacute, SCIM_KEY_8 }, { SCIM_KEY_eacute, SCIM_KEY_0 }, { SCIM_KEY_iacute, SCIM_KEY_9 }, { SCIM_KEY_uacute, SCIM_KEY_bracketleft }, { SCIM_KEY_yacute, SCIM_KEY_7 }, { SCIM_KEY_scaron, SCIM_KEY_3 }, { SCIM_KEY_zcaron, SCIM_KEY_6 }, { SCIM_KEY_ccaron, SCIM_KEY_4 }, { SCIM_KEY_ecaron, SCIM_KEY_2 }, { SCIM_KEY_rcaron, SCIM_KEY_5 }, { SCIM_KEY_uring, SCIM_KEY_semicolon }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_backslash }, }; static __Uint16Pair __us_to_czech_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_section }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_0, SCIM_KEY_eacute }, { SCIM_KEY_1, SCIM_KEY_plus }, { SCIM_KEY_2, SCIM_KEY_ecaron }, { SCIM_KEY_3, SCIM_KEY_scaron }, { SCIM_KEY_4, SCIM_KEY_ccaron }, { SCIM_KEY_5, SCIM_KEY_rcaron }, { SCIM_KEY_6, SCIM_KEY_zcaron }, { SCIM_KEY_7, SCIM_KEY_yacute }, { SCIM_KEY_8, SCIM_KEY_aacute }, { SCIM_KEY_9, SCIM_KEY_iacute }, { SCIM_KEY_semicolon, SCIM_KEY_uring }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_uacute }, { SCIM_KEY_backslash, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_bracketright, SCIM_KEY_parenright }, { SCIM_KEY_grave, SCIM_KEY_semicolon }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, }; static __Uint16Pair __czech_to_us_caps [] = { { SCIM_KEY_parenright, SCIM_KEY_bracketright }, { SCIM_KEY_plus, SCIM_KEY_1 }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_semicolon, SCIM_KEY_grave }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_section, SCIM_KEY_apostrophe }, { SCIM_KEY_Aacute, SCIM_KEY_8 }, { SCIM_KEY_Eacute, SCIM_KEY_0 }, { SCIM_KEY_Iacute, SCIM_KEY_9 }, { SCIM_KEY_Uacute, SCIM_KEY_bracketleft }, { SCIM_KEY_Yacute, SCIM_KEY_7 }, { SCIM_KEY_Scaron, SCIM_KEY_3 }, { SCIM_KEY_Zcaron, SCIM_KEY_6 }, { SCIM_KEY_Ccaron, SCIM_KEY_4 }, { SCIM_KEY_Ecaron, SCIM_KEY_2 }, { SCIM_KEY_Rcaron, SCIM_KEY_5 }, { SCIM_KEY_Uring, SCIM_KEY_semicolon }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_backslash }, }; static __Uint16Pair __us_to_czech_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_section }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_0, SCIM_KEY_Eacute }, { SCIM_KEY_1, SCIM_KEY_plus }, { SCIM_KEY_2, SCIM_KEY_Ecaron }, { SCIM_KEY_3, SCIM_KEY_Scaron }, { SCIM_KEY_4, SCIM_KEY_Ccaron }, { SCIM_KEY_5, SCIM_KEY_Rcaron }, { SCIM_KEY_6, SCIM_KEY_Zcaron }, { SCIM_KEY_7, SCIM_KEY_Yacute }, { SCIM_KEY_8, SCIM_KEY_Aacute }, { SCIM_KEY_9, SCIM_KEY_Iacute }, { SCIM_KEY_semicolon, SCIM_KEY_Uring }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_bracketleft, SCIM_KEY_Uacute }, { SCIM_KEY_backslash, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_bracketright, SCIM_KEY_parenright }, { SCIM_KEY_grave, SCIM_KEY_semicolon }, }; static __Uint16Pair __czech_to_us_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_quotedbl }, { SCIM_KEY_quotedbl, SCIM_KEY_colon }, { SCIM_KEY_percent, SCIM_KEY_underscore }, { SCIM_KEY_apostrophe, SCIM_KEY_bar }, { SCIM_KEY_parenleft, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_braceleft }, { SCIM_KEY_0, SCIM_KEY_parenright }, { SCIM_KEY_1, SCIM_KEY_exclam }, { SCIM_KEY_2, SCIM_KEY_at }, { SCIM_KEY_3, SCIM_KEY_numbersign }, { SCIM_KEY_4, SCIM_KEY_dollar }, { SCIM_KEY_5, SCIM_KEY_percent }, { SCIM_KEY_6, SCIM_KEY_asciicircum }, { SCIM_KEY_7, SCIM_KEY_ampersand }, { SCIM_KEY_8, SCIM_KEY_asterisk }, { SCIM_KEY_9, SCIM_KEY_parenleft }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_question, SCIM_KEY_less }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_dead_abovering, SCIM_KEY_asciitilde }, { SCIM_KEY_dead_caron, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_czech_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_1 }, { SCIM_KEY_quotedbl, SCIM_KEY_exclam }, { SCIM_KEY_numbersign, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_4 }, { SCIM_KEY_percent, SCIM_KEY_5 }, { SCIM_KEY_ampersand, SCIM_KEY_7 }, { SCIM_KEY_parenleft, SCIM_KEY_9 }, { SCIM_KEY_parenright, SCIM_KEY_0 }, { SCIM_KEY_asterisk, SCIM_KEY_8 }, { SCIM_KEY_plus, SCIM_KEY_dead_caron }, { SCIM_KEY_colon, SCIM_KEY_quotedbl }, { SCIM_KEY_less, SCIM_KEY_question }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_2 }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_asciicircum, SCIM_KEY_6 }, { SCIM_KEY_underscore, SCIM_KEY_percent }, { SCIM_KEY_braceleft, SCIM_KEY_slash }, { SCIM_KEY_bar, SCIM_KEY_apostrophe }, { SCIM_KEY_braceright, SCIM_KEY_parenleft }, { SCIM_KEY_asciitilde, SCIM_KEY_dead_abovering }, }; static __Uint16Pair __czech_to_us_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_quotedbl }, { SCIM_KEY_quotedbl, SCIM_KEY_colon }, { SCIM_KEY_percent, SCIM_KEY_underscore }, { SCIM_KEY_apostrophe, SCIM_KEY_bar }, { SCIM_KEY_parenleft, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_braceleft }, { SCIM_KEY_0, SCIM_KEY_parenright }, { SCIM_KEY_1, SCIM_KEY_exclam }, { SCIM_KEY_2, SCIM_KEY_at }, { SCIM_KEY_3, SCIM_KEY_numbersign }, { SCIM_KEY_4, SCIM_KEY_dollar }, { SCIM_KEY_5, SCIM_KEY_percent }, { SCIM_KEY_6, SCIM_KEY_asciicircum }, { SCIM_KEY_7, SCIM_KEY_ampersand }, { SCIM_KEY_8, SCIM_KEY_asterisk }, { SCIM_KEY_9, SCIM_KEY_parenleft }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_question, SCIM_KEY_less }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_dead_abovering, SCIM_KEY_asciitilde }, { SCIM_KEY_dead_caron, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_czech_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_1 }, { SCIM_KEY_quotedbl, SCIM_KEY_exclam }, { SCIM_KEY_numbersign, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_4 }, { SCIM_KEY_percent, SCIM_KEY_5 }, { SCIM_KEY_ampersand, SCIM_KEY_7 }, { SCIM_KEY_parenleft, SCIM_KEY_9 }, { SCIM_KEY_parenright, SCIM_KEY_0 }, { SCIM_KEY_asterisk, SCIM_KEY_8 }, { SCIM_KEY_plus, SCIM_KEY_dead_caron }, { SCIM_KEY_colon, SCIM_KEY_quotedbl }, { SCIM_KEY_less, SCIM_KEY_question }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_2 }, { SCIM_KEY_asciicircum, SCIM_KEY_6 }, { SCIM_KEY_underscore, SCIM_KEY_percent }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_braceleft, SCIM_KEY_slash }, { SCIM_KEY_bar, SCIM_KEY_apostrophe }, { SCIM_KEY_braceright, SCIM_KEY_parenleft }, { SCIM_KEY_asciitilde, SCIM_KEY_dead_abovering }, }; static __Uint16Pair __czech_qwerty_to_us_normal [] = { { SCIM_KEY_parenright, SCIM_KEY_bracketright }, { SCIM_KEY_plus, SCIM_KEY_1 }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_semicolon, SCIM_KEY_grave }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_section, SCIM_KEY_apostrophe }, { SCIM_KEY_aacute, SCIM_KEY_8 }, { SCIM_KEY_eacute, SCIM_KEY_0 }, { SCIM_KEY_iacute, SCIM_KEY_9 }, { SCIM_KEY_uacute, SCIM_KEY_bracketleft }, { SCIM_KEY_yacute, SCIM_KEY_7 }, { SCIM_KEY_scaron, SCIM_KEY_3 }, { SCIM_KEY_zcaron, SCIM_KEY_6 }, { SCIM_KEY_ccaron, SCIM_KEY_4 }, { SCIM_KEY_ecaron, SCIM_KEY_2 }, { SCIM_KEY_rcaron, SCIM_KEY_5 }, { SCIM_KEY_uring, SCIM_KEY_semicolon }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_backslash }, }; static __Uint16Pair __us_to_czech_qwerty_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_section }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_0, SCIM_KEY_eacute }, { SCIM_KEY_1, SCIM_KEY_plus }, { SCIM_KEY_2, SCIM_KEY_ecaron }, { SCIM_KEY_3, SCIM_KEY_scaron }, { SCIM_KEY_4, SCIM_KEY_ccaron }, { SCIM_KEY_5, SCIM_KEY_rcaron }, { SCIM_KEY_6, SCIM_KEY_zcaron }, { SCIM_KEY_7, SCIM_KEY_yacute }, { SCIM_KEY_8, SCIM_KEY_aacute }, { SCIM_KEY_9, SCIM_KEY_iacute }, { SCIM_KEY_semicolon, SCIM_KEY_uring }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_uacute }, { SCIM_KEY_backslash, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_bracketright, SCIM_KEY_parenright }, { SCIM_KEY_grave, SCIM_KEY_semicolon }, }; static __Uint16Pair __czech_qwerty_to_us_caps [] = { { SCIM_KEY_parenright, SCIM_KEY_bracketright }, { SCIM_KEY_plus, SCIM_KEY_1 }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_semicolon, SCIM_KEY_grave }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_section, SCIM_KEY_apostrophe }, { SCIM_KEY_Aacute, SCIM_KEY_8 }, { SCIM_KEY_Eacute, SCIM_KEY_0 }, { SCIM_KEY_Iacute, SCIM_KEY_9 }, { SCIM_KEY_Uacute, SCIM_KEY_bracketleft }, { SCIM_KEY_Yacute, SCIM_KEY_7 }, { SCIM_KEY_Scaron, SCIM_KEY_3 }, { SCIM_KEY_Zcaron, SCIM_KEY_6 }, { SCIM_KEY_Ccaron, SCIM_KEY_4 }, { SCIM_KEY_Ecaron, SCIM_KEY_2 }, { SCIM_KEY_Rcaron, SCIM_KEY_5 }, { SCIM_KEY_Uring, SCIM_KEY_semicolon }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_backslash }, }; static __Uint16Pair __us_to_czech_qwerty_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_section }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_0, SCIM_KEY_Eacute }, { SCIM_KEY_1, SCIM_KEY_plus }, { SCIM_KEY_2, SCIM_KEY_Ecaron }, { SCIM_KEY_3, SCIM_KEY_Scaron }, { SCIM_KEY_4, SCIM_KEY_Ccaron }, { SCIM_KEY_5, SCIM_KEY_Rcaron }, { SCIM_KEY_6, SCIM_KEY_Zcaron }, { SCIM_KEY_7, SCIM_KEY_Yacute }, { SCIM_KEY_8, SCIM_KEY_Aacute }, { SCIM_KEY_9, SCIM_KEY_Iacute }, { SCIM_KEY_semicolon, SCIM_KEY_Uring }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_Uacute }, { SCIM_KEY_backslash, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_bracketright, SCIM_KEY_parenright }, { SCIM_KEY_grave, SCIM_KEY_semicolon }, }; static __Uint16Pair __czech_qwerty_to_us_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_quotedbl }, { SCIM_KEY_quotedbl, SCIM_KEY_colon }, { SCIM_KEY_percent, SCIM_KEY_underscore }, { SCIM_KEY_apostrophe, SCIM_KEY_bar }, { SCIM_KEY_parenleft, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_braceleft }, { SCIM_KEY_0, SCIM_KEY_parenright }, { SCIM_KEY_1, SCIM_KEY_exclam }, { SCIM_KEY_2, SCIM_KEY_at }, { SCIM_KEY_3, SCIM_KEY_numbersign }, { SCIM_KEY_4, SCIM_KEY_dollar }, { SCIM_KEY_5, SCIM_KEY_percent }, { SCIM_KEY_6, SCIM_KEY_asciicircum }, { SCIM_KEY_7, SCIM_KEY_ampersand }, { SCIM_KEY_8, SCIM_KEY_asterisk }, { SCIM_KEY_9, SCIM_KEY_parenleft }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_question, SCIM_KEY_less }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_dead_abovering, SCIM_KEY_asciitilde }, { SCIM_KEY_dead_caron, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_czech_qwerty_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_1 }, { SCIM_KEY_quotedbl, SCIM_KEY_exclam }, { SCIM_KEY_numbersign, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_4 }, { SCIM_KEY_percent, SCIM_KEY_5 }, { SCIM_KEY_ampersand, SCIM_KEY_7 }, { SCIM_KEY_parenleft, SCIM_KEY_9 }, { SCIM_KEY_parenright, SCIM_KEY_0 }, { SCIM_KEY_asterisk, SCIM_KEY_8 }, { SCIM_KEY_plus, SCIM_KEY_dead_caron }, { SCIM_KEY_colon, SCIM_KEY_quotedbl }, { SCIM_KEY_less, SCIM_KEY_question }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_2 }, { SCIM_KEY_asciicircum, SCIM_KEY_6 }, { SCIM_KEY_underscore, SCIM_KEY_percent }, { SCIM_KEY_braceleft, SCIM_KEY_slash }, { SCIM_KEY_bar, SCIM_KEY_apostrophe }, { SCIM_KEY_braceright, SCIM_KEY_parenleft }, { SCIM_KEY_asciitilde, SCIM_KEY_dead_abovering }, }; static __Uint16Pair __czech_qwerty_to_us_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_quotedbl }, { SCIM_KEY_quotedbl, SCIM_KEY_colon }, { SCIM_KEY_percent, SCIM_KEY_underscore }, { SCIM_KEY_apostrophe, SCIM_KEY_bar }, { SCIM_KEY_parenleft, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_braceleft }, { SCIM_KEY_0, SCIM_KEY_parenright }, { SCIM_KEY_1, SCIM_KEY_exclam }, { SCIM_KEY_2, SCIM_KEY_at }, { SCIM_KEY_3, SCIM_KEY_numbersign }, { SCIM_KEY_4, SCIM_KEY_dollar }, { SCIM_KEY_5, SCIM_KEY_percent }, { SCIM_KEY_6, SCIM_KEY_asciicircum }, { SCIM_KEY_7, SCIM_KEY_ampersand }, { SCIM_KEY_8, SCIM_KEY_asterisk }, { SCIM_KEY_9, SCIM_KEY_parenleft }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_question, SCIM_KEY_less }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_dead_abovering, SCIM_KEY_asciitilde }, { SCIM_KEY_dead_caron, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_czech_qwerty_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_1 }, { SCIM_KEY_quotedbl, SCIM_KEY_exclam }, { SCIM_KEY_numbersign, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_4 }, { SCIM_KEY_percent, SCIM_KEY_5 }, { SCIM_KEY_ampersand, SCIM_KEY_7 }, { SCIM_KEY_parenleft, SCIM_KEY_9 }, { SCIM_KEY_parenright, SCIM_KEY_0 }, { SCIM_KEY_asterisk, SCIM_KEY_8 }, { SCIM_KEY_plus, SCIM_KEY_dead_caron }, { SCIM_KEY_colon, SCIM_KEY_quotedbl }, { SCIM_KEY_less, SCIM_KEY_question }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_2 }, { SCIM_KEY_asciicircum, SCIM_KEY_6 }, { SCIM_KEY_underscore, SCIM_KEY_percent }, { SCIM_KEY_braceleft, SCIM_KEY_slash }, { SCIM_KEY_bar, SCIM_KEY_apostrophe }, { SCIM_KEY_braceright, SCIM_KEY_parenleft }, { SCIM_KEY_asciitilde, SCIM_KEY_dead_abovering }, }; static __Uint16Pair __danish_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_onehalf, SCIM_KEY_grave }, { SCIM_KEY_aring, SCIM_KEY_bracketleft }, { SCIM_KEY_ae, SCIM_KEY_semicolon }, { SCIM_KEY_oslash, SCIM_KEY_apostrophe }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_bracketright }, }; static __Uint16Pair __us_to_danish_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_oslash }, { SCIM_KEY_minus, SCIM_KEY_plus }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_ae }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_aring }, { SCIM_KEY_backslash, SCIM_KEY_apostrophe }, { SCIM_KEY_bracketright, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_grave, SCIM_KEY_onehalf }, }; static __Uint16Pair __danish_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_onehalf, SCIM_KEY_grave }, { SCIM_KEY_Aring, SCIM_KEY_bracketleft }, { SCIM_KEY_AE, SCIM_KEY_semicolon }, { SCIM_KEY_Ooblique, SCIM_KEY_apostrophe }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_bracketright }, }; static __Uint16Pair __us_to_danish_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Ooblique }, { SCIM_KEY_minus, SCIM_KEY_plus }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_AE }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_Aring }, { SCIM_KEY_backslash, SCIM_KEY_apostrophe }, { SCIM_KEY_bracketright, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_grave, SCIM_KEY_onehalf }, }; static __Uint16Pair __danish_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_currency, SCIM_KEY_dollar }, { SCIM_KEY_section, SCIM_KEY_asciitilde }, { SCIM_KEY_Aring, SCIM_KEY_braceleft }, { SCIM_KEY_AE, SCIM_KEY_colon }, { SCIM_KEY_Ooblique, SCIM_KEY_quotedbl }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceright }, }; static __Uint16Pair __us_to_danish_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_Ooblique }, { SCIM_KEY_dollar, SCIM_KEY_currency }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_AE }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_Aring }, { SCIM_KEY_bar, SCIM_KEY_asterisk }, { SCIM_KEY_braceright, SCIM_KEY_dead_circumflex }, { SCIM_KEY_asciitilde, SCIM_KEY_section }, }; static __Uint16Pair __danish_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_currency, SCIM_KEY_dollar }, { SCIM_KEY_section, SCIM_KEY_asciitilde }, { SCIM_KEY_aring, SCIM_KEY_braceleft }, { SCIM_KEY_ae, SCIM_KEY_colon }, { SCIM_KEY_oslash, SCIM_KEY_quotedbl }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceright }, }; static __Uint16Pair __us_to_danish_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_oslash }, { SCIM_KEY_dollar, SCIM_KEY_currency }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_ae }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_aring }, { SCIM_KEY_bar, SCIM_KEY_asterisk }, { SCIM_KEY_braceright, SCIM_KEY_dead_circumflex }, { SCIM_KEY_asciitilde, SCIM_KEY_section }, }; static __Uint16Pair __dvorak_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_q }, { SCIM_KEY_comma, SCIM_KEY_w }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_period, SCIM_KEY_e }, { SCIM_KEY_slash, SCIM_KEY_bracketleft }, { SCIM_KEY_semicolon, SCIM_KEY_z }, { SCIM_KEY_equal, SCIM_KEY_bracketright }, { SCIM_KEY_bracketleft, SCIM_KEY_minus }, { SCIM_KEY_bracketright, SCIM_KEY_equal }, { SCIM_KEY_b, SCIM_KEY_n }, { SCIM_KEY_c, SCIM_KEY_i }, { SCIM_KEY_d, SCIM_KEY_h }, { SCIM_KEY_e, SCIM_KEY_d }, { SCIM_KEY_f, SCIM_KEY_y }, { SCIM_KEY_g, SCIM_KEY_u }, { SCIM_KEY_h, SCIM_KEY_j }, { SCIM_KEY_i, SCIM_KEY_g }, { SCIM_KEY_j, SCIM_KEY_c }, { SCIM_KEY_k, SCIM_KEY_v }, { SCIM_KEY_l, SCIM_KEY_p }, { SCIM_KEY_n, SCIM_KEY_l }, { SCIM_KEY_o, SCIM_KEY_s }, { SCIM_KEY_p, SCIM_KEY_r }, { SCIM_KEY_q, SCIM_KEY_x }, { SCIM_KEY_r, SCIM_KEY_o }, { SCIM_KEY_s, SCIM_KEY_semicolon }, { SCIM_KEY_t, SCIM_KEY_k }, { SCIM_KEY_u, SCIM_KEY_f }, { SCIM_KEY_v, SCIM_KEY_period }, { SCIM_KEY_w, SCIM_KEY_comma }, { SCIM_KEY_x, SCIM_KEY_b }, { SCIM_KEY_y, SCIM_KEY_t }, { SCIM_KEY_z, SCIM_KEY_slash }, }; static __Uint16Pair __us_to_dvorak_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_comma, SCIM_KEY_w }, { SCIM_KEY_minus, SCIM_KEY_bracketleft }, { SCIM_KEY_period, SCIM_KEY_v }, { SCIM_KEY_slash, SCIM_KEY_z }, { SCIM_KEY_semicolon, SCIM_KEY_s }, { SCIM_KEY_equal, SCIM_KEY_bracketright }, { SCIM_KEY_bracketleft, SCIM_KEY_slash }, { SCIM_KEY_bracketright, SCIM_KEY_equal }, { SCIM_KEY_b, SCIM_KEY_x }, { SCIM_KEY_c, SCIM_KEY_j }, { SCIM_KEY_d, SCIM_KEY_e }, { SCIM_KEY_e, SCIM_KEY_period }, { SCIM_KEY_f, SCIM_KEY_u }, { SCIM_KEY_g, SCIM_KEY_i }, { SCIM_KEY_h, SCIM_KEY_d }, { SCIM_KEY_i, SCIM_KEY_c }, { SCIM_KEY_j, SCIM_KEY_h }, { SCIM_KEY_k, SCIM_KEY_t }, { SCIM_KEY_l, SCIM_KEY_n }, { SCIM_KEY_n, SCIM_KEY_b }, { SCIM_KEY_o, SCIM_KEY_r }, { SCIM_KEY_p, SCIM_KEY_l }, { SCIM_KEY_q, SCIM_KEY_apostrophe }, { SCIM_KEY_r, SCIM_KEY_p }, { SCIM_KEY_s, SCIM_KEY_o }, { SCIM_KEY_t, SCIM_KEY_y }, { SCIM_KEY_u, SCIM_KEY_g }, { SCIM_KEY_v, SCIM_KEY_k }, { SCIM_KEY_w, SCIM_KEY_comma }, { SCIM_KEY_x, SCIM_KEY_q }, { SCIM_KEY_y, SCIM_KEY_f }, { SCIM_KEY_z, SCIM_KEY_semicolon }, }; static __Uint16Pair __dvorak_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Q }, { SCIM_KEY_comma, SCIM_KEY_W }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_period, SCIM_KEY_E }, { SCIM_KEY_slash, SCIM_KEY_bracketleft }, { SCIM_KEY_semicolon, SCIM_KEY_Z }, { SCIM_KEY_equal, SCIM_KEY_bracketright }, { SCIM_KEY_B, SCIM_KEY_N }, { SCIM_KEY_C, SCIM_KEY_I }, { SCIM_KEY_D, SCIM_KEY_H }, { SCIM_KEY_E, SCIM_KEY_D }, { SCIM_KEY_F, SCIM_KEY_Y }, { SCIM_KEY_G, SCIM_KEY_U }, { SCIM_KEY_H, SCIM_KEY_J }, { SCIM_KEY_I, SCIM_KEY_G }, { SCIM_KEY_J, SCIM_KEY_C }, { SCIM_KEY_K, SCIM_KEY_V }, { SCIM_KEY_L, SCIM_KEY_P }, { SCIM_KEY_N, SCIM_KEY_L }, { SCIM_KEY_O, SCIM_KEY_S }, { SCIM_KEY_P, SCIM_KEY_R }, { SCIM_KEY_Q, SCIM_KEY_X }, { SCIM_KEY_R, SCIM_KEY_O }, { SCIM_KEY_S, SCIM_KEY_semicolon }, { SCIM_KEY_T, SCIM_KEY_K }, { SCIM_KEY_U, SCIM_KEY_F }, { SCIM_KEY_V, SCIM_KEY_period }, { SCIM_KEY_W, SCIM_KEY_comma }, { SCIM_KEY_X, SCIM_KEY_B }, { SCIM_KEY_Y, SCIM_KEY_T }, { SCIM_KEY_Z, SCIM_KEY_slash }, { SCIM_KEY_bracketleft, SCIM_KEY_minus }, { SCIM_KEY_bracketright, SCIM_KEY_equal }, }; static __Uint16Pair __us_to_dvorak_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_comma, SCIM_KEY_W }, { SCIM_KEY_minus, SCIM_KEY_bracketleft }, { SCIM_KEY_period, SCIM_KEY_V }, { SCIM_KEY_slash, SCIM_KEY_Z }, { SCIM_KEY_semicolon, SCIM_KEY_S }, { SCIM_KEY_equal, SCIM_KEY_bracketright }, { SCIM_KEY_B, SCIM_KEY_X }, { SCIM_KEY_C, SCIM_KEY_J }, { SCIM_KEY_D, SCIM_KEY_E }, { SCIM_KEY_E, SCIM_KEY_period }, { SCIM_KEY_F, SCIM_KEY_U }, { SCIM_KEY_G, SCIM_KEY_I }, { SCIM_KEY_H, SCIM_KEY_D }, { SCIM_KEY_I, SCIM_KEY_C }, { SCIM_KEY_J, SCIM_KEY_H }, { SCIM_KEY_K, SCIM_KEY_T }, { SCIM_KEY_L, SCIM_KEY_N }, { SCIM_KEY_N, SCIM_KEY_B }, { SCIM_KEY_O, SCIM_KEY_R }, { SCIM_KEY_P, SCIM_KEY_L }, { SCIM_KEY_Q, SCIM_KEY_apostrophe }, { SCIM_KEY_R, SCIM_KEY_P }, { SCIM_KEY_S, SCIM_KEY_O }, { SCIM_KEY_T, SCIM_KEY_Y }, { SCIM_KEY_U, SCIM_KEY_G }, { SCIM_KEY_V, SCIM_KEY_K }, { SCIM_KEY_W, SCIM_KEY_comma }, { SCIM_KEY_X, SCIM_KEY_Q }, { SCIM_KEY_Y, SCIM_KEY_F }, { SCIM_KEY_Z, SCIM_KEY_semicolon }, { SCIM_KEY_bracketleft, SCIM_KEY_slash }, { SCIM_KEY_bracketright, SCIM_KEY_equal }, }; static __Uint16Pair __dvorak_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_Q }, { SCIM_KEY_plus, SCIM_KEY_braceright }, { SCIM_KEY_colon, SCIM_KEY_Z }, { SCIM_KEY_less, SCIM_KEY_W }, { SCIM_KEY_greater, SCIM_KEY_E }, { SCIM_KEY_question, SCIM_KEY_braceleft }, { SCIM_KEY_B, SCIM_KEY_N }, { SCIM_KEY_C, SCIM_KEY_I }, { SCIM_KEY_D, SCIM_KEY_H }, { SCIM_KEY_E, SCIM_KEY_D }, { SCIM_KEY_F, SCIM_KEY_Y }, { SCIM_KEY_G, SCIM_KEY_U }, { SCIM_KEY_H, SCIM_KEY_J }, { SCIM_KEY_I, SCIM_KEY_G }, { SCIM_KEY_J, SCIM_KEY_C }, { SCIM_KEY_K, SCIM_KEY_V }, { SCIM_KEY_L, SCIM_KEY_P }, { SCIM_KEY_N, SCIM_KEY_L }, { SCIM_KEY_O, SCIM_KEY_S }, { SCIM_KEY_P, SCIM_KEY_R }, { SCIM_KEY_Q, SCIM_KEY_X }, { SCIM_KEY_R, SCIM_KEY_O }, { SCIM_KEY_S, SCIM_KEY_colon }, { SCIM_KEY_T, SCIM_KEY_K }, { SCIM_KEY_U, SCIM_KEY_F }, { SCIM_KEY_V, SCIM_KEY_greater }, { SCIM_KEY_W, SCIM_KEY_less }, { SCIM_KEY_X, SCIM_KEY_B }, { SCIM_KEY_Y, SCIM_KEY_T }, { SCIM_KEY_Z, SCIM_KEY_question }, { SCIM_KEY_underscore, SCIM_KEY_quotedbl }, { SCIM_KEY_braceleft, SCIM_KEY_underscore }, { SCIM_KEY_braceright, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_dvorak_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_underscore }, { SCIM_KEY_plus, SCIM_KEY_braceright }, { SCIM_KEY_colon, SCIM_KEY_S }, { SCIM_KEY_less, SCIM_KEY_W }, { SCIM_KEY_greater, SCIM_KEY_V }, { SCIM_KEY_question, SCIM_KEY_Z }, { SCIM_KEY_B, SCIM_KEY_X }, { SCIM_KEY_C, SCIM_KEY_J }, { SCIM_KEY_D, SCIM_KEY_E }, { SCIM_KEY_E, SCIM_KEY_greater }, { SCIM_KEY_F, SCIM_KEY_U }, { SCIM_KEY_G, SCIM_KEY_I }, { SCIM_KEY_H, SCIM_KEY_D }, { SCIM_KEY_I, SCIM_KEY_C }, { SCIM_KEY_J, SCIM_KEY_H }, { SCIM_KEY_K, SCIM_KEY_T }, { SCIM_KEY_L, SCIM_KEY_N }, { SCIM_KEY_N, SCIM_KEY_B }, { SCIM_KEY_O, SCIM_KEY_R }, { SCIM_KEY_P, SCIM_KEY_L }, { SCIM_KEY_Q, SCIM_KEY_quotedbl }, { SCIM_KEY_R, SCIM_KEY_P }, { SCIM_KEY_S, SCIM_KEY_O }, { SCIM_KEY_T, SCIM_KEY_Y }, { SCIM_KEY_U, SCIM_KEY_G }, { SCIM_KEY_V, SCIM_KEY_K }, { SCIM_KEY_W, SCIM_KEY_less }, { SCIM_KEY_X, SCIM_KEY_Q }, { SCIM_KEY_Y, SCIM_KEY_F }, { SCIM_KEY_Z, SCIM_KEY_colon }, { SCIM_KEY_underscore, SCIM_KEY_braceleft }, { SCIM_KEY_braceleft, SCIM_KEY_question }, { SCIM_KEY_braceright, SCIM_KEY_plus }, }; static __Uint16Pair __dvorak_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_q }, { SCIM_KEY_plus, SCIM_KEY_braceright }, { SCIM_KEY_colon, SCIM_KEY_z }, { SCIM_KEY_less, SCIM_KEY_w }, { SCIM_KEY_greater, SCIM_KEY_e }, { SCIM_KEY_question, SCIM_KEY_braceleft }, { SCIM_KEY_underscore, SCIM_KEY_quotedbl }, { SCIM_KEY_b, SCIM_KEY_n }, { SCIM_KEY_c, SCIM_KEY_i }, { SCIM_KEY_d, SCIM_KEY_h }, { SCIM_KEY_e, SCIM_KEY_d }, { SCIM_KEY_f, SCIM_KEY_y }, { SCIM_KEY_g, SCIM_KEY_u }, { SCIM_KEY_h, SCIM_KEY_j }, { SCIM_KEY_i, SCIM_KEY_g }, { SCIM_KEY_j, SCIM_KEY_c }, { SCIM_KEY_k, SCIM_KEY_v }, { SCIM_KEY_l, SCIM_KEY_p }, { SCIM_KEY_n, SCIM_KEY_l }, { SCIM_KEY_o, SCIM_KEY_s }, { SCIM_KEY_p, SCIM_KEY_r }, { SCIM_KEY_q, SCIM_KEY_x }, { SCIM_KEY_r, SCIM_KEY_o }, { SCIM_KEY_s, SCIM_KEY_colon }, { SCIM_KEY_t, SCIM_KEY_k }, { SCIM_KEY_u, SCIM_KEY_f }, { SCIM_KEY_v, SCIM_KEY_greater }, { SCIM_KEY_w, SCIM_KEY_less }, { SCIM_KEY_x, SCIM_KEY_b }, { SCIM_KEY_y, SCIM_KEY_t }, { SCIM_KEY_z, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_underscore }, { SCIM_KEY_braceright, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_dvorak_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_underscore }, { SCIM_KEY_plus, SCIM_KEY_braceright }, { SCIM_KEY_colon, SCIM_KEY_s }, { SCIM_KEY_less, SCIM_KEY_w }, { SCIM_KEY_greater, SCIM_KEY_v }, { SCIM_KEY_question, SCIM_KEY_z }, { SCIM_KEY_underscore, SCIM_KEY_braceleft }, { SCIM_KEY_b, SCIM_KEY_x }, { SCIM_KEY_c, SCIM_KEY_j }, { SCIM_KEY_d, SCIM_KEY_e }, { SCIM_KEY_e, SCIM_KEY_greater }, { SCIM_KEY_f, SCIM_KEY_u }, { SCIM_KEY_g, SCIM_KEY_i }, { SCIM_KEY_h, SCIM_KEY_d }, { SCIM_KEY_i, SCIM_KEY_c }, { SCIM_KEY_j, SCIM_KEY_h }, { SCIM_KEY_k, SCIM_KEY_t }, { SCIM_KEY_l, SCIM_KEY_n }, { SCIM_KEY_n, SCIM_KEY_b }, { SCIM_KEY_o, SCIM_KEY_r }, { SCIM_KEY_p, SCIM_KEY_l }, { SCIM_KEY_q, SCIM_KEY_quotedbl }, { SCIM_KEY_r, SCIM_KEY_p }, { SCIM_KEY_s, SCIM_KEY_o }, { SCIM_KEY_t, SCIM_KEY_y }, { SCIM_KEY_u, SCIM_KEY_g }, { SCIM_KEY_v, SCIM_KEY_k }, { SCIM_KEY_w, SCIM_KEY_less }, { SCIM_KEY_x, SCIM_KEY_q }, { SCIM_KEY_y, SCIM_KEY_f }, { SCIM_KEY_z, SCIM_KEY_colon }, { SCIM_KEY_braceleft, SCIM_KEY_question }, { SCIM_KEY_braceright, SCIM_KEY_plus }, }; static __Uint16Pair __estonian_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_adiaeresis, SCIM_KEY_apostrophe }, { SCIM_KEY_otilde, SCIM_KEY_bracketright }, { SCIM_KEY_odiaeresis, SCIM_KEY_semicolon }, { SCIM_KEY_udiaeresis, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_caron, SCIM_KEY_grave }, }; static __Uint16Pair __us_to_estonian_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_adiaeresis }, { SCIM_KEY_minus, SCIM_KEY_plus }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_odiaeresis }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_udiaeresis }, { SCIM_KEY_backslash, SCIM_KEY_apostrophe }, { SCIM_KEY_bracketright, SCIM_KEY_otilde }, { SCIM_KEY_grave, SCIM_KEY_dead_caron }, }; static __Uint16Pair __estonian_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_Adiaeresis, SCIM_KEY_apostrophe }, { SCIM_KEY_Otilde, SCIM_KEY_bracketright }, { SCIM_KEY_Odiaeresis, SCIM_KEY_semicolon }, { SCIM_KEY_Udiaeresis, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_caron, SCIM_KEY_grave }, }; static __Uint16Pair __us_to_estonian_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Adiaeresis }, { SCIM_KEY_minus, SCIM_KEY_plus }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Odiaeresis }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_Udiaeresis }, { SCIM_KEY_backslash, SCIM_KEY_apostrophe }, { SCIM_KEY_bracketright, SCIM_KEY_Otilde }, { SCIM_KEY_grave, SCIM_KEY_dead_caron }, }; static __Uint16Pair __estonian_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_currency, SCIM_KEY_dollar }, { SCIM_KEY_Adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_Otilde, SCIM_KEY_braceright }, { SCIM_KEY_Odiaeresis, SCIM_KEY_colon }, { SCIM_KEY_Udiaeresis, SCIM_KEY_braceleft }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, { SCIM_KEY_dead_tilde, SCIM_KEY_asciitilde }, }; static __Uint16Pair __us_to_estonian_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_Adiaeresis }, { SCIM_KEY_dollar, SCIM_KEY_currency }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_Odiaeresis }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_Udiaeresis }, { SCIM_KEY_bar, SCIM_KEY_asterisk }, { SCIM_KEY_braceright, SCIM_KEY_Otilde }, { SCIM_KEY_asciitilde, SCIM_KEY_dead_tilde }, }; static __Uint16Pair __estonian_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_currency, SCIM_KEY_dollar }, { SCIM_KEY_adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_otilde, SCIM_KEY_braceright }, { SCIM_KEY_odiaeresis, SCIM_KEY_colon }, { SCIM_KEY_udiaeresis, SCIM_KEY_braceleft }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, { SCIM_KEY_dead_tilde, SCIM_KEY_asciitilde }, }; static __Uint16Pair __us_to_estonian_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_adiaeresis }, { SCIM_KEY_dollar, SCIM_KEY_currency }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_odiaeresis }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_udiaeresis }, { SCIM_KEY_bar, SCIM_KEY_asterisk }, { SCIM_KEY_braceright, SCIM_KEY_otilde }, { SCIM_KEY_asciitilde, SCIM_KEY_dead_tilde }, }; static __Uint16Pair __finnish_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_section, SCIM_KEY_grave }, { SCIM_KEY_adiaeresis, SCIM_KEY_apostrophe }, { SCIM_KEY_aring, SCIM_KEY_bracketleft }, { SCIM_KEY_odiaeresis, SCIM_KEY_semicolon }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_bracketright }, }; static __Uint16Pair __us_to_finnish_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_adiaeresis }, { SCIM_KEY_minus, SCIM_KEY_plus }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_odiaeresis }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_aring }, { SCIM_KEY_backslash, SCIM_KEY_apostrophe }, { SCIM_KEY_bracketright, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_grave, SCIM_KEY_section }, }; static __Uint16Pair __finnish_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_section, SCIM_KEY_grave }, { SCIM_KEY_Adiaeresis, SCIM_KEY_apostrophe }, { SCIM_KEY_Aring, SCIM_KEY_bracketleft }, { SCIM_KEY_Odiaeresis, SCIM_KEY_semicolon }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_bracketright }, }; static __Uint16Pair __us_to_finnish_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Adiaeresis }, { SCIM_KEY_minus, SCIM_KEY_plus }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Odiaeresis }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_Aring }, { SCIM_KEY_backslash, SCIM_KEY_apostrophe }, { SCIM_KEY_bracketright, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_grave, SCIM_KEY_section }, }; static __Uint16Pair __finnish_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_currency, SCIM_KEY_dollar }, { SCIM_KEY_onehalf, SCIM_KEY_asciitilde }, { SCIM_KEY_Adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_Aring, SCIM_KEY_braceleft }, { SCIM_KEY_Odiaeresis, SCIM_KEY_colon }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceright }, }; static __Uint16Pair __us_to_finnish_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_Adiaeresis }, { SCIM_KEY_dollar, SCIM_KEY_currency }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_Odiaeresis }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_Aring }, { SCIM_KEY_bar, SCIM_KEY_asterisk }, { SCIM_KEY_braceright, SCIM_KEY_dead_circumflex }, { SCIM_KEY_asciitilde, SCIM_KEY_onehalf }, }; static __Uint16Pair __finnish_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_currency, SCIM_KEY_dollar }, { SCIM_KEY_onehalf, SCIM_KEY_asciitilde }, { SCIM_KEY_adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_aring, SCIM_KEY_braceleft }, { SCIM_KEY_odiaeresis, SCIM_KEY_colon }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceright }, }; static __Uint16Pair __us_to_finnish_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_adiaeresis }, { SCIM_KEY_dollar, SCIM_KEY_currency }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_odiaeresis }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_aring }, { SCIM_KEY_bar, SCIM_KEY_asterisk }, { SCIM_KEY_braceright, SCIM_KEY_dead_circumflex }, { SCIM_KEY_asciitilde, SCIM_KEY_onehalf }, }; static __Uint16Pair __french_to_us_normal [] = { { SCIM_KEY_exclam, SCIM_KEY_slash }, { SCIM_KEY_quotedbl, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_bracketright }, { SCIM_KEY_ampersand, SCIM_KEY_1 }, { SCIM_KEY_apostrophe, SCIM_KEY_4 }, { SCIM_KEY_parenleft, SCIM_KEY_5 }, { SCIM_KEY_parenright, SCIM_KEY_minus }, { SCIM_KEY_asterisk, SCIM_KEY_backslash }, { SCIM_KEY_comma, SCIM_KEY_m }, { SCIM_KEY_minus, SCIM_KEY_6 }, { SCIM_KEY_colon, SCIM_KEY_period }, { SCIM_KEY_semicolon, SCIM_KEY_comma }, { SCIM_KEY_underscore, SCIM_KEY_8 }, { SCIM_KEY_a, SCIM_KEY_q }, { SCIM_KEY_m, SCIM_KEY_semicolon }, { SCIM_KEY_q, SCIM_KEY_a }, { SCIM_KEY_w, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_w }, { SCIM_KEY_twosuperior, SCIM_KEY_grave }, { SCIM_KEY_agrave, SCIM_KEY_0 }, { SCIM_KEY_ccedilla, SCIM_KEY_9 }, { SCIM_KEY_egrave, SCIM_KEY_7 }, { SCIM_KEY_eacute, SCIM_KEY_2 }, { SCIM_KEY_ugrave, SCIM_KEY_apostrophe }, { SCIM_KEY_dead_circumflex, SCIM_KEY_bracketleft }, }; static __Uint16Pair __us_to_french_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_ugrave }, { SCIM_KEY_comma, SCIM_KEY_semicolon }, { SCIM_KEY_minus, SCIM_KEY_parenright }, { SCIM_KEY_period, SCIM_KEY_colon }, { SCIM_KEY_slash, SCIM_KEY_exclam }, { SCIM_KEY_0, SCIM_KEY_agrave }, { SCIM_KEY_1, SCIM_KEY_ampersand }, { SCIM_KEY_2, SCIM_KEY_eacute }, { SCIM_KEY_3, SCIM_KEY_quotedbl }, { SCIM_KEY_4, SCIM_KEY_apostrophe }, { SCIM_KEY_5, SCIM_KEY_parenleft }, { SCIM_KEY_6, SCIM_KEY_minus }, { SCIM_KEY_7, SCIM_KEY_egrave }, { SCIM_KEY_8, SCIM_KEY_underscore }, { SCIM_KEY_9, SCIM_KEY_ccedilla }, { SCIM_KEY_semicolon, SCIM_KEY_m }, { SCIM_KEY_bracketleft, SCIM_KEY_dead_circumflex }, { SCIM_KEY_backslash, SCIM_KEY_asterisk }, { SCIM_KEY_bracketright, SCIM_KEY_dollar }, { SCIM_KEY_grave, SCIM_KEY_twosuperior }, { SCIM_KEY_a, SCIM_KEY_q }, { SCIM_KEY_m, SCIM_KEY_comma }, { SCIM_KEY_q, SCIM_KEY_a }, { SCIM_KEY_w, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_w }, }; static __Uint16Pair __french_to_us_caps [] = { { SCIM_KEY_exclam, SCIM_KEY_slash }, { SCIM_KEY_quotedbl, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_bracketright }, { SCIM_KEY_ampersand, SCIM_KEY_1 }, { SCIM_KEY_apostrophe, SCIM_KEY_4 }, { SCIM_KEY_parenleft, SCIM_KEY_5 }, { SCIM_KEY_parenright, SCIM_KEY_minus }, { SCIM_KEY_asterisk, SCIM_KEY_backslash }, { SCIM_KEY_comma, SCIM_KEY_M }, { SCIM_KEY_minus, SCIM_KEY_6 }, { SCIM_KEY_colon, SCIM_KEY_period }, { SCIM_KEY_semicolon, SCIM_KEY_comma }, { SCIM_KEY_A, SCIM_KEY_Q }, { SCIM_KEY_M, SCIM_KEY_semicolon }, { SCIM_KEY_Q, SCIM_KEY_A }, { SCIM_KEY_W, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_W }, { SCIM_KEY_underscore, SCIM_KEY_8 }, { SCIM_KEY_twosuperior, SCIM_KEY_grave }, { SCIM_KEY_Agrave, SCIM_KEY_0 }, { SCIM_KEY_Ccedilla, SCIM_KEY_9 }, { SCIM_KEY_Egrave, SCIM_KEY_7 }, { SCIM_KEY_Eacute, SCIM_KEY_2 }, { SCIM_KEY_Ugrave, SCIM_KEY_apostrophe }, { SCIM_KEY_dead_circumflex, SCIM_KEY_bracketleft }, }; static __Uint16Pair __us_to_french_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Ugrave }, { SCIM_KEY_comma, SCIM_KEY_semicolon }, { SCIM_KEY_minus, SCIM_KEY_parenright }, { SCIM_KEY_period, SCIM_KEY_colon }, { SCIM_KEY_slash, SCIM_KEY_exclam }, { SCIM_KEY_0, SCIM_KEY_Agrave }, { SCIM_KEY_1, SCIM_KEY_ampersand }, { SCIM_KEY_2, SCIM_KEY_Eacute }, { SCIM_KEY_3, SCIM_KEY_quotedbl }, { SCIM_KEY_4, SCIM_KEY_apostrophe }, { SCIM_KEY_5, SCIM_KEY_parenleft }, { SCIM_KEY_6, SCIM_KEY_minus }, { SCIM_KEY_7, SCIM_KEY_Egrave }, { SCIM_KEY_8, SCIM_KEY_underscore }, { SCIM_KEY_9, SCIM_KEY_Ccedilla }, { SCIM_KEY_semicolon, SCIM_KEY_M }, { SCIM_KEY_A, SCIM_KEY_Q }, { SCIM_KEY_M, SCIM_KEY_comma }, { SCIM_KEY_Q, SCIM_KEY_A }, { SCIM_KEY_W, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_W }, { SCIM_KEY_bracketleft, SCIM_KEY_dead_circumflex }, { SCIM_KEY_backslash, SCIM_KEY_asterisk }, { SCIM_KEY_bracketright, SCIM_KEY_dollar }, { SCIM_KEY_grave, SCIM_KEY_twosuperior }, }; static __Uint16Pair __french_to_us_shift [] = { { SCIM_KEY_percent, SCIM_KEY_quotedbl }, { SCIM_KEY_period, SCIM_KEY_less }, { SCIM_KEY_slash, SCIM_KEY_greater }, { SCIM_KEY_0, SCIM_KEY_parenright }, { SCIM_KEY_1, SCIM_KEY_exclam }, { SCIM_KEY_2, SCIM_KEY_at }, { SCIM_KEY_3, SCIM_KEY_numbersign }, { SCIM_KEY_4, SCIM_KEY_dollar }, { SCIM_KEY_5, SCIM_KEY_percent }, { SCIM_KEY_6, SCIM_KEY_asciicircum }, { SCIM_KEY_7, SCIM_KEY_ampersand }, { SCIM_KEY_8, SCIM_KEY_asterisk }, { SCIM_KEY_9, SCIM_KEY_parenleft }, { SCIM_KEY_question, SCIM_KEY_M }, { SCIM_KEY_A, SCIM_KEY_Q }, { SCIM_KEY_M, SCIM_KEY_colon }, { SCIM_KEY_Q, SCIM_KEY_A }, { SCIM_KEY_W, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_W }, { SCIM_KEY_sterling, SCIM_KEY_braceright }, { SCIM_KEY_section, SCIM_KEY_question }, { SCIM_KEY_degree, SCIM_KEY_underscore }, { SCIM_KEY_mu, SCIM_KEY_bar }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_braceleft }, }; static __Uint16Pair __us_to_french_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_1 }, { SCIM_KEY_quotedbl, SCIM_KEY_percent }, { SCIM_KEY_numbersign, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_4 }, { SCIM_KEY_percent, SCIM_KEY_5 }, { SCIM_KEY_ampersand, SCIM_KEY_7 }, { SCIM_KEY_parenleft, SCIM_KEY_9 }, { SCIM_KEY_parenright, SCIM_KEY_0 }, { SCIM_KEY_asterisk, SCIM_KEY_8 }, { SCIM_KEY_colon, SCIM_KEY_M }, { SCIM_KEY_less, SCIM_KEY_period }, { SCIM_KEY_greater, SCIM_KEY_slash }, { SCIM_KEY_question, SCIM_KEY_section }, { SCIM_KEY_at, SCIM_KEY_2 }, { SCIM_KEY_A, SCIM_KEY_Q }, { SCIM_KEY_M, SCIM_KEY_question }, { SCIM_KEY_Q, SCIM_KEY_A }, { SCIM_KEY_W, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_W }, { SCIM_KEY_asciicircum, SCIM_KEY_6 }, { SCIM_KEY_underscore, SCIM_KEY_degree }, { SCIM_KEY_braceleft, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_bar, SCIM_KEY_mu }, { SCIM_KEY_braceright, SCIM_KEY_sterling }, }; static __Uint16Pair __french_to_us_caps_shift [] = { { SCIM_KEY_percent, SCIM_KEY_quotedbl }, { SCIM_KEY_period, SCIM_KEY_less }, { SCIM_KEY_slash, SCIM_KEY_greater }, { SCIM_KEY_0, SCIM_KEY_parenright }, { SCIM_KEY_1, SCIM_KEY_exclam }, { SCIM_KEY_2, SCIM_KEY_at }, { SCIM_KEY_3, SCIM_KEY_numbersign }, { SCIM_KEY_4, SCIM_KEY_dollar }, { SCIM_KEY_5, SCIM_KEY_percent }, { SCIM_KEY_6, SCIM_KEY_asciicircum }, { SCIM_KEY_7, SCIM_KEY_ampersand }, { SCIM_KEY_8, SCIM_KEY_asterisk }, { SCIM_KEY_9, SCIM_KEY_parenleft }, { SCIM_KEY_question, SCIM_KEY_m }, { SCIM_KEY_a, SCIM_KEY_q }, { SCIM_KEY_m, SCIM_KEY_colon }, { SCIM_KEY_q, SCIM_KEY_a }, { SCIM_KEY_w, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_w }, { SCIM_KEY_sterling, SCIM_KEY_braceright }, { SCIM_KEY_section, SCIM_KEY_question }, { SCIM_KEY_degree, SCIM_KEY_underscore }, { SCIM_KEY_mu, SCIM_KEY_bar }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_braceleft }, }; static __Uint16Pair __us_to_french_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_1 }, { SCIM_KEY_quotedbl, SCIM_KEY_percent }, { SCIM_KEY_numbersign, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_4 }, { SCIM_KEY_percent, SCIM_KEY_5 }, { SCIM_KEY_ampersand, SCIM_KEY_7 }, { SCIM_KEY_parenleft, SCIM_KEY_9 }, { SCIM_KEY_parenright, SCIM_KEY_0 }, { SCIM_KEY_asterisk, SCIM_KEY_8 }, { SCIM_KEY_colon, SCIM_KEY_m }, { SCIM_KEY_less, SCIM_KEY_period }, { SCIM_KEY_greater, SCIM_KEY_slash }, { SCIM_KEY_question, SCIM_KEY_section }, { SCIM_KEY_at, SCIM_KEY_2 }, { SCIM_KEY_asciicircum, SCIM_KEY_6 }, { SCIM_KEY_underscore, SCIM_KEY_degree }, { SCIM_KEY_a, SCIM_KEY_q }, { SCIM_KEY_m, SCIM_KEY_question }, { SCIM_KEY_q, SCIM_KEY_a }, { SCIM_KEY_w, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_w }, { SCIM_KEY_braceleft, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_bar, SCIM_KEY_mu }, { SCIM_KEY_braceright, SCIM_KEY_sterling }, }; static __Uint16Pair __french_switzerland_to_us_normal [] = { { SCIM_KEY_dollar, SCIM_KEY_backslash }, { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_section, SCIM_KEY_grave }, { SCIM_KEY_agrave, SCIM_KEY_apostrophe }, { SCIM_KEY_egrave, SCIM_KEY_bracketleft }, { SCIM_KEY_eacute, SCIM_KEY_semicolon }, { SCIM_KEY_dead_circumflex, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_bracketright }, }; static __Uint16Pair __us_to_french_switzerland_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_agrave }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_eacute }, { SCIM_KEY_equal, SCIM_KEY_dead_circumflex }, { SCIM_KEY_bracketleft, SCIM_KEY_egrave }, { SCIM_KEY_backslash, SCIM_KEY_dollar }, { SCIM_KEY_bracketright, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_grave, SCIM_KEY_section }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, }; static __Uint16Pair __french_switzerland_to_us_caps [] = { { SCIM_KEY_dollar, SCIM_KEY_backslash }, { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_section, SCIM_KEY_grave }, { SCIM_KEY_Agrave, SCIM_KEY_apostrophe }, { SCIM_KEY_Egrave, SCIM_KEY_bracketleft }, { SCIM_KEY_Eacute, SCIM_KEY_semicolon }, { SCIM_KEY_dead_circumflex, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_bracketright }, }; static __Uint16Pair __us_to_french_switzerland_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Agrave }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Eacute }, { SCIM_KEY_equal, SCIM_KEY_dead_circumflex }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_bracketleft, SCIM_KEY_Egrave }, { SCIM_KEY_backslash, SCIM_KEY_dollar }, { SCIM_KEY_bracketright, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_grave, SCIM_KEY_section }, }; static __Uint16Pair __french_switzerland_to_us_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_braceright }, { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_numbersign }, { SCIM_KEY_plus, SCIM_KEY_exclam }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_sterling, SCIM_KEY_bar }, { SCIM_KEY_degree, SCIM_KEY_asciitilde }, { SCIM_KEY_adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_ccedilla, SCIM_KEY_dollar }, { SCIM_KEY_odiaeresis, SCIM_KEY_colon }, { SCIM_KEY_udiaeresis, SCIM_KEY_braceleft }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_french_switzerland_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_plus }, { SCIM_KEY_quotedbl, SCIM_KEY_adiaeresis }, { SCIM_KEY_numbersign, SCIM_KEY_asterisk }, { SCIM_KEY_dollar, SCIM_KEY_ccedilla }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_odiaeresis }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_udiaeresis }, { SCIM_KEY_bar, SCIM_KEY_sterling }, { SCIM_KEY_braceright, SCIM_KEY_exclam }, { SCIM_KEY_asciitilde, SCIM_KEY_degree }, }; static __Uint16Pair __french_switzerland_to_us_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_braceright }, { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_numbersign }, { SCIM_KEY_plus, SCIM_KEY_exclam }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_sterling, SCIM_KEY_bar }, { SCIM_KEY_degree, SCIM_KEY_asciitilde }, { SCIM_KEY_Adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_Ccedilla, SCIM_KEY_dollar }, { SCIM_KEY_Odiaeresis, SCIM_KEY_colon }, { SCIM_KEY_Udiaeresis, SCIM_KEY_braceleft }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_french_switzerland_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_plus }, { SCIM_KEY_quotedbl, SCIM_KEY_Adiaeresis }, { SCIM_KEY_numbersign, SCIM_KEY_asterisk }, { SCIM_KEY_dollar, SCIM_KEY_Ccedilla }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_Odiaeresis }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_braceleft, SCIM_KEY_Udiaeresis }, { SCIM_KEY_bar, SCIM_KEY_sterling }, { SCIM_KEY_braceright, SCIM_KEY_exclam }, { SCIM_KEY_asciitilde, SCIM_KEY_degree }, }; static __Uint16Pair __german_deadkeys_to_us_normal [] = { { SCIM_KEY_numbersign, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_bracketright }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_ssharp, SCIM_KEY_minus }, { SCIM_KEY_adiaeresis, SCIM_KEY_apostrophe }, { SCIM_KEY_odiaeresis, SCIM_KEY_semicolon }, { SCIM_KEY_udiaeresis, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_circumflex, SCIM_KEY_grave }, }; static __Uint16Pair __us_to_german_deadkeys_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_adiaeresis }, { SCIM_KEY_minus, SCIM_KEY_ssharp }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_odiaeresis }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_udiaeresis }, { SCIM_KEY_backslash, SCIM_KEY_numbersign }, { SCIM_KEY_bracketright, SCIM_KEY_plus }, { SCIM_KEY_grave, SCIM_KEY_dead_circumflex }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, }; static __Uint16Pair __german_deadkeys_to_us_caps [] = { { SCIM_KEY_numbersign, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_bracketright }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_Adiaeresis, SCIM_KEY_apostrophe }, { SCIM_KEY_Odiaeresis, SCIM_KEY_semicolon }, { SCIM_KEY_Udiaeresis, SCIM_KEY_bracketleft }, { SCIM_KEY_ssharp, SCIM_KEY_minus }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_circumflex, SCIM_KEY_grave }, }; static __Uint16Pair __us_to_german_deadkeys_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Adiaeresis }, { SCIM_KEY_minus, SCIM_KEY_ssharp }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Odiaeresis }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_bracketleft, SCIM_KEY_Udiaeresis }, { SCIM_KEY_backslash, SCIM_KEY_numbersign }, { SCIM_KEY_bracketright, SCIM_KEY_plus }, { SCIM_KEY_grave, SCIM_KEY_dead_circumflex }, }; static __Uint16Pair __german_deadkeys_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_apostrophe, SCIM_KEY_bar }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_section, SCIM_KEY_numbersign }, { SCIM_KEY_degree, SCIM_KEY_asciitilde }, { SCIM_KEY_Adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_Odiaeresis, SCIM_KEY_colon }, { SCIM_KEY_Udiaeresis, SCIM_KEY_braceleft }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_german_deadkeys_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_Adiaeresis }, { SCIM_KEY_numbersign, SCIM_KEY_section }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_Odiaeresis }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_Udiaeresis }, { SCIM_KEY_bar, SCIM_KEY_apostrophe }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_degree }, }; static __Uint16Pair __german_deadkeys_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_apostrophe, SCIM_KEY_bar }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_section, SCIM_KEY_numbersign }, { SCIM_KEY_degree, SCIM_KEY_asciitilde }, { SCIM_KEY_adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_odiaeresis, SCIM_KEY_colon }, { SCIM_KEY_udiaeresis, SCIM_KEY_braceleft }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_german_deadkeys_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_adiaeresis }, { SCIM_KEY_numbersign, SCIM_KEY_section }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_odiaeresis }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_braceleft, SCIM_KEY_udiaeresis }, { SCIM_KEY_bar, SCIM_KEY_apostrophe }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_degree }, }; static __Uint16Pair __german_to_us_normal [] = { { SCIM_KEY_numbersign, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_bracketright }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_asciicircum, SCIM_KEY_grave }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_acute, SCIM_KEY_equal }, { SCIM_KEY_ssharp, SCIM_KEY_minus }, { SCIM_KEY_adiaeresis, SCIM_KEY_apostrophe }, { SCIM_KEY_odiaeresis, SCIM_KEY_semicolon }, { SCIM_KEY_udiaeresis, SCIM_KEY_bracketleft }, }; static __Uint16Pair __us_to_german_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_adiaeresis }, { SCIM_KEY_minus, SCIM_KEY_ssharp }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_odiaeresis }, { SCIM_KEY_equal, SCIM_KEY_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_udiaeresis }, { SCIM_KEY_backslash, SCIM_KEY_numbersign }, { SCIM_KEY_bracketright, SCIM_KEY_plus }, { SCIM_KEY_grave, SCIM_KEY_asciicircum }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, }; static __Uint16Pair __german_to_us_caps [] = { { SCIM_KEY_numbersign, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_bracketright }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_asciicircum, SCIM_KEY_grave }, { SCIM_KEY_acute, SCIM_KEY_equal }, { SCIM_KEY_Adiaeresis, SCIM_KEY_apostrophe }, { SCIM_KEY_Odiaeresis, SCIM_KEY_semicolon }, { SCIM_KEY_Udiaeresis, SCIM_KEY_bracketleft }, { SCIM_KEY_ssharp, SCIM_KEY_minus }, }; static __Uint16Pair __us_to_german_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Adiaeresis }, { SCIM_KEY_minus, SCIM_KEY_ssharp }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Odiaeresis }, { SCIM_KEY_equal, SCIM_KEY_acute }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_bracketleft, SCIM_KEY_Udiaeresis }, { SCIM_KEY_backslash, SCIM_KEY_numbersign }, { SCIM_KEY_bracketright, SCIM_KEY_plus }, { SCIM_KEY_grave, SCIM_KEY_asciicircum }, }; static __Uint16Pair __german_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_apostrophe, SCIM_KEY_bar }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_grave, SCIM_KEY_plus }, { SCIM_KEY_section, SCIM_KEY_numbersign }, { SCIM_KEY_degree, SCIM_KEY_asciitilde }, { SCIM_KEY_Adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_Odiaeresis, SCIM_KEY_colon }, { SCIM_KEY_Udiaeresis, SCIM_KEY_braceleft }, }; static __Uint16Pair __us_to_german_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_Adiaeresis }, { SCIM_KEY_numbersign, SCIM_KEY_section }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_grave }, { SCIM_KEY_colon, SCIM_KEY_Odiaeresis }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_Udiaeresis }, { SCIM_KEY_bar, SCIM_KEY_apostrophe }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_degree }, }; static __Uint16Pair __german_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_apostrophe, SCIM_KEY_bar }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_grave, SCIM_KEY_plus }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_section, SCIM_KEY_numbersign }, { SCIM_KEY_degree, SCIM_KEY_asciitilde }, { SCIM_KEY_adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_odiaeresis, SCIM_KEY_colon }, { SCIM_KEY_udiaeresis, SCIM_KEY_braceleft }, }; static __Uint16Pair __us_to_german_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_adiaeresis }, { SCIM_KEY_numbersign, SCIM_KEY_section }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_grave }, { SCIM_KEY_colon, SCIM_KEY_odiaeresis }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_braceleft, SCIM_KEY_udiaeresis }, { SCIM_KEY_bar, SCIM_KEY_apostrophe }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_degree }, }; static __Uint16Pair __german_swiss_to_us_normal [] = { { SCIM_KEY_dollar, SCIM_KEY_backslash }, { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_section, SCIM_KEY_grave }, { SCIM_KEY_adiaeresis, SCIM_KEY_apostrophe }, { SCIM_KEY_odiaeresis, SCIM_KEY_semicolon }, { SCIM_KEY_udiaeresis, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_circumflex, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_bracketright }, }; static __Uint16Pair __us_to_german_swiss_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_adiaeresis }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_odiaeresis }, { SCIM_KEY_equal, SCIM_KEY_dead_circumflex }, { SCIM_KEY_bracketleft, SCIM_KEY_udiaeresis }, { SCIM_KEY_backslash, SCIM_KEY_dollar }, { SCIM_KEY_bracketright, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_grave, SCIM_KEY_section }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, }; static __Uint16Pair __german_swiss_to_us_caps [] = { { SCIM_KEY_dollar, SCIM_KEY_backslash }, { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_section, SCIM_KEY_grave }, { SCIM_KEY_Adiaeresis, SCIM_KEY_apostrophe }, { SCIM_KEY_Odiaeresis, SCIM_KEY_semicolon }, { SCIM_KEY_Udiaeresis, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_circumflex, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_bracketright }, }; static __Uint16Pair __us_to_german_swiss_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Adiaeresis }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Odiaeresis }, { SCIM_KEY_equal, SCIM_KEY_dead_circumflex }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_bracketleft, SCIM_KEY_Udiaeresis }, { SCIM_KEY_backslash, SCIM_KEY_dollar }, { SCIM_KEY_bracketright, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_grave, SCIM_KEY_section }, }; static __Uint16Pair __german_swiss_to_us_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_braceright }, { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_numbersign }, { SCIM_KEY_plus, SCIM_KEY_exclam }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_sterling, SCIM_KEY_bar }, { SCIM_KEY_degree, SCIM_KEY_asciitilde }, { SCIM_KEY_agrave, SCIM_KEY_quotedbl }, { SCIM_KEY_ccedilla, SCIM_KEY_dollar }, { SCIM_KEY_egrave, SCIM_KEY_braceleft }, { SCIM_KEY_eacute, SCIM_KEY_colon }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_german_swiss_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_plus }, { SCIM_KEY_quotedbl, SCIM_KEY_agrave }, { SCIM_KEY_numbersign, SCIM_KEY_asterisk }, { SCIM_KEY_dollar, SCIM_KEY_ccedilla }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_eacute }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_egrave }, { SCIM_KEY_bar, SCIM_KEY_sterling }, { SCIM_KEY_braceright, SCIM_KEY_exclam }, { SCIM_KEY_asciitilde, SCIM_KEY_degree }, }; static __Uint16Pair __german_swiss_to_us_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_braceright }, { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_numbersign }, { SCIM_KEY_plus, SCIM_KEY_exclam }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_sterling, SCIM_KEY_bar }, { SCIM_KEY_degree, SCIM_KEY_asciitilde }, { SCIM_KEY_Agrave, SCIM_KEY_quotedbl }, { SCIM_KEY_Ccedilla, SCIM_KEY_dollar }, { SCIM_KEY_Egrave, SCIM_KEY_braceleft }, { SCIM_KEY_Eacute, SCIM_KEY_colon }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_german_swiss_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_plus }, { SCIM_KEY_quotedbl, SCIM_KEY_Agrave }, { SCIM_KEY_numbersign, SCIM_KEY_asterisk }, { SCIM_KEY_dollar, SCIM_KEY_Ccedilla }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_Eacute }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_braceleft, SCIM_KEY_Egrave }, { SCIM_KEY_bar, SCIM_KEY_sterling }, { SCIM_KEY_braceright, SCIM_KEY_exclam }, { SCIM_KEY_asciitilde, SCIM_KEY_degree }, }; static __Uint16Pair __hungarian_to_us_normal [] = { { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_0, SCIM_KEY_grave }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_aacute, SCIM_KEY_apostrophe }, { SCIM_KEY_eacute, SCIM_KEY_semicolon }, { SCIM_KEY_oacute, SCIM_KEY_equal }, { SCIM_KEY_odiaeresis, SCIM_KEY_0 }, { SCIM_KEY_uacute, SCIM_KEY_bracketright }, { SCIM_KEY_udiaeresis, SCIM_KEY_minus }, { SCIM_KEY_odoubleacute, SCIM_KEY_bracketleft }, { SCIM_KEY_udoubleacute, SCIM_KEY_backslash }, }; static __Uint16Pair __us_to_hungarian_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_aacute }, { SCIM_KEY_minus, SCIM_KEY_udiaeresis }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_0, SCIM_KEY_odiaeresis }, { SCIM_KEY_semicolon, SCIM_KEY_eacute }, { SCIM_KEY_equal, SCIM_KEY_oacute }, { SCIM_KEY_bracketleft, SCIM_KEY_odoubleacute }, { SCIM_KEY_backslash, SCIM_KEY_udoubleacute }, { SCIM_KEY_bracketright, SCIM_KEY_uacute }, { SCIM_KEY_grave, SCIM_KEY_0 }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, }; static __Uint16Pair __hungarian_to_us_caps [] = { { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_0, SCIM_KEY_grave }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_Aacute, SCIM_KEY_apostrophe }, { SCIM_KEY_Eacute, SCIM_KEY_semicolon }, { SCIM_KEY_Oacute, SCIM_KEY_equal }, { SCIM_KEY_Odiaeresis, SCIM_KEY_0 }, { SCIM_KEY_Uacute, SCIM_KEY_bracketright }, { SCIM_KEY_Udiaeresis, SCIM_KEY_minus }, { SCIM_KEY_Odoubleacute, SCIM_KEY_bracketleft }, { SCIM_KEY_Udoubleacute, SCIM_KEY_backslash }, }; static __Uint16Pair __us_to_hungarian_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Aacute }, { SCIM_KEY_minus, SCIM_KEY_Udiaeresis }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_0, SCIM_KEY_Odiaeresis }, { SCIM_KEY_semicolon, SCIM_KEY_Eacute }, { SCIM_KEY_equal, SCIM_KEY_Oacute }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_bracketleft, SCIM_KEY_Odoubleacute }, { SCIM_KEY_backslash, SCIM_KEY_Udoubleacute }, { SCIM_KEY_bracketright, SCIM_KEY_Uacute }, { SCIM_KEY_grave, SCIM_KEY_0 }, }; static __Uint16Pair __hungarian_to_us_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_dollar }, { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_apostrophe, SCIM_KEY_exclam }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_numbersign }, { SCIM_KEY_slash, SCIM_KEY_asciicircum }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_equal, SCIM_KEY_ampersand }, { SCIM_KEY_question, SCIM_KEY_less }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_section, SCIM_KEY_asciitilde }, { SCIM_KEY_Aacute, SCIM_KEY_quotedbl }, { SCIM_KEY_Eacute, SCIM_KEY_colon }, { SCIM_KEY_Oacute, SCIM_KEY_plus }, { SCIM_KEY_Odiaeresis, SCIM_KEY_parenright }, { SCIM_KEY_Uacute, SCIM_KEY_braceright }, { SCIM_KEY_Udiaeresis, SCIM_KEY_underscore }, { SCIM_KEY_Odoubleacute, SCIM_KEY_braceleft }, { SCIM_KEY_Udoubleacute, SCIM_KEY_bar }, }; static __Uint16Pair __us_to_hungarian_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_apostrophe }, { SCIM_KEY_quotedbl, SCIM_KEY_Aacute }, { SCIM_KEY_numbersign, SCIM_KEY_plus }, { SCIM_KEY_dollar, SCIM_KEY_exclam }, { SCIM_KEY_ampersand, SCIM_KEY_equal }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_Odiaeresis }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_Oacute }, { SCIM_KEY_colon, SCIM_KEY_Eacute }, { SCIM_KEY_less, SCIM_KEY_question }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_asciicircum, SCIM_KEY_slash }, { SCIM_KEY_underscore, SCIM_KEY_Udiaeresis }, { SCIM_KEY_braceleft, SCIM_KEY_Odoubleacute }, { SCIM_KEY_bar, SCIM_KEY_Udoubleacute }, { SCIM_KEY_braceright, SCIM_KEY_Uacute }, { SCIM_KEY_asciitilde, SCIM_KEY_section }, }; static __Uint16Pair __hungarian_to_us_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_dollar }, { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_apostrophe, SCIM_KEY_exclam }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_numbersign }, { SCIM_KEY_slash, SCIM_KEY_asciicircum }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_equal, SCIM_KEY_ampersand }, { SCIM_KEY_question, SCIM_KEY_less }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_section, SCIM_KEY_asciitilde }, { SCIM_KEY_aacute, SCIM_KEY_quotedbl }, { SCIM_KEY_eacute, SCIM_KEY_colon }, { SCIM_KEY_oacute, SCIM_KEY_plus }, { SCIM_KEY_odiaeresis, SCIM_KEY_parenright }, { SCIM_KEY_uacute, SCIM_KEY_braceright }, { SCIM_KEY_udiaeresis, SCIM_KEY_underscore }, { SCIM_KEY_odoubleacute, SCIM_KEY_braceleft }, { SCIM_KEY_udoubleacute, SCIM_KEY_bar }, }; static __Uint16Pair __us_to_hungarian_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_apostrophe }, { SCIM_KEY_quotedbl, SCIM_KEY_aacute }, { SCIM_KEY_numbersign, SCIM_KEY_plus }, { SCIM_KEY_dollar, SCIM_KEY_exclam }, { SCIM_KEY_ampersand, SCIM_KEY_equal }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_odiaeresis }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_oacute }, { SCIM_KEY_colon, SCIM_KEY_eacute }, { SCIM_KEY_less, SCIM_KEY_question }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_slash }, { SCIM_KEY_underscore, SCIM_KEY_udiaeresis }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_braceleft, SCIM_KEY_odoubleacute }, { SCIM_KEY_bar, SCIM_KEY_udoubleacute }, { SCIM_KEY_braceright, SCIM_KEY_uacute }, { SCIM_KEY_asciitilde, SCIM_KEY_section }, }; static __Uint16Pair __italian_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_plus, SCIM_KEY_bracketright }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_backslash, SCIM_KEY_grave }, { SCIM_KEY_agrave, SCIM_KEY_apostrophe }, { SCIM_KEY_egrave, SCIM_KEY_bracketleft }, { SCIM_KEY_igrave, SCIM_KEY_equal }, { SCIM_KEY_ograve, SCIM_KEY_semicolon }, { SCIM_KEY_ugrave, SCIM_KEY_backslash }, }; static __Uint16Pair __us_to_italian_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_agrave }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_ograve }, { SCIM_KEY_equal, SCIM_KEY_igrave }, { SCIM_KEY_bracketleft, SCIM_KEY_egrave }, { SCIM_KEY_backslash, SCIM_KEY_ugrave }, { SCIM_KEY_bracketright, SCIM_KEY_plus }, { SCIM_KEY_grave, SCIM_KEY_backslash }, }; static __Uint16Pair __italian_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_plus, SCIM_KEY_bracketright }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_backslash, SCIM_KEY_grave }, { SCIM_KEY_Agrave, SCIM_KEY_apostrophe }, { SCIM_KEY_Egrave, SCIM_KEY_bracketleft }, { SCIM_KEY_Igrave, SCIM_KEY_equal }, { SCIM_KEY_Ograve, SCIM_KEY_semicolon }, { SCIM_KEY_Ugrave, SCIM_KEY_backslash }, }; static __Uint16Pair __us_to_italian_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Agrave }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Ograve }, { SCIM_KEY_equal, SCIM_KEY_Igrave }, { SCIM_KEY_bracketleft, SCIM_KEY_Egrave }, { SCIM_KEY_backslash, SCIM_KEY_Ugrave }, { SCIM_KEY_bracketright, SCIM_KEY_plus }, { SCIM_KEY_grave, SCIM_KEY_backslash }, }; static __Uint16Pair __italian_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_asciicircum, SCIM_KEY_plus }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_bar, SCIM_KEY_asciitilde }, { SCIM_KEY_sterling, SCIM_KEY_numbersign }, { SCIM_KEY_section, SCIM_KEY_bar }, { SCIM_KEY_degree, SCIM_KEY_quotedbl }, { SCIM_KEY_ccedilla, SCIM_KEY_colon }, { SCIM_KEY_eacute, SCIM_KEY_braceleft }, }; static __Uint16Pair __us_to_italian_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_degree }, { SCIM_KEY_numbersign, SCIM_KEY_sterling }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_asciicircum }, { SCIM_KEY_colon, SCIM_KEY_ccedilla }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_eacute }, { SCIM_KEY_bar, SCIM_KEY_section }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_bar }, }; static __Uint16Pair __italian_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_asciicircum, SCIM_KEY_plus }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_bar, SCIM_KEY_asciitilde }, { SCIM_KEY_sterling, SCIM_KEY_numbersign }, { SCIM_KEY_section, SCIM_KEY_bar }, { SCIM_KEY_degree, SCIM_KEY_quotedbl }, { SCIM_KEY_Ccedilla, SCIM_KEY_colon }, { SCIM_KEY_Eacute, SCIM_KEY_braceleft }, }; static __Uint16Pair __us_to_italian_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_degree }, { SCIM_KEY_numbersign, SCIM_KEY_sterling }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_asciicircum }, { SCIM_KEY_colon, SCIM_KEY_Ccedilla }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_Eacute }, { SCIM_KEY_bar, SCIM_KEY_section }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_bar }, }; static __Uint16Pair __japanese_to_us_normal [] = { { SCIM_KEY_colon, SCIM_KEY_apostrophe }, { SCIM_KEY_at, SCIM_KEY_bracketleft }, { SCIM_KEY_bracketleft, SCIM_KEY_bracketright }, { SCIM_KEY_bracketright, SCIM_KEY_backslash }, { SCIM_KEY_asciicircum, SCIM_KEY_equal }, { SCIM_KEY_Zenkaku_Hankaku, SCIM_KEY_grave }, }; static __Uint16Pair __us_to_japanese_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_colon }, { SCIM_KEY_equal, SCIM_KEY_asciicircum }, { SCIM_KEY_bracketleft, SCIM_KEY_at }, { SCIM_KEY_backslash, SCIM_KEY_bracketright }, { SCIM_KEY_bracketright, SCIM_KEY_bracketleft }, { SCIM_KEY_grave, SCIM_KEY_Zenkaku_Hankaku }, }; static __Uint16Pair __japanese_to_us_caps [] = { { SCIM_KEY_colon, SCIM_KEY_apostrophe }, { SCIM_KEY_at, SCIM_KEY_bracketleft }, { SCIM_KEY_bracketleft, SCIM_KEY_bracketright }, { SCIM_KEY_bracketright, SCIM_KEY_backslash }, { SCIM_KEY_asciicircum, SCIM_KEY_equal }, { SCIM_KEY_Zenkaku_Hankaku, SCIM_KEY_grave }, }; static __Uint16Pair __us_to_japanese_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_colon }, { SCIM_KEY_equal, SCIM_KEY_asciicircum }, { SCIM_KEY_bracketleft, SCIM_KEY_at }, { SCIM_KEY_backslash, SCIM_KEY_bracketright }, { SCIM_KEY_bracketright, SCIM_KEY_bracketleft }, { SCIM_KEY_grave, SCIM_KEY_Zenkaku_Hankaku }, }; static __Uint16Pair __japanese_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_apostrophe, SCIM_KEY_ampersand }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_quotedbl }, { SCIM_KEY_plus, SCIM_KEY_colon }, { SCIM_KEY_equal, SCIM_KEY_underscore }, { SCIM_KEY_grave, SCIM_KEY_braceleft }, { SCIM_KEY_braceleft, SCIM_KEY_braceright }, { SCIM_KEY_braceright, SCIM_KEY_bar }, { SCIM_KEY_asciitilde, SCIM_KEY_parenright }, { SCIM_KEY_asciitilde, SCIM_KEY_plus }, { SCIM_KEY_Zenkaku_Hankaku, SCIM_KEY_asciitilde }, }; static __Uint16Pair __us_to_japanese_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_asterisk }, { SCIM_KEY_ampersand, SCIM_KEY_apostrophe }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_asciitilde }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_asciitilde }, { SCIM_KEY_colon, SCIM_KEY_plus }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_equal }, { SCIM_KEY_braceleft, SCIM_KEY_grave }, { SCIM_KEY_bar, SCIM_KEY_braceright }, { SCIM_KEY_braceright, SCIM_KEY_braceleft }, { SCIM_KEY_asciitilde, SCIM_KEY_Zenkaku_Hankaku }, }; static __Uint16Pair __japanese_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_apostrophe, SCIM_KEY_ampersand }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_quotedbl }, { SCIM_KEY_plus, SCIM_KEY_colon }, { SCIM_KEY_equal, SCIM_KEY_underscore }, { SCIM_KEY_grave, SCIM_KEY_braceleft }, { SCIM_KEY_braceleft, SCIM_KEY_braceright }, { SCIM_KEY_braceright, SCIM_KEY_bar }, { SCIM_KEY_asciitilde, SCIM_KEY_parenright }, { SCIM_KEY_asciitilde, SCIM_KEY_plus }, { SCIM_KEY_Zenkaku_Hankaku, SCIM_KEY_asciitilde }, }; static __Uint16Pair __us_to_japanese_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_asterisk }, { SCIM_KEY_ampersand, SCIM_KEY_apostrophe }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_asciitilde }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_asciitilde }, { SCIM_KEY_colon, SCIM_KEY_plus }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_equal }, { SCIM_KEY_braceleft, SCIM_KEY_grave }, { SCIM_KEY_bar, SCIM_KEY_braceright }, { SCIM_KEY_braceright, SCIM_KEY_braceleft }, { SCIM_KEY_asciitilde, SCIM_KEY_Zenkaku_Hankaku }, }; static __Uint16Pair __norwegian_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_backslash, SCIM_KEY_equal }, { SCIM_KEY_bar, SCIM_KEY_grave }, { SCIM_KEY_aring, SCIM_KEY_bracketleft }, { SCIM_KEY_ae, SCIM_KEY_apostrophe }, { SCIM_KEY_oslash, SCIM_KEY_semicolon }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_bracketright }, }; static __Uint16Pair __us_to_norwegian_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_ae }, { SCIM_KEY_minus, SCIM_KEY_plus }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_oslash }, { SCIM_KEY_equal, SCIM_KEY_backslash }, { SCIM_KEY_bracketleft, SCIM_KEY_aring }, { SCIM_KEY_backslash, SCIM_KEY_apostrophe }, { SCIM_KEY_bracketright, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_grave, SCIM_KEY_bar }, }; static __Uint16Pair __norwegian_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_backslash, SCIM_KEY_equal }, { SCIM_KEY_bar, SCIM_KEY_grave }, { SCIM_KEY_Aring, SCIM_KEY_bracketleft }, { SCIM_KEY_AE, SCIM_KEY_apostrophe }, { SCIM_KEY_Ooblique, SCIM_KEY_semicolon }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_bracketright }, }; static __Uint16Pair __us_to_norwegian_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_AE }, { SCIM_KEY_minus, SCIM_KEY_plus }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Ooblique }, { SCIM_KEY_equal, SCIM_KEY_backslash }, { SCIM_KEY_bracketleft, SCIM_KEY_Aring }, { SCIM_KEY_backslash, SCIM_KEY_apostrophe }, { SCIM_KEY_bracketright, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_grave, SCIM_KEY_bar }, }; static __Uint16Pair __norwegian_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_currency, SCIM_KEY_dollar }, { SCIM_KEY_section, SCIM_KEY_asciitilde }, { SCIM_KEY_Aring, SCIM_KEY_braceleft }, { SCIM_KEY_AE, SCIM_KEY_quotedbl }, { SCIM_KEY_Ooblique, SCIM_KEY_colon }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceright }, }; static __Uint16Pair __us_to_norwegian_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_AE }, { SCIM_KEY_dollar, SCIM_KEY_currency }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_Ooblique }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_Aring }, { SCIM_KEY_bar, SCIM_KEY_asterisk }, { SCIM_KEY_braceright, SCIM_KEY_dead_circumflex }, { SCIM_KEY_asciitilde, SCIM_KEY_section }, }; static __Uint16Pair __norwegian_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_currency, SCIM_KEY_dollar }, { SCIM_KEY_section, SCIM_KEY_asciitilde }, { SCIM_KEY_aring, SCIM_KEY_braceleft }, { SCIM_KEY_ae, SCIM_KEY_quotedbl }, { SCIM_KEY_oslash, SCIM_KEY_colon }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceright }, }; static __Uint16Pair __us_to_norwegian_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_ae }, { SCIM_KEY_dollar, SCIM_KEY_currency }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_oslash }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_aring }, { SCIM_KEY_bar, SCIM_KEY_asterisk }, { SCIM_KEY_braceright, SCIM_KEY_dead_circumflex }, { SCIM_KEY_asciitilde, SCIM_KEY_section }, }; static __Uint16Pair __portuguese_brazil_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_grave }, { SCIM_KEY_semicolon, SCIM_KEY_slash }, { SCIM_KEY_bracketleft, SCIM_KEY_bracketright }, { SCIM_KEY_bracketright, SCIM_KEY_backslash }, { SCIM_KEY_ccedilla, SCIM_KEY_semicolon }, { SCIM_KEY_dead_acute, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_tilde, SCIM_KEY_apostrophe }, }; static __Uint16Pair __us_to_portuguese_brazil_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_dead_tilde }, { SCIM_KEY_slash, SCIM_KEY_semicolon }, { SCIM_KEY_semicolon, SCIM_KEY_ccedilla }, { SCIM_KEY_bracketleft, SCIM_KEY_dead_acute }, { SCIM_KEY_backslash, SCIM_KEY_bracketright }, { SCIM_KEY_bracketright, SCIM_KEY_bracketleft }, { SCIM_KEY_grave, SCIM_KEY_apostrophe }, }; static __Uint16Pair __portuguese_brazil_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_grave }, { SCIM_KEY_semicolon, SCIM_KEY_slash }, { SCIM_KEY_bracketleft, SCIM_KEY_bracketright }, { SCIM_KEY_bracketright, SCIM_KEY_backslash }, { SCIM_KEY_Ccedilla, SCIM_KEY_semicolon }, { SCIM_KEY_dead_acute, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_tilde, SCIM_KEY_apostrophe }, }; static __Uint16Pair __us_to_portuguese_brazil_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_dead_tilde }, { SCIM_KEY_slash, SCIM_KEY_semicolon }, { SCIM_KEY_semicolon, SCIM_KEY_Ccedilla }, { SCIM_KEY_bracketleft, SCIM_KEY_dead_acute }, { SCIM_KEY_backslash, SCIM_KEY_bracketright }, { SCIM_KEY_bracketright, SCIM_KEY_bracketleft }, { SCIM_KEY_grave, SCIM_KEY_apostrophe }, }; static __Uint16Pair __portuguese_brazil_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_asciitilde }, { SCIM_KEY_colon, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_braceright }, { SCIM_KEY_braceright, SCIM_KEY_bar }, { SCIM_KEY_Ccedilla, SCIM_KEY_colon }, { SCIM_KEY_dead_grave, SCIM_KEY_braceleft }, { SCIM_KEY_dead_circumflex, SCIM_KEY_quotedbl }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_asciicircum }, }; static __Uint16Pair __us_to_portuguese_brazil_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_dead_circumflex }, { SCIM_KEY_colon, SCIM_KEY_Ccedilla }, { SCIM_KEY_question, SCIM_KEY_colon }, { SCIM_KEY_asciicircum, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_braceleft, SCIM_KEY_dead_grave }, { SCIM_KEY_bar, SCIM_KEY_braceright }, { SCIM_KEY_braceright, SCIM_KEY_braceleft }, { SCIM_KEY_asciitilde, SCIM_KEY_quotedbl }, }; static __Uint16Pair __portuguese_brazil_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_asciitilde }, { SCIM_KEY_colon, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_braceright }, { SCIM_KEY_braceright, SCIM_KEY_bar }, { SCIM_KEY_ccedilla, SCIM_KEY_colon }, { SCIM_KEY_dead_grave, SCIM_KEY_braceleft }, { SCIM_KEY_dead_circumflex, SCIM_KEY_quotedbl }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_asciicircum }, }; static __Uint16Pair __us_to_portuguese_brazil_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_dead_circumflex }, { SCIM_KEY_colon, SCIM_KEY_ccedilla }, { SCIM_KEY_question, SCIM_KEY_colon }, { SCIM_KEY_asciicircum, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_braceleft, SCIM_KEY_dead_grave }, { SCIM_KEY_bar, SCIM_KEY_braceright }, { SCIM_KEY_braceright, SCIM_KEY_braceleft }, { SCIM_KEY_asciitilde, SCIM_KEY_quotedbl }, }; static __Uint16Pair __portuguese_brazil_us_accents_to_us_normal [] = { { SCIM_KEY_dead_grave, SCIM_KEY_grave }, { SCIM_KEY_dead_acute, SCIM_KEY_apostrophe }, }; static __Uint16Pair __us_to_portuguese_brazil_us_accents_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_dead_acute }, { SCIM_KEY_grave, SCIM_KEY_dead_grave }, }; static __Uint16Pair __portuguese_brazil_us_accents_to_us_caps [] = { { SCIM_KEY_dead_grave, SCIM_KEY_grave }, { SCIM_KEY_dead_acute, SCIM_KEY_apostrophe }, }; static __Uint16Pair __us_to_portuguese_brazil_us_accents_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_dead_acute }, { SCIM_KEY_grave, SCIM_KEY_dead_grave }, }; static __Uint16Pair __portuguese_brazil_us_accents_to_us_shift [] = { { SCIM_KEY_dead_circumflex, SCIM_KEY_asciicircum }, { SCIM_KEY_dead_tilde, SCIM_KEY_asciitilde }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_quotedbl }, }; static __Uint16Pair __us_to_portuguese_brazil_us_accents_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_asciicircum, SCIM_KEY_dead_circumflex }, { SCIM_KEY_asciitilde, SCIM_KEY_dead_tilde }, }; static __Uint16Pair __portuguese_brazil_us_accents_to_us_caps_shift [] = { { SCIM_KEY_dead_circumflex, SCIM_KEY_asciicircum }, { SCIM_KEY_dead_tilde, SCIM_KEY_asciitilde }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_quotedbl }, }; static __Uint16Pair __us_to_portuguese_brazil_us_accents_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_asciicircum, SCIM_KEY_dead_circumflex }, { SCIM_KEY_asciitilde, SCIM_KEY_dead_tilde }, }; static __Uint16Pair __portuguese_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_plus, SCIM_KEY_bracketleft }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_backslash, SCIM_KEY_grave }, { SCIM_KEY_asciitilde, SCIM_KEY_backslash }, { SCIM_KEY_guillemotleft, SCIM_KEY_equal }, { SCIM_KEY_acute, SCIM_KEY_bracketright }, { SCIM_KEY_masculine, SCIM_KEY_apostrophe }, { SCIM_KEY_ccedilla, SCIM_KEY_semicolon }, }; static __Uint16Pair __us_to_portuguese_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_masculine }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_ccedilla }, { SCIM_KEY_equal, SCIM_KEY_guillemotleft }, { SCIM_KEY_bracketleft, SCIM_KEY_plus }, { SCIM_KEY_backslash, SCIM_KEY_asciitilde }, { SCIM_KEY_bracketright, SCIM_KEY_acute }, { SCIM_KEY_grave, SCIM_KEY_backslash }, }; static __Uint16Pair __portuguese_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_plus, SCIM_KEY_bracketleft }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_backslash, SCIM_KEY_grave }, { SCIM_KEY_asciitilde, SCIM_KEY_backslash }, { SCIM_KEY_guillemotleft, SCIM_KEY_equal }, { SCIM_KEY_acute, SCIM_KEY_bracketright }, { SCIM_KEY_masculine, SCIM_KEY_apostrophe }, { SCIM_KEY_Ccedilla, SCIM_KEY_semicolon }, }; static __Uint16Pair __us_to_portuguese_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_masculine }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Ccedilla }, { SCIM_KEY_equal, SCIM_KEY_guillemotleft }, { SCIM_KEY_bracketleft, SCIM_KEY_plus }, { SCIM_KEY_backslash, SCIM_KEY_asciitilde }, { SCIM_KEY_bracketright, SCIM_KEY_acute }, { SCIM_KEY_grave, SCIM_KEY_backslash }, }; static __Uint16Pair __portuguese_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceleft }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_asciicircum, SCIM_KEY_bar }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_grave, SCIM_KEY_braceright }, { SCIM_KEY_bar, SCIM_KEY_asciitilde }, { SCIM_KEY_ordfeminine, SCIM_KEY_quotedbl }, { SCIM_KEY_guillemotright, SCIM_KEY_plus }, { SCIM_KEY_Ccedilla, SCIM_KEY_colon }, }; static __Uint16Pair __us_to_portuguese_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_ordfeminine }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_guillemotright }, { SCIM_KEY_colon, SCIM_KEY_Ccedilla }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_asterisk }, { SCIM_KEY_bar, SCIM_KEY_asciicircum }, { SCIM_KEY_braceright, SCIM_KEY_grave }, { SCIM_KEY_asciitilde, SCIM_KEY_bar }, }; static __Uint16Pair __portuguese_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceleft }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_asciicircum, SCIM_KEY_bar }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_grave, SCIM_KEY_braceright }, { SCIM_KEY_bar, SCIM_KEY_asciitilde }, { SCIM_KEY_ordfeminine, SCIM_KEY_quotedbl }, { SCIM_KEY_guillemotright, SCIM_KEY_plus }, { SCIM_KEY_ccedilla, SCIM_KEY_colon }, }; static __Uint16Pair __us_to_portuguese_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_ordfeminine }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_guillemotright }, { SCIM_KEY_colon, SCIM_KEY_ccedilla }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_asterisk }, { SCIM_KEY_bar, SCIM_KEY_asciicircum }, { SCIM_KEY_braceright, SCIM_KEY_grave }, { SCIM_KEY_asciitilde, SCIM_KEY_bar }, }; static __Uint16Pair __slovak_to_us_normal [] = { { SCIM_KEY_plus, SCIM_KEY_1 }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_semicolon, SCIM_KEY_grave }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_section, SCIM_KEY_apostrophe }, { SCIM_KEY_aacute, SCIM_KEY_8 }, { SCIM_KEY_adiaeresis, SCIM_KEY_bracketright }, { SCIM_KEY_eacute, SCIM_KEY_0 }, { SCIM_KEY_iacute, SCIM_KEY_9 }, { SCIM_KEY_ocircumflex, SCIM_KEY_semicolon }, { SCIM_KEY_uacute, SCIM_KEY_bracketleft }, { SCIM_KEY_yacute, SCIM_KEY_7 }, { SCIM_KEY_lcaron, SCIM_KEY_2 }, { SCIM_KEY_scaron, SCIM_KEY_3 }, { SCIM_KEY_tcaron, SCIM_KEY_5 }, { SCIM_KEY_zcaron, SCIM_KEY_6 }, { SCIM_KEY_ccaron, SCIM_KEY_4 }, { SCIM_KEY_ncaron, SCIM_KEY_backslash }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, }; static __Uint16Pair __us_to_slovak_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_section }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_0, SCIM_KEY_eacute }, { SCIM_KEY_1, SCIM_KEY_plus }, { SCIM_KEY_2, SCIM_KEY_lcaron }, { SCIM_KEY_3, SCIM_KEY_scaron }, { SCIM_KEY_4, SCIM_KEY_ccaron }, { SCIM_KEY_5, SCIM_KEY_tcaron }, { SCIM_KEY_6, SCIM_KEY_zcaron }, { SCIM_KEY_7, SCIM_KEY_yacute }, { SCIM_KEY_8, SCIM_KEY_aacute }, { SCIM_KEY_9, SCIM_KEY_iacute }, { SCIM_KEY_semicolon, SCIM_KEY_ocircumflex }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_uacute }, { SCIM_KEY_backslash, SCIM_KEY_ncaron }, { SCIM_KEY_bracketright, SCIM_KEY_adiaeresis }, { SCIM_KEY_grave, SCIM_KEY_semicolon }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, }; static __Uint16Pair __slovak_to_us_caps [] = { { SCIM_KEY_plus, SCIM_KEY_1 }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_semicolon, SCIM_KEY_grave }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_section, SCIM_KEY_apostrophe }, { SCIM_KEY_Aacute, SCIM_KEY_8 }, { SCIM_KEY_Adiaeresis, SCIM_KEY_bracketright }, { SCIM_KEY_Eacute, SCIM_KEY_0 }, { SCIM_KEY_Iacute, SCIM_KEY_9 }, { SCIM_KEY_Ocircumflex, SCIM_KEY_semicolon }, { SCIM_KEY_Uacute, SCIM_KEY_bracketleft }, { SCIM_KEY_Yacute, SCIM_KEY_7 }, { SCIM_KEY_Lcaron, SCIM_KEY_2 }, { SCIM_KEY_Scaron, SCIM_KEY_3 }, { SCIM_KEY_Tcaron, SCIM_KEY_5 }, { SCIM_KEY_Zcaron, SCIM_KEY_6 }, { SCIM_KEY_Ccaron, SCIM_KEY_4 }, { SCIM_KEY_Ncaron, SCIM_KEY_backslash }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, }; static __Uint16Pair __us_to_slovak_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_section }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_0, SCIM_KEY_Eacute }, { SCIM_KEY_1, SCIM_KEY_plus }, { SCIM_KEY_2, SCIM_KEY_Lcaron }, { SCIM_KEY_3, SCIM_KEY_Scaron }, { SCIM_KEY_4, SCIM_KEY_Ccaron }, { SCIM_KEY_5, SCIM_KEY_Tcaron }, { SCIM_KEY_6, SCIM_KEY_Zcaron }, { SCIM_KEY_7, SCIM_KEY_Yacute }, { SCIM_KEY_8, SCIM_KEY_Aacute }, { SCIM_KEY_9, SCIM_KEY_Iacute }, { SCIM_KEY_semicolon, SCIM_KEY_Ocircumflex }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_bracketleft, SCIM_KEY_Uacute }, { SCIM_KEY_backslash, SCIM_KEY_Ncaron }, { SCIM_KEY_bracketright, SCIM_KEY_Adiaeresis }, { SCIM_KEY_grave, SCIM_KEY_semicolon }, }; static __Uint16Pair __slovak_to_us_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_quotedbl }, { SCIM_KEY_quotedbl, SCIM_KEY_colon }, { SCIM_KEY_percent, SCIM_KEY_underscore }, { SCIM_KEY_parenleft, SCIM_KEY_braceright }, { SCIM_KEY_parenright, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_braceleft }, { SCIM_KEY_0, SCIM_KEY_parenright }, { SCIM_KEY_1, SCIM_KEY_exclam }, { SCIM_KEY_2, SCIM_KEY_at }, { SCIM_KEY_3, SCIM_KEY_numbersign }, { SCIM_KEY_4, SCIM_KEY_dollar }, { SCIM_KEY_5, SCIM_KEY_percent }, { SCIM_KEY_6, SCIM_KEY_asciicircum }, { SCIM_KEY_7, SCIM_KEY_ampersand }, { SCIM_KEY_8, SCIM_KEY_asterisk }, { SCIM_KEY_9, SCIM_KEY_parenleft }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_question, SCIM_KEY_less }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_dead_abovering, SCIM_KEY_asciitilde }, { SCIM_KEY_dead_caron, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_slovak_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_1 }, { SCIM_KEY_quotedbl, SCIM_KEY_exclam }, { SCIM_KEY_numbersign, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_4 }, { SCIM_KEY_percent, SCIM_KEY_5 }, { SCIM_KEY_ampersand, SCIM_KEY_7 }, { SCIM_KEY_parenleft, SCIM_KEY_9 }, { SCIM_KEY_parenright, SCIM_KEY_0 }, { SCIM_KEY_asterisk, SCIM_KEY_8 }, { SCIM_KEY_plus, SCIM_KEY_dead_caron }, { SCIM_KEY_colon, SCIM_KEY_quotedbl }, { SCIM_KEY_less, SCIM_KEY_question }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_2 }, { SCIM_KEY_Y, SCIM_KEY_Z }, { SCIM_KEY_Z, SCIM_KEY_Y }, { SCIM_KEY_asciicircum, SCIM_KEY_6 }, { SCIM_KEY_underscore, SCIM_KEY_percent }, { SCIM_KEY_braceleft, SCIM_KEY_slash }, { SCIM_KEY_bar, SCIM_KEY_parenright }, { SCIM_KEY_braceright, SCIM_KEY_parenleft }, { SCIM_KEY_asciitilde, SCIM_KEY_dead_abovering }, }; static __Uint16Pair __slovak_to_us_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_quotedbl }, { SCIM_KEY_quotedbl, SCIM_KEY_colon }, { SCIM_KEY_percent, SCIM_KEY_underscore }, { SCIM_KEY_parenleft, SCIM_KEY_braceright }, { SCIM_KEY_parenright, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_braceleft }, { SCIM_KEY_0, SCIM_KEY_parenright }, { SCIM_KEY_1, SCIM_KEY_exclam }, { SCIM_KEY_2, SCIM_KEY_at }, { SCIM_KEY_3, SCIM_KEY_numbersign }, { SCIM_KEY_4, SCIM_KEY_dollar }, { SCIM_KEY_5, SCIM_KEY_percent }, { SCIM_KEY_6, SCIM_KEY_asciicircum }, { SCIM_KEY_7, SCIM_KEY_ampersand }, { SCIM_KEY_8, SCIM_KEY_asterisk }, { SCIM_KEY_9, SCIM_KEY_parenleft }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_question, SCIM_KEY_less }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_dead_abovering, SCIM_KEY_asciitilde }, { SCIM_KEY_dead_caron, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_slovak_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_1 }, { SCIM_KEY_quotedbl, SCIM_KEY_exclam }, { SCIM_KEY_numbersign, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_4 }, { SCIM_KEY_percent, SCIM_KEY_5 }, { SCIM_KEY_ampersand, SCIM_KEY_7 }, { SCIM_KEY_parenleft, SCIM_KEY_9 }, { SCIM_KEY_parenright, SCIM_KEY_0 }, { SCIM_KEY_asterisk, SCIM_KEY_8 }, { SCIM_KEY_plus, SCIM_KEY_dead_caron }, { SCIM_KEY_colon, SCIM_KEY_quotedbl }, { SCIM_KEY_less, SCIM_KEY_question }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_2 }, { SCIM_KEY_asciicircum, SCIM_KEY_6 }, { SCIM_KEY_underscore, SCIM_KEY_percent }, { SCIM_KEY_y, SCIM_KEY_z }, { SCIM_KEY_z, SCIM_KEY_y }, { SCIM_KEY_braceleft, SCIM_KEY_slash }, { SCIM_KEY_bar, SCIM_KEY_parenright }, { SCIM_KEY_braceright, SCIM_KEY_parenleft }, { SCIM_KEY_asciitilde, SCIM_KEY_dead_abovering }, }; static __Uint16Pair __slovak_qwerty_to_us_normal [] = { { SCIM_KEY_plus, SCIM_KEY_1 }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_semicolon, SCIM_KEY_grave }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_section, SCIM_KEY_apostrophe }, { SCIM_KEY_aacute, SCIM_KEY_8 }, { SCIM_KEY_adiaeresis, SCIM_KEY_bracketright }, { SCIM_KEY_eacute, SCIM_KEY_0 }, { SCIM_KEY_iacute, SCIM_KEY_9 }, { SCIM_KEY_ocircumflex, SCIM_KEY_semicolon }, { SCIM_KEY_uacute, SCIM_KEY_bracketleft }, { SCIM_KEY_yacute, SCIM_KEY_7 }, { SCIM_KEY_lcaron, SCIM_KEY_2 }, { SCIM_KEY_scaron, SCIM_KEY_3 }, { SCIM_KEY_tcaron, SCIM_KEY_5 }, { SCIM_KEY_zcaron, SCIM_KEY_6 }, { SCIM_KEY_ccaron, SCIM_KEY_4 }, { SCIM_KEY_ncaron, SCIM_KEY_backslash }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, }; static __Uint16Pair __us_to_slovak_qwerty_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_section }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_0, SCIM_KEY_eacute }, { SCIM_KEY_1, SCIM_KEY_plus }, { SCIM_KEY_2, SCIM_KEY_lcaron }, { SCIM_KEY_3, SCIM_KEY_scaron }, { SCIM_KEY_4, SCIM_KEY_ccaron }, { SCIM_KEY_5, SCIM_KEY_tcaron }, { SCIM_KEY_6, SCIM_KEY_zcaron }, { SCIM_KEY_7, SCIM_KEY_yacute }, { SCIM_KEY_8, SCIM_KEY_aacute }, { SCIM_KEY_9, SCIM_KEY_iacute }, { SCIM_KEY_semicolon, SCIM_KEY_ocircumflex }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_uacute }, { SCIM_KEY_backslash, SCIM_KEY_ncaron }, { SCIM_KEY_bracketright, SCIM_KEY_adiaeresis }, { SCIM_KEY_grave, SCIM_KEY_semicolon }, }; static __Uint16Pair __slovak_qwerty_to_us_caps [] = { { SCIM_KEY_plus, SCIM_KEY_1 }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_semicolon, SCIM_KEY_grave }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_section, SCIM_KEY_apostrophe }, { SCIM_KEY_Aacute, SCIM_KEY_8 }, { SCIM_KEY_Adiaeresis, SCIM_KEY_bracketright }, { SCIM_KEY_Eacute, SCIM_KEY_0 }, { SCIM_KEY_Iacute, SCIM_KEY_9 }, { SCIM_KEY_Ocircumflex, SCIM_KEY_semicolon }, { SCIM_KEY_Uacute, SCIM_KEY_bracketleft }, { SCIM_KEY_Yacute, SCIM_KEY_7 }, { SCIM_KEY_Lcaron, SCIM_KEY_2 }, { SCIM_KEY_Scaron, SCIM_KEY_3 }, { SCIM_KEY_Tcaron, SCIM_KEY_5 }, { SCIM_KEY_Zcaron, SCIM_KEY_6 }, { SCIM_KEY_Ccaron, SCIM_KEY_4 }, { SCIM_KEY_Ncaron, SCIM_KEY_backslash }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, }; static __Uint16Pair __us_to_slovak_qwerty_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_section }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_0, SCIM_KEY_Eacute }, { SCIM_KEY_1, SCIM_KEY_plus }, { SCIM_KEY_2, SCIM_KEY_Lcaron }, { SCIM_KEY_3, SCIM_KEY_Scaron }, { SCIM_KEY_4, SCIM_KEY_Ccaron }, { SCIM_KEY_5, SCIM_KEY_Tcaron }, { SCIM_KEY_6, SCIM_KEY_Zcaron }, { SCIM_KEY_7, SCIM_KEY_Yacute }, { SCIM_KEY_8, SCIM_KEY_Aacute }, { SCIM_KEY_9, SCIM_KEY_Iacute }, { SCIM_KEY_semicolon, SCIM_KEY_Ocircumflex }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_Uacute }, { SCIM_KEY_backslash, SCIM_KEY_Ncaron }, { SCIM_KEY_bracketright, SCIM_KEY_Adiaeresis }, { SCIM_KEY_grave, SCIM_KEY_semicolon }, }; static __Uint16Pair __slovak_qwerty_to_us_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_quotedbl }, { SCIM_KEY_quotedbl, SCIM_KEY_colon }, { SCIM_KEY_percent, SCIM_KEY_underscore }, { SCIM_KEY_parenleft, SCIM_KEY_braceright }, { SCIM_KEY_parenright, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_braceleft }, { SCIM_KEY_0, SCIM_KEY_parenright }, { SCIM_KEY_1, SCIM_KEY_exclam }, { SCIM_KEY_2, SCIM_KEY_at }, { SCIM_KEY_3, SCIM_KEY_numbersign }, { SCIM_KEY_4, SCIM_KEY_dollar }, { SCIM_KEY_5, SCIM_KEY_percent }, { SCIM_KEY_6, SCIM_KEY_asciicircum }, { SCIM_KEY_7, SCIM_KEY_ampersand }, { SCIM_KEY_8, SCIM_KEY_asterisk }, { SCIM_KEY_9, SCIM_KEY_parenleft }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_question, SCIM_KEY_less }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_dead_abovering, SCIM_KEY_asciitilde }, { SCIM_KEY_dead_caron, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_slovak_qwerty_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_1 }, { SCIM_KEY_quotedbl, SCIM_KEY_exclam }, { SCIM_KEY_numbersign, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_4 }, { SCIM_KEY_percent, SCIM_KEY_5 }, { SCIM_KEY_ampersand, SCIM_KEY_7 }, { SCIM_KEY_parenleft, SCIM_KEY_9 }, { SCIM_KEY_parenright, SCIM_KEY_0 }, { SCIM_KEY_asterisk, SCIM_KEY_8 }, { SCIM_KEY_plus, SCIM_KEY_dead_caron }, { SCIM_KEY_colon, SCIM_KEY_quotedbl }, { SCIM_KEY_less, SCIM_KEY_question }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_2 }, { SCIM_KEY_asciicircum, SCIM_KEY_6 }, { SCIM_KEY_underscore, SCIM_KEY_percent }, { SCIM_KEY_braceleft, SCIM_KEY_slash }, { SCIM_KEY_bar, SCIM_KEY_parenright }, { SCIM_KEY_braceright, SCIM_KEY_parenleft }, { SCIM_KEY_asciitilde, SCIM_KEY_dead_abovering }, }; static __Uint16Pair __slovak_qwerty_to_us_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_quotedbl }, { SCIM_KEY_quotedbl, SCIM_KEY_colon }, { SCIM_KEY_percent, SCIM_KEY_underscore }, { SCIM_KEY_parenleft, SCIM_KEY_braceright }, { SCIM_KEY_parenright, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_braceleft }, { SCIM_KEY_0, SCIM_KEY_parenright }, { SCIM_KEY_1, SCIM_KEY_exclam }, { SCIM_KEY_2, SCIM_KEY_at }, { SCIM_KEY_3, SCIM_KEY_numbersign }, { SCIM_KEY_4, SCIM_KEY_dollar }, { SCIM_KEY_5, SCIM_KEY_percent }, { SCIM_KEY_6, SCIM_KEY_asciicircum }, { SCIM_KEY_7, SCIM_KEY_ampersand }, { SCIM_KEY_8, SCIM_KEY_asterisk }, { SCIM_KEY_9, SCIM_KEY_parenleft }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_question, SCIM_KEY_less }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_dead_abovering, SCIM_KEY_asciitilde }, { SCIM_KEY_dead_caron, SCIM_KEY_plus }, }; static __Uint16Pair __us_to_slovak_qwerty_caps_shift [] = { { SCIM_KEY_exclam, SCIM_KEY_1 }, { SCIM_KEY_quotedbl, SCIM_KEY_exclam }, { SCIM_KEY_numbersign, SCIM_KEY_3 }, { SCIM_KEY_dollar, SCIM_KEY_4 }, { SCIM_KEY_percent, SCIM_KEY_5 }, { SCIM_KEY_ampersand, SCIM_KEY_7 }, { SCIM_KEY_parenleft, SCIM_KEY_9 }, { SCIM_KEY_parenright, SCIM_KEY_0 }, { SCIM_KEY_asterisk, SCIM_KEY_8 }, { SCIM_KEY_plus, SCIM_KEY_dead_caron }, { SCIM_KEY_colon, SCIM_KEY_quotedbl }, { SCIM_KEY_less, SCIM_KEY_question }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_2 }, { SCIM_KEY_asciicircum, SCIM_KEY_6 }, { SCIM_KEY_underscore, SCIM_KEY_percent }, { SCIM_KEY_braceleft, SCIM_KEY_slash }, { SCIM_KEY_bar, SCIM_KEY_parenright }, { SCIM_KEY_braceright, SCIM_KEY_parenleft }, { SCIM_KEY_asciitilde, SCIM_KEY_dead_abovering }, }; static __Uint16Pair __spanish_cp850_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_plus, SCIM_KEY_bracketright }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_exclamdown, SCIM_KEY_equal }, { SCIM_KEY_masculine, SCIM_KEY_grave }, { SCIM_KEY_ccedilla, SCIM_KEY_backslash }, { SCIM_KEY_ntilde, SCIM_KEY_semicolon }, { SCIM_KEY_dead_grave, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_acute, SCIM_KEY_apostrophe }, }; static __Uint16Pair __us_to_spanish_cp850_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_dead_acute }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_ntilde }, { SCIM_KEY_equal, SCIM_KEY_exclamdown }, { SCIM_KEY_bracketleft, SCIM_KEY_dead_grave }, { SCIM_KEY_backslash, SCIM_KEY_ccedilla }, { SCIM_KEY_bracketright, SCIM_KEY_plus }, { SCIM_KEY_grave, SCIM_KEY_masculine }, }; static __Uint16Pair __spanish_cp850_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_plus, SCIM_KEY_bracketright }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_exclamdown, SCIM_KEY_equal }, { SCIM_KEY_masculine, SCIM_KEY_grave }, { SCIM_KEY_Ccedilla, SCIM_KEY_backslash }, { SCIM_KEY_Ntilde, SCIM_KEY_semicolon }, { SCIM_KEY_dead_grave, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_acute, SCIM_KEY_apostrophe }, }; static __Uint16Pair __us_to_spanish_cp850_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_dead_acute }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Ntilde }, { SCIM_KEY_equal, SCIM_KEY_exclamdown }, { SCIM_KEY_bracketleft, SCIM_KEY_dead_grave }, { SCIM_KEY_backslash, SCIM_KEY_Ccedilla }, { SCIM_KEY_bracketright, SCIM_KEY_plus }, { SCIM_KEY_grave, SCIM_KEY_masculine }, }; static __Uint16Pair __spanish_cp850_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_ordfeminine, SCIM_KEY_asciitilde }, { SCIM_KEY_periodcentered, SCIM_KEY_numbersign }, { SCIM_KEY_questiondown, SCIM_KEY_plus }, { SCIM_KEY_Ccedilla, SCIM_KEY_bar }, { SCIM_KEY_Ntilde, SCIM_KEY_colon }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceleft }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_quotedbl }, }; static __Uint16Pair __us_to_spanish_cp850_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_numbersign, SCIM_KEY_periodcentered }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_questiondown }, { SCIM_KEY_colon, SCIM_KEY_Ntilde }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_dead_circumflex }, { SCIM_KEY_bar, SCIM_KEY_Ccedilla }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_ordfeminine }, }; static __Uint16Pair __spanish_cp850_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_ordfeminine, SCIM_KEY_asciitilde }, { SCIM_KEY_periodcentered, SCIM_KEY_numbersign }, { SCIM_KEY_questiondown, SCIM_KEY_plus }, { SCIM_KEY_ccedilla, SCIM_KEY_bar }, { SCIM_KEY_ntilde, SCIM_KEY_colon }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceleft }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_quotedbl }, }; static __Uint16Pair __us_to_spanish_cp850_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_numbersign, SCIM_KEY_periodcentered }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_questiondown }, { SCIM_KEY_colon, SCIM_KEY_ntilde }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_dead_circumflex }, { SCIM_KEY_bar, SCIM_KEY_ccedilla }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_ordfeminine }, }; static __Uint16Pair __spanish_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_plus, SCIM_KEY_bracketright }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_exclamdown, SCIM_KEY_equal }, { SCIM_KEY_masculine, SCIM_KEY_grave }, { SCIM_KEY_ccedilla, SCIM_KEY_backslash }, { SCIM_KEY_ntilde, SCIM_KEY_semicolon }, { SCIM_KEY_dead_grave, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_acute, SCIM_KEY_apostrophe }, }; static __Uint16Pair __us_to_spanish_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_dead_acute }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_ntilde }, { SCIM_KEY_equal, SCIM_KEY_exclamdown }, { SCIM_KEY_bracketleft, SCIM_KEY_dead_grave }, { SCIM_KEY_backslash, SCIM_KEY_ccedilla }, { SCIM_KEY_bracketright, SCIM_KEY_plus }, { SCIM_KEY_grave, SCIM_KEY_masculine }, }; static __Uint16Pair __spanish_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_plus, SCIM_KEY_bracketright }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_exclamdown, SCIM_KEY_equal }, { SCIM_KEY_masculine, SCIM_KEY_grave }, { SCIM_KEY_Ccedilla, SCIM_KEY_backslash }, { SCIM_KEY_Ntilde, SCIM_KEY_semicolon }, { SCIM_KEY_dead_grave, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_acute, SCIM_KEY_apostrophe }, }; static __Uint16Pair __us_to_spanish_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_dead_acute }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Ntilde }, { SCIM_KEY_equal, SCIM_KEY_exclamdown }, { SCIM_KEY_bracketleft, SCIM_KEY_dead_grave }, { SCIM_KEY_backslash, SCIM_KEY_Ccedilla }, { SCIM_KEY_bracketright, SCIM_KEY_plus }, { SCIM_KEY_grave, SCIM_KEY_masculine }, }; static __Uint16Pair __spanish_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_ordfeminine, SCIM_KEY_asciitilde }, { SCIM_KEY_periodcentered, SCIM_KEY_numbersign }, { SCIM_KEY_questiondown, SCIM_KEY_plus }, { SCIM_KEY_Ccedilla, SCIM_KEY_bar }, { SCIM_KEY_Ntilde, SCIM_KEY_colon }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceleft }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_quotedbl }, }; static __Uint16Pair __us_to_spanish_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_numbersign, SCIM_KEY_periodcentered }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_questiondown }, { SCIM_KEY_colon, SCIM_KEY_Ntilde }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_dead_circumflex }, { SCIM_KEY_bar, SCIM_KEY_Ccedilla }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_ordfeminine }, }; static __Uint16Pair __spanish_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_ordfeminine, SCIM_KEY_asciitilde }, { SCIM_KEY_periodcentered, SCIM_KEY_numbersign }, { SCIM_KEY_questiondown, SCIM_KEY_plus }, { SCIM_KEY_ccedilla, SCIM_KEY_bar }, { SCIM_KEY_ntilde, SCIM_KEY_colon }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceleft }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_quotedbl }, }; static __Uint16Pair __us_to_spanish_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_numbersign, SCIM_KEY_periodcentered }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_questiondown }, { SCIM_KEY_colon, SCIM_KEY_ntilde }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_dead_circumflex }, { SCIM_KEY_bar, SCIM_KEY_ccedilla }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_ordfeminine }, }; static __Uint16Pair __spanish_latin_america_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_plus, SCIM_KEY_bracketright }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_exclamdown, SCIM_KEY_equal }, { SCIM_KEY_masculine, SCIM_KEY_grave }, { SCIM_KEY_ccedilla, SCIM_KEY_backslash }, { SCIM_KEY_ntilde, SCIM_KEY_semicolon }, { SCIM_KEY_dead_grave, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_acute, SCIM_KEY_apostrophe }, }; static __Uint16Pair __us_to_spanish_latin_america_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_dead_acute }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_ntilde }, { SCIM_KEY_equal, SCIM_KEY_exclamdown }, { SCIM_KEY_bracketleft, SCIM_KEY_dead_grave }, { SCIM_KEY_backslash, SCIM_KEY_ccedilla }, { SCIM_KEY_bracketright, SCIM_KEY_plus }, { SCIM_KEY_grave, SCIM_KEY_masculine }, }; static __Uint16Pair __spanish_latin_america_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_minus }, { SCIM_KEY_plus, SCIM_KEY_bracketright }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_exclamdown, SCIM_KEY_equal }, { SCIM_KEY_masculine, SCIM_KEY_grave }, { SCIM_KEY_Ccedilla, SCIM_KEY_backslash }, { SCIM_KEY_Ntilde, SCIM_KEY_semicolon }, { SCIM_KEY_dead_grave, SCIM_KEY_bracketleft }, { SCIM_KEY_dead_acute, SCIM_KEY_apostrophe }, }; static __Uint16Pair __us_to_spanish_latin_america_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_dead_acute }, { SCIM_KEY_minus, SCIM_KEY_apostrophe }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Ntilde }, { SCIM_KEY_equal, SCIM_KEY_exclamdown }, { SCIM_KEY_bracketleft, SCIM_KEY_dead_grave }, { SCIM_KEY_backslash, SCIM_KEY_Ccedilla }, { SCIM_KEY_bracketright, SCIM_KEY_plus }, { SCIM_KEY_grave, SCIM_KEY_masculine }, }; static __Uint16Pair __spanish_latin_america_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_ordfeminine, SCIM_KEY_asciitilde }, { SCIM_KEY_periodcentered, SCIM_KEY_numbersign }, { SCIM_KEY_questiondown, SCIM_KEY_plus }, { SCIM_KEY_Ccedilla, SCIM_KEY_bar }, { SCIM_KEY_Ntilde, SCIM_KEY_colon }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceleft }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_quotedbl }, }; static __Uint16Pair __us_to_spanish_latin_america_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_numbersign, SCIM_KEY_periodcentered }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_questiondown }, { SCIM_KEY_colon, SCIM_KEY_Ntilde }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_dead_circumflex }, { SCIM_KEY_bar, SCIM_KEY_Ccedilla }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_ordfeminine }, }; static __Uint16Pair __spanish_latin_america_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_braceright }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_ordfeminine, SCIM_KEY_asciitilde }, { SCIM_KEY_periodcentered, SCIM_KEY_numbersign }, { SCIM_KEY_questiondown, SCIM_KEY_plus }, { SCIM_KEY_ccedilla, SCIM_KEY_bar }, { SCIM_KEY_ntilde, SCIM_KEY_colon }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceleft }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_quotedbl }, }; static __Uint16Pair __us_to_spanish_latin_america_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_numbersign, SCIM_KEY_periodcentered }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_questiondown }, { SCIM_KEY_colon, SCIM_KEY_ntilde }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_dead_circumflex }, { SCIM_KEY_bar, SCIM_KEY_ccedilla }, { SCIM_KEY_braceright, SCIM_KEY_asterisk }, { SCIM_KEY_asciitilde, SCIM_KEY_ordfeminine }, }; static __Uint16Pair __swedish_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_section, SCIM_KEY_grave }, { SCIM_KEY_adiaeresis, SCIM_KEY_apostrophe }, { SCIM_KEY_aring, SCIM_KEY_bracketleft }, { SCIM_KEY_odiaeresis, SCIM_KEY_semicolon }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_bracketright }, }; static __Uint16Pair __us_to_swedish_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_adiaeresis }, { SCIM_KEY_minus, SCIM_KEY_plus }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_odiaeresis }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_aring }, { SCIM_KEY_backslash, SCIM_KEY_apostrophe }, { SCIM_KEY_bracketright, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_grave, SCIM_KEY_section }, }; static __Uint16Pair __swedish_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_backslash }, { SCIM_KEY_plus, SCIM_KEY_minus }, { SCIM_KEY_minus, SCIM_KEY_slash }, { SCIM_KEY_section, SCIM_KEY_grave }, { SCIM_KEY_Adiaeresis, SCIM_KEY_apostrophe }, { SCIM_KEY_Aring, SCIM_KEY_bracketleft }, { SCIM_KEY_Odiaeresis, SCIM_KEY_semicolon }, { SCIM_KEY_dead_acute, SCIM_KEY_equal }, { SCIM_KEY_dead_diaeresis, SCIM_KEY_bracketright }, }; static __Uint16Pair __us_to_swedish_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_Adiaeresis }, { SCIM_KEY_minus, SCIM_KEY_plus }, { SCIM_KEY_slash, SCIM_KEY_minus }, { SCIM_KEY_semicolon, SCIM_KEY_Odiaeresis }, { SCIM_KEY_equal, SCIM_KEY_dead_acute }, { SCIM_KEY_bracketleft, SCIM_KEY_Aring }, { SCIM_KEY_backslash, SCIM_KEY_apostrophe }, { SCIM_KEY_bracketright, SCIM_KEY_dead_diaeresis }, { SCIM_KEY_grave, SCIM_KEY_section }, }; static __Uint16Pair __swedish_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_currency, SCIM_KEY_dollar }, { SCIM_KEY_onehalf, SCIM_KEY_asciitilde }, { SCIM_KEY_Adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_Aring, SCIM_KEY_braceleft }, { SCIM_KEY_Odiaeresis, SCIM_KEY_colon }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceright }, }; static __Uint16Pair __us_to_swedish_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_Adiaeresis }, { SCIM_KEY_dollar, SCIM_KEY_currency }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_Odiaeresis }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_Aring }, { SCIM_KEY_bar, SCIM_KEY_asterisk }, { SCIM_KEY_braceright, SCIM_KEY_dead_circumflex }, { SCIM_KEY_asciitilde, SCIM_KEY_onehalf }, }; static __Uint16Pair __swedish_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_currency, SCIM_KEY_dollar }, { SCIM_KEY_onehalf, SCIM_KEY_asciitilde }, { SCIM_KEY_adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_aring, SCIM_KEY_braceleft }, { SCIM_KEY_odiaeresis, SCIM_KEY_colon }, { SCIM_KEY_dead_grave, SCIM_KEY_plus }, { SCIM_KEY_dead_circumflex, SCIM_KEY_braceright }, }; static __Uint16Pair __us_to_swedish_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_adiaeresis }, { SCIM_KEY_dollar, SCIM_KEY_currency }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dead_grave }, { SCIM_KEY_colon, SCIM_KEY_odiaeresis }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_aring }, { SCIM_KEY_bar, SCIM_KEY_asterisk }, { SCIM_KEY_braceright, SCIM_KEY_dead_circumflex }, { SCIM_KEY_asciitilde, SCIM_KEY_onehalf }, }; static __Uint16Pair __turkish_to_us_normal [] = { { SCIM_KEY_quotedbl, SCIM_KEY_grave }, { SCIM_KEY_asterisk, SCIM_KEY_minus }, { SCIM_KEY_comma, SCIM_KEY_backslash }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_period, SCIM_KEY_slash }, { SCIM_KEY_i, SCIM_KEY_apostrophe }, { SCIM_KEY_ccedilla, SCIM_KEY_period }, { SCIM_KEY_odiaeresis, SCIM_KEY_comma }, { SCIM_KEY_udiaeresis, SCIM_KEY_bracketright }, { SCIM_KEY_scedilla, SCIM_KEY_semicolon }, { SCIM_KEY_idotless, SCIM_KEY_i }, { SCIM_KEY_gbreve, SCIM_KEY_bracketleft }, }; static __Uint16Pair __us_to_turkish_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_i }, { SCIM_KEY_comma, SCIM_KEY_odiaeresis }, { SCIM_KEY_minus, SCIM_KEY_asterisk }, { SCIM_KEY_period, SCIM_KEY_ccedilla }, { SCIM_KEY_slash, SCIM_KEY_period }, { SCIM_KEY_semicolon, SCIM_KEY_scedilla }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_bracketleft, SCIM_KEY_gbreve }, { SCIM_KEY_backslash, SCIM_KEY_comma }, { SCIM_KEY_bracketright, SCIM_KEY_udiaeresis }, { SCIM_KEY_grave, SCIM_KEY_quotedbl }, { SCIM_KEY_i, SCIM_KEY_idotless }, }; static __Uint16Pair __turkish_to_us_caps [] = { { SCIM_KEY_quotedbl, SCIM_KEY_grave }, { SCIM_KEY_asterisk, SCIM_KEY_minus }, { SCIM_KEY_comma, SCIM_KEY_backslash }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_period, SCIM_KEY_slash }, { SCIM_KEY_I, SCIM_KEY_apostrophe }, { SCIM_KEY_Ccedilla, SCIM_KEY_period }, { SCIM_KEY_Odiaeresis, SCIM_KEY_comma }, { SCIM_KEY_Udiaeresis, SCIM_KEY_bracketright }, { SCIM_KEY_Scedilla, SCIM_KEY_semicolon }, { SCIM_KEY_Gbreve, SCIM_KEY_bracketleft }, { SCIM_KEY_idotless, SCIM_KEY_I }, }; static __Uint16Pair __us_to_turkish_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_I }, { SCIM_KEY_comma, SCIM_KEY_Odiaeresis }, { SCIM_KEY_minus, SCIM_KEY_asterisk }, { SCIM_KEY_period, SCIM_KEY_Ccedilla }, { SCIM_KEY_slash, SCIM_KEY_period }, { SCIM_KEY_semicolon, SCIM_KEY_Scedilla }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_I, SCIM_KEY_idotless }, { SCIM_KEY_bracketleft, SCIM_KEY_Gbreve }, { SCIM_KEY_backslash, SCIM_KEY_comma }, { SCIM_KEY_bracketright, SCIM_KEY_Udiaeresis }, { SCIM_KEY_grave, SCIM_KEY_quotedbl }, }; static __Uint16Pair __turkish_to_us_shift [] = { { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_apostrophe, SCIM_KEY_at }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dollar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_question }, { SCIM_KEY_semicolon, SCIM_KEY_bar }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_backslash, SCIM_KEY_asciitilde }, { SCIM_KEY_asciicircum, SCIM_KEY_numbersign }, { SCIM_KEY_underscore, SCIM_KEY_plus }, { SCIM_KEY_Ccedilla, SCIM_KEY_greater }, { SCIM_KEY_Odiaeresis, SCIM_KEY_less }, { SCIM_KEY_Udiaeresis, SCIM_KEY_braceright }, { SCIM_KEY_Scedilla, SCIM_KEY_colon }, { SCIM_KEY_Iabovedot, SCIM_KEY_quotedbl }, { SCIM_KEY_Gbreve, SCIM_KEY_braceleft }, }; static __Uint16Pair __us_to_turkish_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_Iabovedot }, { SCIM_KEY_numbersign, SCIM_KEY_asciicircum }, { SCIM_KEY_dollar, SCIM_KEY_plus }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_underscore }, { SCIM_KEY_colon, SCIM_KEY_Scedilla }, { SCIM_KEY_less, SCIM_KEY_Odiaeresis }, { SCIM_KEY_greater, SCIM_KEY_Ccedilla }, { SCIM_KEY_question, SCIM_KEY_colon }, { SCIM_KEY_at, SCIM_KEY_apostrophe }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_braceleft, SCIM_KEY_Gbreve }, { SCIM_KEY_bar, SCIM_KEY_semicolon }, { SCIM_KEY_braceright, SCIM_KEY_Udiaeresis }, { SCIM_KEY_asciitilde, SCIM_KEY_backslash }, }; static __Uint16Pair __turkish_to_us_caps_shift [] = { { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_apostrophe, SCIM_KEY_at }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_dollar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_question }, { SCIM_KEY_semicolon, SCIM_KEY_bar }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_underscore }, { SCIM_KEY_I, SCIM_KEY_i }, { SCIM_KEY_backslash, SCIM_KEY_asciitilde }, { SCIM_KEY_asciicircum, SCIM_KEY_numbersign }, { SCIM_KEY_underscore, SCIM_KEY_plus }, { SCIM_KEY_ccedilla, SCIM_KEY_greater }, { SCIM_KEY_odiaeresis, SCIM_KEY_less }, { SCIM_KEY_udiaeresis, SCIM_KEY_braceright }, { SCIM_KEY_scedilla, SCIM_KEY_colon }, { SCIM_KEY_Iabovedot, SCIM_KEY_quotedbl }, { SCIM_KEY_gbreve, SCIM_KEY_braceleft }, }; static __Uint16Pair __us_to_turkish_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_Iabovedot }, { SCIM_KEY_numbersign, SCIM_KEY_asciicircum }, { SCIM_KEY_dollar, SCIM_KEY_plus }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_underscore }, { SCIM_KEY_colon, SCIM_KEY_scedilla }, { SCIM_KEY_less, SCIM_KEY_odiaeresis }, { SCIM_KEY_greater, SCIM_KEY_ccedilla }, { SCIM_KEY_question, SCIM_KEY_colon }, { SCIM_KEY_at, SCIM_KEY_apostrophe }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_question }, { SCIM_KEY_i, SCIM_KEY_I }, { SCIM_KEY_braceleft, SCIM_KEY_gbreve }, { SCIM_KEY_bar, SCIM_KEY_semicolon }, { SCIM_KEY_braceright, SCIM_KEY_udiaeresis }, { SCIM_KEY_asciitilde, SCIM_KEY_backslash }, }; static __Uint16Pair __uk_to_us_normal [] = { { SCIM_KEY_numbersign, SCIM_KEY_backslash }, }; static __Uint16Pair __us_to_uk_normal [] = { { SCIM_KEY_backslash, SCIM_KEY_numbersign }, }; static __Uint16Pair __uk_to_us_caps [] = { { SCIM_KEY_numbersign, SCIM_KEY_backslash }, }; static __Uint16Pair __us_to_uk_caps [] = { { SCIM_KEY_backslash, SCIM_KEY_numbersign }, }; static __Uint16Pair __uk_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciitilde, SCIM_KEY_bar }, { SCIM_KEY_sterling, SCIM_KEY_numbersign }, { SCIM_KEY_notsign, SCIM_KEY_asciitilde }, }; static __Uint16Pair __us_to_uk_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_numbersign, SCIM_KEY_sterling }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_bar, SCIM_KEY_asciitilde }, { SCIM_KEY_asciitilde, SCIM_KEY_notsign }, }; static __Uint16Pair __uk_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciitilde, SCIM_KEY_bar }, { SCIM_KEY_sterling, SCIM_KEY_numbersign }, { SCIM_KEY_notsign, SCIM_KEY_asciitilde }, }; static __Uint16Pair __us_to_uk_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_numbersign, SCIM_KEY_sterling }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_bar, SCIM_KEY_asciitilde }, { SCIM_KEY_asciitilde, SCIM_KEY_notsign }, }; static __Uint16Pair __icelandic_to_us_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_bracketright }, { SCIM_KEY_plus, SCIM_KEY_backslash }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_degree, SCIM_KEY_grave }, { SCIM_KEY_ae, SCIM_KEY_semicolon }, { SCIM_KEY_eth, SCIM_KEY_bracketleft }, { SCIM_KEY_odiaeresis, SCIM_KEY_minus }, { SCIM_KEY_thorn, SCIM_KEY_slash }, { SCIM_KEY_dead_acute, SCIM_KEY_apostrophe }, }; static __Uint16Pair __us_to_icelandic_normal [] = { { SCIM_KEY_apostrophe, SCIM_KEY_dead_acute }, { SCIM_KEY_minus, SCIM_KEY_odiaeresis }, { SCIM_KEY_slash, SCIM_KEY_thorn }, { SCIM_KEY_semicolon, SCIM_KEY_ae }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_bracketleft, SCIM_KEY_eth }, { SCIM_KEY_backslash, SCIM_KEY_plus }, { SCIM_KEY_bracketright, SCIM_KEY_apostrophe }, { SCIM_KEY_grave, SCIM_KEY_degree }, }; static __Uint16Pair __icelandic_to_us_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_bracketright }, { SCIM_KEY_plus, SCIM_KEY_backslash }, { SCIM_KEY_minus, SCIM_KEY_equal }, { SCIM_KEY_degree, SCIM_KEY_grave }, { SCIM_KEY_AE, SCIM_KEY_semicolon }, { SCIM_KEY_ETH, SCIM_KEY_bracketleft }, { SCIM_KEY_Odiaeresis, SCIM_KEY_minus }, { SCIM_KEY_THORN, SCIM_KEY_slash }, { SCIM_KEY_dead_acute, SCIM_KEY_apostrophe }, }; static __Uint16Pair __us_to_icelandic_caps [] = { { SCIM_KEY_apostrophe, SCIM_KEY_dead_acute }, { SCIM_KEY_minus, SCIM_KEY_Odiaeresis }, { SCIM_KEY_slash, SCIM_KEY_THORN }, { SCIM_KEY_semicolon, SCIM_KEY_AE }, { SCIM_KEY_equal, SCIM_KEY_minus }, { SCIM_KEY_bracketleft, SCIM_KEY_ETH }, { SCIM_KEY_backslash, SCIM_KEY_plus }, { SCIM_KEY_bracketright, SCIM_KEY_apostrophe }, { SCIM_KEY_grave, SCIM_KEY_degree }, }; static __Uint16Pair __icelandic_to_us_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_braceright }, { SCIM_KEY_underscore, SCIM_KEY_plus }, { SCIM_KEY_diaeresis, SCIM_KEY_asciitilde }, { SCIM_KEY_Adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_AE, SCIM_KEY_colon }, { SCIM_KEY_ETH, SCIM_KEY_braceleft }, { SCIM_KEY_Odiaeresis, SCIM_KEY_underscore }, { SCIM_KEY_THORN, SCIM_KEY_question }, }; static __Uint16Pair __us_to_icelandic_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_Adiaeresis }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_underscore }, { SCIM_KEY_colon, SCIM_KEY_AE }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_THORN }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_Odiaeresis }, { SCIM_KEY_braceleft, SCIM_KEY_ETH }, { SCIM_KEY_bar, SCIM_KEY_asterisk }, { SCIM_KEY_braceright, SCIM_KEY_question }, { SCIM_KEY_asciitilde, SCIM_KEY_diaeresis }, }; static __Uint16Pair __icelandic_to_us_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_at }, { SCIM_KEY_ampersand, SCIM_KEY_asciicircum }, { SCIM_KEY_parenleft, SCIM_KEY_asterisk }, { SCIM_KEY_parenright, SCIM_KEY_parenleft }, { SCIM_KEY_asterisk, SCIM_KEY_bar }, { SCIM_KEY_slash, SCIM_KEY_ampersand }, { SCIM_KEY_colon, SCIM_KEY_greater }, { SCIM_KEY_semicolon, SCIM_KEY_less }, { SCIM_KEY_equal, SCIM_KEY_parenright }, { SCIM_KEY_question, SCIM_KEY_braceright }, { SCIM_KEY_underscore, SCIM_KEY_plus }, { SCIM_KEY_diaeresis, SCIM_KEY_asciitilde }, { SCIM_KEY_Adiaeresis, SCIM_KEY_quotedbl }, { SCIM_KEY_ae, SCIM_KEY_colon }, { SCIM_KEY_eth, SCIM_KEY_braceleft }, { SCIM_KEY_odiaeresis, SCIM_KEY_underscore }, { SCIM_KEY_thorn, SCIM_KEY_question }, }; static __Uint16Pair __us_to_icelandic_caps_shift [] = { { SCIM_KEY_quotedbl, SCIM_KEY_Adiaeresis }, { SCIM_KEY_ampersand, SCIM_KEY_slash }, { SCIM_KEY_parenleft, SCIM_KEY_parenright }, { SCIM_KEY_parenright, SCIM_KEY_equal }, { SCIM_KEY_asterisk, SCIM_KEY_parenleft }, { SCIM_KEY_plus, SCIM_KEY_underscore }, { SCIM_KEY_colon, SCIM_KEY_ae }, { SCIM_KEY_less, SCIM_KEY_semicolon }, { SCIM_KEY_greater, SCIM_KEY_colon }, { SCIM_KEY_question, SCIM_KEY_thorn }, { SCIM_KEY_at, SCIM_KEY_quotedbl }, { SCIM_KEY_asciicircum, SCIM_KEY_ampersand }, { SCIM_KEY_underscore, SCIM_KEY_odiaeresis }, { SCIM_KEY_braceleft, SCIM_KEY_eth }, { SCIM_KEY_bar, SCIM_KEY_asterisk }, { SCIM_KEY_braceright, SCIM_KEY_question }, { SCIM_KEY_asciitilde, SCIM_KEY_diaeresis }, }; // KeyEvent remapping map static __KeyCodeMap __normal_map [] = { { 0, 0 }, { 0, 0 }, { sizeof(__belgian_to_us_normal) / sizeof (__Uint16Pair), __belgian_to_us_normal }, { 0, 0 }, // Croatian { sizeof(__czech_to_us_normal) / sizeof (__Uint16Pair), __czech_to_us_normal }, { sizeof(__czech_qwerty_to_us_normal) / sizeof (__Uint16Pair), __czech_qwerty_to_us_normal }, { sizeof(__danish_to_us_normal) / sizeof (__Uint16Pair), __danish_to_us_normal }, { 0, 0 }, // Dutch { sizeof(__dvorak_to_us_normal) / sizeof (__Uint16Pair), __dvorak_to_us_normal }, { sizeof(__estonian_to_us_normal) / sizeof (__Uint16Pair), __estonian_to_us_normal }, { sizeof(__finnish_to_us_normal) / sizeof (__Uint16Pair), __finnish_to_us_normal }, { sizeof(__french_to_us_normal) / sizeof (__Uint16Pair), __french_to_us_normal }, { 0, 0 }, // French Canadian { sizeof(__french_switzerland_to_us_normal) / sizeof (__Uint16Pair), __french_switzerland_to_us_normal }, { sizeof(__german_to_us_normal) / sizeof (__Uint16Pair), __german_to_us_normal }, { sizeof(__german_deadkeys_to_us_normal) / sizeof (__Uint16Pair), __german_deadkeys_to_us_normal }, { sizeof(__german_swiss_to_us_normal) / sizeof (__Uint16Pair), __german_swiss_to_us_normal }, { 0, 0 }, // Greek { sizeof(__hungarian_to_us_normal) / sizeof (__Uint16Pair), __hungarian_to_us_normal }, { sizeof(__italian_to_us_normal) / sizeof (__Uint16Pair), __italian_to_us_normal }, { sizeof(__japanese_to_us_normal) / sizeof (__Uint16Pair), __japanese_to_us_normal }, { sizeof(__norwegian_to_us_normal) / sizeof (__Uint16Pair), __norwegian_to_us_normal }, { 0, 0 }, // Polish { sizeof(__portuguese_to_us_normal) / sizeof (__Uint16Pair), __portuguese_to_us_normal }, { sizeof(__portuguese_brazil_to_us_normal) / sizeof (__Uint16Pair), __portuguese_brazil_to_us_normal }, { sizeof(__portuguese_brazil_us_accents_to_us_normal) / sizeof (__Uint16Pair), __portuguese_brazil_us_accents_to_us_normal }, { 0, 0 }, // Russian { sizeof(__slovak_to_us_normal) / sizeof (__Uint16Pair), __slovak_to_us_normal }, { sizeof(__slovak_qwerty_to_us_normal) / sizeof (__Uint16Pair), __slovak_qwerty_to_us_normal }, { 0, 0 }, // Slovene { sizeof(__spanish_to_us_normal) / sizeof (__Uint16Pair), __spanish_to_us_normal }, { sizeof(__spanish_cp850_to_us_normal) / sizeof (__Uint16Pair), __spanish_cp850_to_us_normal }, { sizeof(__spanish_latin_america_to_us_normal) / sizeof (__Uint16Pair), __spanish_latin_america_to_us_normal }, { sizeof(__swedish_to_us_normal) / sizeof (__Uint16Pair), __swedish_to_us_normal }, { sizeof(__turkish_to_us_normal) / sizeof (__Uint16Pair), __turkish_to_us_normal }, { sizeof(__uk_to_us_normal) / sizeof (__Uint16Pair), __uk_to_us_normal }, { sizeof(__icelandic_to_us_normal) / sizeof (__Uint16Pair), __icelandic_to_us_normal }, { 0, 0 }, // Icelandic { 0, 0 }, // Ukrainian }; static __KeyCodeMap __normal_invert_map [] = { { 0, 0 }, { 0, 0 }, { sizeof(__us_to_belgian_normal) / sizeof (__Uint16Pair), __us_to_belgian_normal }, { 0, 0 }, // Croatian { sizeof(__us_to_czech_normal) / sizeof (__Uint16Pair), __us_to_czech_normal }, { sizeof(__us_to_czech_qwerty_normal) / sizeof (__Uint16Pair), __us_to_czech_qwerty_normal }, { sizeof(__us_to_danish_normal) / sizeof (__Uint16Pair), __us_to_danish_normal }, { 0, 0 }, // Dutch { sizeof(__us_to_dvorak_normal) / sizeof (__Uint16Pair), __us_to_dvorak_normal }, { sizeof(__us_to_estonian_normal) / sizeof (__Uint16Pair), __us_to_estonian_normal }, { sizeof(__us_to_finnish_normal) / sizeof (__Uint16Pair), __us_to_finnish_normal }, { sizeof(__us_to_french_normal) / sizeof (__Uint16Pair), __us_to_french_normal }, { 0, 0 }, // French Canadian { sizeof(__us_to_french_switzerland_normal) / sizeof (__Uint16Pair), __us_to_french_switzerland_normal }, { sizeof(__us_to_german_normal) / sizeof (__Uint16Pair), __us_to_german_normal }, { sizeof(__us_to_german_deadkeys_normal) / sizeof (__Uint16Pair), __us_to_german_deadkeys_normal }, { sizeof(__us_to_german_swiss_normal) / sizeof (__Uint16Pair), __us_to_german_swiss_normal }, { 0, 0 }, // Greek { sizeof(__us_to_hungarian_normal) / sizeof (__Uint16Pair), __us_to_hungarian_normal }, { sizeof(__us_to_italian_normal) / sizeof (__Uint16Pair), __us_to_italian_normal }, { sizeof(__us_to_japanese_normal) / sizeof (__Uint16Pair), __us_to_japanese_normal }, { sizeof(__us_to_norwegian_normal) / sizeof (__Uint16Pair), __us_to_norwegian_normal }, { 0, 0 }, // Polish { sizeof(__us_to_portuguese_normal) / sizeof (__Uint16Pair), __us_to_portuguese_normal }, { sizeof(__us_to_portuguese_brazil_normal) / sizeof (__Uint16Pair), __us_to_portuguese_brazil_normal }, { sizeof(__us_to_portuguese_brazil_us_accents_normal) / sizeof (__Uint16Pair), __us_to_portuguese_brazil_us_accents_normal }, { 0, 0 }, // Russian { sizeof(__us_to_slovak_normal) / sizeof (__Uint16Pair), __us_to_slovak_normal }, { sizeof(__us_to_slovak_qwerty_normal) / sizeof (__Uint16Pair), __us_to_slovak_qwerty_normal }, { 0, 0 }, // Slovene { sizeof(__us_to_spanish_normal) / sizeof (__Uint16Pair), __us_to_spanish_normal }, { sizeof(__us_to_spanish_cp850_normal) / sizeof (__Uint16Pair), __us_to_spanish_cp850_normal }, { sizeof(__us_to_spanish_latin_america_normal) / sizeof (__Uint16Pair), __us_to_spanish_latin_america_normal }, { sizeof(__us_to_swedish_normal) / sizeof (__Uint16Pair), __us_to_swedish_normal }, { sizeof(__us_to_turkish_normal) / sizeof (__Uint16Pair), __us_to_turkish_normal }, { sizeof(__us_to_uk_normal) / sizeof (__Uint16Pair), __us_to_uk_normal }, { sizeof(__us_to_icelandic_normal) / sizeof (__Uint16Pair), __us_to_icelandic_normal }, { 0, 0 }, // Icelandic { 0, 0 }, // Ukrainian }; static __KeyCodeMap __caps_map [] = { { 0, 0 }, { 0, 0 }, { sizeof(__belgian_to_us_caps) / sizeof (__Uint16Pair), __belgian_to_us_caps }, { 0, 0 }, // Croatian { sizeof(__czech_to_us_caps) / sizeof (__Uint16Pair), __czech_to_us_caps }, { sizeof(__czech_qwerty_to_us_caps) / sizeof (__Uint16Pair), __czech_qwerty_to_us_caps }, { sizeof(__danish_to_us_caps) / sizeof (__Uint16Pair), __danish_to_us_caps }, { 0, 0 }, // Dutch { sizeof(__dvorak_to_us_caps) / sizeof (__Uint16Pair), __dvorak_to_us_caps }, { sizeof(__estonian_to_us_caps) / sizeof (__Uint16Pair), __estonian_to_us_caps }, { sizeof(__finnish_to_us_caps) / sizeof (__Uint16Pair), __finnish_to_us_caps }, { sizeof(__french_to_us_caps) / sizeof (__Uint16Pair), __french_to_us_caps }, { 0, 0 }, // French Canadian { sizeof(__french_switzerland_to_us_caps) / sizeof (__Uint16Pair), __french_switzerland_to_us_caps }, { sizeof(__german_to_us_caps) / sizeof (__Uint16Pair), __german_to_us_caps }, { sizeof(__german_deadkeys_to_us_caps) / sizeof (__Uint16Pair), __german_deadkeys_to_us_caps }, { sizeof(__german_swiss_to_us_caps) / sizeof (__Uint16Pair), __german_swiss_to_us_caps }, { 0, 0 }, // Greek { sizeof(__hungarian_to_us_caps) / sizeof (__Uint16Pair), __hungarian_to_us_caps }, { sizeof(__italian_to_us_caps) / sizeof (__Uint16Pair), __italian_to_us_caps }, { sizeof(__japanese_to_us_caps) / sizeof (__Uint16Pair), __japanese_to_us_caps }, { sizeof(__norwegian_to_us_caps) / sizeof (__Uint16Pair), __norwegian_to_us_caps }, { 0, 0 }, // Polish { sizeof(__portuguese_to_us_caps) / sizeof (__Uint16Pair), __portuguese_to_us_caps }, { sizeof(__portuguese_brazil_to_us_caps) / sizeof (__Uint16Pair), __portuguese_brazil_to_us_caps }, { sizeof(__portuguese_brazil_us_accents_to_us_caps) / sizeof (__Uint16Pair), __portuguese_brazil_us_accents_to_us_caps }, { 0, 0 }, // Russian { sizeof(__slovak_to_us_caps) / sizeof (__Uint16Pair), __slovak_to_us_caps }, { sizeof(__slovak_qwerty_to_us_caps) / sizeof (__Uint16Pair), __slovak_qwerty_to_us_caps }, { 0, 0 }, // Slovene { sizeof(__spanish_to_us_caps) / sizeof (__Uint16Pair), __spanish_to_us_caps }, { sizeof(__spanish_cp850_to_us_caps) / sizeof (__Uint16Pair), __spanish_cp850_to_us_caps }, { sizeof(__spanish_latin_america_to_us_caps) / sizeof (__Uint16Pair), __spanish_latin_america_to_us_caps }, { sizeof(__swedish_to_us_caps) / sizeof (__Uint16Pair), __swedish_to_us_caps }, { sizeof(__turkish_to_us_caps) / sizeof (__Uint16Pair), __turkish_to_us_caps }, { sizeof(__uk_to_us_caps) / sizeof (__Uint16Pair), __uk_to_us_caps }, { sizeof(__icelandic_to_us_caps) / sizeof (__Uint16Pair), __icelandic_to_us_caps }, { 0, 0 }, // Icelandic { 0, 0 }, // Ukrainian }; static __KeyCodeMap __caps_invert_map [] = { { 0, 0 }, { 0, 0 }, { sizeof(__us_to_belgian_caps) / sizeof (__Uint16Pair), __us_to_belgian_caps }, { 0, 0 }, // Croatian { sizeof(__us_to_czech_caps) / sizeof (__Uint16Pair), __us_to_czech_caps }, { sizeof(__us_to_czech_qwerty_caps) / sizeof (__Uint16Pair), __us_to_czech_qwerty_caps }, { sizeof(__us_to_danish_caps) / sizeof (__Uint16Pair), __us_to_danish_caps }, { 0, 0 }, // Dutch { sizeof(__us_to_dvorak_caps) / sizeof (__Uint16Pair), __us_to_dvorak_caps }, { sizeof(__us_to_estonian_caps) / sizeof (__Uint16Pair), __us_to_estonian_caps }, { sizeof(__us_to_finnish_caps) / sizeof (__Uint16Pair), __us_to_finnish_caps }, { sizeof(__us_to_french_caps) / sizeof (__Uint16Pair), __us_to_french_caps }, { 0, 0 }, // French Canadian { sizeof(__us_to_french_switzerland_caps) / sizeof (__Uint16Pair), __us_to_french_switzerland_caps }, { sizeof(__us_to_german_caps) / sizeof (__Uint16Pair), __us_to_german_caps }, { sizeof(__us_to_german_deadkeys_caps) / sizeof (__Uint16Pair), __us_to_german_deadkeys_caps }, { sizeof(__us_to_german_swiss_caps) / sizeof (__Uint16Pair), __us_to_german_swiss_caps }, { 0, 0 }, // Greek { sizeof(__us_to_hungarian_caps) / sizeof (__Uint16Pair), __us_to_hungarian_caps }, { sizeof(__us_to_italian_caps) / sizeof (__Uint16Pair), __us_to_italian_caps }, { sizeof(__us_to_japanese_caps) / sizeof (__Uint16Pair), __us_to_japanese_caps }, { sizeof(__us_to_norwegian_caps) / sizeof (__Uint16Pair), __us_to_norwegian_caps }, { 0, 0 }, // Polish { sizeof(__us_to_portuguese_caps) / sizeof (__Uint16Pair), __us_to_portuguese_caps }, { sizeof(__us_to_portuguese_brazil_caps) / sizeof (__Uint16Pair), __us_to_portuguese_brazil_caps }, { sizeof(__us_to_portuguese_brazil_us_accents_caps) / sizeof (__Uint16Pair), __us_to_portuguese_brazil_us_accents_caps }, { 0, 0 }, // Russian { sizeof(__us_to_slovak_caps) / sizeof (__Uint16Pair), __us_to_slovak_caps }, { sizeof(__us_to_slovak_qwerty_caps) / sizeof (__Uint16Pair), __us_to_slovak_qwerty_caps }, { 0, 0 }, // Slovene { sizeof(__us_to_spanish_caps) / sizeof (__Uint16Pair), __us_to_spanish_caps }, { sizeof(__us_to_spanish_cp850_caps) / sizeof (__Uint16Pair), __us_to_spanish_cp850_caps }, { sizeof(__us_to_spanish_latin_america_caps) / sizeof (__Uint16Pair), __us_to_spanish_latin_america_caps }, { sizeof(__us_to_swedish_caps) / sizeof (__Uint16Pair), __us_to_swedish_caps }, { sizeof(__us_to_turkish_caps) / sizeof (__Uint16Pair), __us_to_turkish_caps }, { sizeof(__us_to_uk_caps) / sizeof (__Uint16Pair), __us_to_uk_caps }, { sizeof(__us_to_icelandic_caps) / sizeof (__Uint16Pair), __us_to_icelandic_caps }, { 0, 0 }, // Icelandic { 0, 0 }, // Ukrainian }; static __KeyCodeMap __shift_map [] = { { 0, 0 }, { 0, 0 }, { sizeof(__belgian_to_us_shift) / sizeof (__Uint16Pair), __belgian_to_us_shift }, { 0, 0 }, // Croatian { sizeof(__czech_to_us_shift) / sizeof (__Uint16Pair), __czech_to_us_shift }, { sizeof(__czech_qwerty_to_us_shift) / sizeof (__Uint16Pair), __czech_qwerty_to_us_shift }, { sizeof(__danish_to_us_shift) / sizeof (__Uint16Pair), __danish_to_us_shift }, { 0, 0 }, // Dutch { sizeof(__dvorak_to_us_shift) / sizeof (__Uint16Pair), __dvorak_to_us_shift }, { sizeof(__estonian_to_us_shift) / sizeof (__Uint16Pair), __estonian_to_us_shift }, { sizeof(__finnish_to_us_shift) / sizeof (__Uint16Pair), __finnish_to_us_shift }, { sizeof(__french_to_us_shift) / sizeof (__Uint16Pair), __french_to_us_shift }, { 0, 0 }, // French Canadian { sizeof(__french_switzerland_to_us_shift) / sizeof (__Uint16Pair), __french_switzerland_to_us_shift }, { sizeof(__german_to_us_shift) / sizeof (__Uint16Pair), __german_to_us_shift }, { sizeof(__german_deadkeys_to_us_shift) / sizeof (__Uint16Pair), __german_deadkeys_to_us_shift }, { sizeof(__german_swiss_to_us_shift) / sizeof (__Uint16Pair), __german_swiss_to_us_shift }, { 0, 0 }, // Greek { sizeof(__hungarian_to_us_shift) / sizeof (__Uint16Pair), __hungarian_to_us_shift }, { sizeof(__italian_to_us_shift) / sizeof (__Uint16Pair), __italian_to_us_shift }, { sizeof(__japanese_to_us_shift) / sizeof (__Uint16Pair), __japanese_to_us_shift }, { sizeof(__norwegian_to_us_shift) / sizeof (__Uint16Pair), __norwegian_to_us_shift }, { 0, 0 }, // Polish { sizeof(__portuguese_to_us_shift) / sizeof (__Uint16Pair), __portuguese_to_us_shift }, { sizeof(__portuguese_brazil_to_us_shift) / sizeof (__Uint16Pair), __portuguese_brazil_to_us_shift }, { sizeof(__portuguese_brazil_us_accents_to_us_shift) / sizeof (__Uint16Pair), __portuguese_brazil_us_accents_to_us_shift }, { 0, 0 }, // Russian { sizeof(__slovak_to_us_shift) / sizeof (__Uint16Pair), __slovak_to_us_shift }, { sizeof(__slovak_qwerty_to_us_shift) / sizeof (__Uint16Pair), __slovak_qwerty_to_us_shift }, { 0, 0 }, // Slovene { sizeof(__spanish_to_us_shift) / sizeof (__Uint16Pair), __spanish_to_us_shift }, { sizeof(__spanish_cp850_to_us_shift) / sizeof (__Uint16Pair), __spanish_cp850_to_us_shift }, { sizeof(__spanish_latin_america_to_us_shift) / sizeof (__Uint16Pair), __spanish_latin_america_to_us_shift }, { sizeof(__swedish_to_us_shift) / sizeof (__Uint16Pair), __swedish_to_us_shift }, { sizeof(__turkish_to_us_shift) / sizeof (__Uint16Pair), __turkish_to_us_shift }, { sizeof(__uk_to_us_shift) / sizeof (__Uint16Pair), __uk_to_us_shift }, { sizeof(__icelandic_to_us_shift) / sizeof (__Uint16Pair), __icelandic_to_us_shift }, { 0, 0 }, // Icelandic { 0, 0 }, // Ukrainian }; static __KeyCodeMap __shift_invert_map [] = { { 0, 0 }, { 0, 0 }, { sizeof(__us_to_belgian_shift) / sizeof (__Uint16Pair), __us_to_belgian_shift }, { 0, 0 }, // Croatian { sizeof(__us_to_czech_shift) / sizeof (__Uint16Pair), __us_to_czech_shift }, { sizeof(__us_to_czech_qwerty_shift) / sizeof (__Uint16Pair), __us_to_czech_qwerty_shift }, { sizeof(__us_to_danish_shift) / sizeof (__Uint16Pair), __us_to_danish_shift }, { 0, 0 }, // Dutch { sizeof(__us_to_dvorak_shift) / sizeof (__Uint16Pair), __us_to_dvorak_shift }, { sizeof(__us_to_estonian_shift) / sizeof (__Uint16Pair), __us_to_estonian_shift }, { sizeof(__us_to_finnish_shift) / sizeof (__Uint16Pair), __us_to_finnish_shift }, { sizeof(__us_to_french_shift) / sizeof (__Uint16Pair), __us_to_french_shift }, { 0, 0 }, // French Canadian { sizeof(__us_to_french_switzerland_shift) / sizeof (__Uint16Pair), __us_to_french_switzerland_shift }, { sizeof(__us_to_german_shift) / sizeof (__Uint16Pair), __us_to_german_shift }, { sizeof(__us_to_german_deadkeys_shift) / sizeof (__Uint16Pair), __us_to_german_deadkeys_shift }, { sizeof(__us_to_german_swiss_shift) / sizeof (__Uint16Pair), __us_to_german_swiss_shift }, { 0, 0 }, // Greek { sizeof(__us_to_hungarian_shift) / sizeof (__Uint16Pair), __us_to_hungarian_shift }, { sizeof(__us_to_italian_shift) / sizeof (__Uint16Pair), __us_to_italian_shift }, { sizeof(__us_to_japanese_shift) / sizeof (__Uint16Pair), __us_to_japanese_shift }, { sizeof(__us_to_norwegian_shift) / sizeof (__Uint16Pair), __us_to_norwegian_shift }, { 0, 0 }, // Polish { sizeof(__us_to_portuguese_shift) / sizeof (__Uint16Pair), __us_to_portuguese_shift }, { sizeof(__us_to_portuguese_brazil_shift) / sizeof (__Uint16Pair), __us_to_portuguese_brazil_shift }, { sizeof(__us_to_portuguese_brazil_us_accents_shift) / sizeof (__Uint16Pair), __us_to_portuguese_brazil_us_accents_shift }, { 0, 0 }, // Russian { sizeof(__us_to_slovak_shift) / sizeof (__Uint16Pair), __us_to_slovak_shift }, { sizeof(__us_to_slovak_qwerty_shift) / sizeof (__Uint16Pair), __us_to_slovak_qwerty_shift }, { 0, 0 }, // Slovene { sizeof(__us_to_spanish_shift) / sizeof (__Uint16Pair), __us_to_spanish_shift }, { sizeof(__us_to_spanish_cp850_shift) / sizeof (__Uint16Pair), __us_to_spanish_cp850_shift }, { sizeof(__us_to_spanish_latin_america_shift) / sizeof (__Uint16Pair), __us_to_spanish_latin_america_shift }, { sizeof(__us_to_swedish_shift) / sizeof (__Uint16Pair), __us_to_swedish_shift }, { sizeof(__us_to_turkish_shift) / sizeof (__Uint16Pair), __us_to_turkish_shift }, { sizeof(__us_to_uk_shift) / sizeof (__Uint16Pair), __us_to_uk_shift }, { sizeof(__us_to_icelandic_shift) / sizeof (__Uint16Pair), __us_to_icelandic_shift }, { 0, 0 }, // Icelandic { 0, 0 }, // Ukrainian }; static __KeyCodeMap __caps_shift_map [] = { { 0, 0 }, { 0, 0 }, { sizeof(__belgian_to_us_caps_shift) / sizeof (__Uint16Pair), __belgian_to_us_caps_shift }, { 0, 0 }, // Croatian { sizeof(__czech_to_us_caps_shift) / sizeof (__Uint16Pair), __czech_to_us_caps_shift }, { sizeof(__czech_qwerty_to_us_caps_shift) / sizeof (__Uint16Pair), __czech_qwerty_to_us_caps_shift }, { sizeof(__danish_to_us_caps_shift) / sizeof (__Uint16Pair), __danish_to_us_caps_shift }, { 0, 0 }, // Dutch { sizeof(__dvorak_to_us_caps_shift) / sizeof (__Uint16Pair), __dvorak_to_us_caps_shift }, { sizeof(__estonian_to_us_caps_shift) / sizeof (__Uint16Pair), __estonian_to_us_caps_shift }, { sizeof(__finnish_to_us_caps_shift) / sizeof (__Uint16Pair), __finnish_to_us_caps_shift }, { sizeof(__french_to_us_caps_shift) / sizeof (__Uint16Pair), __french_to_us_caps_shift }, { 0, 0 }, // French Canadian { sizeof(__french_switzerland_to_us_caps_shift) / sizeof (__Uint16Pair), __french_switzerland_to_us_caps_shift }, { sizeof(__german_to_us_caps_shift) / sizeof (__Uint16Pair), __german_to_us_caps_shift }, { sizeof(__german_deadkeys_to_us_caps_shift) / sizeof (__Uint16Pair), __german_deadkeys_to_us_caps_shift }, { sizeof(__german_swiss_to_us_caps_shift) / sizeof (__Uint16Pair), __german_swiss_to_us_caps_shift }, { 0, 0 }, // Greek { sizeof(__hungarian_to_us_caps_shift) / sizeof (__Uint16Pair), __hungarian_to_us_caps_shift }, { sizeof(__italian_to_us_caps_shift) / sizeof (__Uint16Pair), __italian_to_us_caps_shift }, { sizeof(__japanese_to_us_caps_shift) / sizeof (__Uint16Pair), __japanese_to_us_caps_shift }, { sizeof(__norwegian_to_us_caps_shift) / sizeof (__Uint16Pair), __norwegian_to_us_caps_shift }, { 0, 0 }, // Polish { sizeof(__portuguese_to_us_caps_shift) / sizeof (__Uint16Pair), __portuguese_to_us_caps_shift }, { sizeof(__portuguese_brazil_to_us_caps_shift) / sizeof (__Uint16Pair), __portuguese_brazil_to_us_caps_shift }, { sizeof(__portuguese_brazil_us_accents_to_us_caps_shift) / sizeof (__Uint16Pair), __portuguese_brazil_us_accents_to_us_caps_shift }, { 0, 0 }, // Russian { sizeof(__slovak_to_us_caps_shift) / sizeof (__Uint16Pair), __slovak_to_us_caps_shift }, { sizeof(__slovak_qwerty_to_us_caps_shift) / sizeof (__Uint16Pair), __slovak_qwerty_to_us_caps_shift }, { 0, 0 }, // Slovene { sizeof(__spanish_to_us_caps_shift) / sizeof (__Uint16Pair), __spanish_to_us_caps_shift }, { sizeof(__spanish_cp850_to_us_caps_shift) / sizeof (__Uint16Pair), __spanish_cp850_to_us_caps_shift }, { sizeof(__spanish_latin_america_to_us_caps_shift) / sizeof (__Uint16Pair), __spanish_latin_america_to_us_caps_shift }, { sizeof(__swedish_to_us_caps_shift) / sizeof (__Uint16Pair), __swedish_to_us_caps_shift }, { sizeof(__turkish_to_us_caps_shift) / sizeof (__Uint16Pair), __turkish_to_us_caps_shift }, { sizeof(__uk_to_us_caps_shift) / sizeof (__Uint16Pair), __uk_to_us_caps_shift }, { sizeof(__icelandic_to_us_caps_shift) / sizeof (__Uint16Pair), __icelandic_to_us_caps_shift }, { 0, 0 }, // Icelandic { 0, 0 }, // Ukrainian }; static __KeyCodeMap __caps_shift_invert_map [] = { { 0, 0 }, { 0, 0 }, { sizeof(__us_to_belgian_caps_shift) / sizeof (__Uint16Pair), __us_to_belgian_caps_shift }, { 0, 0 }, // Croatian { sizeof(__us_to_czech_caps_shift) / sizeof (__Uint16Pair), __us_to_czech_caps_shift }, { sizeof(__us_to_czech_qwerty_caps_shift) / sizeof (__Uint16Pair), __us_to_czech_qwerty_caps_shift }, { sizeof(__us_to_danish_caps_shift) / sizeof (__Uint16Pair), __us_to_danish_caps_shift }, { 0, 0 }, // Dutch { sizeof(__us_to_dvorak_caps_shift) / sizeof (__Uint16Pair), __us_to_dvorak_caps_shift }, { sizeof(__us_to_estonian_caps_shift) / sizeof (__Uint16Pair), __us_to_estonian_caps_shift }, { sizeof(__us_to_finnish_caps_shift) / sizeof (__Uint16Pair), __us_to_finnish_caps_shift }, { sizeof(__us_to_french_caps_shift) / sizeof (__Uint16Pair), __us_to_french_caps_shift }, { 0, 0 }, // French Canadian { sizeof(__us_to_french_switzerland_caps_shift) / sizeof (__Uint16Pair), __us_to_french_switzerland_caps_shift }, { sizeof(__us_to_german_caps_shift) / sizeof (__Uint16Pair), __us_to_german_caps_shift }, { sizeof(__us_to_german_deadkeys_caps_shift) / sizeof (__Uint16Pair), __us_to_german_deadkeys_caps_shift }, { sizeof(__us_to_german_swiss_caps_shift) / sizeof (__Uint16Pair), __us_to_german_swiss_caps_shift }, { 0, 0 }, // Greek { sizeof(__us_to_hungarian_caps_shift) / sizeof (__Uint16Pair), __us_to_hungarian_caps_shift }, { sizeof(__us_to_italian_caps_shift) / sizeof (__Uint16Pair), __us_to_italian_caps_shift }, { sizeof(__us_to_japanese_caps_shift) / sizeof (__Uint16Pair), __us_to_japanese_caps_shift }, { sizeof(__us_to_norwegian_caps_shift) / sizeof (__Uint16Pair), __us_to_norwegian_caps_shift }, { 0, 0 }, // Polish { sizeof(__us_to_portuguese_caps_shift) / sizeof (__Uint16Pair), __us_to_portuguese_caps_shift }, { sizeof(__us_to_portuguese_brazil_caps_shift) / sizeof (__Uint16Pair), __us_to_portuguese_brazil_caps_shift }, { sizeof(__us_to_portuguese_brazil_us_accents_caps_shift) / sizeof (__Uint16Pair), __us_to_portuguese_brazil_us_accents_caps_shift }, { 0, 0 }, // Russian { sizeof(__us_to_slovak_caps_shift) / sizeof (__Uint16Pair), __us_to_slovak_caps_shift }, { sizeof(__us_to_slovak_qwerty_caps_shift) / sizeof (__Uint16Pair), __us_to_slovak_qwerty_caps_shift }, { 0, 0 }, // Slovene { sizeof(__us_to_spanish_caps_shift) / sizeof (__Uint16Pair), __us_to_spanish_caps_shift }, { sizeof(__us_to_spanish_cp850_caps_shift) / sizeof (__Uint16Pair), __us_to_spanish_cp850_caps_shift }, { sizeof(__us_to_spanish_latin_america_caps_shift) / sizeof (__Uint16Pair), __us_to_spanish_latin_america_caps_shift }, { sizeof(__us_to_swedish_caps_shift) / sizeof (__Uint16Pair), __us_to_swedish_caps_shift }, { sizeof(__us_to_turkish_caps_shift) / sizeof (__Uint16Pair), __us_to_turkish_caps_shift }, { sizeof(__us_to_uk_caps_shift) / sizeof (__Uint16Pair), __us_to_uk_caps_shift }, { sizeof(__us_to_icelandic_caps_shift) / sizeof (__Uint16Pair), __us_to_icelandic_caps_shift }, { 0, 0 }, // Icelandic { 0, 0 }, // Ukrainian }; // Keyboard Layout string IDs sorted by code. static __KeyName __scim_keyboard_layout_ids_by_code [] = { {SCIM_KEYBOARD_Unknown ,"Unknown"}, {SCIM_KEYBOARD_Default ,"US_Default"}, {SCIM_KEYBOARD_Belgian ,"Belgian"}, {SCIM_KEYBOARD_Croatian ,"Croatian"}, {SCIM_KEYBOARD_Czech ,"Czech"}, {SCIM_KEYBOARD_Czech_Qwerty ,"Czech_Qwerty"}, {SCIM_KEYBOARD_Danish ,"Danish"}, {SCIM_KEYBOARD_Dutch ,"Dutch"}, {SCIM_KEYBOARD_Dvorak ,"Dvorak"}, {SCIM_KEYBOARD_Estonian ,"Estonian"}, {SCIM_KEYBOARD_Finnish ,"Finnish"}, {SCIM_KEYBOARD_French ,"French"}, {SCIM_KEYBOARD_French_Canadian ,"French_Canadian"}, {SCIM_KEYBOARD_French_Switzerland ,"French_Switzerland"}, {SCIM_KEYBOARD_German ,"German"}, {SCIM_KEYBOARD_German_Deadkeys ,"German_Deadkeys"}, {SCIM_KEYBOARD_German_Swiss ,"German_Swiss"}, {SCIM_KEYBOARD_Greek ,"Greek"}, {SCIM_KEYBOARD_Hungarian ,"Hungarian"}, {SCIM_KEYBOARD_Italian ,"Italian"}, {SCIM_KEYBOARD_Japanese ,"Japanese"}, {SCIM_KEYBOARD_Norwegian ,"Norwegian"}, {SCIM_KEYBOARD_Polish ,"Polish"}, {SCIM_KEYBOARD_Portuguese ,"Portuguese"}, {SCIM_KEYBOARD_Portuguese_Brazil ,"Portuguese_Brazil"}, {SCIM_KEYBOARD_Portuguese_Brazil_US_Accents ,"Portuguese_Brazil_US_Accents"}, {SCIM_KEYBOARD_Russian ,"Russian"}, {SCIM_KEYBOARD_Slovak ,"Slovak"}, {SCIM_KEYBOARD_Slovak_Qwerty ,"Slovak_Qwerty"}, {SCIM_KEYBOARD_Slovene ,"Slovene"}, {SCIM_KEYBOARD_Spanish ,"Spanish"}, {SCIM_KEYBOARD_Spanish_CP850 ,"Spanish_CP850"}, {SCIM_KEYBOARD_Spanish_Latin_America ,"Spanish_Latin_America"}, {SCIM_KEYBOARD_Swedish ,"Swedish"}, {SCIM_KEYBOARD_Turkish ,"Turkish"}, {SCIM_KEYBOARD_UK ,"UK"}, {SCIM_KEYBOARD_Icelandic ,"Icelandic"}, {SCIM_KEYBOARD_Lithuanian ,"Lithuanian"}, {SCIM_KEYBOARD_Ukrainian ,"Ukrainian"}, }; // Keyboard Layout string IDs sorted by name. static __KeyName __scim_keyboard_layout_ids_by_name [] = { {SCIM_KEYBOARD_Unknown ,"Unknown"}, {SCIM_KEYBOARD_Default ,"US_Default"}, {SCIM_KEYBOARD_Belgian ,"Belgian"}, {SCIM_KEYBOARD_Croatian ,"Croatian"}, {SCIM_KEYBOARD_Czech ,"Czech"}, {SCIM_KEYBOARD_Czech_Qwerty ,"Czech_Qwerty"}, {SCIM_KEYBOARD_Danish ,"Danish"}, {SCIM_KEYBOARD_Dutch ,"Dutch"}, {SCIM_KEYBOARD_Dvorak ,"Dvorak"}, {SCIM_KEYBOARD_Estonian ,"Estonian"}, {SCIM_KEYBOARD_Finnish ,"Finnish"}, {SCIM_KEYBOARD_French ,"French"}, {SCIM_KEYBOARD_French_Canadian ,"French_Canadian"}, {SCIM_KEYBOARD_French_Switzerland ,"French_Switzerland"}, {SCIM_KEYBOARD_German ,"German"}, {SCIM_KEYBOARD_German_Deadkeys ,"German_Deadkeys"}, {SCIM_KEYBOARD_German_Swiss ,"German_Swiss"}, {SCIM_KEYBOARD_Greek ,"Greek"}, {SCIM_KEYBOARD_Hungarian ,"Hungarian"}, {SCIM_KEYBOARD_Icelandic ,"Icelandic"}, {SCIM_KEYBOARD_Italian ,"Italian"}, {SCIM_KEYBOARD_Japanese ,"Japanese"}, {SCIM_KEYBOARD_Lithuanian ,"Lithuanian"}, {SCIM_KEYBOARD_Norwegian ,"Norwegian"}, {SCIM_KEYBOARD_Polish ,"Polish"}, {SCIM_KEYBOARD_Portuguese ,"Portuguese"}, {SCIM_KEYBOARD_Portuguese_Brazil ,"Portuguese_Brazil"}, {SCIM_KEYBOARD_Portuguese_Brazil_US_Accents ,"Portuguese_Brazil_US_Accents"}, {SCIM_KEYBOARD_Russian ,"Russian"}, {SCIM_KEYBOARD_Slovak ,"Slovak"}, {SCIM_KEYBOARD_Slovak_Qwerty ,"Slovak_Qwerty"}, {SCIM_KEYBOARD_Slovene ,"Slovene"}, {SCIM_KEYBOARD_Spanish ,"Spanish"}, {SCIM_KEYBOARD_Spanish_CP850 ,"Spanish_CP850"}, {SCIM_KEYBOARD_Spanish_Latin_America ,"Spanish_Latin_America"}, {SCIM_KEYBOARD_Swedish ,"Swedish"}, {SCIM_KEYBOARD_Turkish ,"Turkish"}, {SCIM_KEYBOARD_UK ,"UK"}, {SCIM_KEYBOARD_Ukrainian ,"Ukrainian"}, }; // Keyboard Layout display names. static const char *__scim_keyboard_layout_names [] = { N_("Unknown"), N_("English (US)"), N_("Belgian"), N_("Croatian"), N_("Czech"), N_("Czech (qwerty)"), N_("Danish"), N_("Dutch"), N_("Dvorak"), N_("Estonian"), N_("Finnish"), N_("French"), N_("French (Canadian)"), N_("French (Switzerland)"), N_("German"), N_("German (with deadkeys)"), N_("German (Swiss)"), N_("Greek"), N_("Hungarian"), N_("Italian"), N_("Japanese"), N_("Norwegian"), N_("Polish"), N_("Portuguese"), N_("Portuguese (Brazil)"), N_("Portuguese (Brazil US accents)"), N_("Russian"), N_("Slovak"), N_("Slovak (qwerty)"), N_("Slovenian"), N_("Spanish"), N_("Spanish (CP 850)"), N_("Spanish (Latin America)"), N_("Swedish"), N_("Turkish"), N_("English (UK)"), N_("Icelandic"), N_("Lithuanian"), N_("Ukrainian"), }; /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_imengine_module.h0000644000175000017500000001127712422143415017262 0ustar tzhuantzhuan/** @file scim_imengine_module.h * @brief definition of IMEngineModule related classes. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_imengine_module.h,v 1.4 2005/01/10 08:30:54 suzhe Exp $ */ #ifndef __SCIM_IMENGINE_MODULE_H #define __SCIM_IMENGINE_MODULE_H namespace scim { /** * @addtogroup IMEngine * @{ */ /** * @brief Initialize a IMEngine Module. * * There must be a function called "scim_imengine_module_init" * in each imengine module which complies with this prototype. * This function name can have a prefix like table_LTX_, * in which "table" is the module's name. * * @param config - a ConfigBase instance to maintain the configuration. * @return the number of factories supported by this IMEngine Module. */ typedef unsigned int (*IMEngineModuleInitFunc) (const ConfigPointer &config); /** * @brief Create a factory instance for an engine, * * There must be a function called "scim_imengine_module_create_factory" * which complies with this prototype. * This function name can have a prefix like table_LTX_, * in which "table" is the module's name. * * @param engine - the index of the engine for which a factory object will be created. * @return the pointer of the factory object. */ typedef IMEngineFactoryPointer (*IMEngineModuleCreateFactoryFunc) (unsigned int engine); /** * @brief The class to manipulate the IMEngine modules. * * This is a wrapper of scim::Module class, which is specially * for manipulating the IMEngine modules. */ class IMEngineModule { Module m_module; IMEngineModuleInitFunc m_imengine_init; IMEngineModuleCreateFactoryFunc m_imengine_create_factory; unsigned int m_number_of_factories; IMEngineModule (const IMEngineModule &); IMEngineModule & operator= (const IMEngineModule &); public: /** * @brief Default constructor. */ IMEngineModule (); /** * @brief Constructor. * @param name - the module's name, eg. "rawcode". * @param config - a smart pointer points to a ConfigBase instance. */ IMEngineModule (const String &name, const ConfigPointer &config); /** * @brief Load a IMEngine Module by its name. * * Load a module into memory. * If another module has been loaded into this object, * then the old module will be unloaded first. * If the old module is resident, false will be returned, * and the old module will be untouched. * * @param name - the name of the IMEngine Module. * @param config - the ConfigBase instance to be used for storing/loading configs. * @return true if success. */ bool load (const String &name, const ConfigPointer &config); /** * @brief Unload the IMEngine Module. * @return true if sucessfully unloaded. */ bool unload (); /** * @brief Check if a module is loaded and initialized successfully. * @return true if a module is already loaded and initialized successfully. */ bool valid () const; /** * @brief Get how many IMEngine factories supported by this module. * * @return the number of IMEngine factories. */ unsigned int number_of_factories () const; /** * @brief Create an object for an IMEngine factory. * * @param engine - the index of this IMEngine factory, * must be less than the result of number_of_factories method * and greater than or equal to zero. * @return A smart pointer to the factory object, NULL if failed. */ IMEngineFactoryPointer create_factory (unsigned int engine) const; }; /** * @brief Get a name list of currently available IMEngine modules. * @param mod_list - the result list will be stored here. * @return the number of the modules, equal to mod_list.size (). */ int scim_get_imengine_module_list (std::vector &mod_list); /** @} */ } // namespace scim #endif //__SCIM_IMENGINE_MODULE_H /* vi:ts=4:ai:nowrap:expandtab */ scim-1.4.15/src/scim_imengine_module.cpp0000644000175000017500000000575212422143415017616 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_imengine_module.cpp,v 1.3 2005/01/10 08:30:54 suzhe Exp $ * */ #define Uses_SCIM_IMENGINE_MODULE #define Uses_SCIM_MODULE #include "scim_private.h" #include "scim.h" namespace scim { IMEngineModule::IMEngineModule () : m_imengine_init (0), m_imengine_create_factory (0), m_number_of_factories (0) { } IMEngineModule::IMEngineModule (const String &name, const ConfigPointer &config) : m_imengine_init (0), m_imengine_create_factory (0), m_number_of_factories (0) { load (name, config); } bool IMEngineModule::load (const String &name, const ConfigPointer &config) { try { if (!m_module.load (name, "IMEngine")) return false; m_imengine_init = (IMEngineModuleInitFunc) m_module.symbol ("scim_imengine_module_init"); m_imengine_create_factory = (IMEngineModuleCreateFactoryFunc) m_module.symbol ("scim_imengine_module_create_factory"); if (!m_imengine_init || !m_imengine_create_factory) { m_module.unload (); m_imengine_init = 0; m_imengine_create_factory = 0; m_number_of_factories = 0; return false; } m_number_of_factories = m_imengine_init (config); } catch (...) { m_module.unload (); m_imengine_init = 0; m_imengine_create_factory = 0; m_number_of_factories = 0; return false; } return true; } bool IMEngineModule::unload () { return m_module.unload (); } bool IMEngineModule::valid () const { return (m_module.valid () && m_imengine_init && m_imengine_create_factory && m_number_of_factories > 0); } IMEngineFactoryPointer IMEngineModule::create_factory (unsigned int engine) const { if (valid () && engine < m_number_of_factories ) return m_imengine_create_factory (engine); return IMEngineFactoryPointer (0); } unsigned int IMEngineModule::number_of_factories () const { return m_number_of_factories ; } int scim_get_imengine_module_list (std::vector & engine_list) { return scim_get_module_list (engine_list, "IMEngine"); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_imengine.h0000644000175000017500000006632412422143415015720 0ustar tzhuantzhuan/** * @file scim_imengine.h * @brief Defines scim::IMEngineFactoryBase and scim::IMEngineInstanceBase interfaces. * * scim::IMEngineFactoryBase and scim::IMEngineInstanceBase are the most important * part of SCIM platform. * * These interfaces are used to write input method engine modules. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_imengine.h,v 1.19 2005/08/15 12:45:46 suzhe Exp $ */ #ifndef __SCIM_IMENGINE_H #define __SCIM_IMENGINE_H namespace scim { /** * @addtogroup IMEngine * The base classes for input method engine modules. * @{ */ /** * @brief Enum values of all Client Capabilities bitmask. * * These capabilities are not always supported by all kinds of clients. * So if an IMEngine requires some of them to realize some features, * it should make sure that they are supported by client by checking the cap value * sent by update_client_capabilities() action. */ enum ClientCapability { SCIM_CLIENT_CAP_ONTHESPOT_PREEDIT = (1 << 0), /**< The client support OnTheSpot preedit (embed preedit string into client window) */ SCIM_CLIENT_CAP_SINGLE_LEVEL_PROPERTY = (1 << 1), /**< The client support displaying single level property, property tree may not be supported*/ SCIM_CLIENT_CAP_MULTI_LEVEL_PROPERTY = (1 << 2), /**< The client support displaying multiple level property, aka. property tree */ SCIM_CLIENT_CAP_TRIGGER_PROPERTY = (1 << 3), /**< The client is capabile to trigger the IMEngine property. */ SCIM_CLIENT_CAP_HELPER_MODULE = (1 << 4), /**< The client support helper module */ SCIM_CLIENT_CAP_SURROUNDING_TEXT = (1 << 5), /**< The client support get/delete surrounding text operations */ SCIM_CLIENT_CAP_ALL_CAPABILITIES = 0x3F }; /** * @brief An exception class to hold IMEngine related errors. * * scim::IMEngineBase and its derived classes must throw * scim::IMEngineError object when error. */ class IMEngineError: public Exception { public: IMEngineError (const String& what_arg) : Exception (String("scim::IMEngine: ") + what_arg) { } }; class IMEngineFactoryBase; class IMEngineInstanceBase; /** * @typedef typedef Pointer IMEngineFactoryPointer; * * A smart pointer for scim::IMEngineFactoryBase and its derived classes. */ typedef Pointer IMEngineFactoryPointer; /** * @typedef typedef Pointer IMEngineInstancePointer; * * A smart pointer for scim::IMEngineInstanceBase and its derived classes. */ typedef Pointer IMEngineInstancePointer; typedef Slot1 IMEngineSlotVoid; typedef Slot2 IMEngineSlotInt; typedef Slot2 IMEngineSlotBool; typedef Slot2 IMEngineSlotString; typedef Slot2 IMEngineSlotWideString; typedef Slot2 IMEngineSlotKeyEvent; typedef Slot2 IMEngineSlotLookupTable; typedef Slot2 IMEngineSlotProperty; typedef Slot2 IMEngineSlotPropertyList; typedef Slot3 IMEngineSlotStringTransaction; typedef Slot3 IMEngineSlotWideStringAttributeList; typedef Slot5 IMEngineSlotGetSurroundingText; typedef Slot3 IMEngineSlotDeleteSurroundingText; /** * @brief The base class of the real input methods' IMEngineFactory classes. * * Each input method should implement a class derived from scim::IMEngineFactoryBase, * which takes charge of holding shared data, creating IMEngineInstances etc. */ class IMEngineFactoryBase : public ReferencedObject { class IMEngineFactoryBaseImpl; IMEngineFactoryBaseImpl *m_impl; public: IMEngineFactoryBase (); /** * @brief Virtual destructor. */ virtual ~IMEngineFactoryBase (); /** * @name Pure virtual members. * * These member functions must be implemented in derived classes. * * @{ */ /** * @brief Get the name of this input method engine. * * This name should be a localized string. * * @return A WideString containing the name. */ virtual WideString get_name () const = 0; /** * @brief Get the UUID of this input method engine. * * Each input method engine has an unique UUID to * distinguish itself from other engines. * * You may use uuidgen command shipped with e2fsprogs package to generate this UUID. * * @return A String containing an unique UUID. */ virtual String get_uuid () const = 0; /** * @brief Get the icon file path of this input method engine. * * @return A String containing the icon file path on the local filesystem. */ virtual String get_icon_file () const = 0; /** * @brief Get the authors information of this input method engine. * * This string should be a localized string. * * @return A WideString containing a list of the authors' name. */ virtual WideString get_authors () const = 0; /** * @brief Get the credits information of this input method engine. * * This string should be a localized string. * * @return A WideString containing the credits information. */ virtual WideString get_credits () const = 0; /** * @brief Get the help information of this input method engine. * * This string should be a localized string. * * @return A WideString containing the help information. */ virtual WideString get_help () const = 0; /** * @brief Create a new IMEngineInstance object. * * This method creates a new scim::IMEngineInstanceBase object with the given encoding and id. * * @param encoding - the encoding supported by the client. * @param id - the instance id, should be unique. * @return A smart pointer points to this new IMEngineInstance object. */ virtual IMEngineInstancePointer create_instance (const String& encoding, int id = -1) = 0; /** * @} */ /** * @brief Check if an encoding is supported by this IMEngineFactory. * * The default implementation of this virtual function validates the * encoding against the locale list set by method set_locales. * * It should be enough in most case. * * @param encoding - the encoding name to be checked. * @return true if the encoding is supported, otherwise false. */ virtual bool validate_encoding (const String& encoding) const; /** * @brief Check if a locale is supported by this IMEngineFactory. * * The default implementation of this virtual function validates the * locale against the locale list set by method set_locales. * * It should be enough in most case. * * @param locale - the locale name to be checked. * @return true if the locale is supported, otherwise false. */ virtual bool validate_locale (const String& locale) const; /** * @brief Get the supported language of this input method engine. * * The language name conforms to glibc locale naming standard, like: * zh_CN Simplified Chinese * zh_TW Traditional Chinese * ja_JP Japanese * ru_RU for Russian * * The second part of the name (territory id) can be omitted. * * The default implementation of this method will get the language name * according to the return value of get_default_locale () method. * * This method maybe overwrited to return another language name, * for example returning "~other" means other uncategorized languages. */ virtual String get_language () const; /** * @brief Get the original key string of a composed string. * * For example, in the pinyin input method of Simplified Chinese: * the key string of composed string "中国" can be "zhongguo". * * The default implementation just returns a empty string. * * @param str The composed string to be queried. * * @return the original key string of the given composed string. */ virtual WideString inverse_query (const WideString &str); /** * @brief Get the default locale of this input method engine. * * The default locale is the first locale in the locale list, * which is set by method set_locales. * * @return The default locale name. */ String get_default_locale () const; /** * @brief Get the default encoding of this input method engine. * * The default encoding is the first locale's encoding in the locale list, * which is set by method set_locales. * * @return The default encoding name. */ String get_default_encoding () const; /** * @brief Get a list of all supported locales, separated by comma. * * @return A comma separated locale list. */ String get_locales () const; /** * @brief Get a list of all supported encodings, separated by comma. * * @return A comma separated encoding list. */ String get_encodings () const; protected: /** * @brief Set the locales supported by this input method engine. * * This method should be called within the constructors of the derived classes. * * set_locales () and set_languages () are exclusive with each other. Only one * method should be used for one Factory object. * * @param locales - a comma separated list containing all valid locales * should be supported by this input method engine. * The first locale is the default one. */ void set_locales (const String &locales); /** * @brief Set the languages supported by this input method engine. * * This method should be called within the constructors of the derived classes. * * set_locales () and set_languages () are exclusive with each other. Only one * method should be used for one Factory object. * * @param languages - a comma separated list containing all valid languages * should be supported by this input method engine. * The first language is the default one. */ void set_languages (const String &languages); }; /** * @brief The base class of the real input methods' IMEngineInstance classes. * * Each input method should implement a class derived from scim::IMEngineInstanceBase, * which takes charge of recording Input Context status and processing user input events. */ class IMEngineInstanceBase : public ReferencedObject { class IMEngineInstanceBaseImpl; IMEngineInstanceBaseImpl *m_impl; public: /** * @brief Constructor. * * @param factory - the factory which creates this instance. * @param encoding - the working encoding. * @param id - the unique id of this instance. */ IMEngineInstanceBase (IMEngineFactoryBase *factory, const String &encoding, int id = -1); /** * @brief Virtual destructor. */ virtual ~IMEngineInstanceBase (); /** * @brief Set the working encoding for this instance. * * One engine instance can only support one client encoding at the same time. * This encoding must be supported by the IMEngineFactory as well. * * This method could be overrided in derived class to do some extra job. But * the method of this base class must be invoked within the new method. * * After invoking this method, reset() should be invoked to * let the new encoding take effect. * * @return true if the encoding is supported, otherwise false. */ virtual bool set_encoding (const String &encoding); /** * @brief Get the working encoding of this instance. * * This method returns the encoding passed to the * constructor when constructing this object. * * @return The working encoding. */ String get_encoding () const; /** * @brief Get the unique id of this instance. * * @return The id of this instance. */ int get_id () const; /** * @brief Get the UUID of the engine factory. * * @return The UUID string of the engine factory. */ String get_factory_uuid () const; /** * @brief Attach a pointer to this IMEngineInstance, which is pointed to corresponding FrontEnd data. * * @param data The pointer to corresponding FrontEnd data, eg. input context object. */ void set_frontend_data (void *data); /** * @brief Retrieve the pointer previously attached by set_frontend_data(); * * @return The pointer previously attached by set_frontend_data(); */ void * get_frontend_data (void); public: /** * @name Signal connection functions. * * These functions are used by FrontEnds to connect their corresponding slots to * this IMEngineInstance's signals. * * @{ */ Connection signal_connect_show_preedit_string (IMEngineSlotVoid *slot); Connection signal_connect_show_aux_string (IMEngineSlotVoid *slot); Connection signal_connect_show_lookup_table (IMEngineSlotVoid *slot); Connection signal_connect_hide_preedit_string (IMEngineSlotVoid *slot); Connection signal_connect_hide_aux_string (IMEngineSlotVoid *slot); Connection signal_connect_hide_lookup_table (IMEngineSlotVoid *slot); Connection signal_connect_update_preedit_caret (IMEngineSlotInt *slot); Connection signal_connect_update_preedit_string (IMEngineSlotWideStringAttributeList *slot); Connection signal_connect_update_aux_string (IMEngineSlotWideStringAttributeList *slot); Connection signal_connect_update_lookup_table (IMEngineSlotLookupTable *slot); Connection signal_connect_commit_string (IMEngineSlotWideString *slot); Connection signal_connect_forward_key_event (IMEngineSlotKeyEvent *slot); Connection signal_connect_register_properties (IMEngineSlotPropertyList *slot); Connection signal_connect_update_property (IMEngineSlotProperty *slot); Connection signal_connect_beep (IMEngineSlotVoid *slot); Connection signal_connect_start_helper (IMEngineSlotString *slot); Connection signal_connect_stop_helper (IMEngineSlotString *slot); Connection signal_connect_send_helper_event (IMEngineSlotStringTransaction *slot); Connection signal_connect_get_surrounding_text (IMEngineSlotGetSurroundingText *slot); Connection signal_connect_delete_surrounding_text (IMEngineSlotDeleteSurroundingText *slot); /** @} */ public: /** * @name Action functions. * * These functions will be called by FrontEnds to send events to * this IMEngineInstance. * * @{ */ /** * @brief Process a key event. * * @param key - the key event to be processed. * @return true if the event is processed, otherwise the event * is not processed and should be forward to client application. */ virtual bool process_key_event (const KeyEvent &key) = 0; /** * @brief Move the preedit caret in the preedit string. * * @param pos - the new position that user requested. */ virtual void move_preedit_caret (unsigned int pos); /** * @brief Select a candidate in current lookup table. * * When user click a candidate directly, * this method will be invoked by FrontEnd. * * @param index - the index in current page of the selected candidate. */ virtual void select_candidate (unsigned int index); /** * @brief Update the page size of current lookup table. * * In the next time, the lookup table should page down by * this size. * * @param page_size - the new size of current page. */ virtual void update_lookup_table_page_size (unsigned int page_size); /** * @brief Flip the lookup table to the previous page. * * The method will be invoked by FrontEnd when user click * the lookup table page up button. */ virtual void lookup_table_page_up (); /** * @brief Flip the lookup table to the next page. * * The method will be invoked by FrontEnd when user click * the lookup table page down button. */ virtual void lookup_table_page_down (); /** * @brief Reset this engine instance. * * All status of this engine instance should be reset, * including the working encoding. * * The client encoding may have been changed before calling * this method, so if the IMEngine makes use of the client's encoding * information, it should check whether the encoding has been changed. * IMEngineInstance could call the get_encoding () method of base class * to get the client encoding. */ virtual void reset (); /** * @brief Focus in this engine instance. * * This function should update/show/hide the status area, * preedit area and lookup table, and update the * full width punctuation/letter state. */ virtual void focus_in (); /** * @brief Focus out this engine instance. */ virtual void focus_out (); /** * @brief Trigger a property. * * This function should do some action according * to the triggered property. * For example toggle the input mode, etc. * * @param property the key of the triggered property. */ virtual void trigger_property (const String &property); /** * @brief Process the events sent from a Client Helper process. * * @param helper_uuid The UUID of the Helper process which sent the events. * @param trans The transaction which contains the events. */ virtual void process_helper_event (const String &helper_uuid, const Transaction &trans); /** * @brief Update the capabilities of current client application which is attached to this IMEngineInstance. * * Some client may not support all capabilities provided by the IMEngine API. For example: * * - OnTheSpot preedit string display (Embedded into client window). * - Property display * - Helper module * - etc. * * This method will be called to inform this IMEngineInstance object which capabilities are supported by the * client application. It may be called multiple times, if the capabilities was changed. * * @param cap A bitmask to indicate which client capabilities are supported by the client application. * * @sa scim::ClientCapability */ virtual void update_client_capabilities (unsigned int cap); /** @} */ protected: /** * @name Signal activation functions * * These functions should be called by derived classes * to fire the corresponding signals. The FrontEnd * connected to those signals will receive and process them. * * @{ */ /** * @brief Show the preedit string area. * * The preedit string should be updated by calling * update_preedit_string before or right after this call. */ void show_preedit_string (); /** * @brief Show the aux string area. * * The aux string should be updated by calling * update_aux_string before or right after this call. * * The aux string can contain any additional information whatever * the input method engine want. */ void show_aux_string (); /** * @brief Show the lookup table area. * * The lookup table should be updated by calling * update_lookup_table before or right after this call. */ void show_lookup_table (); /** * @brief Hide the preedit string area. */ void hide_preedit_string (); /** * @brief Hide the aux string area. */ void hide_aux_string (); /** * @brief Hide the lookup table area. */ void hide_lookup_table (); /** * @brief Update the preedit caret position in the preedit string. * * @param caret - the new position of the preedit caret. */ void update_preedit_caret (int caret); /** * @brief Update the content of the preedit string, * * @param str - the string content * @param attrs - the string attributes */ void update_preedit_string (const WideString &str, const AttributeList &attrs = AttributeList ()); /** * @brief Update the content of the aux string, * * @param str - the string content * @param attrs - the string attribute */ void update_aux_string (const WideString &str, const AttributeList &attrs = AttributeList ()); /** * @brief Update the content of the lookup table, * * FrontEnd may reduce the page size of the table * according to screen resolution. If the page size * is changed, FrontEnd will inform this engine instance * by calling update_lookup_table_page_size method. * * @param table - the new LookupTable */ void update_lookup_table (const LookupTable &table); /** * @brief Commit a string to the client application. * * The preedit string should be hid before calling * this method. Otherwise the clients which use * OnTheSpot input mode will flicker annoyingly. * * @param str - the string to be committed. */ void commit_string (const WideString &str); /** * @brief Forward a key event to the client application. * * @param key - the key event to be forwarded. */ void forward_key_event (const KeyEvent &key); /** * @brief Register all properties of this IMEngineInstance into the FrontEnd. * * The old properties previously registered by other IMEngineInstance will be discarded, * so for each time focus_in() is called, all properties should be registered * no matter whether they had been registered before. * * @param properties the PropertyList contains all of the properties. */ void register_properties (const PropertyList &properties); /** * @brief Update a registered property. * * Update a property which already registered by register_properties () method. * * @param property the property to be updated. */ void update_property (const Property &property); /** * @brief Generate a short beep. */ void beep (); /** * @brief Start a Client Helper process. * * @param helper_uuid The UUID of the Helper object. */ void start_helper (const String &helper_uuid); /** * @brief Stop a Client Helper process which was started by start_helper. * * @param helper_uuid The UUID of the Helper object. */ void stop_helper (const String &helper_uuid); /** * @brief Send an events transaction to a client helper process. * * @param helper_uuid The UUID of the Helper object. * @param trans The transaction which contains events. */ void send_helper_event (const String &helper_uuid, const Transaction &trans); /** * @brief Retrieves context around the insertion point. * * Input methods typically want context in order to constrain * input text based on existing text; * this is important for languages such as Thai where * only some sequences of characters are allowed. * * Unlike other signal activation actions, this action will return the result * immediately. * * @param text location to store the context string around the insertion point. * @param cursor location to store index of the insertion cursor within @text. * @param maxlen_before the maxmium length of context string to be retrieved * before the cursor; -1 means unlimited. * @param maxlen_after the maxmium length of context string to be retrieved * after the cursor; -1 means unlimited. * * @return true if surrounding text was provided. */ bool get_surrounding_text (WideString &text, int &cursor, int maxlen_before = -1, int maxlen_after = -1); /** * @brief Ask the client to delete characters around the cursor position. * * In order to use this function, you should first call * get_surrounding_text () to get the current context, and * call this function immediately afterwards to make sure that you * know what you are deleting. You should also account for the fact * that even if the signal was handled, the input context might not * have deleted all the characters that were requested to be deleted. * * @param offset offset from cursor position in chars; * a negative value means start before the cursor. * @param len number of characters to delete. * * @return true if the signal was handled. */ bool delete_surrounding_text (int offset, int len); /** @} */ }; /** * @brief A trivial IMEngine that do nothing. */ class DummyIMEngineFactory : public IMEngineFactoryBase { public: DummyIMEngineFactory (); virtual ~DummyIMEngineFactory (); virtual WideString get_name () const; virtual String get_uuid () const; virtual String get_icon_file () const; virtual WideString get_authors () const; virtual WideString get_credits () const; virtual WideString get_help () const; virtual bool validate_encoding (const String& encoding) const; virtual bool validate_locale (const String& locale) const; virtual IMEngineInstancePointer create_instance (const String& encoding, int id = -1); }; class DummyIMEngineInstance : public IMEngineInstanceBase { public: DummyIMEngineInstance (DummyIMEngineFactory *factory, const String &encoding, int id = -1); virtual ~DummyIMEngineInstance (); virtual bool process_key_event (const KeyEvent& key); virtual void focus_in (); }; /** @} */ } // namespace scim #endif //__SCIM_IMENGINE_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_imengine.cpp0000644000175000017500000004120512422143415016242 0ustar tzhuantzhuan/** @file scim_imengine.cpp * @brief Implementation of class IMEngineFactoryBase and IMEngineInstanceBase. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_imengine.cpp,v 1.15 2005/04/08 15:24:11 suzhe Exp $ * */ #define Uses_SCIM_IMENGINE #define Uses_C_CTYPE #include "scim_private.h" #include "scim.h" #define SCIM_KEYBOARD_ICON_FILE (SCIM_ICONDIR "/keyboard.png") namespace scim { typedef Signal1 IMEngineSignalVoid; typedef Signal2 IMEngineSignalInt; typedef Signal2 IMEngineSignalBool; typedef Signal2 IMEngineSignalString; typedef Signal2 IMEngineSignalWideString; typedef Signal2 IMEngineSignalKeyEvent; typedef Signal2 IMEngineSignalProperty; typedef Signal2 IMEngineSignalPropertyList; typedef Signal2 IMEngineSignalLookupTable; typedef Signal3 IMEngineSignalStringTransaction; typedef Signal3 IMEngineSignalWideStringAttributeList; typedef Signal5 IMEngineSignalGetSurroundingText; typedef Signal3 IMEngineSignalDeleteSurroundingText; class IMEngineFactoryBase::IMEngineFactoryBaseImpl { public: std::vector m_encoding_list; std::vector m_locale_list; String m_language; }; class IMEngineInstanceBase::IMEngineInstanceBaseImpl { public: IMEngineFactoryPointer m_factory; String m_encoding; IMEngineSignalVoid m_signal_show_preedit_string; IMEngineSignalVoid m_signal_show_aux_string; IMEngineSignalVoid m_signal_show_lookup_table; IMEngineSignalVoid m_signal_hide_preedit_string; IMEngineSignalVoid m_signal_hide_aux_string; IMEngineSignalVoid m_signal_hide_lookup_table; IMEngineSignalInt m_signal_update_preedit_caret; IMEngineSignalWideStringAttributeList m_signal_update_preedit_string; IMEngineSignalWideStringAttributeList m_signal_update_aux_string; IMEngineSignalWideString m_signal_commit_string; IMEngineSignalLookupTable m_signal_update_lookup_table; IMEngineSignalKeyEvent m_signal_forward_key_event; IMEngineSignalPropertyList m_signal_register_properties; IMEngineSignalProperty m_signal_update_property; IMEngineSignalVoid m_signal_beep; IMEngineSignalString m_signal_start_helper; IMEngineSignalString m_signal_stop_helper; IMEngineSignalStringTransaction m_signal_send_helper_event; IMEngineSignalGetSurroundingText m_signal_get_surrounding_text; IMEngineSignalDeleteSurroundingText m_signal_delete_surrounding_text; int m_id; void * m_frontend_data; IMEngineInstanceBaseImpl () : m_id (0), m_frontend_data (0) { } }; IMEngineFactoryBase::IMEngineFactoryBase () : m_impl (new IMEngineFactoryBaseImpl ()) { } IMEngineFactoryBase::~IMEngineFactoryBase () { delete m_impl; } bool IMEngineFactoryBase::validate_encoding (const String& encoding) const { if (encoding == "UTF-8") return true; for (size_t i=0; im_encoding_list.size (); ++i) if (m_impl->m_encoding_list [i] == encoding) return true; return false; } bool IMEngineFactoryBase::validate_locale (const String& locale) const { for (size_t i=0; im_locale_list.size (); ++i) if (m_impl->m_locale_list [i] == locale) return true; if (scim_get_locale_encoding (locale) == "UTF-8") return true; return false; } String IMEngineFactoryBase::get_language () const { return m_impl->m_language; } WideString IMEngineFactoryBase::inverse_query (const WideString &str) { return WideString (); } String IMEngineFactoryBase::get_encodings () const { return scim_combine_string_list (m_impl->m_encoding_list); } String IMEngineFactoryBase::get_locales () const { return scim_combine_string_list (m_impl->m_locale_list); } String IMEngineFactoryBase::get_default_encoding () const { if (m_impl->m_encoding_list.size ()) return m_impl->m_encoding_list [0]; return String ("UTF-8"); } String IMEngineFactoryBase::get_default_locale () const { if (m_impl->m_locale_list.size ()) return m_impl->m_locale_list [0]; return String (""); } void IMEngineFactoryBase::set_locales (const String& locales) { m_impl->m_locale_list.clear (); m_impl->m_encoding_list.clear (); if (locales.size () == 0) return; String locale; std::vector lc_list; scim_split_string_list (lc_list, locales); for (size_t i=0; im_locale_list.push_back (locale); m_impl->m_encoding_list.push_back (scim_get_locale_encoding (locale)); } } m_impl->m_language = scim_get_locale_language (get_default_locale ()); } void IMEngineFactoryBase::set_languages (const String& languages) { std::vector lang_list; String locales; String all_locales; scim_split_string_list (lang_list, languages, ','); for (size_t i = 0; i < lang_list.size (); ++ i) { locales = scim_get_language_locales (lang_list [i]); if (locales.length ()) { if (all_locales.length ()) all_locales.push_back (','); all_locales += locales; } } if (all_locales.length ()) set_locales (all_locales); if (lang_list.size ()) m_impl->m_language = scim_validate_language (lang_list [0]); } IMEngineInstanceBase::IMEngineInstanceBase (IMEngineFactoryBase *factory, const String &encoding, int id) : m_impl (new IMEngineInstanceBaseImpl ()) { m_impl->m_factory = factory; m_impl->m_encoding = encoding; m_impl->m_id = id; if (!m_impl->m_factory.null ()) { if (!m_impl->m_factory->validate_encoding (encoding)) { m_impl->m_encoding = m_impl->m_factory->get_default_encoding (); } } else { m_impl->m_encoding = String ("UTF-8"); } } IMEngineInstanceBase::~IMEngineInstanceBase () { delete m_impl; } bool IMEngineInstanceBase::set_encoding (const String &encoding) { if (!m_impl->m_factory.null () && m_impl->m_factory->validate_encoding (encoding)) { m_impl->m_encoding = encoding; return true; } return false; } String IMEngineInstanceBase::get_encoding () const { return m_impl->m_encoding; } int IMEngineInstanceBase::get_id () const { return m_impl->m_id; } String IMEngineInstanceBase::get_factory_uuid () const { if (!m_impl->m_factory.null ()) return m_impl->m_factory->get_uuid (); return String (); } void IMEngineInstanceBase::set_frontend_data (void *data) { m_impl->m_frontend_data = data; } void * IMEngineInstanceBase::get_frontend_data (void) { return m_impl->m_frontend_data; } void IMEngineInstanceBase::move_preedit_caret (unsigned int) { } void IMEngineInstanceBase::select_candidate (unsigned int) { } void IMEngineInstanceBase::update_lookup_table_page_size (unsigned int) { } void IMEngineInstanceBase::lookup_table_page_up () { } void IMEngineInstanceBase::lookup_table_page_down () { } void IMEngineInstanceBase::reset () { } void IMEngineInstanceBase::focus_in () { } void IMEngineInstanceBase::focus_out () { } void IMEngineInstanceBase::trigger_property (const String &) { } void IMEngineInstanceBase::process_helper_event (const String &, const Transaction &) { } void IMEngineInstanceBase::update_client_capabilities (unsigned int /*cap*/) { } Connection IMEngineInstanceBase::signal_connect_show_preedit_string (IMEngineSlotVoid *slot) { return m_impl->m_signal_show_preedit_string.connect (slot); } Connection IMEngineInstanceBase::signal_connect_show_aux_string (IMEngineSlotVoid *slot) { return m_impl->m_signal_show_aux_string.connect (slot); } Connection IMEngineInstanceBase::signal_connect_show_lookup_table (IMEngineSlotVoid *slot) { return m_impl->m_signal_show_lookup_table.connect (slot); } Connection IMEngineInstanceBase::signal_connect_hide_preedit_string (IMEngineSlotVoid *slot) { return m_impl->m_signal_hide_preedit_string.connect (slot); } Connection IMEngineInstanceBase::signal_connect_hide_aux_string (IMEngineSlotVoid *slot) { return m_impl->m_signal_hide_aux_string.connect (slot); } Connection IMEngineInstanceBase::signal_connect_hide_lookup_table (IMEngineSlotVoid *slot) { return m_impl->m_signal_hide_lookup_table.connect (slot); } Connection IMEngineInstanceBase::signal_connect_update_preedit_caret (IMEngineSlotInt *slot) { return m_impl->m_signal_update_preedit_caret.connect (slot); } Connection IMEngineInstanceBase::signal_connect_update_preedit_string (IMEngineSlotWideStringAttributeList *slot) { return m_impl->m_signal_update_preedit_string.connect (slot); } Connection IMEngineInstanceBase::signal_connect_update_aux_string (IMEngineSlotWideStringAttributeList *slot) { return m_impl->m_signal_update_aux_string.connect (slot); } Connection IMEngineInstanceBase::signal_connect_update_lookup_table (IMEngineSlotLookupTable *slot) { return m_impl->m_signal_update_lookup_table.connect (slot); } Connection IMEngineInstanceBase::signal_connect_commit_string (IMEngineSlotWideString *slot) { return m_impl->m_signal_commit_string.connect (slot); } Connection IMEngineInstanceBase::signal_connect_forward_key_event (IMEngineSlotKeyEvent *slot) { return m_impl->m_signal_forward_key_event.connect (slot); } Connection IMEngineInstanceBase::signal_connect_register_properties (IMEngineSlotPropertyList *slot) { return m_impl->m_signal_register_properties.connect (slot); } Connection IMEngineInstanceBase::signal_connect_update_property (IMEngineSlotProperty *slot) { return m_impl->m_signal_update_property.connect (slot); } Connection IMEngineInstanceBase::signal_connect_beep (IMEngineSlotVoid *slot) { return m_impl->m_signal_beep.connect (slot); } Connection IMEngineInstanceBase::signal_connect_start_helper (IMEngineSlotString *slot) { return m_impl->m_signal_start_helper.connect (slot); } Connection IMEngineInstanceBase::signal_connect_stop_helper (IMEngineSlotString *slot) { return m_impl->m_signal_stop_helper.connect (slot); } Connection IMEngineInstanceBase::signal_connect_send_helper_event (IMEngineSlotStringTransaction *slot) { return m_impl->m_signal_send_helper_event.connect (slot); } Connection IMEngineInstanceBase::signal_connect_get_surrounding_text (IMEngineSlotGetSurroundingText *slot) { return m_impl->m_signal_get_surrounding_text.connect (slot); } Connection IMEngineInstanceBase::signal_connect_delete_surrounding_text (IMEngineSlotDeleteSurroundingText *slot) { return m_impl->m_signal_delete_surrounding_text.connect (slot); } void IMEngineInstanceBase::show_preedit_string () { m_impl->m_signal_show_preedit_string (this); } void IMEngineInstanceBase::show_aux_string () { m_impl->m_signal_show_aux_string (this); } void IMEngineInstanceBase::show_lookup_table () { m_impl->m_signal_show_lookup_table (this); } void IMEngineInstanceBase::hide_preedit_string () { m_impl->m_signal_hide_preedit_string (this); } void IMEngineInstanceBase::hide_aux_string () { m_impl->m_signal_hide_aux_string (this); } void IMEngineInstanceBase::hide_lookup_table () { m_impl->m_signal_hide_lookup_table (this); } void IMEngineInstanceBase::update_preedit_caret (int caret) { m_impl->m_signal_update_preedit_caret (this, caret); } void IMEngineInstanceBase::update_preedit_string (const WideString &str, const AttributeList &attrs) { m_impl->m_signal_update_preedit_string (this, str, attrs); } void IMEngineInstanceBase::update_aux_string (const WideString &str, const AttributeList &attrs) { m_impl->m_signal_update_aux_string (this, str, attrs); } void IMEngineInstanceBase::update_lookup_table (const LookupTable &table) { m_impl->m_signal_update_lookup_table (this, table); } void IMEngineInstanceBase::commit_string (const WideString &str) { m_impl->m_signal_commit_string (this, str); } void IMEngineInstanceBase::forward_key_event (const KeyEvent &key) { m_impl->m_signal_forward_key_event (this, key); } void IMEngineInstanceBase::register_properties (const PropertyList &properties) { m_impl->m_signal_register_properties (this, properties); } void IMEngineInstanceBase::update_property (const Property &property) { m_impl->m_signal_update_property (this, property); } void IMEngineInstanceBase::beep () { m_impl->m_signal_beep (this); } void IMEngineInstanceBase::start_helper (const String &helper_uuid) { m_impl->m_signal_start_helper (this, helper_uuid); } void IMEngineInstanceBase::stop_helper (const String &helper_uuid) { m_impl->m_signal_stop_helper (this, helper_uuid); } void IMEngineInstanceBase::send_helper_event (const String &helper_uuid, const Transaction &trans) { m_impl->m_signal_send_helper_event (this, helper_uuid, trans); } bool IMEngineInstanceBase::get_surrounding_text (WideString &text, int &cursor, int maxlen_before, int maxlen_after) { text = WideString (); cursor = 0; if (maxlen_before == 0 && maxlen_after == 0) return false; if (m_impl->m_signal_get_surrounding_text (this, text, cursor, maxlen_before, maxlen_after) && text.length ()) return true; return false; } bool IMEngineInstanceBase::delete_surrounding_text (int offset, int len) { return m_impl->m_signal_delete_surrounding_text (this, offset, len); } // implementation of DummyIMEngine DummyIMEngineFactory::DummyIMEngineFactory () { set_locales ("C"); } DummyIMEngineFactory::~DummyIMEngineFactory () { } WideString DummyIMEngineFactory::get_name () const { return utf8_mbstowcs (_("English/Keyboard")); } WideString DummyIMEngineFactory::get_authors () const { return WideString (); } WideString DummyIMEngineFactory::get_credits () const { return WideString (); } WideString DummyIMEngineFactory::get_help () const { return WideString (); } String DummyIMEngineFactory::get_uuid () const { return String ("0148bcec-850d-45f2-ba95-a493bb31492e"); } String DummyIMEngineFactory::get_icon_file () const { return String (SCIM_KEYBOARD_ICON_FILE); } bool DummyIMEngineFactory::validate_encoding (const String& encoding) const { return true; } bool DummyIMEngineFactory::validate_locale (const String& locale) const { return true; } IMEngineInstancePointer DummyIMEngineFactory::create_instance (const String& encoding, int id) { return new DummyIMEngineInstance (this, encoding, id); } DummyIMEngineInstance::DummyIMEngineInstance (DummyIMEngineFactory *factory, const String& encoding, int id) : IMEngineInstanceBase (factory, encoding, id) { } DummyIMEngineInstance::~DummyIMEngineInstance () { } bool DummyIMEngineInstance::process_key_event (const KeyEvent& key) { return false; } void DummyIMEngineInstance::focus_in () { register_properties (PropertyList ()); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_iconv.h0000644000175000017500000001117012422143415015230 0ustar tzhuantzhuan/** @file scim_iconv.h * @brief definition of IConvert related classes. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_iconv.h,v 1.18 2005/08/15 12:45:46 suzhe Exp $ */ #ifndef __SCIM_ICONVERT_H #define __SCIM_ICONVERT_H namespace scim { /** * @addtogroup Accessories * @{ */ #define SCIM_MAX_BUFSIZE 4096 /** * @brief A class to convert strings between UCS-4 and local encodings. */ class IConvert { class IConvertImpl; IConvertImpl * m_impl; public: /** * @brief Constructor * @param encoding the local encoding to be used. */ IConvert (const String& encoding = String ()); /** * @brief Copy constructor */ IConvert (const IConvert & iconvert); ~IConvert (); /** * @brief Assign operator */ const IConvert & operator = (const IConvert & iconvert); /** * @brief Set the working local encoding. * @param encoding the local encoding to be used. * @return whether the encoding is ok or not. */ bool set_encoding (const String& encoding); /** * @brief Get the current working local encoding. * @return The name of the local encoding, like "UTF-8", "GB2312" etc. */ String get_encoding () const; /** * @brief Convert a UCS-4 encoded WideString into a local encoded String. * @param dest the result string will be stored here. * @param src the WideString to be converted. * @return true if success. */ bool convert (String &dest, const WideString &src) const; /** * @brief Convert a UCS-4 encoded WideString into a local encoded String. * @param dest the result string will be stored here. * @param src the ucs-4 encoded string to be converted. * @param src_len the length of source string. * @return true if success. */ bool convert (String &dest, const ucs4_t *src, int src_len) const; /** * @brief Convert a local encoded String into a UCS-4 encoded WideString. * @param dest the result string will be stored here. * @param src the local encoded string to be converted. * @return ture if success. */ bool convert (WideString &dest, const String &src) const; /** * @brief Convert a local encoded String into a UCS-4 encoded WideString. * @param dest the result string will be stored here. * @param src the local encoded string to be converted. * @param src_len the length of source string. * @return ture if success. */ bool convert (WideString &dest, const char *src, int src_len) const; /** * @brief Test if a UCS-4 encoded WideString can be converted to a local encoded String. * @param src the ucs-4 encoded string to be test. * @return true if it can be converted without any problem. */ bool test_convert (const WideString &src) const; /** * @brief Test if a ucs-4 encoded string can be converted to a local encoded String. * @param src the ucs-4 encoded string to be test. * @param src_len the length of source string. * @return true if it can be converted without any problem. */ bool test_convert (const ucs4_t *src, int src_len) const; /** * @brief Test if a local encoded string can be converted to a UCS-4 encoded WideString. * @param src the local encoded string to be test. * @return true if it can be converted without any problem. */ bool test_convert (const String &src) const; /** * @brief Test if a local encoded string can be converted to a UCS-4 encoded WideString. * @param src the local encoded string to be test. * @param src_len the length of source string. * @return true if it can be converted without any problem. */ bool test_convert (const char *src, int src_len) const; }; /** @} */ } // namespace scim #endif //__SCIM_ICONVERT_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_iconv.cpp0000644000175000017500000001573312422143415015574 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_iconv.cpp,v 1.18.2.1 2007/04/14 08:35:54 suzhe Exp $ * */ #define Uses_SCIM_ICONV #define Uses_C_LIMITS #include "scim_private.h" #include "scim.h" namespace scim { struct IConvert::IConvertImpl { String m_encoding; iconv_t m_iconv_from_unicode; iconv_t m_iconv_to_unicode; IConvertImpl () : m_iconv_from_unicode ((iconv_t)-1), m_iconv_to_unicode ((iconv_t)-1) { } ~IConvertImpl () { if (m_iconv_from_unicode != (iconv_t) -1) iconv_close (m_iconv_from_unicode); if (m_iconv_to_unicode != (iconv_t) -1) iconv_close (m_iconv_to_unicode); } }; IConvert::IConvert (const String& encoding) : m_impl (new IConvertImpl) { set_encoding (encoding); } IConvert::IConvert (const IConvert & iconvert) : m_impl (new IConvertImpl) { set_encoding (iconvert.m_impl->m_encoding); } IConvert::~IConvert () { delete m_impl; } const IConvert & IConvert::operator= (const IConvert & iconvert) { if (this != &iconvert) set_encoding (iconvert.m_impl->m_encoding); return *this; } bool IConvert::set_encoding (const String& encoding) { if (encoding.length () == 0) { if (m_impl->m_iconv_from_unicode != (iconv_t) -1) iconv_close (m_impl->m_iconv_from_unicode); if (m_impl->m_iconv_to_unicode != (iconv_t) -1) iconv_close (m_impl->m_iconv_to_unicode); m_impl->m_iconv_from_unicode = (iconv_t) -1; m_impl->m_iconv_to_unicode = (iconv_t) -1; return true; } if (m_impl->m_iconv_from_unicode != (iconv_t) -1 && m_impl->m_iconv_to_unicode != (iconv_t) -1 && encoding == m_impl->m_encoding) return true; iconv_t new_iconv_from_unicode; iconv_t new_iconv_to_unicode; if (scim_is_little_endian ()) { new_iconv_from_unicode = iconv_open (encoding.c_str (), "UCS-4LE"); new_iconv_to_unicode = iconv_open ("UCS-4LE", encoding.c_str ()); } else { new_iconv_from_unicode = iconv_open (encoding.c_str (), "UCS-4BE"); new_iconv_to_unicode = iconv_open ("UCS-4BE", encoding.c_str ()); } if (new_iconv_from_unicode == (iconv_t) -1 || new_iconv_to_unicode == (iconv_t) -1) { if (new_iconv_from_unicode != (iconv_t) -1) iconv_close (new_iconv_from_unicode); if (new_iconv_to_unicode != (iconv_t) -1) iconv_close (new_iconv_to_unicode); return false; } if (m_impl->m_iconv_from_unicode != (iconv_t) -1) iconv_close (m_impl->m_iconv_from_unicode); if (m_impl->m_iconv_to_unicode != (iconv_t) -1) iconv_close (m_impl->m_iconv_to_unicode); m_impl->m_iconv_from_unicode = new_iconv_from_unicode; m_impl->m_iconv_to_unicode = new_iconv_to_unicode; m_impl->m_encoding = encoding; return true; } String IConvert::get_encoding () const { return m_impl->m_encoding; } bool IConvert::convert (String &dest, const ucs4_t *src, int src_len) const { if (m_impl->m_iconv_from_unicode == (iconv_t) -1) return false; char dest_buf [SCIM_MAX_BUFSIZE * MB_LEN_MAX]; size_t dest_buf_size = 0; size_t src_buf_size = 0; size_t ret; iconv (m_impl->m_iconv_from_unicode, 0, &src_buf_size, 0, &dest_buf_size); char *dest_buf_ptr = dest_buf; ICONV_CONST char *src_buf_ptr = (ICONV_CONST char*) src; dest_buf_size = SCIM_MAX_BUFSIZE * MB_LEN_MAX; src_buf_size = src_len * sizeof (ucs4_t); ret = iconv (m_impl->m_iconv_from_unicode, &src_buf_ptr, &src_buf_size, &dest_buf_ptr, &dest_buf_size); dest.assign (dest_buf, dest_buf_ptr); return ret != (size_t) -1; } bool IConvert::convert (String &dest, const WideString &src) const { return convert (dest, src.data (), src.length ()); } bool IConvert::test_convert (const ucs4_t *src, int src_len) const { if (m_impl->m_iconv_from_unicode == (iconv_t) -1) return false; char dest_buf [SCIM_MAX_BUFSIZE * MB_LEN_MAX]; size_t src_buf_size = 0; size_t dest_buf_size = 0; size_t ret; iconv (m_impl->m_iconv_from_unicode, 0, &src_buf_size, 0, &dest_buf_size); char *dest_buf_ptr = dest_buf; ICONV_CONST char *src_buf_ptr = (ICONV_CONST char*) src; src_buf_size = src_len * sizeof (ucs4_t); dest_buf_size = SCIM_MAX_BUFSIZE * MB_LEN_MAX; ret = iconv (m_impl->m_iconv_from_unicode, &src_buf_ptr, &src_buf_size, &dest_buf_ptr, &dest_buf_size); return ret != (size_t) -1; } bool IConvert::test_convert (const WideString &src) const { return test_convert (src.data (), src.length ()); } bool IConvert::convert (WideString &dest, const char *src, int src_len) const { if (m_impl->m_iconv_to_unicode == (iconv_t) -1) return false; ucs4_t dest_buf [SCIM_MAX_BUFSIZE]; size_t dest_buf_size = 0; size_t src_buf_size = 0; size_t ret; iconv (m_impl->m_iconv_to_unicode, 0, &src_buf_size, 0, &dest_buf_size); char *dest_buf_ptr = (char*) dest_buf; ICONV_CONST char *src_buf_ptr = (ICONV_CONST char*) src; dest_buf_size = SCIM_MAX_BUFSIZE * sizeof (ucs4_t); src_buf_size = src_len; ret = iconv (m_impl->m_iconv_to_unicode, &src_buf_ptr, &src_buf_size, &dest_buf_ptr, &dest_buf_size); dest.assign (dest_buf, (ucs4_t*) dest_buf_ptr); return ret != (size_t) -1; } bool IConvert::convert (WideString &dest, const String &src) const { return convert (dest, src.data (), src.length ()); } bool IConvert::test_convert (const char *src, int src_len) const { if (m_impl->m_iconv_to_unicode == (iconv_t) -1) return false; ucs4_t dest_buf [SCIM_MAX_BUFSIZE]; size_t src_buf_size = 0; size_t dest_buf_size = 0; size_t ret; iconv (m_impl->m_iconv_from_unicode, 0, &src_buf_size, 0, &dest_buf_size); char *dest_buf_ptr = (char*) dest_buf; ICONV_CONST char *src_buf_ptr = (ICONV_CONST char*) src; src_buf_size = src_len; dest_buf_size = SCIM_MAX_BUFSIZE * sizeof (ucs4_t); ret = iconv (m_impl->m_iconv_to_unicode, &src_buf_ptr, &src_buf_size, &dest_buf_ptr, &dest_buf_size); return ret != (size_t) -1; } bool IConvert::test_convert (const String &src) const { return test_convert (src.data (), src.length ()); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_hotkey.h0000644000175000017500000002572512422143415015430 0ustar tzhuantzhuan/** * @file scim_hotkey.h * @brief Defines the scim::HotkeyMatcher and scim::IMEngineHotkeyMatcher classes. */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_hotkey.h,v 1.5 2005/10/06 18:02:06 liuspider Exp $ */ #ifndef __SCIM_HOTKEY_H #define __SCIM_HOTKEY_H namespace scim { /** * @addtogroup Accessories * @{ */ /** * @brief This class is used to match a KeyEvent among a set of hotkeys. * * This class keeps the key event history so that it can match any kind of * key events, including key release events, correctly. * * If there are large amount of hotkeys to be matched, this class can provide * very good performance. */ class HotkeyMatcher { class HotkeyMatcherImpl; HotkeyMatcherImpl *m_impl; HotkeyMatcher (const HotkeyMatcher &); const HotkeyMatcher & operator = (const HotkeyMatcher &); public: /** * @brief Constructor */ HotkeyMatcher (); /** * @brief Destructor. */ ~HotkeyMatcher (); /** * @brief Add a Hotkey into this HotkeyMatcher. * * If a same Hotkey was already added, then it'll be replaced by this new one. * * @param key A Hotkey to be added. * @param id An id to be binded to this Hotkey. */ void add_hotkey (const KeyEvent &key, int id); /** * @brief Add a set of Hotkeys into this HotkeyMatcher. * * If a same Hotkey in the list was already added, then it'll be replaced by the new one. * * @param keys A set of Hotkeys to be added. * @param id An id to be binded to these Hotkeys. */ void add_hotkeys (const KeyEventList &keys, int id); /** * @brief Find all Hotkeys binded to a specific id. * * @param id The id to be found. * @param keys A KeyEventList object to hold all KeyEvents binded to the id. * @return The number of Hotkeys found. */ size_t find_hotkeys (int id, KeyEventList &keys) const; /** * @brief Get all Hotkeys added into this HotkeyMatcher. * * @param keys A KeyEventList object to hold all KeyEvents. * @param ids A int list to hold all corresponding IDs. * * @return The number of available Hotkeys. */ size_t get_all_hotkeys (KeyEventList &keys, std::vector &ids) const; /** * @brief Reset the HotkeyMatcher. * * The KeyEvent queue will be cleared, all state will be reset. * The Hotkeys which were already added will not be touched. */ void reset (void); /** * @brief Clear all Hotkeys. */ void clear (void); /** * @brief Push a KeyEvent into the queue. * * This KeyEvent will be matched against the available Hotkeys immediately. * * @param key The key to be pushed into. */ void push_key_event (const KeyEvent &key); /** * @brief Check if the last KeyEvent pushed by push_key_event () matched with any Hotkey. * * @return true If the KeyEvent matched with a Hotkey. */ bool is_matched (void) const; /** * @brief Get the match result. * * @return The corresponding id of the matched Hotkey. If no Hotkey was matched, return -1. */ int get_match_result (void) const; }; /** * @brief This class hold all Hotkeys for each IMEngines. */ class IMEngineHotkeyMatcher { class IMEngineHotkeyMatcherImpl; IMEngineHotkeyMatcherImpl *m_impl; IMEngineHotkeyMatcher (const IMEngineHotkeyMatcher &); const IMEngineHotkeyMatcher & operator = (const IMEngineHotkeyMatcher &); public: IMEngineHotkeyMatcher (); ~IMEngineHotkeyMatcher (); /** * @brief Load all Hotkeys for IMEngines from Config. * * @param config The Config object in which the Hotkeys are stored. */ void load_hotkeys (const ConfigPointer &config); /** * @brief Save all Hotkeys for IMEngines to Config. * * @param config Store all Hotkeys to this Config object. */ void save_hotkeys (const ConfigPointer &config) const; /** * @brief Add a Hotkey for an IMEngine into this IMEngineHotkeyMatcher. * * @param key The Hotkey. * @param uuid The UUID of the corresponding IMEngine. */ void add_hotkey (const KeyEvent &key, const String &uuid); /** * @brief Add a set of Hotkeys for an IMEngine into this IMEngineHotkeyMatcher. * * @param keys The Hotkeys. * @param uuid The UUID of the corresponding IMEngine. */ void add_hotkeys (const KeyEventList &keys, const String &uuid); /** * @brief Find all Hotkeys binded to a specific IMEngine UUID. * * @param uuid The IMEngine uuid to be found. * @param keys A KeyEventList object to hold all KeyEvents binded to the uuid. * @return The number of Hotkeys found. */ size_t find_hotkeys (const String &uuid, KeyEventList &keys) const; /** * @brief Get all hotkeys in this IMEngineHotkeyMatcher. * * @param keys A list of all Hotkeys. * @param uuids A list of all corresponding IMEngine UUIDs. * @return the number of hotkeys found. */ size_t get_all_hotkeys (KeyEventList &keys, std::vector &uuids) const; /** * @brief Reset the IMEngineHotkeyMatcher. * * The KeyEvent queue will be cleared, all state will be reset. * The Hotkeys which were already added will not be touched. */ void reset (void); /** * @brief Clear all Hotkeys and reset the IMEngineHotkeyMatcher. */ void clear (void); /** * @brief Push a KeyEvent into the queue. * * This KeyEvent will be matched against the available Hotkeys immediately. * * @param key The key to be pushed into. */ void push_key_event (const KeyEvent &key); /** * @brief Check if the last KeyEvent pushed by push_key_event () matched with any Hotkey. * * @return true If the KeyEvent matched with a Hotkey. */ bool is_matched (void) const; /** * @brief Get the match result. * * @return The corresponding UUID of the matched Hotkey. If no Hotkey was matched, return null string. */ String get_match_result (void) const; }; /** * @brief FrontEnd actions which could be binded with Hotkeys. */ enum FrontEndHotkeyAction { SCIM_FRONTEND_HOTKEY_NOOP = 0, /**< No action */ SCIM_FRONTEND_HOTKEY_TRIGGER = 1, /**< Turn on/off the input method. */ SCIM_FRONTEND_HOTKEY_ON = 2, /**< Turn on the input method. */ SCIM_FRONTEND_HOTKEY_OFF = 3, /**< Turn off the input method. */ SCIM_FRONTEND_HOTKEY_NEXT_FACTORY = 4, /**< Switch current Input Context to use the next available IMEngine Factory. */ SCIM_FRONTEND_HOTKEY_PREVIOUS_FACTORY = 5, /**< Switch current Input Context to use the previous available IMEngine Factory. */ SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU = 6 /**< Show a menu of all available IMEngine Factories. */ }; /** * @brief This class hold all FrontEnd specific Hotkeys, such as trigger keys, on/off keys, etc. */ class FrontEndHotkeyMatcher { class FrontEndHotkeyMatcherImpl; FrontEndHotkeyMatcherImpl *m_impl; FrontEndHotkeyMatcher (const FrontEndHotkeyMatcher &); const FrontEndHotkeyMatcher & operator = (const FrontEndHotkeyMatcher &); public: FrontEndHotkeyMatcher (); ~FrontEndHotkeyMatcher (); /** * @brief Load all FrontEnd specific Hotkeys from Config. * * @param config The Config object in which the Hotkeys are stored. */ void load_hotkeys (const ConfigPointer &config); /** * @brief Save all FrontEnd specific Hotkeys to Config. * * @param config Store all Hotkeys to this Config object. */ void save_hotkeys (const ConfigPointer &config) const; /** * @brief Add a Hotkey for an FrontEnd into this FrontEndHotkeyMatcher. * * @param key The Hotkey. * @param action The action to do when the hotkey is matched. */ void add_hotkey (const KeyEvent &key, FrontEndHotkeyAction action); /** * @brief Add a set of Hotkeys for an FrontEnd into this FrontEndHotkeyMatcher. * * @param keys The Hotkeys. * @param action The action to do when the hotkey is matched. */ void add_hotkeys (const KeyEventList &keys, FrontEndHotkeyAction action); /** * @brief Find all Hotkeys binded to a specific action. * * @param action The action to be found. * @param keys A KeyEventList object to hold all KeyEvents binded to the action. * @return The number of Hotkeys found. */ size_t find_hotkeys (FrontEndHotkeyAction action, KeyEventList &keys) const; /** * @brief Get all hotkeys in this FrontEndHotkeyMatcher. * * @param keys A list of all Hotkeys. * @param actions A list of all corresponding actions */ size_t get_all_hotkeys (KeyEventList &keys, std::vector &actions) const; /** * @brief Reset the FrontEndHotkeyMatcher. * * The KeyEvent queue will be cleared, all state will be reset. * The Hotkeys which were already added will not be touched. */ void reset (void); /** * @brief Clear all Hotkeys and reset the FrontEndHotkeyMatcher. */ void clear (void); /** * @brief Push a KeyEvent into the queue. * * This KeyEvent will be matched against the available Hotkeys immediately. * * @param key The key to be pushed into. */ void push_key_event (const KeyEvent &key); /** * @brief Check if the last KeyEvent pushed by push_key_event () matched with any Hotkey. * * @return true If the KeyEvent matched with a Hotkey. */ bool is_matched (void) const; /** * @brief Get the match result. * * @return The corresponding action of the matched Hotkey. */ FrontEndHotkeyAction get_match_result (void) const; }; /** @} */ } // namespace scim #endif //__SCIM_HOTKEY_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_hotkey.cpp0000644000175000017500000002657012422143415015762 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_hotkey.cpp,v 1.8 2005/06/18 13:19:35 suzhe Exp $ */ #define Uses_SCIM_HOTKEY #include "scim_private.h" #include "scim.h" #include "scim_stl_map.h" namespace scim { struct scim_hash_keyevent { size_t operator () (const KeyEvent &key) const { return (key.code & 0xFFFF) | (((uint32)key.mask) << 16); } }; #if SCIM_USE_STL_EXT_HASH_MAP typedef __gnu_cxx::hash_map HotkeyRepository; #elif SCIM_USE_STL_HASH_MAP typedef std::hash_map HotkeyRepository; #else typedef std::map HotkeyRepository; #endif class HotkeyMatcher::HotkeyMatcherImpl { public: HotkeyRepository m_hotkeys; uint32 m_prev_code; bool m_matched; int m_result; HotkeyMatcherImpl () : m_prev_code (0), m_matched (false), m_result (-1) { } }; HotkeyMatcher::HotkeyMatcher () : m_impl (new HotkeyMatcherImpl ()) { } HotkeyMatcher::~HotkeyMatcher () { delete m_impl; } void HotkeyMatcher::add_hotkey (const KeyEvent &key, int id) { if (!key.empty ()) m_impl->m_hotkeys [key] = id; } void HotkeyMatcher::add_hotkeys (const KeyEventList &keys, int id) { for (KeyEventList::const_iterator it = keys.begin (); it != keys.end (); ++it) { if (!it->empty ()) m_impl->m_hotkeys [*it] = id; } } size_t HotkeyMatcher::get_all_hotkeys (KeyEventList &keys, std::vector &ids) const { keys.clear (); ids.clear (); for (HotkeyRepository::iterator it = m_impl->m_hotkeys.begin (); it != m_impl->m_hotkeys.end (); ++it) { keys.push_back (it->first); ids.push_back (it->second); } return keys.size (); } size_t HotkeyMatcher::find_hotkeys (int id, KeyEventList &keys) const { keys.clear (); for (HotkeyRepository::iterator it = m_impl->m_hotkeys.begin (); it != m_impl->m_hotkeys.end (); ++it) { if (it->second == id) keys.push_back (it->first); } return keys.size (); } void HotkeyMatcher::push_key_event (const KeyEvent &key) { HotkeyRepository::iterator it = m_impl->m_hotkeys.find (key); if (it != m_impl->m_hotkeys.end () && (!(key.mask & SCIM_KEY_ReleaseMask) || m_impl->m_prev_code == key.code)) { m_impl->m_matched = true; m_impl->m_result = it->second; } else { m_impl->m_matched = false; m_impl->m_result = -1; } m_impl->m_prev_code = key.code; } void HotkeyMatcher::reset (void) { m_impl->m_prev_code = 0; m_impl->m_matched = false; m_impl->m_result = -1; } void HotkeyMatcher::clear (void) { m_impl->m_hotkeys.clear (); reset (); } bool HotkeyMatcher::is_matched (void) const { return m_impl->m_matched; } int HotkeyMatcher::get_match_result (void) const { return m_impl->m_result; } //===================== IMEngineHotkeyMatcher ======================= class IMEngineHotkeyMatcher::IMEngineHotkeyMatcherImpl { public: HotkeyMatcher m_matcher; std::vector m_uuids; }; IMEngineHotkeyMatcher::IMEngineHotkeyMatcher () : m_impl (new IMEngineHotkeyMatcherImpl ()) { } IMEngineHotkeyMatcher::~IMEngineHotkeyMatcher () { delete m_impl; } void IMEngineHotkeyMatcher::load_hotkeys (const ConfigPointer &config) { clear (); if (config.null () || !config->valid ()) return; std::vector uuids; scim_split_string_list (uuids, config->read (String (SCIM_CONFIG_HOTKEYS_IMENGINE_LIST), String (""))); std::sort (uuids.begin (), uuids.end ()); uuids.erase (std::unique (uuids.begin (), uuids.end ()), uuids.end ()); if (uuids.size ()) { KeyEventList keys; for (std::vector ::iterator uit = uuids.begin (); uit != uuids.end (); ++uit) { if (scim_string_to_key_list (keys, config->read (String (SCIM_CONFIG_HOTKEYS_IMENGINE "/") + *uit, String ("")))) { m_impl->m_matcher.add_hotkeys (keys, (int) m_impl->m_uuids.size ()); m_impl->m_uuids.push_back (*uit); } } } } void IMEngineHotkeyMatcher::save_hotkeys (const ConfigPointer &config) const { if (config.null () || !config->valid () || !m_impl->m_uuids.size ()) return; KeyEventList keys; String keystr; std::vector uuids; for (size_t i = 0; i < m_impl->m_uuids.size (); ++i) { if (m_impl->m_matcher.find_hotkeys ((int) i, keys) > 0 && scim_key_list_to_string (keystr, keys)) { config->write (String (SCIM_CONFIG_HOTKEYS_IMENGINE "/") + m_impl->m_uuids [i], keystr); uuids.push_back (m_impl->m_uuids [i]); } } config->write (String (SCIM_CONFIG_HOTKEYS_IMENGINE_LIST), scim_combine_string_list (uuids)); } void IMEngineHotkeyMatcher::add_hotkey (const KeyEvent &key, const String &uuid) { if (key.empty () || !uuid.length ()) return; size_t i; for (i = 0; i < m_impl->m_uuids.size (); ++i) { if (m_impl->m_uuids [i] == uuid) break; } if (i == m_impl->m_uuids.size ()) m_impl->m_uuids.push_back (uuid); m_impl->m_matcher.add_hotkey (key, i); } void IMEngineHotkeyMatcher::add_hotkeys (const KeyEventList &keys, const String &uuid) { if (!keys.size () || !uuid.length ()) return; size_t i; for (i = 0; i < m_impl->m_uuids.size (); ++i) { if (m_impl->m_uuids [i] == uuid) break; } if (i == m_impl->m_uuids.size ()) m_impl->m_uuids.push_back (uuid); m_impl->m_matcher.add_hotkeys (keys, i); } size_t IMEngineHotkeyMatcher::find_hotkeys (const String &uuid, KeyEventList &keys) const { for (size_t i = 0; i < m_impl->m_uuids.size (); ++i) { if (m_impl->m_uuids [i] == uuid) return m_impl->m_matcher.find_hotkeys ((int) i, keys); } keys.clear (); return 0; } size_t IMEngineHotkeyMatcher::get_all_hotkeys (KeyEventList &keys, std::vector &uuids) const { keys.clear (); uuids.clear (); std::vector ids; if (m_impl->m_matcher.get_all_hotkeys (keys, ids) > 0) { for (size_t i = 0; i < ids.size (); ++i) uuids.push_back (m_impl->m_uuids [ids [i]]); } return keys.size (); } void IMEngineHotkeyMatcher::reset (void) { m_impl->m_matcher.reset (); } void IMEngineHotkeyMatcher::clear (void) { m_impl->m_matcher.clear (); m_impl->m_uuids.clear (); } void IMEngineHotkeyMatcher::push_key_event (const KeyEvent &key) { m_impl->m_matcher.push_key_event (key); } bool IMEngineHotkeyMatcher::is_matched (void) const { return m_impl->m_matcher.is_matched (); } String IMEngineHotkeyMatcher::get_match_result (void) const { int id = m_impl->m_matcher.get_match_result (); if (id >= 0 && id < (int) m_impl->m_uuids.size ()) return m_impl->m_uuids [id]; return String (); } //============================ FrontEndHotkeyMatcher ========================== static const char *__scim_frontend_hotkey_config_paths [] = { 0, SCIM_CONFIG_HOTKEYS_FRONTEND_TRIGGER, SCIM_CONFIG_HOTKEYS_FRONTEND_ON, SCIM_CONFIG_HOTKEYS_FRONTEND_OFF, SCIM_CONFIG_HOTKEYS_FRONTEND_NEXT_FACTORY, SCIM_CONFIG_HOTKEYS_FRONTEND_PREVIOUS_FACTORY, SCIM_CONFIG_HOTKEYS_FRONTEND_SHOW_FACTORY_MENU, 0 }; static const char *__scim_frontend_hotkey_defaults [] = { 0, "Control+space", "", "", "Control+Alt+Down,Control+Shift+Shift_L+KeyRelease,Control+Shift+Shift_R+KeyRelease", "Control+Alt+Up,Control+Shift+Control_L+KeyRelease,Control+Shift+Control_R+KeyRelease", "Control+Alt+Right", 0 }; class FrontEndHotkeyMatcher::FrontEndHotkeyMatcherImpl { public: HotkeyMatcher m_matcher; }; FrontEndHotkeyMatcher::FrontEndHotkeyMatcher () : m_impl (new FrontEndHotkeyMatcherImpl ()) { } FrontEndHotkeyMatcher::~FrontEndHotkeyMatcher () { delete m_impl; } void FrontEndHotkeyMatcher::load_hotkeys (const ConfigPointer &config) { clear (); if (config.null () || !config->valid ()) return; KeyEventList keys; // Load the least important hotkeys first. for (int i = SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU; i >= SCIM_FRONTEND_HOTKEY_TRIGGER; --i) { if (scim_string_to_key_list (keys, config->read (String (__scim_frontend_hotkey_config_paths [i]), String (__scim_frontend_hotkey_defaults [i])))) m_impl->m_matcher.add_hotkeys (keys, i); } } void FrontEndHotkeyMatcher::save_hotkeys (const ConfigPointer &config) const { if (config.null () || !config->valid ()) return; KeyEventList keys; String keystr; for (int i = SCIM_FRONTEND_HOTKEY_TRIGGER; i <= SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU; ++i) { if (m_impl->m_matcher.find_hotkeys (i, keys) > 0 && scim_key_list_to_string (keystr, keys)) config->write (String (__scim_frontend_hotkey_config_paths [i]), keystr); } } void FrontEndHotkeyMatcher::add_hotkey (const KeyEvent &key, FrontEndHotkeyAction action) { if (key.empty () || action < SCIM_FRONTEND_HOTKEY_TRIGGER || action > SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU) return; m_impl->m_matcher.add_hotkey (key, (int) action); } void FrontEndHotkeyMatcher::add_hotkeys (const KeyEventList &keys, FrontEndHotkeyAction action) { if (!keys.size () || action < SCIM_FRONTEND_HOTKEY_TRIGGER || action > SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU) return; m_impl->m_matcher.add_hotkeys (keys, (int) action); } size_t FrontEndHotkeyMatcher::find_hotkeys (FrontEndHotkeyAction action, KeyEventList &keys) const { return m_impl->m_matcher.find_hotkeys ((int) action, keys); } size_t FrontEndHotkeyMatcher::get_all_hotkeys (KeyEventList &keys, std::vector &actions) const { keys.clear (); actions.clear (); std::vector ids; m_impl->m_matcher.get_all_hotkeys (keys, ids); for (size_t i = 0; i < ids.size (); ++i) actions.push_back (static_cast (ids [i])); return keys.size (); } void FrontEndHotkeyMatcher::reset (void) { m_impl->m_matcher.reset (); } void FrontEndHotkeyMatcher::clear (void) { m_impl->m_matcher.clear (); } void FrontEndHotkeyMatcher::push_key_event (const KeyEvent &key) { m_impl->m_matcher.push_key_event (key); } bool FrontEndHotkeyMatcher::is_matched (void) const { return m_impl->m_matcher.is_matched (); } FrontEndHotkeyAction FrontEndHotkeyMatcher::get_match_result (void) const { int id = m_impl->m_matcher.get_match_result (); if (id >= SCIM_FRONTEND_HOTKEY_TRIGGER && id <= SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU) return static_cast (id); return SCIM_FRONTEND_HOTKEY_NOOP; } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_helper_module.h0000644000175000017500000001300612422143415016736 0ustar tzhuantzhuan/** * @file scim_helper_module.h * @brief Defines scim::HelperModule and it's related types. * * scim::HelperModule is a class used to load Client Helper modules. * */ /* * Smart Common Input Method * * Copyright (c) 2004-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_helper_module.h,v 1.6 2005/01/10 08:30:54 suzhe Exp $ */ #ifndef __SCIM_HELPER_MODULE_H #define __SCIM_HELPER_MODULE_H namespace scim { /** * @addtogroup Helper * @{ */ /** * @brief Get the number of Helpers in this module. * * A helper module can have multiple Helpers in it. * But each helper will run in its own process space. * * There must be a function called "scim_helper_module_number_of_helpers" * in each helper module which complies with this prototype. * This function name can have a prefix like kbd_LTX_, * in which "kbd" is the module's name. */ typedef unsigned int (*HelperModuleNumberOfHelpersFunc) (void); /** * @brief Get the information of a Helper. * * There must be a function called "scim_helper_module_get_helper_info" * in each helper module which complies with this prototype. * This function name can have a prefix like kbd_LTX_, * in which "kbd" is the module's name. * * @param idx The index of this helper, must between 0 to (the number of helpers) - 1. * @param info The HelperInfo object to store the information. * @return true if this Helper is valid and the correct information is stored into info. */ typedef bool (*HelperModuleGetHelperInfoFunc) (unsigned int idx, HelperInfo &info); /** * @brief Run a specific Helper. * * This function will be called within an independent process. * * There must be a function called "scim_helper_module_run_helper" * in each helper module which complies with this prototype. * This function name can have a prefix like kbd_LTX_, * in which "kbd" is the module's name. * * @param config The Config object should be used to read/write configurations. * @param uuid The UUID of the Helper to be run. * @param display The display in which this helper should run. */ typedef void (*HelperModuleRunHelperFunc) (const String &uuid, const ConfigPointer &config, const String &display); /** * @brief The class used to load a Helper module and run its Helpers. * * This class should not be used directly. HelperManager should be used instead. */ class HelperModule { Module m_module; HelperModuleNumberOfHelpersFunc m_number_of_helpers; HelperModuleGetHelperInfoFunc m_get_helper_info; HelperModuleRunHelperFunc m_run_helper; HelperModule (const HelperModule &); HelperModule & operator= (const HelperModule &); public: /** * @brief Constructor. * * @param name The name of the Helper module to be loaded. */ HelperModule (const String &name = String ("")); /** * @brief Load a Helper module. * * If a module has already been loaded, then it'll be unloaded first. * * @param name The name of the Helper module to be loaded. * @return true if success. */ bool load (const String &name); /** * @brief Unload the module. * * @return true if success. */ bool unload (); /** * @brief Check if a Helper module has been loaded successfully. * * @return true if a module has been loaded successfully. */ bool valid () const; /** * @brief Get the number of helpers supported by this module. * * @return the number of helpers supported by this module. */ unsigned int number_of_helpers () const; /** * @brief The the information of a specific helper. * * @param idx The index of the helper, must between 0 to number_of_helpers () - 1. * @param info The HeperInfo object to store the information. * @return true if this helper is ok and the information is stored into info successfully. */ bool get_helper_info (unsigned int idx, HelperInfo &info) const; /** * @brief Run a specific helper. * * The helper should be run in an independent process, this function will not return * until the helper exits. * * @param config The Config object to be used to read configurations. * @param uuid The UUID of the helper, which is returned by get_helper_info (). * @param display The display in which this helper should run. */ void run_helper (const String &uuid, const ConfigPointer &config, const String &display) const; }; /** * @brief Get a name list of currently available Helper modules. * @param mod_list - the result list will be stored here. * @return the number of the modules, equal to mod_list.size (). */ int scim_get_helper_module_list (std::vector &mod_list); /** @} */ } // namespace scim #endif //__SCIM_HELPER_MODULE_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_helper_module.cpp0000644000175000017500000000651512422143415017300 0ustar tzhuantzhuan/** @file scim_helper_module.cpp * @brief Implementation of class HelperModule. */ /* * Smart Common Input Method * * Copyright (c) 2004-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_helper_module.cpp,v 1.5 2005/01/05 13:41:10 suzhe Exp $ * */ #define Uses_SCIM_HELPER #define Uses_SCIM_HELPER_MODULE #define Uses_SCIM_CONFIG_MODULE #define Uses_C_STDLIB #include #include #include #include "scim_private.h" #include "scim.h" namespace scim { HelperModule::HelperModule (const String &name) : m_number_of_helpers (0), m_get_helper_info (0), m_run_helper (0) { if (name.length ()) load (name); } bool HelperModule::load (const String &name) { try { if (!m_module.load (name, "Helper")) return false; m_number_of_helpers = (HelperModuleNumberOfHelpersFunc) m_module.symbol ("scim_helper_module_number_of_helpers"); m_get_helper_info = (HelperModuleGetHelperInfoFunc) m_module.symbol ("scim_helper_module_get_helper_info"); m_run_helper = (HelperModuleRunHelperFunc) m_module.symbol ("scim_helper_module_run_helper"); if (!m_number_of_helpers || !m_get_helper_info || !m_run_helper) { m_module.unload (); m_number_of_helpers = 0; m_get_helper_info = 0; m_run_helper = 0; return false; } } catch (...) { m_module.unload (); m_number_of_helpers = 0; m_get_helper_info = 0; m_run_helper = 0; return false; } return true; } bool HelperModule::unload () { return m_module.unload (); } bool HelperModule::valid () const { return (m_module.valid () && m_number_of_helpers && m_get_helper_info && m_run_helper && m_number_of_helpers () > 0); } unsigned int HelperModule::number_of_helpers () const { if (m_module.valid () && m_number_of_helpers && m_get_helper_info && m_run_helper) return m_number_of_helpers (); return 0; } bool HelperModule::get_helper_info (unsigned int idx, HelperInfo &info) const { if (m_module.valid () && m_number_of_helpers && m_get_helper_info && m_run_helper) return m_get_helper_info (idx, info); return false; } void HelperModule::run_helper (const String &uuid, const ConfigPointer &config, const String &display) const { m_run_helper (uuid, config, display); } int scim_get_helper_module_list (std::vector &mod_list) { return scim_get_module_list (mod_list, "Helper"); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_helper_manager_server.cpp0000644000175000017500000003217712422143415021016 0ustar tzhuantzhuan/** @file scim_helper_manager_server.cpp * @brief Implementation of Helper Manager Server. */ /* * Smart Common Input Method * * Copyright (c) 2004-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_helper_manager_server.cpp,v 1.6 2005/01/30 13:24:12 suzhe Exp $ * */ #define Uses_SCIM_TRANSACTION #define Uses_SCIM_TRANS_COMMANDS #define Uses_SCIM_HELPER #define Uses_SCIM_HELPER_MODULE #define Uses_SCIM_SOCKET #define Uses_SCIM_EVENT #include #include #include #include #include "scim_private.h" #include "scim.h" #include "scim_stl_map.h" using namespace scim; ////////////////////////////////////////////////////////////////////////////// // Data type ////////////////////////////////////////////////////////////////////////////// enum ClientType { UNKNOWN_CLIENT, HELPER_MANAGER_CLIENT, }; struct ClientInfo { uint32 key; ClientType type; }; #if SCIM_USE_STL_EXT_HASH_MAP typedef __gnu_cxx::hash_map > ClientRepository; #elif SCIM_USE_STL_HASH_MAP typedef std::hash_map > ClientRepository; #else typedef std::map ClientRepository; #endif typedef std::vector < std::pair > HelperRepository; ////////////////////////////////////////////////////////////////////////////// // Data definition. ////////////////////////////////////////////////////////////////////////////// static ClientRepository __client_repository; static int __socket_timeout = -1; static bool __should_exit = false; static Transaction __recv_trans; static Transaction __send_trans; static HelperRepository __helpers; static SocketServer __socket_server; ////////////////////////////////////////////////////////////////////////////// // Function definition. ////////////////////////////////////////////////////////////////////////////// void load_helper_modules (void) { SCIM_DEBUG_MAIN (1) << "load_helper_modules ()\n"; std::vector mod_list; scim_get_helper_module_list (mod_list); // NOTE on FreeBSD if some module is loaded and unloaded right away here the following module crashes for some unknown reason // seems like some damage is being done by module.unload(); // so I added a workaround: have an array of modules and unload them all together in the end only. // TODO Need to figure out what's going on with this issue. if (mod_list.size ()) { HelperModule *module = new HelperModule[mod_list.size ()]; for (size_t i = 0; i < mod_list.size (); ++i) { SCIM_DEBUG_MAIN (2) << " Load module: " << mod_list [i] << "\n"; if (module[i].load (mod_list [i]) && module[i].valid ()) { HelperInfo info; size_t num = module[i].number_of_helpers (); SCIM_DEBUG_MAIN (2) << " Find " << num << " Helpers:\n"; for (size_t j = 0; j < num; ++j) { if (module[i].get_helper_info (j, info)) { SCIM_DEBUG_MAIN (3) << " " << info.uuid << ": " << info.name << "\n"; __helpers.push_back ( std::make_pair (info, mod_list [i]) ); } } } } for (size_t i = 0; i < mod_list.size (); ++i) { module[i].unload (); } delete[] module; } } void get_helper_list (const Socket &client) { HelperRepository::iterator it = __helpers.begin (); __send_trans.clear (); __send_trans.put_command (SCIM_TRANS_CMD_REPLY); __send_trans.put_data ((uint32)__helpers.size ()); for (; it != __helpers.end (); ++it) { __send_trans.put_data (it->first.uuid); __send_trans.put_data (it->first.name); __send_trans.put_data (it->first.icon); __send_trans.put_data (it->first.description); __send_trans.put_data (it->first.option); } __send_trans.write_to_socket (client); } #ifndef SCIM_HELPER_LAUNCHER_PROGRAM #define SCIM_HELPER_LAUNCHER_PROGRAM (SCIM_LIBEXECDIR "/scim-helper-launcher") #endif void run_helper (const String &uuid, const String &config, const String &display) { SCIM_DEBUG_MAIN(1) << "run_helper (" << uuid << "," << config << "," << display << ")\n"; for (size_t i = 0; i < __helpers.size (); ++i) { if (__helpers [i].first.uuid == uuid && __helpers [i].second.length ()) { int pid; pid = fork (); if (pid < 0) return; if (pid == 0) { char * argv [] = { const_cast (SCIM_HELPER_LAUNCHER_PROGRAM), const_cast ("--daemon"), const_cast ("--config"), const_cast (config.c_str ()), const_cast ("--display"), const_cast (display.c_str ()), const_cast (__helpers [i].second.c_str ()), const_cast (__helpers [i].first.uuid.c_str ()), 0}; SCIM_DEBUG_MAIN(2) << " Call scim-helper-launcher.\n"; execv (SCIM_HELPER_LAUNCHER_PROGRAM, argv); exit (-1); } int status; waitpid (pid, &status, 0); break; } } SCIM_DEBUG_MAIN(2) << " exit run_helper ().\n"; } const ClientInfo & get_client_info (int client) { static ClientInfo null_client = { 0, UNKNOWN_CLIENT }; ClientRepository::iterator it = __client_repository.find (client); if (it != __client_repository.end ()) return it->second; return null_client; } bool check_client_connection (const Socket &client) { SCIM_DEBUG_MAIN (3) << "check_client_connection (" << client.get_id () << ")\n"; unsigned char buf [sizeof(uint32)]; int nbytes = client.read_with_timeout (buf, sizeof(uint32), __socket_timeout); if (nbytes == sizeof (uint32)) return true; if (nbytes < 0) { SCIM_DEBUG_MAIN (4) << "Error occurred when reading socket: " << client.get_error_message () << ".\n"; } else { SCIM_DEBUG_MAIN (4) << "Timeout when reading socket.\n"; } return false; } bool socket_open_connection (SocketServer *server, const Socket &client) { SCIM_DEBUG_MAIN (3) << "socket_open_connection (" << client.get_id () << ")\n"; uint32 key; String type = scim_socket_accept_connection (key, String ("HelperLauncher"), String ("HelperManager"), client, __socket_timeout); if (type.length ()) { ClientInfo info; info.key = key; info.type = HELPER_MANAGER_CLIENT; __client_repository [client.get_id ()] = info; return true; } SCIM_DEBUG_MAIN (4) << "Close client connection " << client.get_id () << "\n"; server->close_connection (client); return false; } void socket_close_connection (SocketServer *server, const Socket &client) { ClientInfo client_info = get_client_info (client.get_id ()); __client_repository.erase (client.get_id ()); server->close_connection (client); if (client_info.type != UNKNOWN_CLIENT && __client_repository.size () == 0) { SCIM_DEBUG_MAIN (4) << "Exit Socket Server.\n"; server->shutdown (); } } void socket_accept_callback (SocketServer *server, const Socket &client) { SCIM_DEBUG_MAIN (2) << "socket_accept_callback (" << client.get_id () << ")\n"; if (__should_exit) { SCIM_DEBUG_MAIN (3) << "Exit Socket Server.\n"; server->shutdown (); } } void socket_receive_callback (SocketServer *server, const Socket &client) { int id = client.get_id (); int cmd = 0; uint32 key = 0; ClientInfo client_info; SCIM_DEBUG_MAIN (2) << "socket_receive_callback (" << id << ")\n"; // If the connection is closed then close this client. if (!check_client_connection (client)) { socket_close_connection (server, client); return; } client_info = get_client_info (id); // If it's a new client, then request to open the connection first. if (client_info.type == UNKNOWN_CLIENT) { socket_open_connection (server, client); return; } // If can not read the transaction, // or the transaction is not started with SCIM_TRANS_CMD_REQUEST, // or the key is mismatch, // just return. if (!__recv_trans.read_from_socket (client, __socket_timeout) || !__recv_trans.get_command (cmd) || cmd != SCIM_TRANS_CMD_REQUEST || !__recv_trans.get_data (key) || key != (uint32) client_info.key) return; while (__recv_trans.get_command (cmd)) { if (cmd == SCIM_TRANS_CMD_HELPER_MANAGER_GET_HELPER_LIST) { get_helper_list (client); } else if (cmd == SCIM_TRANS_CMD_HELPER_MANAGER_RUN_HELPER) { String uuid; String config; String display; if (__recv_trans.get_data (uuid) && uuid.length () && __recv_trans.get_data (config) && __recv_trans.get_data (display)) { run_helper (uuid, config, display); } } } } void socket_exception_callback (SocketServer *server, const Socket &client) { SCIM_DEBUG_MAIN (2) << "socket_exception_callback (" << client.get_id () << ")\n"; socket_close_connection (server, client); } bool initialize_socket_server () { String address = scim_get_default_helper_manager_socket_address (); __socket_timeout = scim_get_default_socket_timeout (); if (!__socket_server.create (SocketAddress (address))) return false; __socket_server.signal_connect_accept (slot (socket_accept_callback)); __socket_server.signal_connect_receive (slot (socket_receive_callback)); __socket_server.signal_connect_exception (slot (socket_exception_callback)); return true; } void signalhandler(int sig) { SCIM_DEBUG_MAIN (1) << "signalhandler ()\n"; __socket_server.shutdown (); } int main (int argc, char * argv []) { int i = 0; bool daemon = true; while (i= argc) break; if (String ("-nd") == argv [i] || String ("--no-daemon") == argv [i]) { daemon = false; continue; } if (String ("-v") == argv [i] || String ("--verbose") == argv [i]) { if (++i >= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; return -1; } DebugOutput::set_verbose_level (atoi (argv [i])); continue; } if (String ("-m") == argv [i] || String ("--mask") == argv [i]) { if (++i >= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; return -1; } if (String (argv [i]) != "none") { std::vector debug_mask_list; scim_split_string_list (debug_mask_list, argv [i], ','); DebugOutput::disable_debug (SCIM_DEBUG_AllMask); for (size_t j=0; j= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; return -1; } DebugOutput::set_output (String (argv [i])); continue; } std::cerr << "Invalid command line option: " << argv [i] << "\n"; return -1; } //End of command line parsing. load_helper_modules (); if (!initialize_socket_server ()) { std::cerr << "Can't initialize SocketServer.\n"; return -1; } if (daemon) scim_daemon (); signal(SIGQUIT, signalhandler); signal(SIGTERM, signalhandler); signal(SIGINT, signalhandler); signal(SIGHUP, signalhandler); __socket_server.run (); SCIM_DEBUG_MAIN (1) << "exit scim-helper-manager.\n"; } /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_helper_manager.h0000644000175000017500000000514412422143415017067 0ustar tzhuantzhuan/** * @file scim_helper_manager.h * @brief Defines scim::HelperManager. * * scim::HelperManager is a class used to manage all Client Helper modules. * */ /* * Smart Common Input Method * * Copyright (c) 2004-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_helper_manager.h,v 1.3 2005/05/17 06:45:15 suzhe Exp $ */ #ifndef __SCIM_HELPER_MANAGER_H #define __SCIM_HELPER_MANAGER_H namespace scim { /** * @addtogroup Helper * @{ */ /** * @brief This class is used to manage all helper objects. * */ class HelperManager { class HelperManagerImpl; HelperManagerImpl *m_impl; HelperManager (const HelperManager &); const HelperManager & operator = (const HelperManager &); public: HelperManager (); ~HelperManager (); /** * @brief Get the total number of helpers supported by all helper modules. */ unsigned int number_of_helpers () const; /** * @brief Get the information of a specific helper by its index. * * @param idx The index of the helper, must between 0 to number_of_helpers () - 1. * @param info The HelperInfo object to store the information. * @return true if this helper is ok and the information is stored correctly. */ bool get_helper_info (unsigned int idx, HelperInfo &info) const; /** * @brief Run a specific helper. * * The helper will run in a newly forked process, so this function will return as soon * as the new process is launched. * * @param config_name The name of the ConfigModule to be used to read configurations. * @param uuid The UUID of the helper to be run. * @param display The display in which the helper will be run. */ void run_helper (const String &uuid, const String &config_name, const String &display) const; }; /** @} */ } // namespace scim #endif //__SCIM_HELPER_MANAGER_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_helper_manager.cpp0000644000175000017500000001706012422143415017422 0ustar tzhuantzhuan/** @file scim_helper_manager.cpp * @brief Implementation of class HelperManager. */ /* * Smart Common Input Method * * Copyright (c) 2004-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_helper_manager.cpp,v 1.2 2005/01/05 13:41:10 suzhe Exp $ * */ #define Uses_SCIM_HELPER_MANAGER #define Uses_SCIM_SOCKET #define Uses_SCIM_TRANSACTION #define Uses_SCIM_TRANS_COMMAND #define Uses_C_STDLIB #include #include #include #include // for strerror #include #include #include #include "scim_private.h" #include "scim.h" namespace scim { #ifndef SCIM_HELPER_MANAGER_PROGRAM #define SCIM_HELPER_MANAGER_PROGRAM (SCIM_LIBEXECDIR "/scim-helper-manager") #endif class HelperManager::HelperManagerImpl { std::vector m_helpers; uint32 m_socket_key; SocketClient m_socket_client; int m_socket_timeout; public: HelperManagerImpl () : m_socket_key (0), m_socket_timeout (scim_get_default_socket_timeout ()) { if (open_connection ()) { get_helper_list (); } } ~HelperManagerImpl () { m_socket_client.close (); } unsigned int number_of_helpers () const { return m_helpers.size (); } bool get_helper_info (unsigned int idx, HelperInfo &info) const { if (idx < m_helpers.size ()) { info = m_helpers [idx]; return true; } return false; } void run_helper (const String &uuid, const String &config_name, const String &display) { if (!m_socket_client.is_connected () || !uuid.length () || !m_helpers.size ()) return; Transaction trans; for (int i = 0; i < 3; ++i) { trans.clear (); trans.put_command (SCIM_TRANS_CMD_REQUEST); trans.put_data (m_socket_key); trans.put_command (SCIM_TRANS_CMD_HELPER_MANAGER_RUN_HELPER); trans.put_data (uuid); trans.put_data (config_name); trans.put_data (display); if (trans.write_to_socket (m_socket_client)) return; m_socket_client.close (); if (!open_connection ()) return; get_helper_list (); } } private: bool open_connection () { if (m_socket_client.is_connected ()) return true; SocketAddress address (scim_get_default_helper_manager_socket_address ()); if (address.valid ()) { if (!m_socket_client.connect (address)) { if (launch_helper_manager () == 0) { for (int i = 0; i < 200; ++i) { if (m_socket_client.connect (address)) break; scim_usleep (100000); } } else { // bail out: can't continue without the helper std::cerr << _("Failed to launch HelperManager: exiting...") << std::endl; exit(-1); } } } if (m_socket_client.is_connected () && scim_socket_open_connection (m_socket_key, "HelperManager", "HelperLauncher", m_socket_client, m_socket_timeout)) { return true; } m_socket_client.close (); return false; } int launch_helper_manager () const { char *argv [] = { (char*)SCIM_HELPER_MANAGER_PROGRAM, 0 }; pid_t child_pid; child_pid = fork (); // Error fork. if (child_pid == -1) { std::cerr << _("Error launching HelperManager") << " (" << SCIM_HELPER_MANAGER_PROGRAM << "): fork " << _("failed") << ": " << strerror(errno) << std::endl; return -1; } // In child process, start scim-helper-manager. if (child_pid == 0) { return execv (SCIM_HELPER_MANAGER_PROGRAM, argv); } // In parent process, wait the child exit. int status; pid_t ret_pid; ret_pid = waitpid (child_pid, &status, 0); if (ret_pid == -1) { std::cerr << _("Error launching HelperManager") << " (" << SCIM_HELPER_MANAGER_PROGRAM << "): waitpid " << _("failed") << ": " << strerror(errno) << std::endl; } assert(ret_pid==child_pid); if (WIFEXITED(status)) { if (WEXITSTATUS(status) != 0) { std::cerr << _("Error launching HelperManager") << " (" << SCIM_HELPER_MANAGER_PROGRAM << "): " << _("abnormal process termination") << std::endl; } return WEXITSTATUS(status); } if (WIFSIGNALED(status)) { std::cerr << _("Error launching HelperManager") << " (" << SCIM_HELPER_MANAGER_PROGRAM << "): " << _("it exited with signal") << " " << WTERMSIG(status) << std::endl; return -1; } std::cerr << _("Error launching HelperManager") << " (" << SCIM_HELPER_MANAGER_PROGRAM << "): " << _("unknown process launch error") << std::endl; return -1; } void get_helper_list () { Transaction trans; uint32 num; int cmd; HelperInfo info; m_helpers.clear (); trans.put_command (SCIM_TRANS_CMD_REQUEST); trans.put_data (m_socket_key); trans.put_command (SCIM_TRANS_CMD_HELPER_MANAGER_GET_HELPER_LIST); if (trans.write_to_socket (m_socket_client) && trans.read_from_socket (m_socket_client, m_socket_timeout)) { if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && trans.get_data (num) && num > 0) { for (uint32 j = 0; j < num; ++j) { if (trans.get_data (info.uuid) && trans.get_data (info.name) && trans.get_data (info.icon) && trans.get_data (info.description) && trans.get_data (info.option)) { m_helpers.push_back (info); } } } } } }; HelperManager::HelperManager () : m_impl (new HelperManagerImpl ()) { } HelperManager::~HelperManager () { delete m_impl; } unsigned int HelperManager::number_of_helpers () const { return m_impl->number_of_helpers (); } bool HelperManager::get_helper_info (unsigned int idx, HelperInfo &info) const { return m_impl->get_helper_info (idx, info); } void HelperManager::run_helper (const String &uuid, const String &config_name, const String &display) const { return m_impl->run_helper (uuid, config_name, display); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_helper_launcher.cpp0000644000175000017500000001252212422143415017607 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2004-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_helper_launcher.cpp,v 1.6 2005/05/16 01:25:46 suzhe Exp $ * */ #define Uses_SCIM_HELPER_MODULE #define Uses_SCIM_GLOBAL_CONFIG #define Uses_SCIM_CONFIG_PATH #include #include "scim_private.h" #include "scim.h" using namespace scim; int main (int argc, char *argv []) { int i = 0; int j = 0; String config; String display; String helper; String uuid; bool daemon = false; char *p = getenv ("DISPLAY"); if (p) display = String (p); config = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_CONFIG_MODULE, String ("simple")); while (i < argc) { if (++i >= argc) break; if (String ("-c") == argv [i] || String ("--config") == argv [i]) { if (++i >= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; exit (-1); } config = argv [i]; continue; } if (String ("-d") == argv [i] || String ("--daemon") == argv [i]) { daemon = true; continue; } if (String ("--display") == argv [i]) { if (++i >= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; exit (-1); } display = argv [i]; continue; } if (String ("-h") == argv [i] || String ("--help") == argv [i]) { std::cout << "Usage: " << argv [0] << " [options] module uuid\n\n" << "The options are:\n" << " -c, --config name Use specified config module, default is \"simple\".\n" << " -d, --daemon Run as daemon.\n" << " --display name run setup on a specified DISPLAY.\n" << " -h, --help Show this help message.\n" << "module The name of the Helper module\n" << "uuid The uuid of the Helper to be launched.\n"; return 0; } if (String ("-v") == argv [i] || String ("--verbose") == argv [i]) { if (++i >= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; return -1; } DebugOutput::set_verbose_level (atoi (argv [i])); continue; } if (String ("-m") == argv [i] || String ("--mask") == argv [i]) { if (++i >= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; return -1; } if (String (argv [i]) != "none") { std::vector debug_mask_list; scim_split_string_list (debug_mask_list, argv [i], ','); DebugOutput::disable_debug (SCIM_DEBUG_AllMask); for (size_t j=0; j= argc) { std::cerr << "No argument for option " << argv [i-1] << "\n"; return -1; } DebugOutput::set_output (String (argv [i])); continue; } ++j; if (j == 1) { helper = String (argv [i]); continue; } else if (j == 2) { uuid = String (argv [i]); continue; } std::cerr << "Invalid command line option: " << argv [i] << "\n"; return -1; } SCIM_DEBUG_MAIN(1) << "scim-helper-launcher: " << config << " " << display << " " << helper << " " << uuid << "\n"; if (!helper.length () || !uuid.length ()) { std::cerr << "Module name or Helper UUID is missing.\n"; return -1; } HelperModule helper_module (helper); if (!helper_module.valid () || helper_module.number_of_helpers () == 0) { std::cerr << "Unable to load Helper module: " << helper << "\n"; return -1; } ConfigModule config_module (config); ConfigPointer config_pointer; if (config_module.valid ()) { config_pointer = config_module.create_config (); } if (config_pointer.null ()) { config_pointer = new DummyConfig (); } if (daemon) scim_daemon (); helper_module.run_helper (uuid, config_pointer, display); } /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_helper.h0000644000175000017500000003405412422143415015377 0ustar tzhuantzhuan/** * @file scim_helper.h * @brief Defines scim::HelperAgent and it's related types. * * scim::HelperAgent is a class used to write Client Helper modules. * */ /* * Smart Common Input Method * * Copyright (c) 2004-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_helper.h,v 1.16 2005/05/24 12:22:51 suzhe Exp $ */ #ifndef __SCIM_HELPER_H #define __SCIM_HELPER_H namespace scim { /** * @addtogroup Helper * The accessory classes to help develop and manage Client Helper objects. * @{ */ class HelperError: public Exception { public: HelperError (const String& what_arg) : Exception (String("scim::Helper: ") + what_arg) { } }; /** * @brief Helper option indicates that it's a stand alone Helper. * * Stand alone Helper has no corresponding IMEngine Factory, * Such Helper can not be started by IMEngine Factory. * So Panel must provide a menu, or something else, which contains * all stand alone Helper items, so that user can start them by * clicking the items. */ const uint32 SCIM_HELPER_STAND_ALONE = 1; /** * @brief Helper option indicates that it must be started * automatically when Panel starts. * * If Helper objects want to start itself as soon as * the Panel starts, set this option. */ const uint32 SCIM_HELPER_AUTO_START = (1<<1); /** * @brief Helper option indicates that it should be restarted * when it exits abnormally. * * This option should not be used with #SCIM_HELPER_STAND_ALONE. */ const uint32 SCIM_HELPER_AUTO_RESTART = (1<<2); /** * @brief Helper option indicates that it needs the screen update * information. * * Helper object with this option will receive the UPDATE_SCREEN event * when the screen of focused ic is changed. */ const uint32 SCIM_HELPER_NEED_SCREEN_INFO = (1<<3); /** * @brief Helper option indicates that it needs the spot location * information. * * Helper object with this option will receive the SPOT_LOCATION_INFO event * when the spot location of focused ic is changed. */ const uint32 SCIM_HELPER_NEED_SPOT_LOCATION_INFO = (1<<4); /** * @brief Structure to hold the information of a Helper object. */ struct HelperInfo { String uuid; /**< The UUID of this Helper object */ String name; /**< The Name of this Helper object, UTF-8 encoding. */ String icon; /**< The Icon file path of this Helper object. */ String description; /**< The short description of this Helper object. */ uint32 option; /**< The options of this Helper object. @sa #SCIM_HELPER_STAND_ALONE etc.*/ HelperInfo (const String &puuid = String (), const String &pname = String (), const String &picon = String (), const String &pdesc = String (), uint32 opt = 0) : uuid (puuid), name (pname), icon (picon), description (pdesc), option (opt) { } }; class HelperAgent; typedef Slot3 HelperAgentSlotVoid; typedef Slot4 HelperAgentSlotString; typedef Slot4 HelperAgentSlotInt; typedef Slot5 HelperAgentSlotIntInt; typedef Slot4 HelperAgentSlotTransaction; /** * @brief The accessory class to write a Helper object. * * This class implements all Socket Transaction protocol between * Helper object and Panel. */ class HelperAgent { class HelperAgentImpl; HelperAgentImpl *m_impl; HelperAgent (const HelperAgent &); const HelperAgent & operator = (const HelperAgent &); public: HelperAgent (); ~HelperAgent (); /** * @brief Open socket connection to the Panel. * * Helper objects and Panel communicate with each other via the Socket * created by Panel, just same as the Socket between FrontEnds and Panel. * * Helper object can select/poll on the connection id returned by this function * to see if there are any data available to be read. If any data are available, * Helper object should call HelperAgent::filter_event() to process the data. * * This method should be called after the necessary signal-slots are connected. * If this Helper is started by an IMEngine Instance, then signal attach_input_context * will be emitted during this call. * * Signal update_screen will be emitted during this call as well to set the startup * screen of this Helper. The ic and ic_uuid parameters are invalid here. * * @param info The information of this Helper object. * @param display The display which this Helper object should run on. * * @return The connection socket id. -1 means failed to create * the connection. */ int open_connection (const HelperInfo &info, const String &display); /** * @brief Close the socket connection to Panel. */ void close_connection (); /** * @brief Get the connection id previously returned by open_connection(). */ int get_connection_number () const; /** * @brief Return whether this HelperAgent has been connected to a Panel. */ bool is_connected () const; /** * @brief Check if there are any events available to be processed. * * If it returns true then Helper object should call * HelperAgent::filter_event() to process them. * * @return true if there are any events available. */ bool has_pending_event () const; /** * @brief Process the pending events. * * This function will emit the corresponding signals according * to the events. * * @return false if the connection is broken, otherwise return true. */ bool filter_event (); /** * @brief Request SCIM to reload all configuration. * * This function should only by used by Setup Helper to request * scim's reloading the configuration. */ void reload_config () const; /** * @brief Register some properties into Panel. * * This function send the request to Panel to register a list * of Properties. * * @param properties The list of Properties to be registered into Panel. * * @sa scim::Property. */ void register_properties (const PropertyList &properties) const; /** * @brief Update a registered property. * * @param property The property to be updated. */ void update_property (const Property &property) const; /** * @brief Send a set of events to an IMEngineInstance. * * All events should be put into a Transaction. * And the events can only be received by one IMEngineInstance object. * * @param ic The handle of the Input Context to receive the events. * @param ic_uuid The UUID of the Input Context. * @param trans The Transaction object holds the events. */ void send_imengine_event (int ic, const String &ic_uuid, const Transaction &trans) const; /** * @brief Send a KeyEvent to an IMEngineInstance. * * @param ic The handle of the IMEngineInstance to receive the event. * -1 means the currently focused IMEngineInstance. * @param ic_uuid The UUID of the IMEngineInstance. Empty means don't match. * @param key The KeyEvent to be sent. */ void send_key_event (int ic, const String &ic_uuid, const KeyEvent &key) const; /** * @brief Forward a KeyEvent to client application directly. * * @param ic The handle of the client Input Context to receive the event. * -1 means the currently focused Input Context. * @param ic_uuid The UUID of the IMEngine used by the Input Context. * Empty means don't match. * @param key The KeyEvent to be forwarded. */ void forward_key_event (int ic, const String &ic_uuid, const KeyEvent &key) const; /** * @brief Commit a WideString to client application directly. * * @param ic The handle of the client Input Context to receive the WideString. * -1 means the currently focused Input Context. * @param ic_uuid The UUID of the IMEngine used by the Input Context. * Empty means don't match. * @param wstr The WideString to be committed. */ void commit_string (int ic, const String &ic_uuid, const WideString &wstr) const; public: /** * @brief Connect a slot to Helper exit signal. * * This signal is used to let the Helper exit. * * The prototype of the slot is: * * void exit (const HelperAgent *agent, int ic, const String &ic_uuid); * * Parameters: * - agent The pointer to the HelperAgent object which emits this signal. * - ic An opaque handle of the currently focused input context. * - ic_uuid The UUID of the IMEngineInstance associated with the focused input context. */ Connection signal_connect_exit (HelperAgentSlotVoid *slot); /** * @brief Connect a slot to Helper attach input context signal. * * This signal is used to attach an input context to this helper. * * When an input context requst to start this helper, then this * signal will be emitted as soon as the helper is started. * * When an input context want to start an already started helper, * this signal will also be emitted. * * Helper can send some events back to the IMEngineInstance in this * signal-slot, to inform that it has been started sccessfully. * * The prototype of the slot is: * * void attach_input_context (const HelperAgent *agent, int ic, const String &ic_uuid); */ Connection signal_connect_attach_input_context (HelperAgentSlotVoid *slot); /** * @brief Connect a slot to Helper detach input context signal. * * This signal is used to detach an input context from this helper. * * When an input context requst to stop this helper, then this * signal will be emitted. * * Helper shouldn't send any event back to the IMEngineInstance, because * the IMEngineInstance attached to the ic should have been destroyed. * * The prototype of the slot is: * * void detach_input_context (const HelperAgent *agent, int ic, const String &ic_uuid); */ Connection signal_connect_detach_input_context (HelperAgentSlotVoid *slot); /** * @brief Connect a slot to Helper reload config signal. * * This signal is used to let the Helper reload configuration. * * The prototype of the slot is: * * void reload_config (const HelperAgent *agent, int ic, const String &ic_uuid); */ Connection signal_connect_reload_config (HelperAgentSlotVoid *slot); /** * @brief Connect a slot to Helper update screen signal. * * This signal is used to let the Helper move its GUI to another screen. * It can only be emitted when SCIM_HELPER_NEED_SCREEN_INFO is set in HelperInfo.option. * * The prototype of the slot is: * * void update_screen (const HelperAgent *agent, int ic, const String &ic_uuid, int screen_number); */ Connection signal_connect_update_screen (HelperAgentSlotInt *slot); /** * @brief Connect a slot to Helper update spot location signal. * * This signal is used to let the Helper move its GUI according to the current spot location. * It can only be emitted when SCIM_HELPER_NEED_SPOT_LOCATION_INFO is set in HelperInfo.option. * * The prototype of the slot is: * void update_spot_location (const HelperAgent *agent, int ic, const String &ic_uuid, int x, int y); */ Connection signal_connect_update_spot_location (HelperAgentSlotIntInt *slot); /** * @brief Connect a slot to Helper trigger property signal. * * This signal is used to trigger a property registered by this Helper. * A property will be triggered when user clicks on it. * * The prototype of the slot is: * void trigger_property (const HelperAgent *agent, int ic, const String &ic_uuid, const String &property); */ Connection signal_connect_trigger_property (HelperAgentSlotString *slot); /** * @brief Connect a slot to Helper process imengine event signal. * * This signal is used to deliver the events sent from IMEngine to Helper. * * The prototype of the slot is: * void process_imengine_event (const HelperAgent *agent, int ic, const String &ic_uuid, const Transaction &transaction); */ Connection signal_connect_process_imengine_event (HelperAgentSlotTransaction *slot); }; /** @} */ } // namespace scim #endif //__SCIM_HELPER_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_helper.cpp0000644000175000017500000003123212422143415015725 0ustar tzhuantzhuan/** @file scim_helper.cpp * @brief Implementation of class HelperAgent. */ /* * Smart Common Input Method * * Copyright (c) 2004-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_helper.cpp,v 1.13 2005/05/24 12:22:51 suzhe Exp $ * */ #define Uses_SCIM_TRANSACTION #define Uses_SCIM_TRANS_COMMANDS #define Uses_SCIM_HELPER #define Uses_SCIM_SOCKET #define Uses_SCIM_EVENT #include "scim_private.h" #include "scim.h" namespace scim { typedef Signal3 HelperAgentSignalVoid; typedef Signal4 HelperAgentSignalString; typedef Signal4 HelperAgentSignalInt; typedef Signal5 HelperAgentSignalIntInt; typedef Signal4 HelperAgentSignalTransaction; class HelperAgent::HelperAgentImpl { public: SocketClient socket; Transaction recv; Transaction send; uint32 magic; int timeout; HelperAgentSignalVoid signal_exit; HelperAgentSignalVoid signal_attach_input_context; HelperAgentSignalVoid signal_detach_input_context; HelperAgentSignalVoid signal_reload_config; HelperAgentSignalInt signal_update_screen; HelperAgentSignalIntInt signal_update_spot_location; HelperAgentSignalString signal_trigger_property; HelperAgentSignalTransaction signal_process_imengine_event; public: HelperAgentImpl () : magic (0), timeout (-1) { } }; HelperAgent::HelperAgent () : m_impl (new HelperAgentImpl ()) { } HelperAgent::~HelperAgent () { delete m_impl; } int HelperAgent::open_connection (const HelperInfo &info, const String &display) { if (m_impl->socket.is_connected ()) close_connection (); SocketAddress address (scim_get_default_panel_socket_address (display)); int timeout = scim_get_default_socket_timeout (); uint32 magic; if (!address.valid ()) return -1; if (!m_impl->socket.connect (address)) return -1; if (!scim_socket_open_connection (magic, String ("Helper"), String ("Panel"), m_impl->socket, timeout)) { m_impl->socket.close (); return -1; } m_impl->send.clear (); m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST); m_impl->send.put_data (magic); m_impl->send.put_command (SCIM_TRANS_CMD_PANEL_REGISTER_HELPER); m_impl->send.put_data (info.uuid); m_impl->send.put_data (info.name); m_impl->send.put_data (info.icon); m_impl->send.put_data (info.description); m_impl->send.put_data (info.option); if (!m_impl->send.write_to_socket (m_impl->socket, magic)) { m_impl->socket.close (); return -1; } int cmd; if (m_impl->recv.read_from_socket (m_impl->socket, timeout) && m_impl->recv.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && m_impl->recv.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) { m_impl->magic = magic; m_impl->timeout = timeout; while (m_impl->recv.get_command (cmd)) { switch (cmd) { case SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT: { uint32 ic; String ic_uuid; while (m_impl->recv.get_data (ic) && m_impl->recv.get_data (ic_uuid)) m_impl->signal_attach_input_context (this, ic, ic_uuid); break; } case SCIM_TRANS_CMD_UPDATE_SCREEN: { uint32 screen; if (m_impl->recv.get_data (screen)) m_impl->signal_update_screen (this, (uint32) -1, String (""), (int) screen); break; } } } return m_impl->socket.get_id (); } m_impl->socket.close (); return -1; } void HelperAgent::close_connection () { m_impl->socket.close (); m_impl->send.clear (); m_impl->recv.clear (); m_impl->magic = 0; m_impl->timeout = 0; } int HelperAgent::get_connection_number () const { if (m_impl->socket.is_connected ()) return m_impl->socket.get_id (); return -1; } bool HelperAgent::is_connected () const { return m_impl->socket.is_connected (); } bool HelperAgent::has_pending_event () const { if (m_impl->socket.is_connected () && m_impl->socket.wait_for_data (0) > 0) return true; return false; } bool HelperAgent::filter_event () { if (!m_impl->socket.is_connected () || !m_impl->recv.read_from_socket (m_impl->socket, m_impl->timeout)) return false; int cmd; uint32 ic = (uint32) -1; String ic_uuid; if (!m_impl->recv.get_command (cmd) || cmd != SCIM_TRANS_CMD_REPLY) return true; // If there are ic and ic_uuid then read them. if (!(m_impl->recv.get_data_type () == SCIM_TRANS_DATA_COMMAND) && !(m_impl->recv.get_data (ic) && m_impl->recv.get_data (ic_uuid))) return true; while (m_impl->recv.get_command (cmd)) { switch (cmd) { case SCIM_TRANS_CMD_EXIT: m_impl->signal_exit (this, ic, ic_uuid); break; case SCIM_TRANS_CMD_RELOAD_CONFIG: m_impl->signal_reload_config (this, ic, ic_uuid); break; case SCIM_TRANS_CMD_UPDATE_SCREEN: { uint32 screen; if (m_impl->recv.get_data (screen)) m_impl->signal_update_screen (this, ic, ic_uuid, (int) screen); break; } case SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION: { uint32 x, y; if (m_impl->recv.get_data (x) && m_impl->recv.get_data (y)) m_impl->signal_update_spot_location (this, ic, ic_uuid, (int) x, (int) y); break; } case SCIM_TRANS_CMD_TRIGGER_PROPERTY: { String property; if (m_impl->recv.get_data (property)) m_impl->signal_trigger_property (this, ic, ic_uuid, property); break; } case SCIM_TRANS_CMD_HELPER_PROCESS_IMENGINE_EVENT: { Transaction trans; if (m_impl->recv.get_data (trans)) m_impl->signal_process_imengine_event (this, ic, ic_uuid, trans); break; } case SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT: m_impl->signal_attach_input_context (this, ic, ic_uuid); break; case SCIM_TRANS_CMD_HELPER_DETACH_INPUT_CONTEXT: m_impl->signal_detach_input_context (this, ic, ic_uuid); break; } } return true; } void HelperAgent::reload_config () const { if (m_impl->socket.is_connected ()) { m_impl->send.clear (); m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST); m_impl->send.put_data (m_impl->magic); m_impl->send.put_command (SCIM_TRANS_CMD_RELOAD_CONFIG); m_impl->send.write_to_socket (m_impl->socket, m_impl->magic); } } void HelperAgent::register_properties (const PropertyList &properties) const { if (m_impl->socket.is_connected ()) { m_impl->send.clear (); m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST); m_impl->send.put_data (m_impl->magic); m_impl->send.put_command (SCIM_TRANS_CMD_REGISTER_PROPERTIES); m_impl->send.put_data (properties); m_impl->send.write_to_socket (m_impl->socket, m_impl->magic); } } void HelperAgent::update_property (const Property &property) const { if (m_impl->socket.is_connected ()) { m_impl->send.clear (); m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST); m_impl->send.put_data (m_impl->magic); m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PROPERTY); m_impl->send.put_data (property); m_impl->send.write_to_socket (m_impl->socket, m_impl->magic); } } void HelperAgent::send_imengine_event (int ic, const String &ic_uuid, const Transaction &trans) const { if (m_impl->socket.is_connected ()) { m_impl->send.clear (); m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST); m_impl->send.put_data (m_impl->magic); m_impl->send.put_command (SCIM_TRANS_CMD_PANEL_SEND_IMENGINE_EVENT); m_impl->send.put_data ((uint32)ic); m_impl->send.put_data (ic_uuid); m_impl->send.put_data (trans); m_impl->send.write_to_socket (m_impl->socket, m_impl->magic); } } void HelperAgent::send_key_event (int ic, const String &ic_uuid, const KeyEvent &key) const { if (m_impl->socket.is_connected ()) { m_impl->send.clear (); m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST); m_impl->send.put_data (m_impl->magic); m_impl->send.put_command (SCIM_TRANS_CMD_PANEL_SEND_KEY_EVENT); m_impl->send.put_data ((uint32)ic); m_impl->send.put_data (ic_uuid); m_impl->send.put_data (key); m_impl->send.write_to_socket (m_impl->socket, m_impl->magic); } } void HelperAgent::forward_key_event (int ic, const String &ic_uuid, const KeyEvent &key) const { if (m_impl->socket.is_connected ()) { m_impl->send.clear (); m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST); m_impl->send.put_data (m_impl->magic); m_impl->send.put_command (SCIM_TRANS_CMD_FORWARD_KEY_EVENT); m_impl->send.put_data ((uint32)ic); m_impl->send.put_data (ic_uuid); m_impl->send.put_data (key); m_impl->send.write_to_socket (m_impl->socket, m_impl->magic); } } void HelperAgent::commit_string (int ic, const String &ic_uuid, const WideString &wstr) const { if (m_impl->socket.is_connected ()) { m_impl->send.clear (); m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST); m_impl->send.put_data (m_impl->magic); m_impl->send.put_command (SCIM_TRANS_CMD_COMMIT_STRING); m_impl->send.put_data ((uint32)ic); m_impl->send.put_data (ic_uuid); m_impl->send.put_data (wstr); m_impl->send.write_to_socket (m_impl->socket, m_impl->magic); } } Connection HelperAgent::signal_connect_exit (HelperAgentSlotVoid *slot) { return m_impl->signal_exit.connect (slot); } Connection HelperAgent::signal_connect_attach_input_context (HelperAgentSlotVoid *slot) { return m_impl->signal_attach_input_context.connect (slot); } Connection HelperAgent::signal_connect_detach_input_context (HelperAgentSlotVoid *slot) { return m_impl->signal_detach_input_context.connect (slot); } Connection HelperAgent::signal_connect_reload_config (HelperAgentSlotVoid *slot) { return m_impl->signal_reload_config.connect (slot); } Connection HelperAgent::signal_connect_update_screen (HelperAgentSlotInt *slot) { return m_impl->signal_update_screen.connect (slot); } Connection HelperAgent::signal_connect_update_spot_location (HelperAgentSlotIntInt *slot) { return m_impl->signal_update_spot_location.connect (slot); } Connection HelperAgent::signal_connect_trigger_property (HelperAgentSlotString *slot) { return m_impl->signal_trigger_property.connect (slot); } Connection HelperAgent::signal_connect_process_imengine_event (HelperAgentSlotTransaction *slot) { return m_impl->signal_process_imengine_event.connect (slot); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_global_config.h0000644000175000017500000001202312422143415016675 0ustar tzhuantzhuan/** @file scim_global_config.h * @brief functions to read the global configurations. * * The global configuration file (normally /etc/scim/global) is used to store * the configurations for libscim itself and the system wide configurations which * will be read before any Config module is loaded. */ /* * Smart Common Input Method * * Copyright (c) 2004-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_global_config.h,v 1.4 2005/01/10 08:30:54 suzhe Exp $ */ #ifndef __SCIM_GLOBAL_CONFIG_H #define __SCIM_GLOBAL_CONFIG_H namespace scim { /** * @addtogroup Accessories * @{ */ /** * @brief Read a string value from the global configuration file. * * @param key The key to be read, like /PanelProgram etc. * @param defVal The default value to be returned if there is no such key in the configuration file. * * @return the value string of the key. */ String scim_global_config_read (const String &key, const String &defVal = String ()); /** * @brief Read an int value from the global configuration file. * * @param key The key to be read, like /SocketTimeout etc. * @param defVal The default value to be returned if there is no such key in the configuration file. * * @return the value of the key. */ int scim_global_config_read (const String &key, int defVal); /** * @brief Read a bool value from the global configuration file. * * @param key The key to be read. * @param defVal The default value to be returned if there is no such key in the configuration file. * * @return the value of the key. */ bool scim_global_config_read (const String &key, bool defVal); /** * @brief Read a double value from the global configuration file. * * @param key The key to be read. * @param defVal The default value to be returned if there is no such key in the configuration file. * * @return the value of the key. */ double scim_global_config_read (const String &key, double defVal); /** * @brief Read a string list from the global configuration file. * * @param key The key to be read. * @param defVal The default value to be returned if there is no such key in the configuration file. * * @return the value of the key. */ std::vector scim_global_config_read (const String &key, const std::vector &defVal); /** * @brief Read an int list from the global configuration file. * * @param key The key to be read. * @param defVal The default value to be returned if there is no such key in the configuration file. * * @return the value of the key. */ std::vector scim_global_config_read (const String &key, const std::vector &defVal); /** * @brief Write a string value into the user global config. * * @param key The key to be associated. * @param val The string value to be written. */ void scim_global_config_write (const String &key, const String &val); /** * @brief Write an int value into the user global config. * * @param key The key to be associated. * @param val The int value to be written. */ void scim_global_config_write (const String &key, int val); /** * @brief Write a bool value into the user global config. * * @param key The key to be associated. * @param val The bool value to be written. */ void scim_global_config_write (const String &key, bool val); /** * @brief Write a double value into the user global config. * * @param key The key to be associated. * @param val The double value to be written. */ void scim_global_config_write (const String &key, double val); /** * @brief Write a string list into the user global config. * * @param key The key to be associated. * @param val The string list to be written. */ void scim_global_config_write (const String &key, const std::vector &val); /** * @brief Write an int list into the user global config. * * @param key The key to be associated. * @param val The int list to be written. */ void scim_global_config_write (const String &key, const std::vector &val); /** * @brief Reset the value associated to the specified key to its default value. * * @param key The key to be reset. */ void scim_global_config_reset (const String &key); /** * @brief Flush the updated global config into user global config file. * @return true if success. */ bool scim_global_config_flush (); /** @} */ } // namespace scim #endif //__SCIM_GLOBAL_CONFIG_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_global_config.cpp0000644000175000017500000003116112422143415017234 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2004-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_global_config.cpp,v 1.7 2005/09/29 10:51:25 suzhe Exp $ */ #define Uses_SCIM_UTILITY #define Uses_SCIM_GLOBAL_CONFIG #define Uses_C_STDLIB #define Uses_C_STDIO #define Uses_C_STRING #define Uses_STL_FSTREAM #include #include #include #include "scim_private.h" #include "scim.h" #include "scim_stl_map.h" namespace scim { #if SCIM_USE_STL_EXT_HASH_MAP typedef __gnu_cxx::hash_map KeyValueRepository; #elif SCIM_USE_STL_HASH_MAP typedef std::hash_map KeyValueRepository; #else typedef std::map KeyValueRepository; #endif class GlobalConfigRepository { public: KeyValueRepository sys; KeyValueRepository usr; KeyValueRepository updated; bool initialized; public: GlobalConfigRepository () : initialized (false) { } ~GlobalConfigRepository () { scim_global_config_flush (); } }; static GlobalConfigRepository __config_repository; static String __trim_blank (const String &str) { String::size_type begin, len; begin = str.find_first_not_of (" \t\n\v"); if (begin == String::npos) return String (); len = str.find_last_not_of (" \t\n\v") - begin + 1; return str.substr (begin, len); } static String __get_param_portion (const String &str) { String ret = str; return (ret.erase (ret.find_first_of (" \t\n\v="), ret.length() - 1)); } static String __get_value_portion (const String &str) { String ret = str; ret.erase (0, ret.find_first_of ("=") + 1); ret.erase (0, ret.find_first_not_of(" \n\t\v")); return (ret.erase (ret.find_last_not_of(" \t\n\v") + 1)); } static void __parse_config (std::ifstream &is, KeyValueRepository &repository) { char *conf_line = new char [10000]; while (!is.eof ()) { is.getline (conf_line, 10000); String normalized_line = __trim_blank(conf_line); if ((normalized_line.find_first_of("#") > 0) && (normalized_line.length() != 0)) { if (normalized_line.find_first_of("=") == String::npos) { SCIM_DEBUG_MAIN (2) << " Invalid global config line : " << normalized_line << "\n"; continue; } if (normalized_line[0] == '=') { SCIM_DEBUG_MAIN (2) << " Invalid global config line : " << normalized_line << "\n"; continue; } String param = __get_param_portion(normalized_line); String value = __get_value_portion (normalized_line); repository [param] = value; SCIM_DEBUG_MAIN (2) << " Global config entry " << param << "=" << value << " is successfully read.\n"; } } delete [] conf_line; } static void __initialize_config () { __config_repository.sys.clear (); __config_repository.usr.clear (); String sys_conf_file = String (SCIM_SYSCONFDIR) + String (SCIM_PATH_DELIM_STRING) + String ("scim") + String (SCIM_PATH_DELIM_STRING) + String ("global"); String usr_conf_file = scim_get_home_dir () + String (SCIM_PATH_DELIM_STRING) + String (".scim") + String (SCIM_PATH_DELIM_STRING) + String ("global"); std::ifstream sys_is (sys_conf_file.c_str ()); std::ifstream usr_is (usr_conf_file.c_str ()); if (sys_is) { __parse_config (sys_is, __config_repository.sys); __config_repository.initialized = true; } if (usr_is) { __parse_config (usr_is, __config_repository.usr); __config_repository.initialized = true; } } String scim_global_config_read (const String &key, const String &defVal) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized) { KeyValueRepository::iterator it = __config_repository.usr.find (key); if (it == __config_repository.usr.end ()) { it = __config_repository.sys.find (key); if (it == __config_repository.sys.end ()) return defVal; } return it->second; } return defVal; } int scim_global_config_read (const String &key, int defVal) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized) { KeyValueRepository::iterator it = __config_repository.usr.find (key); if (it == __config_repository.usr.end ()) { it = __config_repository.sys.find (key); if (it == __config_repository.sys.end ()) return defVal; } if (it->second.length ()) return strtol (it->second.c_str (), (char **) NULL, 10); } return defVal; } bool scim_global_config_read (const String &key, bool defVal) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized) { KeyValueRepository::iterator it = __config_repository.usr.find (key); if (it == __config_repository.usr.end ()) { it = __config_repository.sys.find (key); if (it == __config_repository.sys.end ()) return defVal; } if (it->second.length ()) { if (it->second == "true" || it->second == "TRUE" || it->second == "True" || it->second == "1") return true; else if (it->second == "false" || it->second == "FALSE" || it->second == "False" || it->second == "0") return false; } } return defVal; } double scim_global_config_read (const String &key, double defVal) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized) { KeyValueRepository::iterator it = __config_repository.usr.find (key); if (it == __config_repository.usr.end ()) { it = __config_repository.sys.find (key); if (it == __config_repository.sys.end ()) return defVal; } if (it->second.length ()) return strtod (it->second.c_str (), (char **) NULL); } return defVal; } std::vector scim_global_config_read (const String &key, const std::vector &defVal) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized) { KeyValueRepository::iterator it = __config_repository.usr.find (key); if (it == __config_repository.usr.end ()) { it = __config_repository.sys.find (key); if (it == __config_repository.sys.end ()) return defVal; } if (it->second.length ()) { std::vector strs; scim_split_string_list (strs, it->second, ','); return strs; } } return defVal; } std::vector scim_global_config_read (const String &key, const std::vector &defVal) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized) { KeyValueRepository::iterator it = __config_repository.usr.find (key); if (it == __config_repository.usr.end ()) { it = __config_repository.sys.find (key); if (it == __config_repository.sys.end ()) return defVal; } if (it->second.length ()) { std::vector strs; std::vector ints; scim_split_string_list (strs, it->second, ','); for (std::vector ::iterator i = strs.begin (); i != strs.end (); ++i) ints.push_back (strtol (i->c_str (), (char **)NULL, 10)); return ints; } } return defVal; } void scim_global_config_write (const String &key, const String &val) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized && key.length ()) { __config_repository.usr [key] = val; __config_repository.updated [key] = "updated"; } } void scim_global_config_write (const String &key, int val) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized && key.length ()) { char buf [80]; snprintf (buf, 80, "%d", val); __config_repository.usr [key] = String (buf); __config_repository.updated [key] = "updated"; } } void scim_global_config_write (const String &key, bool val) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized && key.length ()) { __config_repository.usr [key] = (val ? "true" : "false"); __config_repository.updated [key] = "updated"; } } void scim_global_config_write (const String &key, double val) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized && key.length ()) { char buf [80]; snprintf (buf, 80, "%lf", val); __config_repository.usr [key] = String (buf); __config_repository.updated [key] = "updated"; } } void scim_global_config_write (const String &key, const std::vector &val) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized && key.length ()) { __config_repository.usr [key] = scim_combine_string_list (val, ','); __config_repository.updated [key] = "updated"; } } void scim_global_config_write (const String &key, const std::vector &val) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized && key.length ()) { std::vector strvec; char buf [80]; for (size_t i = 0; i < val.size (); ++i) { snprintf (buf, 80, "%d", val [i]); strvec.push_back (buf); } __config_repository.usr [key] = scim_combine_string_list (strvec, ','); __config_repository.updated [key] = "updated"; } } void scim_global_config_reset (const String &key) { if (!__config_repository.initialized) __initialize_config (); if (__config_repository.initialized && key.length ()) { __config_repository.usr.erase (key); __config_repository.updated [key] = "erased"; } } bool scim_global_config_flush () { if (!__config_repository.initialized) return false; if (!__config_repository.updated.size ()) return true; String usr_conf_dir = scim_get_home_dir () + String (SCIM_PATH_DELIM_STRING) + String (".scim"); String usr_conf_file = usr_conf_dir + String (SCIM_PATH_DELIM_STRING) + String ("global"); if (access (usr_conf_dir.c_str (), R_OK | W_OK) != 0) { mkdir (usr_conf_dir.c_str (), S_IRUSR | S_IWUSR | S_IXUSR); if (access (usr_conf_dir.c_str (), R_OK | W_OK) != 0) return false; } KeyValueRepository backup_usr = __config_repository.usr; // Reload all configuration. __initialize_config (); for (KeyValueRepository::iterator it = __config_repository.updated.begin (); it != __config_repository.updated.end (); ++it) { if (it->second == "updated") __config_repository.usr [it->first] = backup_usr [it->first]; else if (it->second == "erased") __config_repository.usr.erase (it->first); } std::ofstream usr_os (usr_conf_file.c_str ()); if (usr_os) { for (KeyValueRepository::iterator it = __config_repository.usr.begin (); it != __config_repository.usr.end (); ++it) { usr_os << it->first << " = " << it->second << "\n"; } __config_repository.updated.clear (); return true; } return false; } } // namespace scim /* vi:ts=4:ai:nowrap:expandtab */ scim-1.4.15/src/scim_frontend_module.h0000644000175000017500000001127712422143415017306 0ustar tzhuantzhuan/** @file scim_frontend_module.h * @brief definition of FrontEndModule related classes. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_frontend_module.h,v 1.16 2005/01/10 08:30:54 suzhe Exp $ */ #ifndef __SCIM_FRONTEND_MODULE_H #define __SCIM_FRONTEND_MODULE_H namespace scim { /** * @addtogroup FrontEnd * @{ */ /** * @brief Initialize a FrontEnd Module. * * There must be a function called "scim_frontend_module_init" * in each frontend module which complies with this prototype. * This function name can have a prefix like x11_LTX_, * in which "x11" is the module's name. * * @param backend - a BackEnd instance which hold all IMEngineFactory instances. * @param config - a ConfigBase instance to maintain the configuration. */ typedef void (*FrontEndModuleInitFunc) (const BackEndPointer &backend, const ConfigPointer &config, int argc, char **argv); /** * @brief Run a FrontEnd Module. * * There must be a function called "scim_frontend_module_run" * in each frontend module which complies with this prototype. * This function name can have a prefix like x11_LTX_, * in which "x11" is the module's name. */ typedef void (*FrontEndModuleRunFunc) (void); /** * @brief The class to manipulate the frontend modules. * * This is a wrapper of scim::Module class, which is specially * for manipulating the frontend modules. */ class FrontEndModule { Module m_module; FrontEndModuleInitFunc m_frontend_init; FrontEndModuleRunFunc m_frontend_run; FrontEndModule (const FrontEndModule &); FrontEndModule & operator= (const FrontEndModule &); public: /** * @brief Default constructor. */ FrontEndModule (); /** * @brief Constructor. * @param name - the module's name, eg. "rawcode". * @param backend - a BackEnd instance which holds all IMEngineFactory instances. * @param config - a smart pointer points to a ConfigBase instance. * @param argc - the number of (fake) command line arguments * @param argv - the (fake) command line argument vector */ FrontEndModule (const String &name, const BackEndPointer &backend, const ConfigPointer &config, int argc, char **argv); /** * @brief Load a FrontEnd module by its name. * * Load a module into memory. * If another module has been loaded into this object, * then the old module will be unloaded first. * If the old module is resident, false will be returned, * and the old module will be untouched. * * @param name - the module's name, eg. "rawcode". * @param backend - a BackEnd instance which holds all IMEngineFactory instances. * @param config - a smart pointer points to a ConfigBase instance. * @param argc - the number of (fake) command line arguments * @param argv - the (fake) command line argument vector */ bool load (const String &name, const BackEndPointer &backend, const ConfigPointer &config, int argc, char **argv); /** * @brief Check if a module is loaded and initialized successfully. * @return true if a module is already loaded and initialized successfully. */ bool valid () const; /** * @brief run this FrontEnd module. */ void run () const; }; /** * @brief Get a name list of currently available frontend modules. * @param mod_list - the result list will be stored here. * @return the number of the modules, equal to mod_list.size (). */ int scim_get_frontend_module_list (std::vector & mod_list); /** @} */ } // namespace scim #endif //__SCIM_FRONTEND_MODULE_H /* vi:ts=4:ai:nowrap:expandtab */ scim-1.4.15/src/scim_frontend_module.cpp0000644000175000017500000000552012422143415017633 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_frontend_module.cpp,v 1.13 2005/01/10 08:30:54 suzhe Exp $ * */ #define Uses_SCIM_FRONTEND_MODULE #include "scim_private.h" #include "scim.h" namespace scim { FrontEndModule::FrontEndModule () : m_frontend_init (0), m_frontend_run (0) { } FrontEndModule::FrontEndModule (const String &name, const BackEndPointer &backend, const ConfigPointer &config, int argc, char **argv) : m_frontend_init (0), m_frontend_run (0) { load (name, backend, config, argc, argv); } bool FrontEndModule::load (const String &name, const BackEndPointer &backend, const ConfigPointer &config, int argc, char **argv) { try { if (!m_module.load (name, "FrontEnd")) return false; m_frontend_init = (FrontEndModuleInitFunc) m_module.symbol ("scim_frontend_module_init"); m_frontend_run = (FrontEndModuleRunFunc) m_module.symbol ("scim_frontend_module_run"); if (!m_frontend_init || !m_frontend_run) { m_module.unload (); m_frontend_init = 0; m_frontend_run = 0; return false; } m_frontend_init (backend, config, argc, argv); } catch (...) { /* Don't unload FrontEnd module to avoid possible crash, when the * exception is thrown by the module itself. * m_module.unload (); */ m_frontend_init = 0; m_frontend_run = 0; return false; } return true; } bool FrontEndModule::valid () const { return (m_module.valid () && m_frontend_init && m_frontend_run); } void FrontEndModule::run () const { if (valid ()) m_frontend_run (); } int scim_get_frontend_module_list (std::vector & mod_list) { return scim_get_module_list (mod_list, "FrontEnd"); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_frontend.h0000644000175000017500000005156212422143415015742 0ustar tzhuantzhuan/** @file scim_frontend.h * @brief Defines scim::FrontEndBase interface. * */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_frontend.h,v 1.42 2005/10/06 18:02:06 liuspider Exp $ */ #ifndef __SCIM_FRONTEND_H #define __SCIM_FRONTEND_H namespace scim { /** * @addtogroup FrontEnd * The base classes for FrontEnd modules. * @{ */ /** * @brief An exception class to hold FrontEnd related errors. * * scim::FrontEndBase and its derived classes must throw * scim::FrontEndError object when error. */ class FrontEndError: public Exception { public: FrontEndError (const String& what_arg) : Exception (String("scim::FrontEnd: ") + what_arg) { } }; class FrontEndBase; /** * @typedef typedef Pointer FrontEndPointer; * * A smart pointer for scim::FrontEndBase and its derived classes. */ typedef Pointer FrontEndPointer; /** * @brief The base class to implement the FrontEnd objects. * * FrontEnd is an interface between IMEngineFactory/IMEngineInstance objects * and the user applications. It forward the user requests to * IMEngineFactory/IMEngineInstance objects, and handle the requests sent back. */ class FrontEndBase : public ReferencedObject { class FrontEndBaseImpl; FrontEndBaseImpl *m_impl; friend class FrontEndBaseImpl; public: /** * @brief Constructor. * @param backend A BackEnd object which holds all IMEngineFactory objects. */ FrontEndBase (const BackEndPointer &backend); /** * @brief Virtual destructor. */ virtual ~FrontEndBase (); protected: /** * @name functions can be used by derived classes. * * @{ */ /** * @brief Get the IMEngine factories list for specific encoding * * @param uuids the vector to store the factories' uuids which * support the encoding. * @param encoding the encoding to be queried. If empty, * all IMEngine factories will be returned. * * @return the number of IMEngine factories found. */ uint32 get_factory_list_for_encoding (std::vector &uuids, const String &encoding) const; /** * @brief Get the IMEngine factories list for specific language * * @param uuids the vector to store the factories' uuids which * support the encoding. * @param language the language to be queried. If empty, * all IMEngine factories will be returned. * * @return the number of IMEngine factories found. */ uint32 get_factory_list_for_language (std::vector &uuids, const String &language) const; /** * @brief Get the default IMEngineFactory UUID for a specific language and encoding. * * @param language the language to be queried. * @param encoding the encoding to be queried, if empty then don't match encoding. * * @return the UUID of the default IMEngineFactory for this language. */ String get_default_factory (const String &language, const String &encoding) const; /** * @brief Set the default IMEngineFactory for a specific language. * * @param language the language to be set. * @param uuid the uuid of the default IMEngineFactory for this language. */ void set_default_factory (const String &language, const String &uuid); /** * @brief Get the next IMEngineFactory for a specific language and encoding. * * @param language the language to be queried, if empty then don't match language. * @param encoding the encoding to be queried, if empty then don't match encoding. * @param cur_uuid the UUID of current IMEngineFactory. * * @return the UUID of the next IMEngineFactory for this language and encoding * corresponding to the current IMEngineFactory. */ String get_next_factory (const String &language, const String &encoding, const String &cur_uuid) const; /** * @brief Get the previous IMEngineFactory for a specific language and encoding. * * @param language the language to be queried, if empty then don't match language. * @param encoding the encoding to be queried, if empty then don't match encoding. * @param cur_uuid the UUID of current IMEngineFactory. * * @return the UUID of the previous IMEngineFactory for this language and encoding * corresponding to the current IMEngineFactory. */ String get_previous_factory (const String &language, const String &encoding, const String &cur_uuid) const; /** * @brief get the name of an IMEngine factory. * * @param uuid the uuid of the IMEngine factory * @return the name of the IMEngine factory. */ WideString get_factory_name (const String &uuid) const; /** * @brief get the authors info of an IMEngine factory. * @param uuid the uuid of the IMEngine factory * @return the authors info of the IMEngine factory. */ WideString get_factory_authors (const String &uuid) const; /** * @brief get the credits info of an IMEngine factory. * @param uuid the uuid of the IMEngine factory * @return the credits info of the IMEngine factory. */ WideString get_factory_credits (const String &uuid) const; /** * @brief get the help info of an IMEngine factory. * @param uuid the uuid of the IMEngine factory * @return the help info of the IMEngine factory. */ WideString get_factory_help (const String &uuid) const; /** * @brief get the icon file of an IMEngine factory. * @param uuid the uuid of the IMEngine factory * @return the icon file name of the IMEngine factory. */ String get_factory_icon_file (const String &uuid) const; /** * @brief get the supported locales of an IMEngine factory. * @param uuid the uuid of the IMEngine factory * @return a comma separated list of the supported locales. */ String get_factory_locales (const String &uuid) const; /** * @brief get the language of an IMEngine factory. * @param uuid the uuid of the IMEngine factory * @return the language of this IMEngine factory. */ String get_factory_language (const String &uuid) const; /** * @brief Check if an IMEngine factory is valid and the given encoding is supported by it. * * @param uuid The uuid of the IMEngine factory to be checked. * @param encoding The encoding should be supported by the factory. * @return true if the factory is valid and the given encoding is supported. */ bool validate_factory (const String &uuid, const String &encoding = String ("")) const; /** * @brief get all locales supported by BackEnd. * @return a comman separated list of all supported locales. */ String get_all_locales () const; // IMEngine instance related functions. /** * @brief create a new IMEngine instance for specific encoding. * * @param sf_uuid the IMEngineFactory UUID. * @param encoding the encoding to be used. * * @return the newly created IMEngine instance id, -1 means error occurred. */ int new_instance (const String &sf_uuid, const String &encoding); /** * @brief replace an IMEngine instance by a new instance created by another factory. * * This function is used to change the input method for an input context on the fly. * * @param si_id the IMEngine instance to be replaced. * @param sf_uuid the new IMEngine factory to be used. * @return true if success. */ bool replace_instance (int si_id, const String &sf_uuid); /** * @brief delete an IMEngine instance according to its id. * @param id the id of the IMEngine instance to be deleted. * @return true if success, false if there is no such instance. */ bool delete_instance (int id); /** * @brief delete all IMEngine instances. * * This function should be called just before quitting the FrontEnd. */ void delete_all_instances (); /** * @brief get the factory uuid of this instance. * @param id the IMEngine instance id. * @return the factory uuid of this instance. */ String get_instance_uuid (int id) const; /** * @brief get the working encoding of an IMEngine instance. * @param id the IMEngine instance id. * @return the working encoding of this IMEngine instance. */ String get_instance_encoding (int id) const; /** * @brief get the name of an IMEngine instance. * @param id the IMEngine instance id. * @return the name of this IMEngine instance, * aka. the name of its factory. */ WideString get_instance_name (int id) const; /** * @brief get the authors info of an IMEngine instance. * @param id the IMEngine instance id. * @return the authors info of this IMEngine instance, * aka. the authors of its factory. */ WideString get_instance_authors (int id) const; /** * @brief get the credits info of an IMEngine instance. * @param id the IMEngine instance id. * @return the credits info of this IMEngine instance, * aka. the credits of its factory. */ WideString get_instance_credits (int id) const; /** * @brief get the help of an IMEngine instance. * @param id the IMEngine instance id. * @return the help of this IMEngine instance, * aka. the help of its factory. */ WideString get_instance_help (int id) const; /** * @brief get the icon file of an IMEngine instance. * @param id the IMEngine instance id. * @return the icon file name of this IMEngine instance. */ String get_instance_icon_file (int id) const; /** * @brief process a key event using specific IMEngine instance. * @param id the IMEngine instance id. * @param key the key event to be processed. * @return true if the event was processed successfully, * false if the event was not processed and should * be forward to the client application. */ bool process_key_event (int id, const KeyEvent& key) const; /** * @brief let a specific IMEngine instance move its preedit caret. * @param id the IMEngine instance id. * @param pos the new preedit caret position. */ void move_preedit_caret (int id, unsigned int pos) const; /** * @brief let a specific IMEngine instance select a candidate in its current lookup table. * @param id the IMEngine instance id. * @param index the candidate index in current lookup table page to be selected. */ void select_candidate (int id, unsigned int index) const; /** * @brief update the page size of a specific IMEngine instance's lookup table. * @param id the IMEngine instance id. * @param page_size the new page size to be used. */ void update_lookup_table_page_size (int id, unsigned int page_size) const; /** * @brief Let a specific IMEngine instance flip its lookup table to the previous page. */ void lookup_table_page_up (int id) const; /** * @brief Let a specific IMEngine instance flip its lookup table to the previous page. */ void lookup_table_page_down (int id) const; /** * @brief reset a specific IMEngine instance. * @param id the id of the IMEngine instance to be reset. */ void reset (int id) const; /** * @brief focus in a specific IMEngine instance. * @param id the id of the IMEngine instance to be focused in. */ void focus_in (int id) const; /** * @brief focus out a specific IMEngine instance. * @param id the id of the IMEngine instance to be focused out. */ void focus_out (int id) const; /** * @brief trigger a property of a specific IMEngine instance. * @param id the id of the IMEngine instance. * @param property the key of the property to be triggered. */ void trigger_property (int id, const String &property) const; /** * @brief let a specific IMEngine instance to process the events sent from a Helper process. * @param id the id of the IMEngine instance. * @param helper_uuid the uuid of the Helper process. * @param trans the transaction which contains the events. */ void process_helper_event (int id, const String &helper_uuid, const Transaction &trans) const; /** * @brief let a specific IMEngine instance to update itself according to the capabilities of the client application. * @param id the id of the IMEngine instance. * @param cap the bitset of the capabilities which are supported by client. */ void update_client_capabilities (int id, unsigned int cap) const; /** * @} */ protected: /** * @name Virtual protected methods. * * The following methods should be implemented by derivation classes. * these functions handle the real things. * * @{ */ /** * @brief show preedit string area for an IMEngine instance. * @param id the id of the IMEngine instance. It must have been focused in. */ virtual void show_preedit_string (int id); /** * @brief show aux string area for an IMEngine instance. * @param id the id of the IMEngine instance. It must have been focused in. */ virtual void show_aux_string (int id); /** * @brief show lookup table area for an IMEngine instance. * @param id the id of the IMEngine instance. It must have been focused in. */ virtual void show_lookup_table (int id); /** * @brief hide preedit string area for an IMEngine instance. * @param id the id of the IMEngine instance. It must have been focused in. */ virtual void hide_preedit_string (int id); /** * @brief hide aux string area for an IMEngine instance. * @param id the id of the IMEngine instance. It must have been focused in. */ virtual void hide_aux_string (int id); /** * @brief hide lookup table area for an IMEngine instance. * @param id the id of the IMEngine instance. It must have been focused in. */ virtual void hide_lookup_table (int id); /** * @brief update the position of preedit caret for an IMEngine instance. * @param id the id of the IMEngine instance. It must have been focused in. * @param caret the new caret position. */ virtual void update_preedit_caret (int id, int caret); /** * @brief update the content of preedit string for an IMEngine instance. * @param id the id of the IMEngine instance. It must have been focused in. * @param str the new content of preedit string. * @param attrs the string attributes. */ virtual void update_preedit_string (int id, const WideString & str, const AttributeList & attrs); /** * @brief update the content of aux string for an IMEngine instance. * @param id the id of the IMEngine instance. It must have been focused in. * @param str the new content of aux string. * @param attrs the string attributes. */ virtual void update_aux_string (int id, const WideString & str, const AttributeList & attrs); /** * @brief update the content of lookup table for an IMEngine instance. * @param id the id of the IMEngine instance. It must have been focused in. * @param table the new lookup table. */ virtual void update_lookup_table (int id, const LookupTable & table); /** * @brief commit a string to client for an IMEngine instance. * @param id the id of the IMEngine instance to commit the string. * @param str the string to be committed. */ virtual void commit_string (int id, const WideString & str); /** * @brief forward a keyevent to the client of an IMEngine instance. * @param id the id of the IMEngine instance. * @param key the key event to be forwarded. */ virtual void forward_key_event (int id, const KeyEvent & key); /** * @brief register all the properties of an IMEngine instance into this FrontEnd. * @param id the id of the IMEngine instance. It must have been focused in. * @param properties the PropertyList contains all the properties of this IMEngine instance. */ virtual void register_properties (int id, const PropertyList & properties); /** * @brief update a property of an IMEngine instance. * @param id the id of the IMEngine instance. It must have been focused in. * @param property the Property to be updated. */ virtual void update_property (int id, const Property & property); /** * @brief generate a short beep. * @param id the id of the IMEngine instance. It must have been focused in. */ virtual void beep (int id); /** * @brief start a Client Helper process. * * @param id the id of the IMEngine instance. It must have been focused in. * @param helper_uuid The UUID of the Helper object. */ virtual void start_helper (int id, const String &helper_uuid); /** * @brief stop a Client Helper process. * * @param id the id of the IMEngine instance. It must have been focused in. * @param helper_uuid The UUID of the Helper object. */ virtual void stop_helper (int id, const String &helper_uuid); /** * @brief send an events transaction to a Client Helper process. * * @param id the id of the IMEngine instance. It must have been focused in. * @param helper_uuid The UUID of the Helper object. * @param trans the transaction which contains events. */ virtual void send_helper_event (int id, const String &helper_uuid, const Transaction &trans); /** * @brief Retrieves context around the insertion point. * * Input methods typically want context in order to constrain * input text based on existing text; * this is important for languages such as Thai where * only some sequences of characters are allowed. * * Unlike other signal activation actions, this action will return the result * immediately. * * @param id the id of the IMEngine instance. It must have been focused in. * @param text location to store the context string around the insertion point. * @param cursor location to store index of the insertion cursor within @text. * @param maxlen_before the maxmium length of context string to be retrieved * before the cursor; -1 means unlimited. * @param maxlen_after the maxmium length of context string to be retrieved * after the cursor; -1 means unlimited. * * @return true if surrounding text was provided. */ virtual bool get_surrounding_text (int id, WideString &text, int &cursor, int maxlen_before, int maxlen_after); /** * @brief Ask the client to delete characters around the cursor position. * * In order to use this function, you should first call * get_surrounding_text () to get the current context, and * call this function immediately afterwards to make sure that you * know what you are deleting. You should also account for the fact * that even if the signal was handled, the input context might not * have deleted all the characters that were requested to be deleted. * * @param id the id of the IMEngine instance. It must have been focused in. * @param offset offset from cursor position in chars; * a negative value means start before the cursor. * @param len number of characters to delete. * * @return true if the signal was handled. */ virtual bool delete_surrounding_text (int id, int offset, int len); /** * @} */ public: /** * @brief init the frontend. * * This method must be implemented by derivation classes. */ virtual void init (int argc, char **argv) = 0; /** * @brief run the frontend. * * This method must be implemented by derivation classes. */ virtual void run () = 0; }; /** @} */ } // namespace scim #endif //__SCIM_FRONTEND_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_frontend.cpp0000644000175000017500000004620012422143415016266 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_frontend.cpp,v 1.44 2005/06/26 16:35:33 suzhe Exp $ * */ #define Uses_SCIM_FRONTEND #include "scim_private.h" #include "scim.h" namespace scim { #if SCIM_USE_STL_EXT_HASH_MAP typedef __gnu_cxx::hash_map > IMEngineInstanceRepository; #elif SCIM_USE_STL_HASH_MAP typedef std::hash_map > IMEngineInstanceRepository; #else typedef std::map IMEngineInstanceRepository; #endif class FrontEndBase::FrontEndBaseImpl { public: FrontEndBase *m_frontend; BackEndPointer m_backend; IMEngineInstanceRepository m_instance_repository; int m_instance_count; public: FrontEndBaseImpl (FrontEndBase *fe, const BackEndPointer &backend) :m_frontend (fe), m_backend (backend), m_instance_count (0) { } IMEngineInstancePointer find_instance (int id) const { IMEngineInstanceRepository::const_iterator it = m_instance_repository.find (id); if (it != m_instance_repository.end ()) return it->second; return IMEngineInstancePointer (0); } void slot_show_preedit_string (IMEngineInstanceBase * si) { m_frontend->show_preedit_string (si->get_id ()); } void slot_show_aux_string (IMEngineInstanceBase * si) { m_frontend->show_aux_string (si->get_id ()); } void slot_show_lookup_table (IMEngineInstanceBase * si) { m_frontend->show_lookup_table (si->get_id ()); } void slot_hide_preedit_string (IMEngineInstanceBase * si) { m_frontend->hide_preedit_string (si->get_id ()); } void slot_hide_aux_string (IMEngineInstanceBase * si) { m_frontend->hide_aux_string (si->get_id ()); } void slot_hide_lookup_table (IMEngineInstanceBase * si) { m_frontend->hide_lookup_table (si->get_id ()); } void slot_update_preedit_caret (IMEngineInstanceBase * si, int caret) { m_frontend->update_preedit_caret (si->get_id (), caret); } void slot_update_preedit_string (IMEngineInstanceBase * si, const WideString & str, const AttributeList & attrs) { m_frontend->update_preedit_string (si->get_id (), str, attrs); } void slot_update_aux_string (IMEngineInstanceBase * si, const WideString & str, const AttributeList & attrs) { m_frontend->update_aux_string (si->get_id (), str, attrs); } void slot_update_lookup_table (IMEngineInstanceBase * si, const LookupTable & table) { m_frontend->update_lookup_table (si->get_id (), table); } void slot_commit_string (IMEngineInstanceBase * si, const WideString & str) { m_frontend->commit_string (si->get_id (), str); } void slot_forward_key_event (IMEngineInstanceBase * si, const KeyEvent & key) { m_frontend->forward_key_event (si->get_id (), key); } void slot_register_properties (IMEngineInstanceBase * si, const PropertyList & properties) { m_frontend->register_properties (si->get_id (), properties); } void slot_update_property (IMEngineInstanceBase * si, const Property & property) { m_frontend->update_property (si->get_id (), property); } void slot_beep (IMEngineInstanceBase * si) { m_frontend->beep (si->get_id ()); } void slot_start_helper (IMEngineInstanceBase * si, const String & helper_uuid) { m_frontend->start_helper (si->get_id (), helper_uuid); } void slot_stop_helper (IMEngineInstanceBase * si, const String & helper_uuid) { m_frontend->stop_helper (si->get_id (), helper_uuid); } void slot_send_helper_event (IMEngineInstanceBase * si, const String & helper_uuid, const Transaction & trans) { m_frontend->send_helper_event (si->get_id (), helper_uuid, trans); } bool slot_get_surrounding_text (IMEngineInstanceBase * si, WideString &text, int &cursor, int maxlen_before, int maxlen_after) { return m_frontend->get_surrounding_text (si->get_id (), text, cursor, maxlen_before, maxlen_after); } bool slot_delete_surrounding_text(IMEngineInstanceBase * si, int offset, int len) { return m_frontend->delete_surrounding_text (si->get_id (), offset, len); } void attach_instance (const IMEngineInstancePointer &si) { si->signal_connect_show_preedit_string ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_show_preedit_string)); si->signal_connect_show_aux_string ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_show_aux_string)); si->signal_connect_show_lookup_table ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_show_lookup_table)); si->signal_connect_hide_preedit_string ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_hide_preedit_string)); si->signal_connect_hide_aux_string ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_hide_aux_string)); si->signal_connect_hide_lookup_table ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_hide_lookup_table)); si->signal_connect_update_preedit_caret ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_update_preedit_caret)); si->signal_connect_update_preedit_string ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_update_preedit_string)); si->signal_connect_update_aux_string ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_update_aux_string)); si->signal_connect_update_lookup_table ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_update_lookup_table)); si->signal_connect_commit_string ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_commit_string)); si->signal_connect_forward_key_event ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_forward_key_event)); si->signal_connect_register_properties ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_register_properties)); si->signal_connect_update_property ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_update_property)); si->signal_connect_beep ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_beep)); si->signal_connect_start_helper ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_start_helper)); si->signal_connect_stop_helper ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_stop_helper)); si->signal_connect_send_helper_event ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_send_helper_event)); si->signal_connect_get_surrounding_text ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_get_surrounding_text)); si->signal_connect_delete_surrounding_text ( slot (this, &FrontEndBase::FrontEndBaseImpl::slot_delete_surrounding_text)); } }; FrontEndBase::FrontEndBase (const BackEndPointer &backend) : m_impl (new FrontEndBaseImpl (this, backend)) { } FrontEndBase::~FrontEndBase () { delete m_impl; } uint32 FrontEndBase::get_factory_list_for_encoding (std::vector& uuids, const String &encoding) const { std::vector factories; m_impl->m_backend->get_factories_for_encoding (factories, encoding); uuids.clear (); for (std::vector::iterator it = factories.begin (); it != factories.end (); ++it) uuids.push_back ((*it)->get_uuid ()); return uuids.size (); } uint32 FrontEndBase::get_factory_list_for_language (std::vector& uuids, const String &language) const { std::vector factories; m_impl->m_backend->get_factories_for_language (factories, language); uuids.clear (); for (std::vector::iterator it = factories.begin (); it != factories.end (); ++it) uuids.push_back ((*it)->get_uuid ()); return uuids.size (); } String FrontEndBase::get_default_factory (const String &language, const String &encoding) const { IMEngineFactoryPointer def = m_impl->m_backend->get_default_factory (language, encoding); if (!def.null ()) return def->get_uuid (); return String (); } void FrontEndBase::set_default_factory (const String &language, const String &uuid) { m_impl->m_backend->set_default_factory (language, uuid); } String FrontEndBase::get_next_factory (const String &language, const String &encoding, const String &cur_uuid) const { IMEngineFactoryPointer next = m_impl->m_backend->get_next_factory (language, encoding, cur_uuid); if (!next.null ()) return next->get_uuid (); return String (); } String FrontEndBase::get_previous_factory (const String &language, const String &encoding, const String &cur_uuid) const { IMEngineFactoryPointer prev = m_impl->m_backend->get_previous_factory (language, encoding, cur_uuid); if (!prev.null ()) return prev->get_uuid (); return String (); } WideString FrontEndBase::get_factory_name (const String &uuid) const { IMEngineFactoryPointer factory = m_impl->m_backend->get_factory (uuid); if (!factory.null ()) return factory->get_name (); return WideString (); } WideString FrontEndBase::get_factory_authors (const String &uuid) const { IMEngineFactoryPointer factory = m_impl->m_backend->get_factory (uuid); if (!factory.null ()) return factory->get_authors (); return WideString (); } WideString FrontEndBase::get_factory_credits (const String &uuid) const { IMEngineFactoryPointer factory = m_impl->m_backend->get_factory (uuid); if (!factory.null ()) return factory->get_credits (); return WideString (); } WideString FrontEndBase::get_factory_help (const String &uuid) const { IMEngineFactoryPointer factory = m_impl->m_backend->get_factory (uuid); if (!factory.null ()) return factory->get_help (); return WideString (); } String FrontEndBase::get_factory_locales (const String &uuid) const { IMEngineFactoryPointer factory = m_impl->m_backend->get_factory (uuid); if (!factory.null ()) return factory->get_locales (); return String (); } String FrontEndBase::get_factory_language (const String &uuid) const { IMEngineFactoryPointer factory = m_impl->m_backend->get_factory (uuid); if (!factory.null ()) return factory->get_language (); return String (); } String FrontEndBase::get_factory_icon_file (const String &uuid) const { IMEngineFactoryPointer factory = m_impl->m_backend->get_factory (uuid); if (!factory.null ()) return factory->get_icon_file (); return String (); } bool FrontEndBase::validate_factory (const String &uuid, const String &encoding) const { IMEngineFactoryPointer factory = m_impl->m_backend->get_factory (uuid); return !factory.null () && (encoding.length () == 0 || factory->validate_encoding (encoding)); } String FrontEndBase::get_all_locales () const { return m_impl->m_backend->get_all_locales (); } int FrontEndBase::new_instance (const String &sf_uuid, const String& encoding) { IMEngineFactoryPointer factory = m_impl->m_backend->get_factory (sf_uuid); if (factory.null () || !factory->validate_encoding (encoding)) { SCIM_DEBUG_FRONTEND (1) << "IMEngineFactory " << sf_uuid << " does not support encoding " << encoding << "\n"; return -1; } IMEngineInstancePointer si = factory->create_instance (encoding, m_impl->m_instance_count); if (si.null ()) { SCIM_DEBUG_BACKEND(1) << "IMEngineFactory " << sf_uuid << " failed to create new instance!\n"; return -1; } ++ m_impl->m_instance_count; if (m_impl->m_instance_count < 0) m_impl->m_instance_count = 0; m_impl->m_instance_repository [si->get_id ()] = si; m_impl->attach_instance (si); return si->get_id (); } bool FrontEndBase::replace_instance (int si_id, const String &sf_uuid) { IMEngineFactoryPointer sf = m_impl->m_backend->get_factory (sf_uuid); if (sf.null ()) return false; IMEngineInstanceRepository::iterator it = m_impl->m_instance_repository.find (si_id); if (it != m_impl->m_instance_repository.end ()) { if (it->second->get_factory_uuid () == sf_uuid) return true; String encoding = it->second->get_encoding (); if (sf->validate_encoding (encoding)) { IMEngineInstancePointer si = sf->create_instance (encoding, si_id); if (!si.null ()) { it->second = si; m_impl->attach_instance (it->second); return true; } } } SCIM_DEBUG_BACKEND(1) << "Cannot find IMEngine Instance " << si_id << " to replace.\n"; return false; } bool FrontEndBase::delete_instance (int id) { IMEngineInstanceRepository::iterator it = m_impl->m_instance_repository.find (id); if (it != m_impl->m_instance_repository.end ()) { m_impl->m_instance_repository.erase (it); return true; } return false; } void FrontEndBase::delete_all_instances () { m_impl->m_instance_repository.clear (); } String FrontEndBase::get_instance_uuid (int id) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) return si->get_factory_uuid (); return String (); } String FrontEndBase::get_instance_encoding (int id) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) return si->get_encoding (); return String (); } WideString FrontEndBase::get_instance_name (int id) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) return get_factory_name (si->get_factory_uuid ()); return WideString (); } WideString FrontEndBase::get_instance_authors (int id) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) return get_factory_authors (si->get_factory_uuid ()); return WideString (); } WideString FrontEndBase::get_instance_credits (int id) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) return get_factory_credits (si->get_factory_uuid ()); return WideString (); } WideString FrontEndBase::get_instance_help (int id) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) return get_factory_help (si->get_factory_uuid ()); return WideString (); } String FrontEndBase::get_instance_icon_file (int id) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) return get_factory_icon_file (si->get_factory_uuid ()); return String (); } void FrontEndBase::focus_in (int id) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) si->focus_in (); } void FrontEndBase::focus_out (int id) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) si->focus_out (); } void FrontEndBase::reset (int id) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) si->reset (); } bool FrontEndBase::process_key_event (int id, const KeyEvent& key) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) return si->process_key_event (key); return false; } void FrontEndBase::move_preedit_caret (int id, unsigned int pos) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) si->move_preedit_caret (pos); } void FrontEndBase::select_candidate (int id, unsigned int index) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) si->select_candidate (index); } void FrontEndBase::update_lookup_table_page_size (int id, unsigned int page_size) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) si->update_lookup_table_page_size (page_size); } void FrontEndBase::lookup_table_page_up (int id) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) si->lookup_table_page_up (); } void FrontEndBase::lookup_table_page_down (int id) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) si->lookup_table_page_down (); } void FrontEndBase::trigger_property (int id, const String & property) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) si->trigger_property (property); } void FrontEndBase::process_helper_event (int id, const String & helper_uuid, const Transaction & trans) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) si->process_helper_event (helper_uuid, trans); } void FrontEndBase::update_client_capabilities (int id, unsigned int cap) const { IMEngineInstancePointer si = m_impl->find_instance (id); if (!si.null ()) si->update_client_capabilities (cap); } void FrontEndBase::show_preedit_string (int id) { } void FrontEndBase::show_aux_string (int id) { } void FrontEndBase::show_lookup_table (int id) { } void FrontEndBase::hide_preedit_string (int id) { } void FrontEndBase::hide_aux_string (int id) { } void FrontEndBase::hide_lookup_table (int id) { } void FrontEndBase::update_preedit_caret (int id, int caret) { } void FrontEndBase::update_preedit_string (int id, const WideString & str, const AttributeList & attrs) { } void FrontEndBase::update_aux_string (int id, const WideString & str, const AttributeList & attrs) { } void FrontEndBase::update_lookup_table (int id, const LookupTable & table) { } void FrontEndBase::commit_string (int id, const WideString & str) { } void FrontEndBase::forward_key_event (int id, const KeyEvent & key) { } void FrontEndBase::register_properties (int id, const PropertyList & properties) { } void FrontEndBase::update_property (int id, const Property & property) { } void FrontEndBase::beep (int id) { } void FrontEndBase::start_helper (int id, const String &helper_uuid) { } void FrontEndBase::stop_helper (int id, const String &helper_uuid) { } void FrontEndBase::send_helper_event (int id, const String &helper_uuid, const Transaction &trans) { } bool FrontEndBase::get_surrounding_text (int id, WideString &text, int &cursor, int maxlen_before, int maxlen_after) { return false; } bool FrontEndBase::delete_surrounding_text (int id, int offset, int len) { return false; } } // namespace scim /* vi:ts=4:ai:nowrap:expandtab */ scim-1.4.15/src/scim_filter_module.h0000644000175000017500000001470712422143415016755 0ustar tzhuantzhuan/** @file scim_filter_module.h * @brief definition of FilterModule related classes. */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_filter_module.h,v 1.7 2005/10/06 18:02:06 liuspider Exp $ */ #ifndef __SCIM_FILTER_MODULE_H #define __SCIM_FILTER_MODULE_H namespace scim { /** * @addtogroup IMEngine * @{ */ /** * @brief Initialize a Filter Module. * * There must be a function called "scim_filter_module_init" * in each filter module which complies with this prototype. * This function name can have a prefix like sctc_LTX_, * in which "sctc" is the module's name. * * If a filter needs services from other IMEngineFactory objects, it should * obtain the pointer of these IMEngineFactory objects from the given BacnEnd * pointer. But please note that, those IMEngineFactory objects may not be loaded yet, * when initializing this Filter module. * So the pointers of available IMEngineFactory objects should only be queried from * the BackEnd at the first time to used by this Filter. * * @param config a ConfigBase instance to maintain the configuration. * * @return the number of filters provided by this module. */ typedef unsigned int (*FilterModuleInitFunc) (const ConfigPointer &config); /** * @brief Create an object of this FilterFactory class * * There must be a function called "scim_filter_module_create_filter" * which complies with this prototype. * This function name can have a prefix like sctc_LTX_, * in which "sctc" is the module's name. * * A new FilterFactory object should be returned for each call. Because * multiple objects would be used at the same time. * * @param index the index of the FilterFactory to be used to create the object. * Must between 0 and (number_of_filters - 1). * @param backend the BackEnd instance which holds all real IMEngineFactory objects. * Some filter may want to use other IMEngineFactory object * to do some job, eg. inverse convert. * * @return the pointer of the FilterFactory object. */ typedef FilterFactoryPointer (*FilterModuleCreateFilterFunc) (unsigned int index); /** * @brief Get basic information of the FilterFactory class provided by this module. * * There must be a function called "scim_filter_module_get_filter_info" * which complies with this prototype. * This function name can have a prefix like sctc_LTX_, * in which "sctc" is the module's name. * * * @param index The index of the FilterFactory to be queried. * * @param info The object to hold the information. * @param index the index of the Filter to be queried. * * @return The uuid of this FilterFactory class. */ typedef bool (*FilterModuleGetFilterInfoFunc) (unsigned int index, FilterInfo &info); /** * @brief The class to manipulate the Filter modules. * * This is a wrapper of scim::Module class, which is specially * for manipulating the Filter modules. */ class FilterModule { Module m_module; FilterModuleInitFunc m_filter_init; FilterModuleCreateFilterFunc m_filter_create_filter; FilterModuleGetFilterInfoFunc m_filter_get_filter_info; unsigned int m_number_of_filters; FilterModule (const FilterModule &); FilterModule & operator= (const FilterModule &); public: /** * @brief Default constructor. */ FilterModule (); /** * @brief Constructor. * @param name the module's name, eg. "sctc". * @param config a ConfigBase instance to maintain the configuration. */ FilterModule (const String &name, const ConfigPointer &config); /** * @brief Load a Filter Module by its name. * * Load a module into memory. * If another module has been loaded into this object, * then the old module will be unloaded first. * If the old module is resident, false will be returned, * and the old module will be untouched. * * @param name - the name of the Filter Module. * @param config a ConfigBase instance to maintain the configuration. * * @return true if success. */ bool load (const String &name, const ConfigPointer &config); /** * @brief Unload the Filter Module. * @return true if sucessfully unloaded. */ bool unload (); /** * @brief Check if a module is loaded and initialized successfully. * @return true if a module is already loaded and initialized successfully. */ bool valid () const; /** * @brief Get how many Filter factories supported by this module. * * @return the number of Filter factories. */ unsigned int number_of_filters () const; /** * @brief Create an object for a Filter factory. * * @param index The index of the Filter factory, * must be less than the result of number_of_factories method * and greater than or equal to zero. * @return A smart pointer to the factory object, NULL if failed. */ FilterFactoryPointer create_filter (unsigned int index) const; /** * @brief Get basic information of the FilterFactory class provided by this module. * * @param index The index of the Filter factory to be queried. * @param info The result will be stored in this parameter. * * @return whether the info is successfully retrieved */ bool get_filter_info (unsigned int index, FilterInfo &info) const; }; /** * @brief Get a name list of currently available Filter modules. * @param mod_list - the result list will be stored here. * @return the number of the modules, equal to mod_list.size (). */ int scim_get_filter_module_list (std::vector &mod_list); /** @} */ } // namespace scim #endif //__SCIM_FILTER_MODULE_H /* vi:ts=4:ai:nowrap:expandtab */ scim-1.4.15/src/scim_filter_module.cpp0000644000175000017500000000652212422143415017304 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_filter_module.cpp,v 1.5 2005/05/24 12:22:51 suzhe Exp $ * */ #define Uses_SCIM_FILTER_MODULE #include "scim_private.h" #include "scim.h" namespace scim { FilterModule::FilterModule () : m_filter_init (0), m_filter_create_filter (0), m_filter_get_filter_info (0), m_number_of_filters (0) { } FilterModule::FilterModule (const String &name, const ConfigPointer &config) : m_filter_init (0), m_filter_create_filter (0), m_filter_get_filter_info (0), m_number_of_filters (0) { load (name, config); } bool FilterModule::load (const String &name, const ConfigPointer &config) { try { if (!m_module.load (name, "Filter")) return false; m_filter_init = (FilterModuleInitFunc) m_module.symbol ("scim_filter_module_init"); m_filter_create_filter = (FilterModuleCreateFilterFunc) m_module.symbol ("scim_filter_module_create_filter"); m_filter_get_filter_info = (FilterModuleGetFilterInfoFunc) m_module.symbol ("scim_filter_module_get_filter_info"); if (!m_filter_init || !m_filter_create_filter || !m_filter_get_filter_info || (m_number_of_filters = m_filter_init (config)) == 0) { m_module.unload (); m_filter_init = 0; m_filter_create_filter = 0; m_filter_get_filter_info = 0; return false; } } catch (...) { m_module.unload (); m_filter_init = 0; m_filter_create_filter = 0; m_filter_get_filter_info = 0; return false; } return true; } bool FilterModule::unload () { return m_module.unload (); } bool FilterModule::valid () const { return (m_module.valid () && m_filter_init && m_number_of_filters > 0 && m_filter_create_filter && m_filter_get_filter_info); } FilterFactoryPointer FilterModule::create_filter (unsigned int index) const { if (valid () && index < m_number_of_filters) return m_filter_create_filter (index); return FilterFactoryPointer (0); } bool FilterModule::get_filter_info (unsigned int index, FilterInfo &info) const { if (valid () && index < m_number_of_filters) return m_filter_get_filter_info (index, info); return false; } unsigned int FilterModule::number_of_filters () const { return m_number_of_filters; } int scim_get_filter_module_list (std::vector & engine_list) { return scim_get_module_list (engine_list, "Filter"); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_filter_manager.h0000644000175000017500000001066612422143415017102 0ustar tzhuantzhuan/** * @file scim_filter_manager.h * @brief Defines scim::FilterManager. * * scim::FilterManager is a class used to manage all Filter modules. * */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_filter_manager.h,v 1.3 2005/05/28 13:54:59 suzhe Exp $ */ #ifndef __SCIM_FILTER_MANAGER_H #define __SCIM_FILTER_MANAGER_H namespace scim { /** * @addtogroup IMEngine * @{ */ class FilterManager { class FilterManagerImpl; FilterManagerImpl *m_impl; FilterManager (const FilterManager &); const FilterManager & operator = (const FilterManager &); public: FilterManager (const ConfigPointer &config); ~FilterManager (); /** * @brief Get the total number of Filters supported by all filter modules. */ unsigned int number_of_filters () const; /** * @brief Get the information of a specific filter by its index. * * @param idx The index of the filter, must between 0 to number_of_filters () - 1. * @param info The FilterInfo object to store the information. * @return true if this filter is ok and the information is stored correctly. */ bool get_filter_info (unsigned int idx, FilterInfo &info) const; /** * @brief Get the information of a specific filter by its uuid. * * @param uuid The uuid of the filter. * @param info The FilterInfo object to store the information. * @return true if this filter is ok and the information is stored correctly. */ bool get_filter_info (const String &uuid, FilterInfo &info) const; /** * @brief Clear all Filter settings for IMEngines. */ void clear_all_filter_settings () const; /** * @brief Get a list of Filters binded to an IMEngine. * * @param uuid The uuid of the IMEngine to be queried. * @param filters The list of Filters' UUIDs binded to the IMEngine will be stored here. * * @return How many filters binded to this IMEngine. */ size_t get_filters_for_imengine (const String &uuid, std::vector &filters) const; /** * @brief Bind one or more Filters to an IMEngine. * * @param uuid The uuid of the IMEngine to be binded. * @param filters The list of Filters' UUIDs to be binded to the IMEngine. */ void set_filters_for_imengine (const String &uuid, const std::vector &filters) const; /** * @brief Get a list of imengines which have one or more filters attached. * * @param imengines The UUIDs of filtered imengines will be stored here. * @return How many imengines are being filtered. */ size_t get_filtered_imengines (std::vector &imengines) const; /** * @brief Create a FilterFactory according to its index. * * @param idx The index of the filter to be created, must be less than number_of_filters() - 1. * @return The pointer of the FilterFactory object. */ FilterFactoryPointer create_filter (unsigned int idx) const; /** * @brief Create a FilterFactory according to its UUID. * * @param uuid The UUID of the filter to be created. * @return The pointer of the FilterFactory object. */ FilterFactoryPointer create_filter (const String &uuid) const; /** * @brief Attach all binded Filters to an IMEngineFactory object. * * @param factory The pointer to an IMEngineFactory object which would be filtered. * * @return New pointer of IMEngineFactory object which has Filters binded. */ IMEngineFactoryPointer attach_filters_to_factory (const IMEngineFactoryPointer &factory) const; }; /** @} */ } // namespace scim #endif //__SCIM_FILTER_MANAGER_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_filter_manager.cpp0000644000175000017500000002031012422143415017420 0ustar tzhuantzhuan/** @file scim_filter_manager.cpp * @brief Implementation of class FilterManager. */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_filter_manager.cpp,v 1.4 2005/12/16 11:12:27 suzhe Exp $ */ #define Uses_SCIM_FILTER_MODULE #define Uses_SCIM_FILTER_MANAGER #define Uses_SCIM_CONFIG_PATH #include "scim_private.h" #include "scim.h" namespace scim { struct FilterModuleIndex { FilterModule *module; unsigned int index; FilterModuleIndex () : module (0), index (0) { } }; static bool __filter_initialized = false; static unsigned int __number_of_modules = 0; static FilterModule *__filter_modules = 0; static std::vector > __filter_infos; static void __initialize_modules (const ConfigPointer &config) { if (__filter_initialized) return; __filter_initialized = true; std::vector mod_list; __number_of_modules = scim_get_filter_module_list (mod_list); if (!__number_of_modules) return; __filter_modules = new FilterModule [__number_of_modules]; unsigned int i, j; for (i = 0; i < __number_of_modules; ++i) { if (__filter_modules [i].load (mod_list [i], config)) { for (j = 0; j < __filter_modules [i].number_of_filters (); ++j) { FilterModuleIndex index; FilterInfo info; if (__filter_modules [i].get_filter_info (j, info)) { index.module = & __filter_modules [i]; index.index = j; __filter_infos.push_back (std::make_pair (index, info)); } } } } } class FilterManager::FilterManagerImpl { public: ConfigPointer m_config; FilterManagerImpl (const ConfigPointer &config) : m_config (config) { } }; FilterManager::FilterManager (const ConfigPointer &config) : m_impl (new FilterManagerImpl (config)) { } FilterManager::~FilterManager () { delete m_impl; } unsigned int FilterManager::number_of_filters () const { if (!__filter_initialized) __initialize_modules (m_impl->m_config); return __filter_infos.size (); } bool FilterManager::get_filter_info (unsigned int idx, FilterInfo &info) const { if (!__filter_initialized) __initialize_modules (m_impl->m_config); if (idx < number_of_filters ()) { info = __filter_infos [idx].second; return true; } return false; } bool FilterManager::get_filter_info (const String &uuid, FilterInfo &info) const { if (!__filter_initialized) __initialize_modules (m_impl->m_config); for (size_t i = 0; i < __filter_infos.size (); ++i) { if (__filter_infos [i].second.uuid == uuid) { info = __filter_infos [i].second; return true; } } return false; } FilterFactoryPointer FilterManager::create_filter (unsigned int idx) const { if (!__filter_initialized) __initialize_modules (m_impl->m_config); if (idx < __filter_infos.size () && __filter_infos [idx].first.module && __filter_infos [idx].first.module->valid ()) { return __filter_infos [idx].first.module->create_filter (__filter_infos [idx].first.index); } return FilterFactoryPointer (0); } FilterFactoryPointer FilterManager::create_filter (const String &uuid) const { if (!__filter_initialized) __initialize_modules (m_impl->m_config); for (size_t i = 0; i < __filter_infos.size (); ++i) { if (__filter_infos [i].second.uuid == uuid && __filter_infos [i].first.module && __filter_infos [i].first.module->valid ()) return __filter_infos [i].first.module->create_filter (__filter_infos [i].first.index); } return FilterFactoryPointer (0); } void FilterManager::clear_all_filter_settings () const { if (!m_impl->m_config.null () && m_impl->m_config->valid ()) { std::vector tmp; scim_split_string_list (tmp, m_impl->m_config->read (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST), String (""))); for (size_t i = 0; i < tmp.size (); ++i) m_impl->m_config->erase (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES) + String ("/") + tmp [i]); m_impl->m_config->erase (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST)); } } size_t FilterManager::get_filters_for_imengine (const String &uuid, std::vector &filters) const { filters.clear (); if (!m_impl->m_config.null () && m_impl->m_config->valid ()) { std::vector tmp; scim_split_string_list (tmp, m_impl->m_config->read (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST), String (""))); if (std::find (tmp.begin (), tmp.end (), uuid) != tmp.end ()) { FilterInfo info; scim_split_string_list (tmp, m_impl->m_config->read (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES) + String ("/") + uuid, String (""))); for (size_t i = 0; i < tmp.size (); ++i) { if (std::find (filters.begin (), filters.end (), tmp [i]) == filters.end () && get_filter_info (tmp [i], info)) filters.push_back (tmp [i]); } } } return filters.size (); } void FilterManager::set_filters_for_imengine (const String &uuid, const std::vector &filters) const { if (!m_impl->m_config.null () && m_impl->m_config->valid ()) { std::vector valid_filters; FilterInfo info; for (size_t i = 0; i < filters.size (); ++i) { if (std::find (valid_filters.begin (), valid_filters.end (), filters [i]) == valid_filters.end () && get_filter_info (filters [i], info)) valid_filters.push_back (filters [i]); } std::vector filtered_ims; scim_split_string_list (filtered_ims, m_impl->m_config->read (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST), String (""))); if (valid_filters.size ()) { if (std::find (filtered_ims.begin (), filtered_ims.end (), uuid) == filtered_ims.end ()) filtered_ims.push_back (uuid); m_impl->m_config->write (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES) + String ("/") + uuid, scim_combine_string_list (valid_filters)); } else { std::vector ::iterator it = std::find (filtered_ims.begin (), filtered_ims.end (), uuid); if (it != filtered_ims.end ()) filtered_ims.erase (it); m_impl->m_config->erase (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES) + String ("/") + uuid); } m_impl->m_config->write (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST), scim_combine_string_list (filtered_ims)); } } size_t FilterManager::get_filtered_imengines (std::vector &imengines) const { scim_split_string_list (imengines, m_impl->m_config->read (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST), String (""))); return imengines.size (); } IMEngineFactoryPointer FilterManager::attach_filters_to_factory (const IMEngineFactoryPointer &factory) const { IMEngineFactoryPointer root = factory; std::vector filters; if (!factory.null () && get_filters_for_imengine (factory->get_uuid (), filters)) { for (size_t i = 0; i < filters.size (); ++i) { FilterFactoryPointer filter = create_filter (filters [i]); if (!filter.null ()) { filter->attach_imengine_factory (root); root = filter; } } } return root; } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_filter.h0000644000175000017500000003543512422143415015411 0ustar tzhuantzhuan/** * @file scim_filter.h * @brief Defines scim::FilterFactoryBase and scim::FilterInstanceBase interfaces. * * scim::FilterFactoryBase and scim::FilterInstanceBase are used to implement * filter IMEngines, such as Simplified Chinese <-> Traditional Chinese converter etc. * */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_filter.h,v 1.5 2005/05/28 13:54:59 suzhe Exp $ */ #ifndef __SCIM_FILTER_H #define __SCIM_FILTER_H namespace scim { /** * @addtogroup IMEngine * The base classes for filter input method engine modules. * @{ */ /** * @brief An exception class to hold Filter related errors. * * scim::FilterFactoryBase, scim::FilterInstanceBase * and their derived classes must throw scim::FilterError object when error. */ class FilterError: public Exception { public: FilterError (const String& what_arg) : Exception (String("scim::Filter: ") + what_arg) { } }; /** * @brief Structure to hold information for a Filter. */ struct FilterInfo { String uuid; ///< The UUID. String name; ///< The localized name, in UTF-8 encoding. String langs; ///< The supported languages, separated by comma. String icon; ///< The icon file path. String desc; ///< The description. FilterInfo () { } FilterInfo (const String &u, const String &n = String (""), const String &l = String (""), const String &i = String (""), const String &d = String ("")) : uuid (u), name (n), langs (l), icon (i), desc (d) { } }; /** * @brief The base class to implement FilterFactory classes. * * All FilterFactory classes should derive from this class and some base methods * should be overrided in the derived classes. * * If a FilterFactory object need large amount of data (eg. mapping table etc.), * it'd better to share these data among all other objects of the same class. * Because multiple objects of one FilterFactory class maybe used at the same time * to filter several real IMEngineFactory objects. */ class FilterFactoryBase : public IMEngineFactoryBase { IMEngineFactoryPointer m_orig; public: /** * @brief Default Constructor. */ FilterFactoryBase (); virtual ~FilterFactoryBase (); /** * @brief Attach an IMEngineFactory object to this filter. * * The attached object could also be a filter. * * This method will set the supported locales of this filter factory * to the locales supported by the original IMEngineFactory object. * * This method could be overrided in derived class, in which some special * tasks could be done, for example, set additional supported locales. * But this method of base class must be invoked to attach the factory correctly. * * The IMEngineFactoryPointer orig may not be kept and used by derived class directly. * All tasks related to the original IMEngineFactory object should be done by * calling the corresponding methods of FilterFactoryBase class. * * @param orig The original IMEngineFactory object to be filtered. */ virtual void attach_imengine_factory (const IMEngineFactoryPointer &orig); /** * @brief Return the name of the original IMEngineFactory object * specified in contructor or by attach_imengine_factory() method. * * If there is no IMEngineFactory attached yet, * then an empty string would be returned. * * The derived class should override this method to return * the name of the filter itself when it returns an empty string. * * The derived method should look like: * *
     * WideString
     * XXXFilterFactory::get_name ()
     * {
     *     WideString name = FilterFactoryBase::get_name ();
     *     return name.length () ? name : _("XXX");
     * }
     * 
*/ virtual WideString get_name () const; /** * @brief Return the uuid of the original IMEngineFactory object * specified in contructor or by attach_imengine_factory() method. * * If there is no IMEngineFactory attached yet, * then an empty string would be returned. * * The derived class should override this method to return * the uuid of the filter itself when it returns an empty string. */ virtual String get_uuid () const; /** * @brief Return the icon file path of the original IMEngineFactory object * specified in contructor or by attach_imengine_factory() method. * * If there is no IMEngineFactory attached yet, * then an empty string would be returned. * * The derived class should override this method to return * the icon file path of the filter itself when it returns an empty string. */ virtual String get_icon_file () const; /** * @brief Return the authors information of the original IMEngineFactory object * specified in contructor or by attach_imengine_factory() method. * * If there is no IMEngineFactory attached yet, * then an empty string would be returned. * * The derived class should override this method to return * the authors information of the filter itself when it returns an empty string. */ virtual WideString get_authors () const; /** * @brief Return the credits information of the original IMEngineFactory object * specified in contructor or by attach_imengine_factory() method. * * If there is no IMEngineFactory attached yet, * then an empty string would be returned. * * The derived class should override this method to return * the credits information of the filter itself when it returns an empty string. */ virtual WideString get_credits () const; /** * @brief Return the help information of the original IMEngineFactory object * specified in contructor or by attach_imengine_factory() method. * * If there is no IMEngineFactory attached yet, * then an empty string would be returned. * * The derived class should override this method to return the combined * help information of the filter itself and the original IMEngineFactory to be filtered. */ virtual WideString get_help () const; /** * @brief Return the supported language of the original IMEngineFactory object * specified in contructor or by attach_imengine_factory() method. * * If there is no IMEngineFactory attached yet, * then an empty string would be returned. * * The derived class may override this method to return * a different language which is supported by the filter itself. */ virtual String get_language () const; /** * @brief Check if an encoding is supported by the original IMEngineFactory object * specified in constructor or by attach_imengine_factory() method. * * If there is no IMEngineFactory attached yet, then false would be returned. * * The derived class may override this method to provide its own validate routing. */ virtual bool validate_encoding (const String& encoding) const; /** * @brief Check if an locale is supported by the original IMEngineFactory object * specified in constructor or by attach_imengine_factory() method. * * If there is no IMEngineFactory attached yet, then false would be returned. * * The derived class may override this method to provide its own validate routing. */ virtual bool validate_locale (const String& locale) const; /** * @brief Get the original key string of a composed string by calling the same method of * the original IMEngineFactory object specified in constructor or by attach_imengine_factory() method. * * If there is no IMEngineFactory attached yet, then an empty string would be returned. */ virtual WideString inverse_query (const WideString &str); /** * @brief Create an IMEngineInstance object of the original IMEngineFactory object * specified in constructor or by attach_imengine_factory() method. * * The derived class should override this method and create its own instance object * from the result of this base method. * * The code may look like: * *
     * IMEngineInstancePointer
     * XXXFilterFactory::create_instance (const String& encoding, int id)
     * {
     *     return new XXXFilterInstance (this, FilterFactoryBase::create_instance (encoding, id));
     * }
     * 
*/ virtual IMEngineInstancePointer create_instance (const String& encoding, int id = -1); }; /** * @typedef typedef Pointer FilterFactoryPointer; * * A smart pointer for scim::FilterFactoryBase and its derived classes. */ typedef Pointer FilterFactoryPointer; /** * @brief The base class to implement FilterInstance classes. * * All FilterInstance classes should derive from this base class, * and some base methods should be override in the derived classes. */ class FilterInstanceBase : public IMEngineInstanceBase { class FilterInstanceBaseImpl; FilterInstanceBaseImpl *m_impl; friend class FilterInstanceBaseImpl; public: /** * @brief Constructor. * * The Constructor of derived class should call this Contructor with the following * two parameters. * * The orig_inst should be created by invoking FilterFactoryBase::create_instance() * within the same method of derived FilterFactory classes. * * @param factory the FilterFactory which creates this instance. * @param orig_inst the original IMEngineInstance to be filtered. */ FilterInstanceBase (FilterFactoryBase *factory, const IMEngineInstancePointer &orig_inst); virtual ~FilterInstanceBase (); /** * @brief Set the working encoding for this filter instance * as well as the original instance which is currently filtered. * * This method could be overrided in derived class to do some extra job. But * the method of this base class must be invoked within the new method. * * After invoking this method, reset() should be invoked to * let the new encoding take effect. * * If you want to use different encodings in this filter instance and * the original instance which is currently filtered, this method should * be overrided in the derived class and two different encodings should be * set respectively by calling FilterInstanceBase::set_encoding() and * IMEngineInstanceBase::set_encoding (); The code may look like: * * bool * XXXFilterInstance::set_encoding (const String &encoding) * { * FilterInstanceBase::set_encoding ("Other Encoding"); // Set the encoding of the original instance to another one. * return IMEngineInstanceBase::set_encoding (encoding); // Set the encoding of this filter instance to the desired one. * } * * @return true if the encoding is supported, otherwise false. */ virtual bool set_encoding (const String &encoding); public: /** * @name Action functions. * * These functions will be called by FrontEnds to send events to * this FilterInstance. * * These methods can be overrided, if the derived class wants to filter these events. * * The default implementation of these methods are just to call the corresponding methods * of the original IMEngineInstance object which is filtered by this filter. * * @{ */ virtual bool process_key_event (const KeyEvent &key); virtual void move_preedit_caret (unsigned int pos); virtual void select_candidate (unsigned int index); virtual void update_lookup_table_page_size (unsigned int page_size); virtual void lookup_table_page_up (); virtual void lookup_table_page_down (); virtual void reset (); virtual void focus_in (); virtual void focus_out (); virtual void trigger_property (const String &property); virtual void process_helper_event (const String &helper_uuid, const Transaction &trans); virtual void update_client_capabilities (unsigned int cap); /** @ */ protected: /** * @name Signal activation functions. * * These methods will be called by FilterInstanceBase class when the corresponding signals are * emitted by the original IMEngineInstance object which is filtered by this filter. * * These methods can be overrided, if the derived class wants to filter these signals. * The default implementation of these methods are just to deliver the signals to FrontEnd directly. * * @{ */ virtual void filter_show_preedit_string (); virtual void filter_show_aux_string (); virtual void filter_show_lookup_table (); virtual void filter_hide_preedit_string (); virtual void filter_hide_aux_string (); virtual void filter_hide_lookup_table (); virtual void filter_update_preedit_caret (int caret); virtual void filter_update_preedit_string (const WideString &str, const AttributeList &attrs = AttributeList ()); virtual void filter_update_aux_string (const WideString &str, const AttributeList &attrs = AttributeList ()); virtual void filter_update_lookup_table (const LookupTable &table); virtual void filter_commit_string (const WideString &str); virtual void filter_forward_key_event (const KeyEvent &key); virtual void filter_register_properties (const PropertyList &properties); virtual void filter_update_property (const Property &property); virtual void filter_beep (); virtual void filter_start_helper (const String &helper_uuid); virtual void filter_stop_helper (const String &helper_uuid); virtual void filter_send_helper_event (const String &helper_uuid, const Transaction &trans); virtual bool filter_get_surrounding_text (WideString &text, int &cursor, int maxlen_before = -1, int maxlen_after = -1); virtual bool filter_delete_surrounding_text (int offset, int len); /** @} */ }; /** @} */ } // namespace scim #endif //__SCIM_FILTER_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_filter.cpp0000644000175000017500000003553712422143415015747 0ustar tzhuantzhuan/** @file scim_filter.cpp * @brief Implementation of class FilterFactoryBase and FilterInstanceBase. */ /* * Smart Common Input Method * * Copyright (c) 2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_filter.cpp,v 1.4 2005/05/16 01:25:46 suzhe Exp $ * */ #define Uses_SCIM_FILTER #include "scim_private.h" #include "scim.h" namespace scim { FilterFactoryBase::FilterFactoryBase () { } FilterFactoryBase::~FilterFactoryBase () { } void FilterFactoryBase::attach_imengine_factory (const IMEngineFactoryPointer &orig) { m_orig = orig; if (!m_orig.null ()) set_locales (m_orig->get_locales ()); else set_locales (""); } WideString FilterFactoryBase::get_name () const { return m_orig.null () ? WideString () : m_orig->get_name (); } String FilterFactoryBase::get_uuid () const { return m_orig.null () ? String () : m_orig->get_uuid (); } String FilterFactoryBase::get_icon_file () const { return m_orig.null () ? String () : m_orig->get_icon_file (); } WideString FilterFactoryBase::get_authors () const { return m_orig.null () ? WideString () : m_orig->get_authors (); } WideString FilterFactoryBase::get_credits () const { return m_orig.null () ? WideString () : m_orig->get_credits (); } WideString FilterFactoryBase::get_help () const { return m_orig.null () ? WideString () : m_orig->get_help (); } String FilterFactoryBase::get_language () const { return m_orig.null () ? IMEngineFactoryBase::get_language () : m_orig->get_language (); } bool FilterFactoryBase::validate_encoding (const String &encoding) const { return m_orig.null () ? IMEngineFactoryBase::validate_encoding (encoding) : m_orig->validate_encoding (encoding); } bool FilterFactoryBase::validate_locale (const String &locale) const { return m_orig.null () ? IMEngineFactoryBase::validate_locale (locale) : m_orig->validate_locale (locale); } WideString FilterFactoryBase::inverse_query (const WideString &str) { return m_orig.null () ? WideString () : m_orig->inverse_query (str); } IMEngineInstancePointer FilterFactoryBase::create_instance (const String& encoding, int id) { return m_orig.null () ? IMEngineInstancePointer (0) : m_orig->create_instance (encoding, id); } class FilterInstanceBase::FilterInstanceBaseImpl { FilterInstanceBase *m_parent; IMEngineInstancePointer m_orig; public: FilterInstanceBaseImpl (FilterInstanceBase *parent, const IMEngineInstancePointer &orig) : m_parent (parent), m_orig (orig) { if (!m_orig.null ()) { m_orig->signal_connect_show_preedit_string ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_show_preedit_string)); m_orig->signal_connect_show_aux_string ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_show_aux_string)); m_orig->signal_connect_show_lookup_table ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_show_lookup_table)); m_orig->signal_connect_hide_preedit_string ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_hide_preedit_string)); m_orig->signal_connect_hide_aux_string ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_hide_aux_string)); m_orig->signal_connect_hide_lookup_table ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_hide_lookup_table)); m_orig->signal_connect_update_preedit_caret ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_update_preedit_caret)); m_orig->signal_connect_update_preedit_string ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_update_preedit_string)); m_orig->signal_connect_update_aux_string ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_update_aux_string)); m_orig->signal_connect_update_lookup_table ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_update_lookup_table)); m_orig->signal_connect_commit_string ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_commit_string)); m_orig->signal_connect_forward_key_event ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_forward_key_event)); m_orig->signal_connect_register_properties ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_register_properties)); m_orig->signal_connect_update_property ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_update_property)); m_orig->signal_connect_beep ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_beep)); m_orig->signal_connect_start_helper ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_start_helper)); m_orig->signal_connect_stop_helper ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_stop_helper)); m_orig->signal_connect_send_helper_event ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_send_helper_event)); m_orig->signal_connect_get_surrounding_text ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_get_surrounding_text)); m_orig->signal_connect_delete_surrounding_text ( slot (this, &FilterInstanceBase::FilterInstanceBaseImpl::slot_delete_surrounding_text)); } } bool set_encoding (const String &encoding) { return m_orig.null () ? false : m_orig->set_encoding (encoding); } bool process_key_event (const KeyEvent &key) { return m_orig.null () ? false : m_orig->process_key_event (key); } void move_preedit_caret (unsigned int pos) { if (!m_orig.null ()) m_orig->move_preedit_caret (pos); } void select_candidate (unsigned int index) { if (!m_orig.null ()) m_orig->select_candidate (index); } void update_lookup_table_page_size (unsigned int page_size) { if (!m_orig.null ()) m_orig->update_lookup_table_page_size (page_size); } void lookup_table_page_up () { if (!m_orig.null ()) m_orig->lookup_table_page_up (); } void lookup_table_page_down () { if (!m_orig.null ()) m_orig->lookup_table_page_down (); } void reset () { if (!m_orig.null ()) m_orig->reset (); } void focus_in () { if (!m_orig.null ()) m_orig->focus_in (); } void focus_out () { if (!m_orig.null ()) m_orig->focus_out (); } void trigger_property (const String &property) { if (!m_orig.null ()) m_orig->trigger_property (property); } void process_helper_event (const String &helper_uuid, const Transaction &trans) { if (!m_orig.null ()) m_orig->process_helper_event (helper_uuid, trans); } void update_client_capabilities (unsigned int cap) { if (!m_orig.null ()) m_orig->update_client_capabilities (cap); } private: void slot_show_preedit_string (IMEngineInstanceBase * si) { m_parent->filter_show_preedit_string (); } void slot_show_aux_string (IMEngineInstanceBase * si) { m_parent->filter_show_aux_string (); } void slot_show_lookup_table (IMEngineInstanceBase * si) { m_parent->filter_show_lookup_table (); } void slot_hide_preedit_string (IMEngineInstanceBase * si) { m_parent->filter_hide_preedit_string (); } void slot_hide_aux_string (IMEngineInstanceBase * si) { m_parent->filter_hide_aux_string (); } void slot_hide_lookup_table (IMEngineInstanceBase * si) { m_parent->filter_hide_lookup_table (); } void slot_update_preedit_caret (IMEngineInstanceBase * si, int caret) { m_parent->filter_update_preedit_caret (caret); } void slot_update_preedit_string (IMEngineInstanceBase * si, const WideString & str, const AttributeList & attrs) { m_parent->filter_update_preedit_string (str, attrs); } void slot_update_aux_string (IMEngineInstanceBase * si, const WideString & str, const AttributeList & attrs) { m_parent->filter_update_aux_string (str, attrs); } void slot_update_lookup_table (IMEngineInstanceBase * si, const LookupTable & table) { m_parent->filter_update_lookup_table (table); } void slot_commit_string (IMEngineInstanceBase * si, const WideString & str) { m_parent->filter_commit_string (str); } void slot_forward_key_event (IMEngineInstanceBase * si, const KeyEvent & key) { m_parent->filter_forward_key_event (key); } void slot_register_properties (IMEngineInstanceBase * si, const PropertyList & properties) { m_parent->filter_register_properties (properties); } void slot_update_property (IMEngineInstanceBase * si, const Property & property) { m_parent->filter_update_property (property); } void slot_beep (IMEngineInstanceBase * si) { m_parent->filter_beep (); } void slot_start_helper (IMEngineInstanceBase * si, const String & helper_uuid) { m_parent->filter_start_helper (helper_uuid); } void slot_stop_helper (IMEngineInstanceBase * si, const String & helper_uuid) { m_parent->filter_stop_helper (helper_uuid); } void slot_send_helper_event (IMEngineInstanceBase * si, const String & helper_uuid, const Transaction & trans) { m_parent->filter_send_helper_event (helper_uuid, trans); } bool slot_get_surrounding_text (IMEngineInstanceBase * si, WideString &text, int &cursor, int maxlen_before, int maxlen_after) { return m_parent->filter_get_surrounding_text (text, cursor, maxlen_before, maxlen_after); } bool slot_delete_surrounding_text(IMEngineInstanceBase * si, int offset, int len) { return m_parent->filter_delete_surrounding_text (offset, len); } }; FilterInstanceBase::FilterInstanceBase (FilterFactoryBase *factory, const IMEngineInstancePointer &orig_inst) : IMEngineInstanceBase (factory, (orig_inst.null () ? "UTF-8" : orig_inst->get_encoding ()), (orig_inst.null () ? -1 : orig_inst->get_id ())), m_impl (new FilterInstanceBaseImpl (this, orig_inst)) { } FilterInstanceBase::~FilterInstanceBase () { delete m_impl; } bool FilterInstanceBase::set_encoding (const String &encoding) { return IMEngineInstanceBase::set_encoding (encoding) && m_impl->set_encoding (encoding); } bool FilterInstanceBase::process_key_event (const KeyEvent &key) { return m_impl->process_key_event (key); } void FilterInstanceBase::move_preedit_caret (unsigned int pos) { m_impl->move_preedit_caret (pos); } void FilterInstanceBase::select_candidate (unsigned int index) { m_impl->select_candidate (index); } void FilterInstanceBase::update_lookup_table_page_size (unsigned int page_size) { m_impl->update_lookup_table_page_size (page_size); } void FilterInstanceBase::lookup_table_page_up () { m_impl->lookup_table_page_up (); } void FilterInstanceBase::lookup_table_page_down () { m_impl->lookup_table_page_down (); } void FilterInstanceBase::reset () { m_impl->reset (); } void FilterInstanceBase::focus_in () { m_impl->focus_in (); } void FilterInstanceBase::focus_out () { m_impl->focus_out (); } void FilterInstanceBase::trigger_property (const String &property) { m_impl->trigger_property (property); } void FilterInstanceBase::process_helper_event (const String &helper_uuid, const Transaction &trans) { m_impl->process_helper_event (helper_uuid, trans); } void FilterInstanceBase::update_client_capabilities (unsigned int cap) { m_impl->update_client_capabilities (cap); } void FilterInstanceBase::filter_show_preedit_string () { show_preedit_string (); } void FilterInstanceBase::filter_show_aux_string () { show_aux_string (); } void FilterInstanceBase::filter_show_lookup_table () { show_lookup_table (); } void FilterInstanceBase::filter_hide_preedit_string () { hide_preedit_string (); } void FilterInstanceBase::filter_hide_aux_string () { hide_aux_string (); } void FilterInstanceBase::filter_hide_lookup_table () { hide_lookup_table (); } void FilterInstanceBase::filter_update_preedit_caret (int caret) { update_preedit_caret (caret); } void FilterInstanceBase::filter_update_preedit_string (const WideString &str, const AttributeList &attrs) { update_preedit_string (str, attrs); } void FilterInstanceBase::filter_update_aux_string (const WideString &str, const AttributeList &attrs) { update_aux_string (str, attrs); } void FilterInstanceBase::filter_update_lookup_table (const LookupTable &table) { update_lookup_table (table); } void FilterInstanceBase::filter_commit_string (const WideString &str) { commit_string (str); } void FilterInstanceBase::filter_forward_key_event (const KeyEvent &key) { forward_key_event (key); } void FilterInstanceBase::filter_register_properties (const PropertyList &properties) { register_properties (properties); } void FilterInstanceBase::filter_update_property (const Property &property) { update_property (property); } void FilterInstanceBase::filter_beep () { beep (); } void FilterInstanceBase::filter_start_helper (const String &helper_uuid) { start_helper (helper_uuid); } void FilterInstanceBase::filter_stop_helper (const String &helper_uuid) { stop_helper (helper_uuid); } void FilterInstanceBase::filter_send_helper_event (const String &helper_uuid, const Transaction &trans) { send_helper_event (helper_uuid, trans); } bool FilterInstanceBase::filter_get_surrounding_text (WideString &text, int &cursor, int maxlen_before, int maxlen_after) { return get_surrounding_text (text, cursor, maxlen_before, maxlen_after); } bool FilterInstanceBase::filter_delete_surrounding_text (int offset, int len) { return delete_surrounding_text (offset, len); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_exception.h0000644000175000017500000000307012422143415016110 0ustar tzhuantzhuan/** * @file scim_exception.h * @brief Defines the scim::Exception class. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_exception.h,v 1.10 2005/01/10 08:30:53 suzhe Exp $ */ #ifndef __SCIM_EXCEPTION_H #define __SCIM_EXCEPTION_H namespace scim { /** * @addtogroup Accessories * @{ */ /** * @brief A base class of all other exception classes. * * All other exception classes in namespace scim * should be derived from this class. */ class Exception: public std::exception { String m_what; public: Exception (const String& what_arg) : m_what (what_arg) { } ~Exception () throw () {} virtual const char* what () const throw () { return m_what.c_str (); } }; /** @} */ } // namespace scim #endif //__SCIM_EXCEPTION_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_event.h0000644000175000017500000034361412422143415015246 0ustar tzhuantzhuan/** * @file scim_event.h * @brief Defines the scim::KeyEvent class and related enums, functions. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_event.h,v 1.26.2.1 2007/04/11 15:24:10 suzhe Exp $ */ #ifndef __SCIM_EVENT_H #define __SCIM_EVENT_H namespace scim { /** * @addtogroup Accessories * @{ */ /** * @brief Enum values of all valid key masks. * * The key masks indicate which modifier keys * is pressed down during the keyboard hit. * * The special SCIM_KEY_ReleaseMask indicates * the key release event. * */ enum KeyMask { SCIM_KEY_NullMask = 0, /**< Key press event without modifier key. */ SCIM_KEY_ShiftMask = (1<<0), /**< The Shift key is pressed down */ SCIM_KEY_CapsLockMask = (1<<1), /**< The CapsLock key is pressed down */ SCIM_KEY_ControlMask = (1<<2), /**< The Control key is pressed down */ SCIM_KEY_AltMask = (1<<3), /**< The Alt key is pressed down */ SCIM_KEY_MetaMask = (1<<4), /**< The Meta key is pressed down */ SCIM_KEY_SuperMask = (1<<5), /**< The Super key is pressed down */ SCIM_KEY_HyperMask = (1<<6), /**< The Hyper key is pressed down */ SCIM_KEY_NumLockMask = (1<<7), /**< The NumLock key is pressed down */ SCIM_KEY_LockMask = SCIM_KEY_CapsLockMask, /**< For backward API compatibility, do not use it in new code */ SCIM_KEY_Mod1Mask = SCIM_KEY_AltMask, /**< For backward API compatibility, do not use it in new code */ SCIM_KEY_Mod2Mask = SCIM_KEY_MetaMask, /**< For backward API compatibility, do not use it in new code */ SCIM_KEY_Mod3Mask = SCIM_KEY_SuperMask, /**< For backward API compatibility, do not use it in new code */ SCIM_KEY_Mod4Mask = SCIM_KEY_HyperMask, /**< For backward API compatibility, do not use it in new code */ SCIM_KEY_Mod5Mask = SCIM_KEY_NumLockMask, /**< For backward API compatibility, do not use it in new code */ SCIM_KEY_ScrollLockMask = 0, /**< For backward API compatibility, do not use it in new code */ SCIM_KEY_QuirkKanaRoMask= (1<<14), /**< Special mask to distinguish two backslash keys on jp106 keyboard */ SCIM_KEY_ReleaseMask = (1<<15), /**< It's a key release event */ SCIM_KEY_AllMasks = 0xC0FF /**< All valid Masks */ }; /** * @brief Enum values of all valid key codes. * * If keycode & 0xff000000 == 0x01000000 then this key code is directly encoded 24-bit UCS character. * The UCS value is keycode & 0x00ffffff. */ enum KeyCode { SCIM_KEY_NullKey = 0, SCIM_KEY_VoidSymbol = 0xFFFFFF, /* function keys */ SCIM_KEY_BackSpace = 0xFF08, /* back space, back char */ SCIM_KEY_Tab = 0xFF09, SCIM_KEY_Linefeed = 0xFF0A, /* Linefeed, LF */ SCIM_KEY_Clear = 0xFF0B, SCIM_KEY_Return = 0xFF0D, /* Return, enter */ SCIM_KEY_Pause = 0xFF13, /* Pause, hold */ SCIM_KEY_Scroll_Lock = 0xFF14, SCIM_KEY_Sys_Req = 0xFF15, SCIM_KEY_Escape = 0xFF1B, SCIM_KEY_Delete = 0xFFFF, /* Delete, rubout */ /* International & multi-key character composition */ SCIM_KEY_Multi_key = 0xFF20, /* Multi-key character compose */ SCIM_KEY_Codeinput = 0xFF37, SCIM_KEY_SingleCandidate = 0xFF3C, SCIM_KEY_MultipleCandidate = 0xFF3D, SCIM_KEY_PreviousCandidate = 0xFF3E, /* Japanese keyboard support */ SCIM_KEY_Kanji = 0xFF21, /* Kanji, Kanji convert */ SCIM_KEY_Muhenkan = 0xFF22, /* Cancel Conversion */ SCIM_KEY_Henkan_Mode = 0xFF23, /* Start/Stop Conversion */ SCIM_KEY_Henkan = 0xFF23, /* Alias for Henkan_Mode */ SCIM_KEY_Romaji = 0xFF24, /* to Romaji */ SCIM_KEY_Hiragana = 0xFF25, /* to Hiragana */ SCIM_KEY_Katakana = 0xFF26, /* to Katakana */ SCIM_KEY_Hiragana_Katakana = 0xFF27, /* Hiragana/Katakana toggle */ SCIM_KEY_Zenkaku = 0xFF28, /* to Zenkaku */ SCIM_KEY_Hankaku = 0xFF29, /* to Hankaku */ SCIM_KEY_Zenkaku_Hankaku = 0xFF2A, /* Zenkaku/Hankaku toggle */ SCIM_KEY_Touroku = 0xFF2B, /* Add to Dictionary */ SCIM_KEY_Massyo = 0xFF2C, /* Delete from Dictionary */ SCIM_KEY_Kana_Lock = 0xFF2D, /* Kana Lock */ SCIM_KEY_Kana_Shift = 0xFF2E, /* Kana Shift */ SCIM_KEY_Eisu_Shift = 0xFF2F, /* Alphanumeric Shift */ SCIM_KEY_Eisu_toggle = 0xFF30, /* Alphanumeric toggle */ SCIM_KEY_Kanji_Bangou = 0xFF37, /* Codeinput */ SCIM_KEY_Zen_Koho = 0xFF3D, /* Multiple/All Candidate(s) */ SCIM_KEY_Mae_Koho = 0xFF3E, /* Previous Candidate */ /* Cursor control & motion */ SCIM_KEY_Home = 0xFF50, SCIM_KEY_Left = 0xFF51, /* Move left, left arrow */ SCIM_KEY_Up = 0xFF52, /* Move up, up arrow */ SCIM_KEY_Right = 0xFF53, /* Move right, right arrow */ SCIM_KEY_Down = 0xFF54, /* Move down, down arrow */ SCIM_KEY_Prior = 0xFF55, /* Prior, previous */ SCIM_KEY_Page_Up = 0xFF55, SCIM_KEY_Next = 0xFF56, /* Next */ SCIM_KEY_Page_Down = 0xFF56, SCIM_KEY_End = 0xFF57, /* EOL */ SCIM_KEY_Begin = 0xFF58, /* BOL */ /* Misc Functions */ SCIM_KEY_Select = 0xFF60, /* Select, mark */ SCIM_KEY_Print = 0xFF61, SCIM_KEY_Execute = 0xFF62, /* Execute, run, do */ SCIM_KEY_Insert = 0xFF63, /* Insert, insert here */ SCIM_KEY_Undo = 0xFF65, /* Undo, oops */ SCIM_KEY_Redo = 0xFF66, /* redo, again */ SCIM_KEY_Menu = 0xFF67, SCIM_KEY_Find = 0xFF68, /* Find, search */ SCIM_KEY_Cancel = 0xFF69, /* Cancel, stop, abort, exit */ SCIM_KEY_Help = 0xFF6A, /* Help */ SCIM_KEY_Break = 0xFF6B, SCIM_KEY_Mode_switch = 0xFF7E, /* Character set switch */ SCIM_KEY_Num_Lock = 0xFF7F, /* keypad */ SCIM_KEY_KP_Space = 0xFF80, /* space */ SCIM_KEY_KP_Tab = 0xFF89, SCIM_KEY_KP_Enter = 0xFF8D, /* enter */ SCIM_KEY_KP_F1 = 0xFF91, /* PF1, KP_A, ... */ SCIM_KEY_KP_F2 = 0xFF92, SCIM_KEY_KP_F3 = 0xFF93, SCIM_KEY_KP_F4 = 0xFF94, SCIM_KEY_KP_Home = 0xFF95, SCIM_KEY_KP_Left = 0xFF96, SCIM_KEY_KP_Up = 0xFF97, SCIM_KEY_KP_Right = 0xFF98, SCIM_KEY_KP_Down = 0xFF99, SCIM_KEY_KP_Prior = 0xFF9A, SCIM_KEY_KP_Page_Up = 0xFF9A, SCIM_KEY_KP_Next = 0xFF9B, SCIM_KEY_KP_Page_Down = 0xFF9B, SCIM_KEY_KP_End = 0xFF9C, SCIM_KEY_KP_Begin = 0xFF9D, SCIM_KEY_KP_Insert = 0xFF9E, SCIM_KEY_KP_Delete = 0xFF9F, SCIM_KEY_KP_Equal = 0xFFBD, /* equals */ SCIM_KEY_KP_Multiply = 0xFFAA, SCIM_KEY_KP_Add = 0xFFAB, SCIM_KEY_KP_Separator = 0xFFAC, /* separator, often comma */ SCIM_KEY_KP_Subtract = 0xFFAD, SCIM_KEY_KP_Decimal = 0xFFAE, SCIM_KEY_KP_Divide = 0xFFAF, SCIM_KEY_KP_0 = 0xFFB0, SCIM_KEY_KP_1 = 0xFFB1, SCIM_KEY_KP_2 = 0xFFB2, SCIM_KEY_KP_3 = 0xFFB3, SCIM_KEY_KP_4 = 0xFFB4, SCIM_KEY_KP_5 = 0xFFB5, SCIM_KEY_KP_6 = 0xFFB6, SCIM_KEY_KP_7 = 0xFFB7, SCIM_KEY_KP_8 = 0xFFB8, SCIM_KEY_KP_9 = 0xFFB9, /* Auxilliary Functions */ SCIM_KEY_F1 = 0xFFBE, SCIM_KEY_F2 = 0xFFBF, SCIM_KEY_F3 = 0xFFC0, SCIM_KEY_F4 = 0xFFC1, SCIM_KEY_F5 = 0xFFC2, SCIM_KEY_F6 = 0xFFC3, SCIM_KEY_F7 = 0xFFC4, SCIM_KEY_F8 = 0xFFC5, SCIM_KEY_F9 = 0xFFC6, SCIM_KEY_F10 = 0xFFC7, SCIM_KEY_F11 = 0xFFC8, SCIM_KEY_F12 = 0xFFC9, SCIM_KEY_F13 = 0xFFCA, SCIM_KEY_F14 = 0xFFCB, SCIM_KEY_F15 = 0xFFCC, SCIM_KEY_F16 = 0xFFCD, SCIM_KEY_F17 = 0xFFCE, SCIM_KEY_F18 = 0xFFCF, SCIM_KEY_F19 = 0xFFD0, SCIM_KEY_F20 = 0xFFD1, SCIM_KEY_F21 = 0xFFD2, SCIM_KEY_F22 = 0xFFD3, SCIM_KEY_F23 = 0xFFD4, SCIM_KEY_F24 = 0xFFD5, SCIM_KEY_F25 = 0xFFD6, SCIM_KEY_F26 = 0xFFD7, SCIM_KEY_F27 = 0xFFD8, SCIM_KEY_F28 = 0xFFD9, SCIM_KEY_F29 = 0xFFDA, SCIM_KEY_F30 = 0xFFDB, SCIM_KEY_F31 = 0xFFDC, SCIM_KEY_F32 = 0xFFDD, SCIM_KEY_F33 = 0xFFDE, SCIM_KEY_F34 = 0xFFDF, SCIM_KEY_F35 = 0xFFE0, /* modifier keys */ SCIM_KEY_Shift_L = 0xFFE1, /* Left shift */ SCIM_KEY_Shift_R = 0xFFE2, /* Right shift */ SCIM_KEY_Control_L = 0xFFE3, /* Left control */ SCIM_KEY_Control_R = 0xFFE4, /* Right control */ SCIM_KEY_Caps_Lock = 0xFFE5, /* Caps lock */ SCIM_KEY_Shift_Lock = 0xFFE6, /* Shift lock */ SCIM_KEY_Meta_L = 0xFFE7, /* Left meta */ SCIM_KEY_Meta_R = 0xFFE8, /* Right meta */ SCIM_KEY_Alt_L = 0xFFE9, /* Left alt */ SCIM_KEY_Alt_R = 0xFFEA, /* Right alt */ SCIM_KEY_Super_L = 0xFFEB, /* Left super */ SCIM_KEY_Super_R = 0xFFEC, /* Right super */ SCIM_KEY_Hyper_L = 0xFFED, /* Left hyper */ SCIM_KEY_Hyper_R = 0xFFEE, /* Right hyper */ /* * ISO 9995 Function and Modifier Keys * Byte 3 = 0xFE */ SCIM_KEY_ISO_Lock = 0xFE01, SCIM_KEY_ISO_Level2_Latch = 0xFE02, SCIM_KEY_ISO_Level3_Shift = 0xFE03, SCIM_KEY_ISO_Level3_Latch = 0xFE04, SCIM_KEY_ISO_Level3_Lock = 0xFE05, SCIM_KEY_ISO_Group_Shift = 0xFF7E, /* Alias for mode_switch */ SCIM_KEY_ISO_Group_Latch = 0xFE06, SCIM_KEY_ISO_Group_Lock = 0xFE07, SCIM_KEY_ISO_Next_Group = 0xFE08, SCIM_KEY_ISO_Next_Group_Lock = 0xFE09, SCIM_KEY_ISO_Prev_Group = 0xFE0A, SCIM_KEY_ISO_Prev_Group_Lock = 0xFE0B, SCIM_KEY_ISO_First_Group = 0xFE0C, SCIM_KEY_ISO_First_Group_Lock = 0xFE0D, SCIM_KEY_ISO_Last_Group = 0xFE0E, SCIM_KEY_ISO_Last_Group_Lock = 0xFE0F, SCIM_KEY_ISO_Left_Tab = 0xFE20, SCIM_KEY_ISO_Move_Line_Up = 0xFE21, SCIM_KEY_ISO_Move_Line_Down = 0xFE22, SCIM_KEY_ISO_Partial_Line_Up = 0xFE23, SCIM_KEY_ISO_Partial_Line_Down = 0xFE24, SCIM_KEY_ISO_Partial_Space_Left = 0xFE25, SCIM_KEY_ISO_Partial_Space_Right = 0xFE26, SCIM_KEY_ISO_Set_Margin_Left = 0xFE27, SCIM_KEY_ISO_Set_Margin_Right = 0xFE28, SCIM_KEY_ISO_Release_Margin_Left = 0xFE29, SCIM_KEY_ISO_Release_Margin_Right = 0xFE2A, SCIM_KEY_ISO_Release_Both_Margins = 0xFE2B, SCIM_KEY_ISO_Fast_Cursor_Left = 0xFE2C, SCIM_KEY_ISO_Fast_Cursor_Right = 0xFE2D, SCIM_KEY_ISO_Fast_Cursor_Up = 0xFE2E, SCIM_KEY_ISO_Fast_Cursor_Down = 0xFE2F, SCIM_KEY_ISO_Continuous_Underline = 0xFE30, SCIM_KEY_ISO_Discontinuous_Underline = 0xFE31, SCIM_KEY_ISO_Emphasize = 0xFE32, SCIM_KEY_ISO_Center_Object = 0xFE33, SCIM_KEY_ISO_Enter = 0xFE34, SCIM_KEY_dead_grave = 0xFE50, SCIM_KEY_dead_acute = 0xFE51, SCIM_KEY_dead_circumflex = 0xFE52, SCIM_KEY_dead_tilde = 0xFE53, SCIM_KEY_dead_macron = 0xFE54, SCIM_KEY_dead_breve = 0xFE55, SCIM_KEY_dead_abovedot = 0xFE56, SCIM_KEY_dead_diaeresis = 0xFE57, SCIM_KEY_dead_abovering = 0xFE58, SCIM_KEY_dead_doubleacute = 0xFE59, SCIM_KEY_dead_caron = 0xFE5A, SCIM_KEY_dead_cedilla = 0xFE5B, SCIM_KEY_dead_ogonek = 0xFE5C, SCIM_KEY_dead_iota = 0xFE5D, SCIM_KEY_dead_voiced_sound = 0xFE5E, SCIM_KEY_dead_semivoiced_sound = 0xFE5F, SCIM_KEY_dead_belowdot = 0xFE60, SCIM_KEY_dead_hook = 0xFE61, SCIM_KEY_dead_horn = 0xFE62, SCIM_KEY_First_Virtual_Screen = 0xFED0, SCIM_KEY_Prev_Virtual_Screen = 0xFED1, SCIM_KEY_Next_Virtual_Screen = 0xFED2, SCIM_KEY_Last_Virtual_Screen = 0xFED4, SCIM_KEY_Terminate_Server = 0xFED5, SCIM_KEY_AccessX_Enable = 0xFE70, SCIM_KEY_AccessX_Feedback_Enable = 0xFE71, SCIM_KEY_RepeatKeys_Enable = 0xFE72, SCIM_KEY_SlowKeys_Enable = 0xFE73, SCIM_KEY_BounceKeys_Enable = 0xFE74, SCIM_KEY_StickyKeys_Enable = 0xFE75, SCIM_KEY_MouseKeys_Enable = 0xFE76, SCIM_KEY_MouseKeys_Accel_Enable = 0xFE77, SCIM_KEY_Overlay1_Enable = 0xFE78, SCIM_KEY_Overlay2_Enable = 0xFE79, SCIM_KEY_AudibleBell_Enable = 0xFE7A, SCIM_KEY_Pointer_Left = 0xFEE0, SCIM_KEY_Pointer_Right = 0xFEE1, SCIM_KEY_Pointer_Up = 0xFEE2, SCIM_KEY_Pointer_Down = 0xFEE3, SCIM_KEY_Pointer_UpLeft = 0xFEE4, SCIM_KEY_Pointer_UpRight = 0xFEE5, SCIM_KEY_Pointer_DownLeft = 0xFEE6, SCIM_KEY_Pointer_DownRight = 0xFEE7, SCIM_KEY_Pointer_Button_Dflt = 0xFEE8, SCIM_KEY_Pointer_Button1 = 0xFEE9, SCIM_KEY_Pointer_Button2 = 0xFEEA, SCIM_KEY_Pointer_Button3 = 0xFEEB, SCIM_KEY_Pointer_Button4 = 0xFEEC, SCIM_KEY_Pointer_Button5 = 0xFEED, SCIM_KEY_Pointer_DblClick_Dflt = 0xFEEE, SCIM_KEY_Pointer_DblClick1 = 0xFEEF, SCIM_KEY_Pointer_DblClick2 = 0xFEF0, SCIM_KEY_Pointer_DblClick3 = 0xFEF1, SCIM_KEY_Pointer_DblClick4 = 0xFEF2, SCIM_KEY_Pointer_DblClick5 = 0xFEF3, SCIM_KEY_Pointer_Drag_Dflt = 0xFEF4, SCIM_KEY_Pointer_Drag1 = 0xFEF5, SCIM_KEY_Pointer_Drag2 = 0xFEF6, SCIM_KEY_Pointer_Drag3 = 0xFEF7, SCIM_KEY_Pointer_Drag4 = 0xFEF8, SCIM_KEY_Pointer_Drag5 = 0xFEFD, SCIM_KEY_Pointer_EnableKeys = 0xFEF9, SCIM_KEY_Pointer_Accelerate = 0xFEFA, SCIM_KEY_Pointer_DfltBtnNext = 0xFEFB, SCIM_KEY_Pointer_DfltBtnPrev = 0xFEFC, /* * 3270 Terminal Keys * Byte 3 = 0xFD */ SCIM_KEY_3270_Duplicate = 0xFD01, SCIM_KEY_3270_FieldMark = 0xFD02, SCIM_KEY_3270_Right2 = 0xFD03, SCIM_KEY_3270_Left2 = 0xFD04, SCIM_KEY_3270_BackTab = 0xFD05, SCIM_KEY_3270_EraseEOF = 0xFD06, SCIM_KEY_3270_EraseInput = 0xFD07, SCIM_KEY_3270_Reset = 0xFD08, SCIM_KEY_3270_Quit = 0xFD09, SCIM_KEY_3270_PA1 = 0xFD0A, SCIM_KEY_3270_PA2 = 0xFD0B, SCIM_KEY_3270_PA3 = 0xFD0C, SCIM_KEY_3270_Test = 0xFD0D, SCIM_KEY_3270_Attn = 0xFD0E, SCIM_KEY_3270_CursorBlink = 0xFD0F, SCIM_KEY_3270_AltCursor = 0xFD10, SCIM_KEY_3270_KeyClick = 0xFD11, SCIM_KEY_3270_Jump = 0xFD12, SCIM_KEY_3270_Ident = 0xFD13, SCIM_KEY_3270_Rule = 0xFD14, SCIM_KEY_3270_Copy = 0xFD15, SCIM_KEY_3270_Play = 0xFD16, SCIM_KEY_3270_Setup = 0xFD17, SCIM_KEY_3270_Record = 0xFD18, SCIM_KEY_3270_ChangeScreen = 0xFD19, SCIM_KEY_3270_DeleteWord = 0xFD1A, SCIM_KEY_3270_ExSelect = 0xFD1B, SCIM_KEY_3270_CursorSelect = 0xFD1C, SCIM_KEY_3270_PrintScreen = 0xFD1D, SCIM_KEY_3270_Enter = 0xFD1E, /* Latin 1 */ SCIM_KEY_space = 0x020, SCIM_KEY_exclam = 0x021, SCIM_KEY_quotedbl = 0x022, SCIM_KEY_numbersign = 0x023, SCIM_KEY_dollar = 0x024, SCIM_KEY_percent = 0x025, SCIM_KEY_ampersand = 0x026, SCIM_KEY_apostrophe = 0x027, SCIM_KEY_quoteright = 0x027, /* deprecated */ SCIM_KEY_parenleft = 0x028, SCIM_KEY_parenright = 0x029, SCIM_KEY_asterisk = 0x02a, SCIM_KEY_plus = 0x02b, SCIM_KEY_comma = 0x02c, SCIM_KEY_minus = 0x02d, SCIM_KEY_period = 0x02e, SCIM_KEY_slash = 0x02f, SCIM_KEY_0 = 0x030, SCIM_KEY_1 = 0x031, SCIM_KEY_2 = 0x032, SCIM_KEY_3 = 0x033, SCIM_KEY_4 = 0x034, SCIM_KEY_5 = 0x035, SCIM_KEY_6 = 0x036, SCIM_KEY_7 = 0x037, SCIM_KEY_8 = 0x038, SCIM_KEY_9 = 0x039, SCIM_KEY_colon = 0x03a, SCIM_KEY_semicolon = 0x03b, SCIM_KEY_less = 0x03c, SCIM_KEY_equal = 0x03d, SCIM_KEY_greater = 0x03e, SCIM_KEY_question = 0x03f, SCIM_KEY_at = 0x040, SCIM_KEY_A = 0x041, SCIM_KEY_B = 0x042, SCIM_KEY_C = 0x043, SCIM_KEY_D = 0x044, SCIM_KEY_E = 0x045, SCIM_KEY_F = 0x046, SCIM_KEY_G = 0x047, SCIM_KEY_H = 0x048, SCIM_KEY_I = 0x049, SCIM_KEY_J = 0x04a, SCIM_KEY_K = 0x04b, SCIM_KEY_L = 0x04c, SCIM_KEY_M = 0x04d, SCIM_KEY_N = 0x04e, SCIM_KEY_O = 0x04f, SCIM_KEY_P = 0x050, SCIM_KEY_Q = 0x051, SCIM_KEY_R = 0x052, SCIM_KEY_S = 0x053, SCIM_KEY_T = 0x054, SCIM_KEY_U = 0x055, SCIM_KEY_V = 0x056, SCIM_KEY_W = 0x057, SCIM_KEY_X = 0x058, SCIM_KEY_Y = 0x059, SCIM_KEY_Z = 0x05a, SCIM_KEY_bracketleft = 0x05b, SCIM_KEY_backslash = 0x05c, SCIM_KEY_bracketright = 0x05d, SCIM_KEY_asciicircum = 0x05e, SCIM_KEY_underscore = 0x05f, SCIM_KEY_grave = 0x060, SCIM_KEY_a = 0x061, SCIM_KEY_b = 0x062, SCIM_KEY_c = 0x063, SCIM_KEY_d = 0x064, SCIM_KEY_e = 0x065, SCIM_KEY_f = 0x066, SCIM_KEY_g = 0x067, SCIM_KEY_h = 0x068, SCIM_KEY_i = 0x069, SCIM_KEY_j = 0x06a, SCIM_KEY_k = 0x06b, SCIM_KEY_l = 0x06c, SCIM_KEY_m = 0x06d, SCIM_KEY_n = 0x06e, SCIM_KEY_o = 0x06f, SCIM_KEY_p = 0x070, SCIM_KEY_q = 0x071, SCIM_KEY_r = 0x072, SCIM_KEY_s = 0x073, SCIM_KEY_t = 0x074, SCIM_KEY_u = 0x075, SCIM_KEY_v = 0x076, SCIM_KEY_w = 0x077, SCIM_KEY_x = 0x078, SCIM_KEY_y = 0x079, SCIM_KEY_z = 0x07a, SCIM_KEY_braceleft = 0x07b, SCIM_KEY_bar = 0x07c, SCIM_KEY_braceright = 0x07d, SCIM_KEY_asciitilde = 0x07e, SCIM_KEY_nobreakspace = 0x0a0, SCIM_KEY_exclamdown = 0x0a1, SCIM_KEY_cent = 0x0a2, SCIM_KEY_sterling = 0x0a3, SCIM_KEY_currency = 0x0a4, SCIM_KEY_yen = 0x0a5, SCIM_KEY_brokenbar = 0x0a6, SCIM_KEY_section = 0x0a7, SCIM_KEY_diaeresis = 0x0a8, SCIM_KEY_copyright = 0x0a9, SCIM_KEY_ordfeminine = 0x0aa, SCIM_KEY_guillemotleft = 0x0ab, /* left angle quotation mark */ SCIM_KEY_notsign = 0x0ac, SCIM_KEY_hyphen = 0x0ad, SCIM_KEY_registered = 0x0ae, SCIM_KEY_macron = 0x0af, SCIM_KEY_degree = 0x0b0, SCIM_KEY_plusminus = 0x0b1, SCIM_KEY_twosuperior = 0x0b2, SCIM_KEY_threesuperior = 0x0b3, SCIM_KEY_acute = 0x0b4, SCIM_KEY_mu = 0x0b5, SCIM_KEY_paragraph = 0x0b6, SCIM_KEY_periodcentered = 0x0b7, SCIM_KEY_cedilla = 0x0b8, SCIM_KEY_onesuperior = 0x0b9, SCIM_KEY_masculine = 0x0ba, SCIM_KEY_guillemotright = 0x0bb, /* right angle quotation mark */ SCIM_KEY_onequarter = 0x0bc, SCIM_KEY_onehalf = 0x0bd, SCIM_KEY_threequarters = 0x0be, SCIM_KEY_questiondown = 0x0bf, SCIM_KEY_Agrave = 0x0c0, SCIM_KEY_Aacute = 0x0c1, SCIM_KEY_Acircumflex = 0x0c2, SCIM_KEY_Atilde = 0x0c3, SCIM_KEY_Adiaeresis = 0x0c4, SCIM_KEY_Aring = 0x0c5, SCIM_KEY_AE = 0x0c6, SCIM_KEY_Ccedilla = 0x0c7, SCIM_KEY_Egrave = 0x0c8, SCIM_KEY_Eacute = 0x0c9, SCIM_KEY_Ecircumflex = 0x0ca, SCIM_KEY_Ediaeresis = 0x0cb, SCIM_KEY_Igrave = 0x0cc, SCIM_KEY_Iacute = 0x0cd, SCIM_KEY_Icircumflex = 0x0ce, SCIM_KEY_Idiaeresis = 0x0cf, SCIM_KEY_ETH = 0x0d0, SCIM_KEY_Eth = 0x0d0, /* deprecated */ SCIM_KEY_Ntilde = 0x0d1, SCIM_KEY_Ograve = 0x0d2, SCIM_KEY_Oacute = 0x0d3, SCIM_KEY_Ocircumflex = 0x0d4, SCIM_KEY_Otilde = 0x0d5, SCIM_KEY_Odiaeresis = 0x0d6, SCIM_KEY_multiply = 0x0d7, SCIM_KEY_Ooblique = 0x0d8, SCIM_KEY_Oslash = SCIM_KEY_Ooblique, SCIM_KEY_Ugrave = 0x0d9, SCIM_KEY_Uacute = 0x0da, SCIM_KEY_Ucircumflex = 0x0db, SCIM_KEY_Udiaeresis = 0x0dc, SCIM_KEY_Yacute = 0x0dd, SCIM_KEY_THORN = 0x0de, SCIM_KEY_Thorn = 0x0de, /* deprecated */ SCIM_KEY_ssharp = 0x0df, SCIM_KEY_agrave = 0x0e0, SCIM_KEY_aacute = 0x0e1, SCIM_KEY_acircumflex = 0x0e2, SCIM_KEY_atilde = 0x0e3, SCIM_KEY_adiaeresis = 0x0e4, SCIM_KEY_aring = 0x0e5, SCIM_KEY_ae = 0x0e6, SCIM_KEY_ccedilla = 0x0e7, SCIM_KEY_egrave = 0x0e8, SCIM_KEY_eacute = 0x0e9, SCIM_KEY_ecircumflex = 0x0ea, SCIM_KEY_ediaeresis = 0x0eb, SCIM_KEY_igrave = 0x0ec, SCIM_KEY_iacute = 0x0ed, SCIM_KEY_icircumflex = 0x0ee, SCIM_KEY_idiaeresis = 0x0ef, SCIM_KEY_eth = 0x0f0, SCIM_KEY_ntilde = 0x0f1, SCIM_KEY_ograve = 0x0f2, SCIM_KEY_oacute = 0x0f3, SCIM_KEY_ocircumflex = 0x0f4, SCIM_KEY_otilde = 0x0f5, SCIM_KEY_odiaeresis = 0x0f6, SCIM_KEY_division = 0x0f7, SCIM_KEY_oslash = 0x0f8, SCIM_KEY_ooblique = SCIM_KEY_oslash, SCIM_KEY_ugrave = 0x0f9, SCIM_KEY_uacute = 0x0fa, SCIM_KEY_ucircumflex = 0x0fb, SCIM_KEY_udiaeresis = 0x0fc, SCIM_KEY_yacute = 0x0fd, SCIM_KEY_thorn = 0x0fe, SCIM_KEY_ydiaeresis = 0x0ff, /* * Latin 2 * Byte 3 = 1 */ SCIM_KEY_Aogonek = 0x1a1, SCIM_KEY_breve = 0x1a2, SCIM_KEY_Lstroke = 0x1a3, SCIM_KEY_Lcaron = 0x1a5, SCIM_KEY_Sacute = 0x1a6, SCIM_KEY_Scaron = 0x1a9, SCIM_KEY_Scedilla = 0x1aa, SCIM_KEY_Tcaron = 0x1ab, SCIM_KEY_Zacute = 0x1ac, SCIM_KEY_Zcaron = 0x1ae, SCIM_KEY_Zabovedot = 0x1af, SCIM_KEY_aogonek = 0x1b1, SCIM_KEY_ogonek = 0x1b2, SCIM_KEY_lstroke = 0x1b3, SCIM_KEY_lcaron = 0x1b5, SCIM_KEY_sacute = 0x1b6, SCIM_KEY_caron = 0x1b7, SCIM_KEY_scaron = 0x1b9, SCIM_KEY_scedilla = 0x1ba, SCIM_KEY_tcaron = 0x1bb, SCIM_KEY_zacute = 0x1bc, SCIM_KEY_doubleacute = 0x1bd, SCIM_KEY_zcaron = 0x1be, SCIM_KEY_zabovedot = 0x1bf, SCIM_KEY_Racute = 0x1c0, SCIM_KEY_Abreve = 0x1c3, SCIM_KEY_Lacute = 0x1c5, SCIM_KEY_Cacute = 0x1c6, SCIM_KEY_Ccaron = 0x1c8, SCIM_KEY_Eogonek = 0x1ca, SCIM_KEY_Ecaron = 0x1cc, SCIM_KEY_Dcaron = 0x1cf, SCIM_KEY_Dstroke = 0x1d0, SCIM_KEY_Nacute = 0x1d1, SCIM_KEY_Ncaron = 0x1d2, SCIM_KEY_Odoubleacute = 0x1d5, SCIM_KEY_Rcaron = 0x1d8, SCIM_KEY_Uring = 0x1d9, SCIM_KEY_Udoubleacute = 0x1db, SCIM_KEY_Tcedilla = 0x1de, SCIM_KEY_racute = 0x1e0, SCIM_KEY_abreve = 0x1e3, SCIM_KEY_lacute = 0x1e5, SCIM_KEY_cacute = 0x1e6, SCIM_KEY_ccaron = 0x1e8, SCIM_KEY_eogonek = 0x1ea, SCIM_KEY_ecaron = 0x1ec, SCIM_KEY_dcaron = 0x1ef, SCIM_KEY_dstroke = 0x1f0, SCIM_KEY_nacute = 0x1f1, SCIM_KEY_ncaron = 0x1f2, SCIM_KEY_odoubleacute = 0x1f5, SCIM_KEY_udoubleacute = 0x1fb, SCIM_KEY_rcaron = 0x1f8, SCIM_KEY_uring = 0x1f9, SCIM_KEY_tcedilla = 0x1fe, SCIM_KEY_abovedot = 0x1ff, /* * Latin 3 * Byte 3 = 2 */ SCIM_KEY_Hstroke = 0x2a1, SCIM_KEY_Hcircumflex = 0x2a6, SCIM_KEY_Iabovedot = 0x2a9, SCIM_KEY_Gbreve = 0x2ab, SCIM_KEY_Jcircumflex = 0x2ac, SCIM_KEY_hstroke = 0x2b1, SCIM_KEY_hcircumflex = 0x2b6, SCIM_KEY_idotless = 0x2b9, SCIM_KEY_gbreve = 0x2bb, SCIM_KEY_jcircumflex = 0x2bc, SCIM_KEY_Cabovedot = 0x2c5, SCIM_KEY_Ccircumflex = 0x2c6, SCIM_KEY_Gabovedot = 0x2d5, SCIM_KEY_Gcircumflex = 0x2d8, SCIM_KEY_Ubreve = 0x2dd, SCIM_KEY_Scircumflex = 0x2de, SCIM_KEY_cabovedot = 0x2e5, SCIM_KEY_ccircumflex = 0x2e6, SCIM_KEY_gabovedot = 0x2f5, SCIM_KEY_gcircumflex = 0x2f8, SCIM_KEY_ubreve = 0x2fd, SCIM_KEY_scircumflex = 0x2fe, /* * Latin 4 * Byte 3 = 3 */ SCIM_KEY_kra = 0x3a2, SCIM_KEY_kappa = 0x3a2, /* deprecated */ SCIM_KEY_Rcedilla = 0x3a3, SCIM_KEY_Itilde = 0x3a5, SCIM_KEY_Lcedilla = 0x3a6, SCIM_KEY_Emacron = 0x3aa, SCIM_KEY_Gcedilla = 0x3ab, SCIM_KEY_Tslash = 0x3ac, SCIM_KEY_rcedilla = 0x3b3, SCIM_KEY_itilde = 0x3b5, SCIM_KEY_lcedilla = 0x3b6, SCIM_KEY_emacron = 0x3ba, SCIM_KEY_gcedilla = 0x3bb, SCIM_KEY_tslash = 0x3bc, SCIM_KEY_ENG = 0x3bd, SCIM_KEY_eng = 0x3bf, SCIM_KEY_Amacron = 0x3c0, SCIM_KEY_Iogonek = 0x3c7, SCIM_KEY_Eabovedot = 0x3cc, SCIM_KEY_Imacron = 0x3cf, SCIM_KEY_Ncedilla = 0x3d1, SCIM_KEY_Omacron = 0x3d2, SCIM_KEY_Kcedilla = 0x3d3, SCIM_KEY_Uogonek = 0x3d9, SCIM_KEY_Utilde = 0x3dd, SCIM_KEY_Umacron = 0x3de, SCIM_KEY_amacron = 0x3e0, SCIM_KEY_iogonek = 0x3e7, SCIM_KEY_eabovedot = 0x3ec, SCIM_KEY_imacron = 0x3ef, SCIM_KEY_ncedilla = 0x3f1, SCIM_KEY_omacron = 0x3f2, SCIM_KEY_kcedilla = 0x3f3, SCIM_KEY_uogonek = 0x3f9, SCIM_KEY_utilde = 0x3fd, SCIM_KEY_umacron = 0x3fe, /* * Latin-8 * Byte 3 = 18 */ SCIM_KEY_Babovedot = 0x12a1, SCIM_KEY_babovedot = 0x12a2, SCIM_KEY_Dabovedot = 0x12a6, SCIM_KEY_Wgrave = 0x12a8, SCIM_KEY_Wacute = 0x12aa, SCIM_KEY_dabovedot = 0x12ab, SCIM_KEY_Ygrave = 0x12ac, SCIM_KEY_Fabovedot = 0x12b0, SCIM_KEY_fabovedot = 0x12b1, SCIM_KEY_Mabovedot = 0x12b4, SCIM_KEY_mabovedot = 0x12b5, SCIM_KEY_Pabovedot = 0x12b7, SCIM_KEY_wgrave = 0x12b8, SCIM_KEY_pabovedot = 0x12b9, SCIM_KEY_wacute = 0x12ba, SCIM_KEY_Sabovedot = 0x12bb, SCIM_KEY_ygrave = 0x12bc, SCIM_KEY_Wdiaeresis = 0x12bd, SCIM_KEY_wdiaeresis = 0x12be, SCIM_KEY_sabovedot = 0x12bf, SCIM_KEY_Wcircumflex = 0x12d0, SCIM_KEY_Tabovedot = 0x12d7, SCIM_KEY_Ycircumflex = 0x12de, SCIM_KEY_wcircumflex = 0x12f0, SCIM_KEY_tabovedot = 0x12f7, SCIM_KEY_ycircumflex = 0x12fe, /* * Latin-9 (a.k.a. Latin-0) * Byte 3 = 19 */ SCIM_KEY_OE = 0x13bc, SCIM_KEY_oe = 0x13bd, SCIM_KEY_Ydiaeresis = 0x13be, /* * Katakana * Byte 3 = 4 */ SCIM_KEY_overline = 0x47e, SCIM_KEY_kana_fullstop = 0x4a1, SCIM_KEY_kana_openingbracket = 0x4a2, SCIM_KEY_kana_closingbracket = 0x4a3, SCIM_KEY_kana_comma = 0x4a4, SCIM_KEY_kana_conjunctive = 0x4a5, SCIM_KEY_kana_middledot = 0x4a5, /* deprecated */ SCIM_KEY_kana_WO = 0x4a6, SCIM_KEY_kana_a = 0x4a7, SCIM_KEY_kana_i = 0x4a8, SCIM_KEY_kana_u = 0x4a9, SCIM_KEY_kana_e = 0x4aa, SCIM_KEY_kana_o = 0x4ab, SCIM_KEY_kana_ya = 0x4ac, SCIM_KEY_kana_yu = 0x4ad, SCIM_KEY_kana_yo = 0x4ae, SCIM_KEY_kana_tsu = 0x4af, SCIM_KEY_kana_tu = 0x4af, /* deprecated */ SCIM_KEY_prolongedsound = 0x4b0, SCIM_KEY_kana_A = 0x4b1, SCIM_KEY_kana_I = 0x4b2, SCIM_KEY_kana_U = 0x4b3, SCIM_KEY_kana_E = 0x4b4, SCIM_KEY_kana_O = 0x4b5, SCIM_KEY_kana_KA = 0x4b6, SCIM_KEY_kana_KI = 0x4b7, SCIM_KEY_kana_KU = 0x4b8, SCIM_KEY_kana_KE = 0x4b9, SCIM_KEY_kana_KO = 0x4ba, SCIM_KEY_kana_SA = 0x4bb, SCIM_KEY_kana_SHI = 0x4bc, SCIM_KEY_kana_SU = 0x4bd, SCIM_KEY_kana_SE = 0x4be, SCIM_KEY_kana_SO = 0x4bf, SCIM_KEY_kana_TA = 0x4c0, SCIM_KEY_kana_CHI = 0x4c1, SCIM_KEY_kana_TI = 0x4c1, /* deprecated */ SCIM_KEY_kana_TSU = 0x4c2, SCIM_KEY_kana_TU = 0x4c2, /* deprecated */ SCIM_KEY_kana_TE = 0x4c3, SCIM_KEY_kana_TO = 0x4c4, SCIM_KEY_kana_NA = 0x4c5, SCIM_KEY_kana_NI = 0x4c6, SCIM_KEY_kana_NU = 0x4c7, SCIM_KEY_kana_NE = 0x4c8, SCIM_KEY_kana_NO = 0x4c9, SCIM_KEY_kana_HA = 0x4ca, SCIM_KEY_kana_HI = 0x4cb, SCIM_KEY_kana_FU = 0x4cc, SCIM_KEY_kana_HU = 0x4cc, /* deprecated */ SCIM_KEY_kana_HE = 0x4cd, SCIM_KEY_kana_HO = 0x4ce, SCIM_KEY_kana_MA = 0x4cf, SCIM_KEY_kana_MI = 0x4d0, SCIM_KEY_kana_MU = 0x4d1, SCIM_KEY_kana_ME = 0x4d2, SCIM_KEY_kana_MO = 0x4d3, SCIM_KEY_kana_YA = 0x4d4, SCIM_KEY_kana_YU = 0x4d5, SCIM_KEY_kana_YO = 0x4d6, SCIM_KEY_kana_RA = 0x4d7, SCIM_KEY_kana_RI = 0x4d8, SCIM_KEY_kana_RU = 0x4d9, SCIM_KEY_kana_RE = 0x4da, SCIM_KEY_kana_RO = 0x4db, SCIM_KEY_kana_WA = 0x4dc, SCIM_KEY_kana_N = 0x4dd, SCIM_KEY_voicedsound = 0x4de, SCIM_KEY_semivoicedsound = 0x4df, SCIM_KEY_kana_switch = 0xFF7E, /* Alias for mode_switch */ /* * Arabic * Byte 3 = 5 */ SCIM_KEY_Farsi_0 = 0x590, SCIM_KEY_Farsi_1 = 0x591, SCIM_KEY_Farsi_2 = 0x592, SCIM_KEY_Farsi_3 = 0x593, SCIM_KEY_Farsi_4 = 0x594, SCIM_KEY_Farsi_5 = 0x595, SCIM_KEY_Farsi_6 = 0x596, SCIM_KEY_Farsi_7 = 0x597, SCIM_KEY_Farsi_8 = 0x598, SCIM_KEY_Farsi_9 = 0x599, SCIM_KEY_Arabic_percent = 0x5a5, SCIM_KEY_Arabic_superscript_alef = 0x5a6, SCIM_KEY_Arabic_tteh = 0x5a7, SCIM_KEY_Arabic_peh = 0x5a8, SCIM_KEY_Arabic_tcheh = 0x5a9, SCIM_KEY_Arabic_ddal = 0x5aa, SCIM_KEY_Arabic_rreh = 0x5ab, SCIM_KEY_Arabic_comma = 0x5ac, SCIM_KEY_Arabic_fullstop = 0x5ae, SCIM_KEY_Arabic_0 = 0x5b0, SCIM_KEY_Arabic_1 = 0x5b1, SCIM_KEY_Arabic_2 = 0x5b2, SCIM_KEY_Arabic_3 = 0x5b3, SCIM_KEY_Arabic_4 = 0x5b4, SCIM_KEY_Arabic_5 = 0x5b5, SCIM_KEY_Arabic_6 = 0x5b6, SCIM_KEY_Arabic_7 = 0x5b7, SCIM_KEY_Arabic_8 = 0x5b8, SCIM_KEY_Arabic_9 = 0x5b9, SCIM_KEY_Arabic_semicolon = 0x5bb, SCIM_KEY_Arabic_question_mark = 0x5bf, SCIM_KEY_Arabic_hamza = 0x5c1, SCIM_KEY_Arabic_maddaonalef = 0x5c2, SCIM_KEY_Arabic_hamzaonalef = 0x5c3, SCIM_KEY_Arabic_hamzaonwaw = 0x5c4, SCIM_KEY_Arabic_hamzaunderalef = 0x5c5, SCIM_KEY_Arabic_hamzaonyeh = 0x5c6, SCIM_KEY_Arabic_alef = 0x5c7, SCIM_KEY_Arabic_beh = 0x5c8, SCIM_KEY_Arabic_tehmarbuta = 0x5c9, SCIM_KEY_Arabic_teh = 0x5ca, SCIM_KEY_Arabic_theh = 0x5cb, SCIM_KEY_Arabic_jeem = 0x5cc, SCIM_KEY_Arabic_hah = 0x5cd, SCIM_KEY_Arabic_khah = 0x5ce, SCIM_KEY_Arabic_dal = 0x5cf, SCIM_KEY_Arabic_thal = 0x5d0, SCIM_KEY_Arabic_ra = 0x5d1, SCIM_KEY_Arabic_zain = 0x5d2, SCIM_KEY_Arabic_seen = 0x5d3, SCIM_KEY_Arabic_sheen = 0x5d4, SCIM_KEY_Arabic_sad = 0x5d5, SCIM_KEY_Arabic_dad = 0x5d6, SCIM_KEY_Arabic_tah = 0x5d7, SCIM_KEY_Arabic_zah = 0x5d8, SCIM_KEY_Arabic_ain = 0x5d9, SCIM_KEY_Arabic_ghain = 0x5da, SCIM_KEY_Arabic_tatweel = 0x5e0, SCIM_KEY_Arabic_feh = 0x5e1, SCIM_KEY_Arabic_qaf = 0x5e2, SCIM_KEY_Arabic_kaf = 0x5e3, SCIM_KEY_Arabic_lam = 0x5e4, SCIM_KEY_Arabic_meem = 0x5e5, SCIM_KEY_Arabic_noon = 0x5e6, SCIM_KEY_Arabic_ha = 0x5e7, SCIM_KEY_Arabic_heh = 0x5e7, /* deprecated */ SCIM_KEY_Arabic_waw = 0x5e8, SCIM_KEY_Arabic_alefmaksura = 0x5e9, SCIM_KEY_Arabic_yeh = 0x5ea, SCIM_KEY_Arabic_fathatan = 0x5eb, SCIM_KEY_Arabic_dammatan = 0x5ec, SCIM_KEY_Arabic_kasratan = 0x5ed, SCIM_KEY_Arabic_fatha = 0x5ee, SCIM_KEY_Arabic_damma = 0x5ef, SCIM_KEY_Arabic_kasra = 0x5f0, SCIM_KEY_Arabic_shadda = 0x5f1, SCIM_KEY_Arabic_sukun = 0x5f2, SCIM_KEY_Arabic_madda_above = 0x5f3, SCIM_KEY_Arabic_hamza_above = 0x5f4, SCIM_KEY_Arabic_hamza_below = 0x5f5, SCIM_KEY_Arabic_jeh = 0x5f6, SCIM_KEY_Arabic_veh = 0x5f7, SCIM_KEY_Arabic_keheh = 0x5f8, SCIM_KEY_Arabic_gaf = 0x5f9, SCIM_KEY_Arabic_noon_ghunna = 0x5fa, SCIM_KEY_Arabic_heh_doachashmee = 0x5fb, SCIM_KEY_Farsi_yeh = 0x5fc, SCIM_KEY_Arabic_farsi_yeh = SCIM_KEY_Farsi_yeh, SCIM_KEY_Arabic_yeh_baree = 0x5fd, SCIM_KEY_Arabic_heh_goal = 0x5fe, SCIM_KEY_Arabic_switch = 0xFF7E, /* Alias for mode_switch */ /* * Cyrillic * Byte 3 = 6 */ SCIM_KEY_Cyrillic_GHE_bar = 0x680, SCIM_KEY_Cyrillic_ghe_bar = 0x690, SCIM_KEY_Cyrillic_ZHE_descender = 0x681, SCIM_KEY_Cyrillic_zhe_descender = 0x691, SCIM_KEY_Cyrillic_KA_descender = 0x682, SCIM_KEY_Cyrillic_ka_descender = 0x692, SCIM_KEY_Cyrillic_KA_vertstroke = 0x683, SCIM_KEY_Cyrillic_ka_vertstroke = 0x693, SCIM_KEY_Cyrillic_EN_descender = 0x684, SCIM_KEY_Cyrillic_en_descender = 0x694, SCIM_KEY_Cyrillic_U_straight = 0x685, SCIM_KEY_Cyrillic_u_straight = 0x695, SCIM_KEY_Cyrillic_U_straight_bar = 0x686, SCIM_KEY_Cyrillic_u_straight_bar = 0x696, SCIM_KEY_Cyrillic_HA_descender = 0x687, SCIM_KEY_Cyrillic_ha_descender = 0x697, SCIM_KEY_Cyrillic_CHE_descender = 0x688, SCIM_KEY_Cyrillic_che_descender = 0x698, SCIM_KEY_Cyrillic_CHE_vertstroke = 0x689, SCIM_KEY_Cyrillic_che_vertstroke = 0x699, SCIM_KEY_Cyrillic_SHHA = 0x68a, SCIM_KEY_Cyrillic_shha = 0x69a, SCIM_KEY_Cyrillic_SCHWA = 0x68c, SCIM_KEY_Cyrillic_schwa = 0x69c, SCIM_KEY_Cyrillic_I_macron = 0x68d, SCIM_KEY_Cyrillic_i_macron = 0x69d, SCIM_KEY_Cyrillic_O_bar = 0x68e, SCIM_KEY_Cyrillic_o_bar = 0x69e, SCIM_KEY_Cyrillic_U_macron = 0x68f, SCIM_KEY_Cyrillic_u_macron = 0x69f, SCIM_KEY_Serbian_dje = 0x6a1, SCIM_KEY_Macedonia_gje = 0x6a2, SCIM_KEY_Cyrillic_io = 0x6a3, SCIM_KEY_Ukrainian_ie = 0x6a4, SCIM_KEY_Ukranian_je = 0x6a4, /* deprecated */ SCIM_KEY_Macedonia_dse = 0x6a5, SCIM_KEY_Ukrainian_i = 0x6a6, SCIM_KEY_Ukranian_i = 0x6a6, /* deprecated */ SCIM_KEY_Ukrainian_yi = 0x6a7, SCIM_KEY_Ukranian_yi = 0x6a7, /* deprecated */ SCIM_KEY_Cyrillic_je = 0x6a8, SCIM_KEY_Serbian_je = 0x6a8, /* deprecated */ SCIM_KEY_Cyrillic_lje = 0x6a9, SCIM_KEY_Serbian_lje = 0x6a9, /* deprecated */ SCIM_KEY_Cyrillic_nje = 0x6aa, SCIM_KEY_Serbian_nje = 0x6aa, /* deprecated */ SCIM_KEY_Serbian_tshe = 0x6ab, SCIM_KEY_Macedonia_kje = 0x6ac, SCIM_KEY_Ukrainian_ghe_with_upturn = 0x6ad, SCIM_KEY_Byelorussian_shortu = 0x6ae, SCIM_KEY_Cyrillic_dzhe = 0x6af, SCIM_KEY_Serbian_dze = 0x6af, /* deprecated */ SCIM_KEY_numerosign = 0x6b0, SCIM_KEY_Serbian_DJE = 0x6b1, SCIM_KEY_Macedonia_GJE = 0x6b2, SCIM_KEY_Cyrillic_IO = 0x6b3, SCIM_KEY_Ukrainian_IE = 0x6b4, SCIM_KEY_Ukranian_JE = 0x6b4, /* deprecated */ SCIM_KEY_Macedonia_DSE = 0x6b5, SCIM_KEY_Ukrainian_I = 0x6b6, SCIM_KEY_Ukranian_I = 0x6b6, /* deprecated */ SCIM_KEY_Ukrainian_YI = 0x6b7, SCIM_KEY_Ukranian_YI = 0x6b7, /* deprecated */ SCIM_KEY_Cyrillic_JE = 0x6b8, SCIM_KEY_Serbian_JE = 0x6b8, /* deprecated */ SCIM_KEY_Cyrillic_LJE = 0x6b9, SCIM_KEY_Serbian_LJE = 0x6b9, /* deprecated */ SCIM_KEY_Cyrillic_NJE = 0x6ba, SCIM_KEY_Serbian_NJE = 0x6ba, /* deprecated */ SCIM_KEY_Serbian_TSHE = 0x6bb, SCIM_KEY_Macedonia_KJE = 0x6bc, SCIM_KEY_Ukrainian_GHE_WITH_UPTURN = 0x6bd, SCIM_KEY_Byelorussian_SHORTU = 0x6be, SCIM_KEY_Cyrillic_DZHE = 0x6bf, SCIM_KEY_Serbian_DZE = 0x6bf, /* deprecated */ SCIM_KEY_Cyrillic_yu = 0x6c0, SCIM_KEY_Cyrillic_a = 0x6c1, SCIM_KEY_Cyrillic_be = 0x6c2, SCIM_KEY_Cyrillic_tse = 0x6c3, SCIM_KEY_Cyrillic_de = 0x6c4, SCIM_KEY_Cyrillic_ie = 0x6c5, SCIM_KEY_Cyrillic_ef = 0x6c6, SCIM_KEY_Cyrillic_ghe = 0x6c7, SCIM_KEY_Cyrillic_ha = 0x6c8, SCIM_KEY_Cyrillic_i = 0x6c9, SCIM_KEY_Cyrillic_shorti = 0x6ca, SCIM_KEY_Cyrillic_ka = 0x6cb, SCIM_KEY_Cyrillic_el = 0x6cc, SCIM_KEY_Cyrillic_em = 0x6cd, SCIM_KEY_Cyrillic_en = 0x6ce, SCIM_KEY_Cyrillic_o = 0x6cf, SCIM_KEY_Cyrillic_pe = 0x6d0, SCIM_KEY_Cyrillic_ya = 0x6d1, SCIM_KEY_Cyrillic_er = 0x6d2, SCIM_KEY_Cyrillic_es = 0x6d3, SCIM_KEY_Cyrillic_te = 0x6d4, SCIM_KEY_Cyrillic_u = 0x6d5, SCIM_KEY_Cyrillic_zhe = 0x6d6, SCIM_KEY_Cyrillic_ve = 0x6d7, SCIM_KEY_Cyrillic_softsign = 0x6d8, SCIM_KEY_Cyrillic_yeru = 0x6d9, SCIM_KEY_Cyrillic_ze = 0x6da, SCIM_KEY_Cyrillic_sha = 0x6db, SCIM_KEY_Cyrillic_e = 0x6dc, SCIM_KEY_Cyrillic_shcha = 0x6dd, SCIM_KEY_Cyrillic_che = 0x6de, SCIM_KEY_Cyrillic_hardsign = 0x6df, SCIM_KEY_Cyrillic_YU = 0x6e0, SCIM_KEY_Cyrillic_A = 0x6e1, SCIM_KEY_Cyrillic_BE = 0x6e2, SCIM_KEY_Cyrillic_TSE = 0x6e3, SCIM_KEY_Cyrillic_DE = 0x6e4, SCIM_KEY_Cyrillic_IE = 0x6e5, SCIM_KEY_Cyrillic_EF = 0x6e6, SCIM_KEY_Cyrillic_GHE = 0x6e7, SCIM_KEY_Cyrillic_HA = 0x6e8, SCIM_KEY_Cyrillic_I = 0x6e9, SCIM_KEY_Cyrillic_SHORTI = 0x6ea, SCIM_KEY_Cyrillic_KA = 0x6eb, SCIM_KEY_Cyrillic_EL = 0x6ec, SCIM_KEY_Cyrillic_EM = 0x6ed, SCIM_KEY_Cyrillic_EN = 0x6ee, SCIM_KEY_Cyrillic_O = 0x6ef, SCIM_KEY_Cyrillic_PE = 0x6f0, SCIM_KEY_Cyrillic_YA = 0x6f1, SCIM_KEY_Cyrillic_ER = 0x6f2, SCIM_KEY_Cyrillic_ES = 0x6f3, SCIM_KEY_Cyrillic_TE = 0x6f4, SCIM_KEY_Cyrillic_U = 0x6f5, SCIM_KEY_Cyrillic_ZHE = 0x6f6, SCIM_KEY_Cyrillic_VE = 0x6f7, SCIM_KEY_Cyrillic_SOFTSIGN = 0x6f8, SCIM_KEY_Cyrillic_YERU = 0x6f9, SCIM_KEY_Cyrillic_ZE = 0x6fa, SCIM_KEY_Cyrillic_SHA = 0x6fb, SCIM_KEY_Cyrillic_E = 0x6fc, SCIM_KEY_Cyrillic_SHCHA = 0x6fd, SCIM_KEY_Cyrillic_CHE = 0x6fe, SCIM_KEY_Cyrillic_HARDSIGN = 0x6ff, /* * Greek * Byte 3 = 7 */ SCIM_KEY_Greek_ALPHAaccent = 0x7a1, SCIM_KEY_Greek_EPSILONaccent = 0x7a2, SCIM_KEY_Greek_ETAaccent = 0x7a3, SCIM_KEY_Greek_IOTAaccent = 0x7a4, SCIM_KEY_Greek_IOTAdieresis = 0x7a5, SCIM_KEY_Greek_IOTAdiaeresis = SCIM_KEY_Greek_IOTAdieresis, /* old typo */ SCIM_KEY_Greek_OMICRONaccent = 0x7a7, SCIM_KEY_Greek_UPSILONaccent = 0x7a8, SCIM_KEY_Greek_UPSILONdieresis = 0x7a9, SCIM_KEY_Greek_OMEGAaccent = 0x7ab, SCIM_KEY_Greek_accentdieresis = 0x7ae, SCIM_KEY_Greek_horizbar = 0x7af, SCIM_KEY_Greek_alphaaccent = 0x7b1, SCIM_KEY_Greek_epsilonaccent = 0x7b2, SCIM_KEY_Greek_etaaccent = 0x7b3, SCIM_KEY_Greek_iotaaccent = 0x7b4, SCIM_KEY_Greek_iotadieresis = 0x7b5, SCIM_KEY_Greek_iotaaccentdieresis = 0x7b6, SCIM_KEY_Greek_omicronaccent = 0x7b7, SCIM_KEY_Greek_upsilonaccent = 0x7b8, SCIM_KEY_Greek_upsilondieresis = 0x7b9, SCIM_KEY_Greek_upsilonaccentdieresis = 0x7ba, SCIM_KEY_Greek_omegaaccent = 0x7bb, SCIM_KEY_Greek_ALPHA = 0x7c1, SCIM_KEY_Greek_BETA = 0x7c2, SCIM_KEY_Greek_GAMMA = 0x7c3, SCIM_KEY_Greek_DELTA = 0x7c4, SCIM_KEY_Greek_EPSILON = 0x7c5, SCIM_KEY_Greek_ZETA = 0x7c6, SCIM_KEY_Greek_ETA = 0x7c7, SCIM_KEY_Greek_THETA = 0x7c8, SCIM_KEY_Greek_IOTA = 0x7c9, SCIM_KEY_Greek_KAPPA = 0x7ca, SCIM_KEY_Greek_LAMDA = 0x7cb, SCIM_KEY_Greek_LAMBDA = 0x7cb, SCIM_KEY_Greek_MU = 0x7cc, SCIM_KEY_Greek_NU = 0x7cd, SCIM_KEY_Greek_XI = 0x7ce, SCIM_KEY_Greek_OMICRON = 0x7cf, SCIM_KEY_Greek_PI = 0x7d0, SCIM_KEY_Greek_RHO = 0x7d1, SCIM_KEY_Greek_SIGMA = 0x7d2, SCIM_KEY_Greek_TAU = 0x7d4, SCIM_KEY_Greek_UPSILON = 0x7d5, SCIM_KEY_Greek_PHI = 0x7d6, SCIM_KEY_Greek_CHI = 0x7d7, SCIM_KEY_Greek_PSI = 0x7d8, SCIM_KEY_Greek_OMEGA = 0x7d9, SCIM_KEY_Greek_alpha = 0x7e1, SCIM_KEY_Greek_beta = 0x7e2, SCIM_KEY_Greek_gamma = 0x7e3, SCIM_KEY_Greek_delta = 0x7e4, SCIM_KEY_Greek_epsilon = 0x7e5, SCIM_KEY_Greek_zeta = 0x7e6, SCIM_KEY_Greek_eta = 0x7e7, SCIM_KEY_Greek_theta = 0x7e8, SCIM_KEY_Greek_iota = 0x7e9, SCIM_KEY_Greek_kappa = 0x7ea, SCIM_KEY_Greek_lamda = 0x7eb, SCIM_KEY_Greek_lambda = 0x7eb, SCIM_KEY_Greek_mu = 0x7ec, SCIM_KEY_Greek_nu = 0x7ed, SCIM_KEY_Greek_xi = 0x7ee, SCIM_KEY_Greek_omicron = 0x7ef, SCIM_KEY_Greek_pi = 0x7f0, SCIM_KEY_Greek_rho = 0x7f1, SCIM_KEY_Greek_sigma = 0x7f2, SCIM_KEY_Greek_finalsmallsigma = 0x7f3, SCIM_KEY_Greek_tau = 0x7f4, SCIM_KEY_Greek_upsilon = 0x7f5, SCIM_KEY_Greek_phi = 0x7f6, SCIM_KEY_Greek_chi = 0x7f7, SCIM_KEY_Greek_psi = 0x7f8, SCIM_KEY_Greek_omega = 0x7f9, SCIM_KEY_Greek_switch = 0xFF7E, /* Alias for mode_switch */ /* * Technical * Byte 3 = 8 */ SCIM_KEY_leftradical = 0x8a1, SCIM_KEY_topleftradical = 0x8a2, SCIM_KEY_horizconnector = 0x8a3, SCIM_KEY_topintegral = 0x8a4, SCIM_KEY_botintegral = 0x8a5, SCIM_KEY_vertconnector = 0x8a6, SCIM_KEY_topleftsqbracket = 0x8a7, SCIM_KEY_botleftsqbracket = 0x8a8, SCIM_KEY_toprightsqbracket = 0x8a9, SCIM_KEY_botrightsqbracket = 0x8aa, SCIM_KEY_topleftparens = 0x8ab, SCIM_KEY_botleftparens = 0x8ac, SCIM_KEY_toprightparens = 0x8ad, SCIM_KEY_botrightparens = 0x8ae, SCIM_KEY_leftmiddlecurlybrace = 0x8af, SCIM_KEY_rightmiddlecurlybrace = 0x8b0, SCIM_KEY_topleftsummation = 0x8b1, SCIM_KEY_botleftsummation = 0x8b2, SCIM_KEY_topvertsummationconnector = 0x8b3, SCIM_KEY_botvertsummationconnector = 0x8b4, SCIM_KEY_toprightsummation = 0x8b5, SCIM_KEY_botrightsummation = 0x8b6, SCIM_KEY_rightmiddlesummation = 0x8b7, SCIM_KEY_lessthanequal = 0x8bc, SCIM_KEY_notequal = 0x8bd, SCIM_KEY_greaterthanequal = 0x8be, SCIM_KEY_integral = 0x8bf, SCIM_KEY_therefore = 0x8c0, SCIM_KEY_variation = 0x8c1, SCIM_KEY_infinity = 0x8c2, SCIM_KEY_nabla = 0x8c5, SCIM_KEY_approximate = 0x8c8, SCIM_KEY_similarequal = 0x8c9, SCIM_KEY_ifonlyif = 0x8cd, SCIM_KEY_implies = 0x8ce, SCIM_KEY_identical = 0x8cf, SCIM_KEY_radical = 0x8d6, SCIM_KEY_includedin = 0x8da, SCIM_KEY_includes = 0x8db, SCIM_KEY_intersection = 0x8dc, SCIM_KEY_union = 0x8dd, SCIM_KEY_logicaland = 0x8de, SCIM_KEY_logicalor = 0x8df, SCIM_KEY_partialderivative = 0x8ef, SCIM_KEY_function = 0x8f6, SCIM_KEY_leftarrow = 0x8fb, SCIM_KEY_uparrow = 0x8fc, SCIM_KEY_rightarrow = 0x8fd, SCIM_KEY_downarrow = 0x8fe, /* * Special * Byte 3 = 9 */ SCIM_KEY_blank = 0x9df, SCIM_KEY_soliddiamond = 0x9e0, SCIM_KEY_checkerboard = 0x9e1, SCIM_KEY_ht = 0x9e2, SCIM_KEY_ff = 0x9e3, SCIM_KEY_cr = 0x9e4, SCIM_KEY_lf = 0x9e5, SCIM_KEY_nl = 0x9e8, SCIM_KEY_vt = 0x9e9, SCIM_KEY_lowrightcorner = 0x9ea, SCIM_KEY_uprightcorner = 0x9eb, SCIM_KEY_upleftcorner = 0x9ec, SCIM_KEY_lowleftcorner = 0x9ed, SCIM_KEY_crossinglines = 0x9ee, SCIM_KEY_horizlinescan1 = 0x9ef, SCIM_KEY_horizlinescan3 = 0x9f0, SCIM_KEY_horizlinescan5 = 0x9f1, SCIM_KEY_horizlinescan7 = 0x9f2, SCIM_KEY_horizlinescan9 = 0x9f3, SCIM_KEY_leftt = 0x9f4, SCIM_KEY_rightt = 0x9f5, SCIM_KEY_bott = 0x9f6, SCIM_KEY_topt = 0x9f7, SCIM_KEY_vertbar = 0x9f8, /* * Publishing * Byte 3 = a */ SCIM_KEY_emspace = 0xaa1, SCIM_KEY_enspace = 0xaa2, SCIM_KEY_em3space = 0xaa3, SCIM_KEY_em4space = 0xaa4, SCIM_KEY_digitspace = 0xaa5, SCIM_KEY_punctspace = 0xaa6, SCIM_KEY_thinspace = 0xaa7, SCIM_KEY_hairspace = 0xaa8, SCIM_KEY_emdash = 0xaa9, SCIM_KEY_endash = 0xaaa, SCIM_KEY_signifblank = 0xaac, SCIM_KEY_ellipsis = 0xaae, SCIM_KEY_doubbaselinedot = 0xaaf, SCIM_KEY_onethird = 0xab0, SCIM_KEY_twothirds = 0xab1, SCIM_KEY_onefifth = 0xab2, SCIM_KEY_twofifths = 0xab3, SCIM_KEY_threefifths = 0xab4, SCIM_KEY_fourfifths = 0xab5, SCIM_KEY_onesixth = 0xab6, SCIM_KEY_fivesixths = 0xab7, SCIM_KEY_careof = 0xab8, SCIM_KEY_figdash = 0xabb, SCIM_KEY_leftanglebracket = 0xabc, SCIM_KEY_decimalpoint = 0xabd, SCIM_KEY_rightanglebracket = 0xabe, SCIM_KEY_marker = 0xabf, SCIM_KEY_oneeighth = 0xac3, SCIM_KEY_threeeighths = 0xac4, SCIM_KEY_fiveeighths = 0xac5, SCIM_KEY_seveneighths = 0xac6, SCIM_KEY_trademark = 0xac9, SCIM_KEY_signaturemark = 0xaca, SCIM_KEY_trademarkincircle = 0xacb, SCIM_KEY_leftopentriangle = 0xacc, SCIM_KEY_rightopentriangle = 0xacd, SCIM_KEY_emopencircle = 0xace, SCIM_KEY_emopenrectangle = 0xacf, SCIM_KEY_leftsinglequotemark = 0xad0, SCIM_KEY_rightsinglequotemark = 0xad1, SCIM_KEY_leftdoublequotemark = 0xad2, SCIM_KEY_rightdoublequotemark = 0xad3, SCIM_KEY_prescription = 0xad4, SCIM_KEY_minutes = 0xad6, SCIM_KEY_seconds = 0xad7, SCIM_KEY_latincross = 0xad9, SCIM_KEY_hexagram = 0xada, SCIM_KEY_filledrectbullet = 0xadb, SCIM_KEY_filledlefttribullet = 0xadc, SCIM_KEY_filledrighttribullet = 0xadd, SCIM_KEY_emfilledcircle = 0xade, SCIM_KEY_emfilledrect = 0xadf, SCIM_KEY_enopencircbullet = 0xae0, SCIM_KEY_enopensquarebullet = 0xae1, SCIM_KEY_openrectbullet = 0xae2, SCIM_KEY_opentribulletup = 0xae3, SCIM_KEY_opentribulletdown = 0xae4, SCIM_KEY_openstar = 0xae5, SCIM_KEY_enfilledcircbullet = 0xae6, SCIM_KEY_enfilledsqbullet = 0xae7, SCIM_KEY_filledtribulletup = 0xae8, SCIM_KEY_filledtribulletdown = 0xae9, SCIM_KEY_leftpointer = 0xaea, SCIM_KEY_rightpointer = 0xaeb, SCIM_KEY_club = 0xaec, SCIM_KEY_diamond = 0xaed, SCIM_KEY_heart = 0xaee, SCIM_KEY_maltesecross = 0xaf0, SCIM_KEY_dagger = 0xaf1, SCIM_KEY_doubledagger = 0xaf2, SCIM_KEY_checkmark = 0xaf3, SCIM_KEY_ballotcross = 0xaf4, SCIM_KEY_musicalsharp = 0xaf5, SCIM_KEY_musicalflat = 0xaf6, SCIM_KEY_malesymbol = 0xaf7, SCIM_KEY_femalesymbol = 0xaf8, SCIM_KEY_telephone = 0xaf9, SCIM_KEY_telephonerecorder = 0xafa, SCIM_KEY_phonographcopyright = 0xafb, SCIM_KEY_caret = 0xafc, SCIM_KEY_singlelowquotemark = 0xafd, SCIM_KEY_doublelowquotemark = 0xafe, SCIM_KEY_cursor = 0xaff, /* * APL * Byte 3 = b */ SCIM_KEY_leftcaret = 0xba3, SCIM_KEY_rightcaret = 0xba6, SCIM_KEY_downcaret = 0xba8, SCIM_KEY_upcaret = 0xba9, SCIM_KEY_overbar = 0xbc0, SCIM_KEY_downtack = 0xbc2, SCIM_KEY_upshoe = 0xbc3, SCIM_KEY_downstile = 0xbc4, SCIM_KEY_underbar = 0xbc6, SCIM_KEY_jot = 0xbca, SCIM_KEY_quad = 0xbcc, SCIM_KEY_uptack = 0xbce, SCIM_KEY_circle = 0xbcf, SCIM_KEY_upstile = 0xbd3, SCIM_KEY_downshoe = 0xbd6, SCIM_KEY_rightshoe = 0xbd8, SCIM_KEY_leftshoe = 0xbda, SCIM_KEY_lefttack = 0xbdc, SCIM_KEY_righttack = 0xbfc, /* * Hebrew * Byte 3 = c */ SCIM_KEY_hebrew_doublelowline = 0xcdf, SCIM_KEY_hebrew_aleph = 0xce0, SCIM_KEY_hebrew_bet = 0xce1, SCIM_KEY_hebrew_beth = 0xce1, /* deprecated */ SCIM_KEY_hebrew_gimel = 0xce2, SCIM_KEY_hebrew_gimmel = 0xce2, /* deprecated */ SCIM_KEY_hebrew_dalet = 0xce3, SCIM_KEY_hebrew_daleth = 0xce3, /* deprecated */ SCIM_KEY_hebrew_he = 0xce4, SCIM_KEY_hebrew_waw = 0xce5, SCIM_KEY_hebrew_zain = 0xce6, SCIM_KEY_hebrew_zayin = 0xce6, /* deprecated */ SCIM_KEY_hebrew_chet = 0xce7, SCIM_KEY_hebrew_het = 0xce7, /* deprecated */ SCIM_KEY_hebrew_tet = 0xce8, SCIM_KEY_hebrew_teth = 0xce8, /* deprecated */ SCIM_KEY_hebrew_yod = 0xce9, SCIM_KEY_hebrew_finalkaph = 0xcea, SCIM_KEY_hebrew_kaph = 0xceb, SCIM_KEY_hebrew_lamed = 0xcec, SCIM_KEY_hebrew_finalmem = 0xced, SCIM_KEY_hebrew_mem = 0xcee, SCIM_KEY_hebrew_finalnun = 0xcef, SCIM_KEY_hebrew_nun = 0xcf0, SCIM_KEY_hebrew_samech = 0xcf1, SCIM_KEY_hebrew_samekh = 0xcf1, /* deprecated */ SCIM_KEY_hebrew_ayin = 0xcf2, SCIM_KEY_hebrew_finalpe = 0xcf3, SCIM_KEY_hebrew_pe = 0xcf4, SCIM_KEY_hebrew_finalzade = 0xcf5, SCIM_KEY_hebrew_finalzadi = 0xcf5, /* deprecated */ SCIM_KEY_hebrew_zade = 0xcf6, SCIM_KEY_hebrew_zadi = 0xcf6, /* deprecated */ SCIM_KEY_hebrew_qoph = 0xcf7, SCIM_KEY_hebrew_kuf = 0xcf7, /* deprecated */ SCIM_KEY_hebrew_resh = 0xcf8, SCIM_KEY_hebrew_shin = 0xcf9, SCIM_KEY_hebrew_taw = 0xcfa, SCIM_KEY_hebrew_taf = 0xcfa, /* deprecated */ SCIM_KEY_Hebrew_switch = 0xFF7E, /* Alias for mode_switch */ /* * Thai * Byte 3 = d */ SCIM_KEY_Thai_kokai = 0xda1, SCIM_KEY_Thai_khokhai = 0xda2, SCIM_KEY_Thai_khokhuat = 0xda3, SCIM_KEY_Thai_khokhwai = 0xda4, SCIM_KEY_Thai_khokhon = 0xda5, SCIM_KEY_Thai_khorakhang = 0xda6, SCIM_KEY_Thai_ngongu = 0xda7, SCIM_KEY_Thai_chochan = 0xda8, SCIM_KEY_Thai_choching = 0xda9, SCIM_KEY_Thai_chochang = 0xdaa, SCIM_KEY_Thai_soso = 0xdab, SCIM_KEY_Thai_chochoe = 0xdac, SCIM_KEY_Thai_yoying = 0xdad, SCIM_KEY_Thai_dochada = 0xdae, SCIM_KEY_Thai_topatak = 0xdaf, SCIM_KEY_Thai_thothan = 0xdb0, SCIM_KEY_Thai_thonangmontho = 0xdb1, SCIM_KEY_Thai_thophuthao = 0xdb2, SCIM_KEY_Thai_nonen = 0xdb3, SCIM_KEY_Thai_dodek = 0xdb4, SCIM_KEY_Thai_totao = 0xdb5, SCIM_KEY_Thai_thothung = 0xdb6, SCIM_KEY_Thai_thothahan = 0xdb7, SCIM_KEY_Thai_thothong = 0xdb8, SCIM_KEY_Thai_nonu = 0xdb9, SCIM_KEY_Thai_bobaimai = 0xdba, SCIM_KEY_Thai_popla = 0xdbb, SCIM_KEY_Thai_phophung = 0xdbc, SCIM_KEY_Thai_fofa = 0xdbd, SCIM_KEY_Thai_phophan = 0xdbe, SCIM_KEY_Thai_fofan = 0xdbf, SCIM_KEY_Thai_phosamphao = 0xdc0, SCIM_KEY_Thai_moma = 0xdc1, SCIM_KEY_Thai_yoyak = 0xdc2, SCIM_KEY_Thai_rorua = 0xdc3, SCIM_KEY_Thai_ru = 0xdc4, SCIM_KEY_Thai_loling = 0xdc5, SCIM_KEY_Thai_lu = 0xdc6, SCIM_KEY_Thai_wowaen = 0xdc7, SCIM_KEY_Thai_sosala = 0xdc8, SCIM_KEY_Thai_sorusi = 0xdc9, SCIM_KEY_Thai_sosua = 0xdca, SCIM_KEY_Thai_hohip = 0xdcb, SCIM_KEY_Thai_lochula = 0xdcc, SCIM_KEY_Thai_oang = 0xdcd, SCIM_KEY_Thai_honokhuk = 0xdce, SCIM_KEY_Thai_paiyannoi = 0xdcf, SCIM_KEY_Thai_saraa = 0xdd0, SCIM_KEY_Thai_maihanakat = 0xdd1, SCIM_KEY_Thai_saraaa = 0xdd2, SCIM_KEY_Thai_saraam = 0xdd3, SCIM_KEY_Thai_sarai = 0xdd4, SCIM_KEY_Thai_saraii = 0xdd5, SCIM_KEY_Thai_saraue = 0xdd6, SCIM_KEY_Thai_sarauee = 0xdd7, SCIM_KEY_Thai_sarau = 0xdd8, SCIM_KEY_Thai_sarauu = 0xdd9, SCIM_KEY_Thai_phinthu = 0xdda, SCIM_KEY_Thai_maihanakat_maitho = 0xdde, SCIM_KEY_Thai_baht = 0xddf, SCIM_KEY_Thai_sarae = 0xde0, SCIM_KEY_Thai_saraae = 0xde1, SCIM_KEY_Thai_sarao = 0xde2, SCIM_KEY_Thai_saraaimaimuan = 0xde3, SCIM_KEY_Thai_saraaimaimalai = 0xde4, SCIM_KEY_Thai_lakkhangyao = 0xde5, SCIM_KEY_Thai_maiyamok = 0xde6, SCIM_KEY_Thai_maitaikhu = 0xde7, SCIM_KEY_Thai_maiek = 0xde8, SCIM_KEY_Thai_maitho = 0xde9, SCIM_KEY_Thai_maitri = 0xdea, SCIM_KEY_Thai_maichattawa = 0xdeb, SCIM_KEY_Thai_thanthakhat = 0xdec, SCIM_KEY_Thai_nikhahit = 0xded, SCIM_KEY_Thai_leksun = 0xdf0, SCIM_KEY_Thai_leknung = 0xdf1, SCIM_KEY_Thai_leksong = 0xdf2, SCIM_KEY_Thai_leksam = 0xdf3, SCIM_KEY_Thai_leksi = 0xdf4, SCIM_KEY_Thai_lekha = 0xdf5, SCIM_KEY_Thai_lekhok = 0xdf6, SCIM_KEY_Thai_lekchet = 0xdf7, SCIM_KEY_Thai_lekpaet = 0xdf8, SCIM_KEY_Thai_lekkao = 0xdf9, /* * Korean * Byte 3 = e */ SCIM_KEY_Hangul = 0xff31, /* Hangul start/stop(toggle) */ SCIM_KEY_Hangul_Start = 0xff32, /* Hangul start */ SCIM_KEY_Hangul_End = 0xff33, /* Hangul end, English start */ SCIM_KEY_Hangul_Hanja = 0xff34, /* Start Hangul->Hanja Conversion */ SCIM_KEY_Hangul_Jamo = 0xff35, /* Hangul Jamo mode */ SCIM_KEY_Hangul_Romaja = 0xff36, /* Hangul Romaja mode */ SCIM_KEY_Hangul_Codeinput = 0xff37, /* Hangul code input mode */ SCIM_KEY_Hangul_Jeonja = 0xff38, /* Jeonja mode */ SCIM_KEY_Hangul_Banja = 0xff39, /* Banja mode */ SCIM_KEY_Hangul_PreHanja = 0xff3a, /* Pre Hanja conversion */ SCIM_KEY_Hangul_PostHanja = 0xff3b, /* Post Hanja conversion */ SCIM_KEY_Hangul_SingleCandidate = 0xff3c, /* Single candidate */ SCIM_KEY_Hangul_MultipleCandidate = 0xff3d, /* Multiple candidate */ SCIM_KEY_Hangul_PreviousCandidate = 0xff3e, /* Previous candidate */ SCIM_KEY_Hangul_Special = 0xff3f, /* Special symbols */ SCIM_KEY_Hangul_switch = 0xFF7E, /* Alias for mode_switch */ /* Hangul Consonant Characters */ SCIM_KEY_Hangul_Kiyeog = 0xea1, SCIM_KEY_Hangul_SsangKiyeog = 0xea2, SCIM_KEY_Hangul_KiyeogSios = 0xea3, SCIM_KEY_Hangul_Nieun = 0xea4, SCIM_KEY_Hangul_NieunJieuj = 0xea5, SCIM_KEY_Hangul_NieunHieuh = 0xea6, SCIM_KEY_Hangul_Dikeud = 0xea7, SCIM_KEY_Hangul_SsangDikeud = 0xea8, SCIM_KEY_Hangul_Rieul = 0xea9, SCIM_KEY_Hangul_RieulKiyeog = 0xeaa, SCIM_KEY_Hangul_RieulMieum = 0xeab, SCIM_KEY_Hangul_RieulPieub = 0xeac, SCIM_KEY_Hangul_RieulSios = 0xead, SCIM_KEY_Hangul_RieulTieut = 0xeae, SCIM_KEY_Hangul_RieulPhieuf = 0xeaf, SCIM_KEY_Hangul_RieulHieuh = 0xeb0, SCIM_KEY_Hangul_Mieum = 0xeb1, SCIM_KEY_Hangul_Pieub = 0xeb2, SCIM_KEY_Hangul_SsangPieub = 0xeb3, SCIM_KEY_Hangul_PieubSios = 0xeb4, SCIM_KEY_Hangul_Sios = 0xeb5, SCIM_KEY_Hangul_SsangSios = 0xeb6, SCIM_KEY_Hangul_Ieung = 0xeb7, SCIM_KEY_Hangul_Jieuj = 0xeb8, SCIM_KEY_Hangul_SsangJieuj = 0xeb9, SCIM_KEY_Hangul_Cieuc = 0xeba, SCIM_KEY_Hangul_Khieuq = 0xebb, SCIM_KEY_Hangul_Tieut = 0xebc, SCIM_KEY_Hangul_Phieuf = 0xebd, SCIM_KEY_Hangul_Hieuh = 0xebe, /* Hangul Vowel Characters */ SCIM_KEY_Hangul_A = 0xebf, SCIM_KEY_Hangul_AE = 0xec0, SCIM_KEY_Hangul_YA = 0xec1, SCIM_KEY_Hangul_YAE = 0xec2, SCIM_KEY_Hangul_EO = 0xec3, SCIM_KEY_Hangul_E = 0xec4, SCIM_KEY_Hangul_YEO = 0xec5, SCIM_KEY_Hangul_YE = 0xec6, SCIM_KEY_Hangul_O = 0xec7, SCIM_KEY_Hangul_WA = 0xec8, SCIM_KEY_Hangul_WAE = 0xec9, SCIM_KEY_Hangul_OE = 0xeca, SCIM_KEY_Hangul_YO = 0xecb, SCIM_KEY_Hangul_U = 0xecc, SCIM_KEY_Hangul_WEO = 0xecd, SCIM_KEY_Hangul_WE = 0xece, SCIM_KEY_Hangul_WI = 0xecf, SCIM_KEY_Hangul_YU = 0xed0, SCIM_KEY_Hangul_EU = 0xed1, SCIM_KEY_Hangul_YI = 0xed2, SCIM_KEY_Hangul_I = 0xed3, /* Hangul syllable-final (JongSeong) Characters */ SCIM_KEY_Hangul_J_Kiyeog = 0xed4, SCIM_KEY_Hangul_J_SsangKiyeog = 0xed5, SCIM_KEY_Hangul_J_KiyeogSios = 0xed6, SCIM_KEY_Hangul_J_Nieun = 0xed7, SCIM_KEY_Hangul_J_NieunJieuj = 0xed8, SCIM_KEY_Hangul_J_NieunHieuh = 0xed9, SCIM_KEY_Hangul_J_Dikeud = 0xeda, SCIM_KEY_Hangul_J_Rieul = 0xedb, SCIM_KEY_Hangul_J_RieulKiyeog = 0xedc, SCIM_KEY_Hangul_J_RieulMieum = 0xedd, SCIM_KEY_Hangul_J_RieulPieub = 0xede, SCIM_KEY_Hangul_J_RieulSios = 0xedf, SCIM_KEY_Hangul_J_RieulTieut = 0xee0, SCIM_KEY_Hangul_J_RieulPhieuf = 0xee1, SCIM_KEY_Hangul_J_RieulHieuh = 0xee2, SCIM_KEY_Hangul_J_Mieum = 0xee3, SCIM_KEY_Hangul_J_Pieub = 0xee4, SCIM_KEY_Hangul_J_PieubSios = 0xee5, SCIM_KEY_Hangul_J_Sios = 0xee6, SCIM_KEY_Hangul_J_SsangSios = 0xee7, SCIM_KEY_Hangul_J_Ieung = 0xee8, SCIM_KEY_Hangul_J_Jieuj = 0xee9, SCIM_KEY_Hangul_J_Cieuc = 0xeea, SCIM_KEY_Hangul_J_Khieuq = 0xeeb, SCIM_KEY_Hangul_J_Tieut = 0xeec, SCIM_KEY_Hangul_J_Phieuf = 0xeed, SCIM_KEY_Hangul_J_Hieuh = 0xeee, /* Ancient Hangul Consonant Characters */ SCIM_KEY_Hangul_RieulYeorinHieuh = 0xeef, SCIM_KEY_Hangul_SunkyeongeumMieum = 0xef0, SCIM_KEY_Hangul_SunkyeongeumPieub = 0xef1, SCIM_KEY_Hangul_PanSios = 0xef2, SCIM_KEY_Hangul_KkogjiDalrinIeung = 0xef3, SCIM_KEY_Hangul_SunkyeongeumPhieuf = 0xef4, SCIM_KEY_Hangul_YeorinHieuh = 0xef5, /* Ancient Hangul Vowel Characters */ SCIM_KEY_Hangul_AraeA = 0xef6, SCIM_KEY_Hangul_AraeAE = 0xef7, /* Ancient Hangul syllable-final (JongSeong) Characters */ SCIM_KEY_Hangul_J_PanSios = 0xef8, SCIM_KEY_Hangul_J_KkogjiDalrinIeung = 0xef9, SCIM_KEY_Hangul_J_YeorinHieuh = 0xefa, /* Korean currency symbol */ SCIM_KEY_Korean_Won = 0xeff, /* * Armenian * Byte 3 = 0x14 */ SCIM_KEY_Armenian_eternity = 0x14a1, SCIM_KEY_Armenian_ligature_ew = 0x14a2, SCIM_KEY_Armenian_full_stop = 0x14a3, SCIM_KEY_Armenian_verjaket = 0x14a3, SCIM_KEY_Armenian_parenright = 0x14a4, SCIM_KEY_Armenian_parenleft = 0x14a5, SCIM_KEY_Armenian_guillemotright = 0x14a6, SCIM_KEY_Armenian_guillemotleft = 0x14a7, SCIM_KEY_Armenian_em_dash = 0x14a8, SCIM_KEY_Armenian_dot = 0x14a9, SCIM_KEY_Armenian_mijaket = 0x14a9, SCIM_KEY_Armenian_separation_mark = 0x14aa, SCIM_KEY_Armenian_but = 0x14aa, SCIM_KEY_Armenian_comma = 0x14ab, SCIM_KEY_Armenian_en_dash = 0x14ac, SCIM_KEY_Armenian_hyphen = 0x14ad, SCIM_KEY_Armenian_yentamna = 0x14ad, SCIM_KEY_Armenian_ellipsis = 0x14ae, SCIM_KEY_Armenian_exclam = 0x14af, SCIM_KEY_Armenian_amanak = 0x14af, SCIM_KEY_Armenian_accent = 0x14b0, SCIM_KEY_Armenian_shesht = 0x14b0, SCIM_KEY_Armenian_question = 0x14b1, SCIM_KEY_Armenian_paruyk = 0x14b1, SCIM_KEY_Armenian_AYB = 0x14b2, SCIM_KEY_Armenian_ayb = 0x14b3, SCIM_KEY_Armenian_BEN = 0x14b4, SCIM_KEY_Armenian_ben = 0x14b5, SCIM_KEY_Armenian_GIM = 0x14b6, SCIM_KEY_Armenian_gim = 0x14b7, SCIM_KEY_Armenian_DA = 0x14b8, SCIM_KEY_Armenian_da = 0x14b9, SCIM_KEY_Armenian_YECH = 0x14ba, SCIM_KEY_Armenian_yech = 0x14bb, SCIM_KEY_Armenian_ZA = 0x14bc, SCIM_KEY_Armenian_za = 0x14bd, SCIM_KEY_Armenian_E = 0x14be, SCIM_KEY_Armenian_e = 0x14bf, SCIM_KEY_Armenian_AT = 0x14c0, SCIM_KEY_Armenian_at = 0x14c1, SCIM_KEY_Armenian_TO = 0x14c2, SCIM_KEY_Armenian_to = 0x14c3, SCIM_KEY_Armenian_ZHE = 0x14c4, SCIM_KEY_Armenian_zhe = 0x14c5, SCIM_KEY_Armenian_INI = 0x14c6, SCIM_KEY_Armenian_ini = 0x14c7, SCIM_KEY_Armenian_LYUN = 0x14c8, SCIM_KEY_Armenian_lyun = 0x14c9, SCIM_KEY_Armenian_KHE = 0x14ca, SCIM_KEY_Armenian_khe = 0x14cb, SCIM_KEY_Armenian_TSA = 0x14cc, SCIM_KEY_Armenian_tsa = 0x14cd, SCIM_KEY_Armenian_KEN = 0x14ce, SCIM_KEY_Armenian_ken = 0x14cf, SCIM_KEY_Armenian_HO = 0x14d0, SCIM_KEY_Armenian_ho = 0x14d1, SCIM_KEY_Armenian_DZA = 0x14d2, SCIM_KEY_Armenian_dza = 0x14d3, SCIM_KEY_Armenian_GHAT = 0x14d4, SCIM_KEY_Armenian_ghat = 0x14d5, SCIM_KEY_Armenian_TCHE = 0x14d6, SCIM_KEY_Armenian_tche = 0x14d7, SCIM_KEY_Armenian_MEN = 0x14d8, SCIM_KEY_Armenian_men = 0x14d9, SCIM_KEY_Armenian_HI = 0x14da, SCIM_KEY_Armenian_hi = 0x14db, SCIM_KEY_Armenian_NU = 0x14dc, SCIM_KEY_Armenian_nu = 0x14dd, SCIM_KEY_Armenian_SHA = 0x14de, SCIM_KEY_Armenian_sha = 0x14df, SCIM_KEY_Armenian_VO = 0x14e0, SCIM_KEY_Armenian_vo = 0x14e1, SCIM_KEY_Armenian_CHA = 0x14e2, SCIM_KEY_Armenian_cha = 0x14e3, SCIM_KEY_Armenian_PE = 0x14e4, SCIM_KEY_Armenian_pe = 0x14e5, SCIM_KEY_Armenian_JE = 0x14e6, SCIM_KEY_Armenian_je = 0x14e7, SCIM_KEY_Armenian_RA = 0x14e8, SCIM_KEY_Armenian_ra = 0x14e9, SCIM_KEY_Armenian_SE = 0x14ea, SCIM_KEY_Armenian_se = 0x14eb, SCIM_KEY_Armenian_VEV = 0x14ec, SCIM_KEY_Armenian_vev = 0x14ed, SCIM_KEY_Armenian_TYUN = 0x14ee, SCIM_KEY_Armenian_tyun = 0x14ef, SCIM_KEY_Armenian_RE = 0x14f0, SCIM_KEY_Armenian_re = 0x14f1, SCIM_KEY_Armenian_TSO = 0x14f2, SCIM_KEY_Armenian_tso = 0x14f3, SCIM_KEY_Armenian_VYUN = 0x14f4, SCIM_KEY_Armenian_vyun = 0x14f5, SCIM_KEY_Armenian_PYUR = 0x14f6, SCIM_KEY_Armenian_pyur = 0x14f7, SCIM_KEY_Armenian_KE = 0x14f8, SCIM_KEY_Armenian_ke = 0x14f9, SCIM_KEY_Armenian_O = 0x14fa, SCIM_KEY_Armenian_o = 0x14fb, SCIM_KEY_Armenian_FE = 0x14fc, SCIM_KEY_Armenian_fe = 0x14fd, SCIM_KEY_Armenian_apostrophe = 0x14fe, SCIM_KEY_Armenian_section_sign = 0x14ff, /* * Georgian * Byte 3 = 0x15 */ SCIM_KEY_Georgian_an = 0x15d0, SCIM_KEY_Georgian_ban = 0x15d1, SCIM_KEY_Georgian_gan = 0x15d2, SCIM_KEY_Georgian_don = 0x15d3, SCIM_KEY_Georgian_en = 0x15d4, SCIM_KEY_Georgian_vin = 0x15d5, SCIM_KEY_Georgian_zen = 0x15d6, SCIM_KEY_Georgian_tan = 0x15d7, SCIM_KEY_Georgian_in = 0x15d8, SCIM_KEY_Georgian_kan = 0x15d9, SCIM_KEY_Georgian_las = 0x15da, SCIM_KEY_Georgian_man = 0x15db, SCIM_KEY_Georgian_nar = 0x15dc, SCIM_KEY_Georgian_on = 0x15dd, SCIM_KEY_Georgian_par = 0x15de, SCIM_KEY_Georgian_zhar = 0x15df, SCIM_KEY_Georgian_rae = 0x15e0, SCIM_KEY_Georgian_san = 0x15e1, SCIM_KEY_Georgian_tar = 0x15e2, SCIM_KEY_Georgian_un = 0x15e3, SCIM_KEY_Georgian_phar = 0x15e4, SCIM_KEY_Georgian_khar = 0x15e5, SCIM_KEY_Georgian_ghan = 0x15e6, SCIM_KEY_Georgian_qar = 0x15e7, SCIM_KEY_Georgian_shin = 0x15e8, SCIM_KEY_Georgian_chin = 0x15e9, SCIM_KEY_Georgian_can = 0x15ea, SCIM_KEY_Georgian_jil = 0x15eb, SCIM_KEY_Georgian_cil = 0x15ec, SCIM_KEY_Georgian_char = 0x15ed, SCIM_KEY_Georgian_xan = 0x15ee, SCIM_KEY_Georgian_jhan = 0x15ef, SCIM_KEY_Georgian_hae = 0x15f0, SCIM_KEY_Georgian_he = 0x15f1, SCIM_KEY_Georgian_hie = 0x15f2, SCIM_KEY_Georgian_we = 0x15f3, SCIM_KEY_Georgian_har = 0x15f4, SCIM_KEY_Georgian_hoe = 0x15f5, SCIM_KEY_Georgian_fi = 0x15f6, /* * Azeri (and other Turkic or Caucasian languages of ex-USSR) * Byte 3 = 0x16 */ /* latin */ SCIM_KEY_Ccedillaabovedot = 0x16a2, SCIM_KEY_Xabovedot = 0x16a3, SCIM_KEY_Qabovedot = 0x16a5, SCIM_KEY_Ibreve = 0x16a6, SCIM_KEY_IE = 0x16a7, SCIM_KEY_UO = 0x16a8, SCIM_KEY_Zstroke = 0x16a9, SCIM_KEY_Gcaron = 0x16aa, SCIM_KEY_Obarred = 0x16af, SCIM_KEY_ccedillaabovedot = 0x16b2, SCIM_KEY_xabovedot = 0x16b3, SCIM_KEY_Ocaron = 0x16b4, SCIM_KEY_qabovedot = 0x16b5, SCIM_KEY_ibreve = 0x16b6, SCIM_KEY_ie = 0x16b7, SCIM_KEY_uo = 0x16b8, SCIM_KEY_zstroke = 0x16b9, SCIM_KEY_gcaron = 0x16ba, SCIM_KEY_ocaron = 0x16bd, SCIM_KEY_obarred = 0x16bf, SCIM_KEY_SCHWA = 0x16c6, SCIM_KEY_schwa = 0x16f6, /* those are not really Caucasus, but I put them here for now */ /* For Inupiak */ SCIM_KEY_Lbelowdot = 0x16d1, SCIM_KEY_Lstrokebelowdot = 0x16d2, SCIM_KEY_lbelowdot = 0x16e1, SCIM_KEY_lstrokebelowdot = 0x16e2, /* For Guarani */ SCIM_KEY_Gtilde = 0x16d3, SCIM_KEY_gtilde = 0x16e3, /* * Vietnamese * Byte 3 = 0x1e */ SCIM_KEY_Abelowdot = 0x1ea0, SCIM_KEY_abelowdot = 0x1ea1, SCIM_KEY_Ahook = 0x1ea2, SCIM_KEY_ahook = 0x1ea3, SCIM_KEY_Acircumflexacute = 0x1ea4, SCIM_KEY_acircumflexacute = 0x1ea5, SCIM_KEY_Acircumflexgrave = 0x1ea6, SCIM_KEY_acircumflexgrave = 0x1ea7, SCIM_KEY_Acircumflexhook = 0x1ea8, SCIM_KEY_acircumflexhook = 0x1ea9, SCIM_KEY_Acircumflextilde = 0x1eaa, SCIM_KEY_acircumflextilde = 0x1eab, SCIM_KEY_Acircumflexbelowdot = 0x1eac, SCIM_KEY_acircumflexbelowdot = 0x1ead, SCIM_KEY_Abreveacute = 0x1eae, SCIM_KEY_abreveacute = 0x1eaf, SCIM_KEY_Abrevegrave = 0x1eb0, SCIM_KEY_abrevegrave = 0x1eb1, SCIM_KEY_Abrevehook = 0x1eb2, SCIM_KEY_abrevehook = 0x1eb3, SCIM_KEY_Abrevetilde = 0x1eb4, SCIM_KEY_abrevetilde = 0x1eb5, SCIM_KEY_Abrevebelowdot = 0x1eb6, SCIM_KEY_abrevebelowdot = 0x1eb7, SCIM_KEY_Ebelowdot = 0x1eb8, SCIM_KEY_ebelowdot = 0x1eb9, SCIM_KEY_Ehook = 0x1eba, SCIM_KEY_ehook = 0x1ebb, SCIM_KEY_Etilde = 0x1ebc, SCIM_KEY_etilde = 0x1ebd, SCIM_KEY_Ecircumflexacute = 0x1ebe, SCIM_KEY_ecircumflexacute = 0x1ebf, SCIM_KEY_Ecircumflexgrave = 0x1ec0, SCIM_KEY_ecircumflexgrave = 0x1ec1, SCIM_KEY_Ecircumflexhook = 0x1ec2, SCIM_KEY_ecircumflexhook = 0x1ec3, SCIM_KEY_Ecircumflextilde = 0x1ec4, SCIM_KEY_ecircumflextilde = 0x1ec5, SCIM_KEY_Ecircumflexbelowdot = 0x1ec6, SCIM_KEY_ecircumflexbelowdot = 0x1ec7, SCIM_KEY_Ihook = 0x1ec8, SCIM_KEY_ihook = 0x1ec9, SCIM_KEY_Ibelowdot = 0x1eca, SCIM_KEY_ibelowdot = 0x1ecb, SCIM_KEY_Obelowdot = 0x1ecc, SCIM_KEY_obelowdot = 0x1ecd, SCIM_KEY_Ohook = 0x1ece, SCIM_KEY_ohook = 0x1ecf, SCIM_KEY_Ocircumflexacute = 0x1ed0, SCIM_KEY_ocircumflexacute = 0x1ed1, SCIM_KEY_Ocircumflexgrave = 0x1ed2, SCIM_KEY_ocircumflexgrave = 0x1ed3, SCIM_KEY_Ocircumflexhook = 0x1ed4, SCIM_KEY_ocircumflexhook = 0x1ed5, SCIM_KEY_Ocircumflextilde = 0x1ed6, SCIM_KEY_ocircumflextilde = 0x1ed7, SCIM_KEY_Ocircumflexbelowdot = 0x1ed8, SCIM_KEY_ocircumflexbelowdot = 0x1ed9, SCIM_KEY_Ohornacute = 0x1eda, SCIM_KEY_ohornacute = 0x1edb, SCIM_KEY_Ohorngrave = 0x1edc, SCIM_KEY_ohorngrave = 0x1edd, SCIM_KEY_Ohornhook = 0x1ede, SCIM_KEY_ohornhook = 0x1edf, SCIM_KEY_Ohorntilde = 0x1ee0, SCIM_KEY_ohorntilde = 0x1ee1, SCIM_KEY_Ohornbelowdot = 0x1ee2, SCIM_KEY_ohornbelowdot = 0x1ee3, SCIM_KEY_Ubelowdot = 0x1ee4, SCIM_KEY_ubelowdot = 0x1ee5, SCIM_KEY_Uhook = 0x1ee6, SCIM_KEY_uhook = 0x1ee7, SCIM_KEY_Uhornacute = 0x1ee8, SCIM_KEY_uhornacute = 0x1ee9, SCIM_KEY_Uhorngrave = 0x1eea, SCIM_KEY_uhorngrave = 0x1eeb, SCIM_KEY_Uhornhook = 0x1eec, SCIM_KEY_uhornhook = 0x1eed, SCIM_KEY_Uhorntilde = 0x1eee, SCIM_KEY_uhorntilde = 0x1eef, SCIM_KEY_Uhornbelowdot = 0x1ef0, SCIM_KEY_uhornbelowdot = 0x1ef1, SCIM_KEY_Ybelowdot = 0x1ef4, SCIM_KEY_ybelowdot = 0x1ef5, SCIM_KEY_Yhook = 0x1ef6, SCIM_KEY_yhook = 0x1ef7, SCIM_KEY_Ytilde = 0x1ef8, SCIM_KEY_ytilde = 0x1ef9, SCIM_KEY_Ohorn = 0x1efa, /* U+01a0 */ SCIM_KEY_ohorn = 0x1efb, /* U+01a1 */ SCIM_KEY_Uhorn = 0x1efc, /* U+01af */ SCIM_KEY_uhorn = 0x1efd, /* U+01b0 */ SCIM_KEY_combining_tilde = 0x1e9f, /* U+0303 */ SCIM_KEY_combining_grave = 0x1ef2, /* U+0300 */ SCIM_KEY_combining_acute = 0x1ef3, /* U+0301 */ SCIM_KEY_combining_hook = 0x1efe, /* U+0309 */ SCIM_KEY_combining_belowdot = 0x1eff, /* U+0323 */ SCIM_KEY_EcuSign = 0x20a0, SCIM_KEY_ColonSign = 0x20a1, SCIM_KEY_CruzeiroSign = 0x20a2, SCIM_KEY_FFrancSign = 0x20a3, SCIM_KEY_LiraSign = 0x20a4, SCIM_KEY_MillSign = 0x20a5, SCIM_KEY_NairaSign = 0x20a6, SCIM_KEY_PesetaSign = 0x20a7, SCIM_KEY_RupeeSign = 0x20a8, SCIM_KEY_WonSign = 0x20a9, SCIM_KEY_NewSheqelSign = 0x20aa, SCIM_KEY_DongSign = 0x20ab, SCIM_KEY_EuroSign = 0x20ac }; /** * @brief Enum values of all valid Keyboard Layout type. * * This types are used by the Keyboard Layout mapping * function of KeyEvent class to map a KeyEvent of a * certain Keyboard Layout to another. * * But this function only covers the key range of * default US PC keyboard. All additional keys * in other layouts will never be mapped. * * The default layout is standard US PC keyboard. * * If the layout of a KeyEvent is Unknown, then it'll never * be mapped. */ enum KeyboardLayout { SCIM_KEYBOARD_Unknown = 0, SCIM_KEYBOARD_Default = 1, SCIM_KEYBOARD_US = 1, SCIM_KEYBOARD_Belgian = 2, SCIM_KEYBOARD_Croatian = 3, SCIM_KEYBOARD_Czech = 4, SCIM_KEYBOARD_Czech_Qwerty = 5, SCIM_KEYBOARD_Danish = 6, SCIM_KEYBOARD_Dutch = 7, SCIM_KEYBOARD_Dvorak = 8, SCIM_KEYBOARD_Estonian = 9, SCIM_KEYBOARD_Finnish = 10, SCIM_KEYBOARD_French = 11, SCIM_KEYBOARD_French_Canadian = 12, SCIM_KEYBOARD_French_Switzerland = 13, SCIM_KEYBOARD_German = 14, SCIM_KEYBOARD_German_Deadkeys = 15, SCIM_KEYBOARD_German_Swiss = 16, SCIM_KEYBOARD_Greek = 17, SCIM_KEYBOARD_Hungarian = 18, SCIM_KEYBOARD_Italian = 19, SCIM_KEYBOARD_Japanese = 20, SCIM_KEYBOARD_Norwegian = 21, SCIM_KEYBOARD_Polish = 22, SCIM_KEYBOARD_Portuguese = 23, SCIM_KEYBOARD_Portuguese_Brazil = 24, SCIM_KEYBOARD_Portuguese_Brazil_US_Accents = 25, SCIM_KEYBOARD_Russian = 26, SCIM_KEYBOARD_Slovak = 27, SCIM_KEYBOARD_Slovak_Qwerty = 28, SCIM_KEYBOARD_Slovene = 29, SCIM_KEYBOARD_Spanish = 30, SCIM_KEYBOARD_Spanish_CP850 = 31, SCIM_KEYBOARD_Spanish_Latin_America = 32, SCIM_KEYBOARD_Swedish = 33, SCIM_KEYBOARD_Turkish = 34, SCIM_KEYBOARD_UK = 35, SCIM_KEYBOARD_Icelandic = 36, SCIM_KEYBOARD_Lithuanian = 37, SCIM_KEYBOARD_Ukrainian = 38, SCIM_KEYBOARD_NUM_LAYOUTS = 39 }; struct KeyEvent; /** * @typedef typedef std::vector KeyEventList * @brief The container to store a set of KeyEvent objects. * * You should use the STL container methods to manipulate its objects. */ typedef std::vector KeyEventList; /** * @brief Convert a key event to a string. * @param str - the result string will be stored here. * @param key - the KeyEvent to be converted. * @return true if success. */ bool scim_key_to_string (String &str, const KeyEvent & key); /** * @brief Convert a string to a KeyEvent. * @param key - the result KeyEvent will be stored here. * @param str - the string to be converted. * @return true if success. */ bool scim_string_to_key (KeyEvent &key, const String & str); /** * @brief Convert a set of KeyEvents to a string. * @param str - the result string will be stored here. * @param keylist - the keys to be converted. * @return true if success. */ bool scim_key_list_to_string (String &str, const KeyEventList & keylist); /** * @brief Covnert a string to a set of KeyEvents. * @param keylist - the result KeyEvents will be stored here. * @param str - the string to be converted. * @return true if success. */ bool scim_string_to_key_list (KeyEventList &keylist, const String &str); /** * @brief Convert a Keyboard Layout enum value to its String name. * @param layout The Keyboard Layout type. * @return The name of this layout. */ String scim_keyboard_layout_to_string (KeyboardLayout layout); /** * @brief Convert a String name to the corresponding Keyboard Layout value. * @param str The Keyboard Layout name. * @return The Keyboard Layout type corresponding to this name, or SCIM_KEYBOARD_Unknown. */ KeyboardLayout scim_string_to_keyboard_layout (const String &str); /** * @brief Get the display name of a Keyboard Layout enum value. * @param layout The Keyboard Layout type. * @return The localized display name of this layout. */ String scim_keyboard_layout_get_display_name (KeyboardLayout layout); /** * @brief Get default Keyboard Layout setting. * * This function return the Keyboard Layout setting stored * in global config repository as /DefaultKeyboardLayout key. * * This function is mainly used by FrontEnds and Setup tools. * IMEngines should not use it. */ KeyboardLayout scim_get_default_keyboard_layout (); /** * @brief Change the default Keyboard Layout setting. * * The default layout setting will be stored in global config * repository as /DefaultKeyboardLayout key. * * This function is mainly used by FrontEnds and Setup tools. * IMEngines should not use it. */ void scim_set_default_keyboard_layout (KeyboardLayout layout); /** * @brief The class to store a keyboard event. * * A keyboard event contains a key code and a set of key masks. * The key masks indicate which modifier keys are pressed down and * if it's a key release event. * * It also contains the Keyboard Layout information. IMEngines can * map a KeyEvent to another layout by calling method #map_to_layout(). */ struct KeyEvent { uint32 code; /**< key code */ uint16 mask; /**< modifier keys' mask */ uint16 layout; /**< keyboard layout identifier */ /** * @brief Default constructor. * @param c - the key code. * @param m - the key masks. * @param l - the keyboard layout */ KeyEvent (uint32 c = 0, uint16 m = 0, uint16 l = 0) : code (c), mask (m), layout (l) { } /** * @brief Constructor, construct a key event from a string. * * @param str the key string, eg. "Control+space" */ KeyEvent (const String &str) : code (0), mask (0), layout (0) { scim_string_to_key (*this, str); } /** * @brief Check if this KeyEvent is empty. * @return true if this is a empty event. */ bool empty () const { return mask == 0 && code == 0; } /** * @brief Get the ascii code of this key event. * * Not all key events have ascii codes. * * @return the ascii code of this key event. * Zero means no ascii code. */ char get_ascii_code () const; /** * @brief Get the Unicode code of this key event. * * Not all key events have unicode codes. * * @return The Unicode code of this key event. * Zero means no unicode code. */ ucs4_t get_unicode_code () const; /** * @brief Get the string of this key event. * * Not all key events can be converted to string. * * @return The string of this key event. */ String get_key_string () const; /** * @brief Map this KeyEvent to another Keyboard Layout. * * This function only covers the key range of * default US PC keyboard. All additional keys * in other layouts will never be mapped. * * If the current layout is Unknown or the new_layout is * invalid or it's an Unicode embedded KeyEvent, * then it'll not be mapped and the identical KeyEvent * will be returned. * * If you want to check if the mapping is successful, * just compare the layout of returned KeyEvent and new_layout * to see if they are equal. * * @param new_layout The Keyboard Layout to be mapped to. * * @return The new KeyEvent according to the given layout. */ KeyEvent map_to_layout (KeyboardLayout new_layout) const; /** * @brief Check if the Shift key is pressed down. */ bool is_shift_down () const { return (mask & SCIM_KEY_ShiftMask) != 0; } /** * @brief Check if the CapsLock key is pressed down. */ bool is_caps_lock_down () const { return (mask & SCIM_KEY_CapsLockMask) != 0; } /** * @brief Check if the Ctrl key is pressed down. */ bool is_control_down () const { return (mask & SCIM_KEY_ControlMask) != 0; } /** * @brief Check if the Alt key is pressed down. */ bool is_alt_down () const { return (mask & SCIM_KEY_AltMask) != 0; } /** * @brief Check if the Meta key is pressed down. */ bool is_meta_down () const { return (mask & SCIM_KEY_MetaMask) != 0; } /** * @brief Check if the Super key is pressed down. */ bool is_super_down () const { return (mask & SCIM_KEY_SuperMask) != 0; } /** * @brief Check if the Hyper key is pressed down. */ bool is_hyper_down () const { return (mask & SCIM_KEY_HyperMask) != 0; } /** * @brief Check if the num lock key is pressed down. */ bool is_num_lock_down () const { return (mask & SCIM_KEY_NumLockMask) != 0; } /** * @brief Check if it's a key press event. */ bool is_key_press () const { return (mask & SCIM_KEY_ReleaseMask) == 0; } /** * @brief Check if it's a key release event. */ bool is_key_release () const { return (mask & SCIM_KEY_ReleaseMask) != 0; } /** * @brief Compare two key events. * @return true if they are equal. */ bool operator == (const KeyEvent & key) const { return code == key.code && mask == key.mask; } /** * @brief Compare two key events. * @return true if they are not equal. */ bool operator != (const KeyEvent & key) const { return code != key.code || mask != key.mask; } /** * @brief Compare two key events. * * This operator is mainly for sorting. * * @return true if the first is smaller. */ bool operator < (const KeyEvent & key) const { return code < key.code || (code == key.code && mask < key.mask); } /** * @brief Check if the lock key is pressed down. * * For backward API compatibility, do not use it in new code. */ bool is_lock_down () const { return (mask & SCIM_KEY_LockMask) != 0; } /** * @brief Check if the mod1 key is pressed down. * * For backward API compatibility, do not use it in new code. */ bool is_mod1_down () const { return (mask & SCIM_KEY_Mod1Mask) != 0; } /** * @brief Check if the mod2 key is pressed down. * * For backward API compatibility, do not use it in new code. */ bool is_mod2_down () const { return (mask & SCIM_KEY_Mod2Mask) != 0; } /** * @brief Check if the mod3 key is pressed down. * * For backward API compatibility, do not use it in new code. */ bool is_mod3_down () const { return (mask & SCIM_KEY_Mod3Mask) != 0; } /** * @brief Check if the mod4 key is pressed down. * * For backward API compatibility, do not use it in new code. */ bool is_mod4_down () const { return (mask & SCIM_KEY_Mod4Mask) != 0; } /** * @brief Check if the mod5 key is pressed down. * * For backward API compatibility, do not use it in new code. */ bool is_mod5_down () const { return (mask & SCIM_KEY_Mod5Mask) != 0; } /** * @brief Check if the scroll lock key is pressed down. * * For backward API compatibility, do not use it in new code. */ bool is_scroll_lock_down () const { return (mask & SCIM_KEY_ScrollLockMask) != 0; } }; /** @} */ } // namespace scim #endif //__SCIM_EVENT_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_event.cpp0000644000175000017500000002641312422143415015574 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_event.cpp,v 1.29 2005/07/13 08:54:55 suzhe Exp $ */ #define Uses_SCIM_EVENT #define Uses_SCIM_GLOBAL_CONFIG #define Uses_SCIM_CONFIG_PATH #define Uses_C_STDIO #define Uses_C_STRING #include "scim_private.h" #include "scim.h" #include "scim_stl_map.h" namespace scim { struct __Uint16Pair { uint16 first; uint16 second; }; struct __KeyCodeMap { size_t size; __Uint16Pair *map; }; struct __KeyName { uint16 value; const char *name; }; class __Uint16PairLessByFirst { public: bool operator ()(const __Uint16Pair &lhs, const __Uint16Pair &rhs) const { return lhs.first < rhs.first; } bool operator ()(const __Uint16Pair &lhs, const uint16 &rhs) const { return lhs.first < rhs; } bool operator ()(const uint16 &lhs, const __Uint16Pair &rhs) const { return lhs < rhs.first; } }; class __KeyNameLessByCode { public: bool operator ()(const __KeyName &lhs, const __KeyName &rhs) const { return lhs.value < rhs.value; } bool operator ()(const __KeyName &lhs, const uint16 &rhs) const { return lhs.value < rhs; } bool operator ()(const uint16 &lhs, const __KeyName &rhs) const { return lhs < rhs.value; } }; class __KeyNameLessByName { public: bool operator ()(const __KeyName &lhs, const __KeyName &rhs) const { return strcmp (lhs.name, rhs.name) < 0; } bool operator ()(const __KeyName &lhs, const char *rhs) const { return strcmp (lhs.name, rhs) < 0; } bool operator ()(const char *lhs, const __KeyName &rhs) const { return strcmp (lhs, rhs.name) < 0; } }; // Keyboard Layout data #include "scim_keyboard_layout_data.h" // KeyEvent data #include "scim_keyevent_data.h" char KeyEvent::get_ascii_code () const { if (code >= SCIM_KEY_space && code <= SCIM_KEY_asciitilde) return (char) code; if (code >= SCIM_KEY_KP_0 && code <= SCIM_KEY_KP_9) return (char) (code - SCIM_KEY_KP_0 + SCIM_KEY_0); if (code == SCIM_KEY_Return) return 0x0d; if (code == SCIM_KEY_Linefeed) return 0x0a; if (code == SCIM_KEY_Tab) return 0x09; if (code == SCIM_KEY_BackSpace) return 0x08; if (code == SCIM_KEY_Escape) return 0x1b; return 0; } ucs4_t KeyEvent::get_unicode_code () const { /* First check for Latin-1 characters (1:1 mapping) */ if ((code >= 0x0020 && code <= 0x007e) || (code >= 0x00a0 && code <= 0x00ff)) return code; /* Also check for directly encoded 24-bit UCS characters: */ if ((code & 0xff000000) == 0x01000000) return code & 0x00ffffff; /* Translation of KP_Decimal depends on locale. if (code == SCIM_KP_Decimal) return get_decimal_char (); */ /* Invalid keyevent code. */ if (code > 0xFFFF) return 0; /* binary search in table */ __Uint16Pair * it = std::lower_bound (__scim_key_to_unicode_tab, __scim_key_to_unicode_tab + SCIM_NUM_KEY_UNICODES, (uint16) code, __Uint16PairLessByFirst ()); if (it != __scim_key_to_unicode_tab + SCIM_NUM_KEY_UNICODES && it->first == (uint16) code) return it->second; /* No matching Unicode value found */ return 0; } String KeyEvent::get_key_string () const { size_t i; String maskstr; String codestr; uint16 mask_skip = 0; for (i=0; i < SCIM_NUM_KEY_MASKS; ++i) { if ((__scim_key_mask_names [i].value & mask) && !(__scim_key_mask_names [i].value & mask_skip)) { if (maskstr.length ()) maskstr += (String ("+") + String (__scim_key_mask_names [i].name)); else maskstr += String (__scim_key_mask_names [i].name); } mask_skip |= __scim_key_mask_names [i].value; } if (code == 0xFFFFFF) { codestr = String ("VoidSymbol"); } else if (code <= 0xFFFF){ __KeyName *it = std::lower_bound (__scim_keys_by_code, __scim_keys_by_code + SCIM_NUM_KEY_NAMES, (uint16) code, __KeyNameLessByCode ()); if (it != __scim_keys_by_code + SCIM_NUM_KEY_NAMES && it->value == code) codestr = String (it->name); } if (!codestr.length () && code) { char buf [20]; snprintf (buf, 20, ((code <= 0xFFFF) ? "0x%04x" : "0x%06x"), code); codestr = String (buf); } if (maskstr.length () && codestr.length ()) return maskstr + String ("+") + codestr; if (maskstr.length()) return maskstr; if (codestr.length ()) return codestr; return String (); } static uint16 inline __remap_keycode (uint16 from, const __KeyCodeMap &map) { if (map.size == 0) return from; __Uint16Pair *it = std::lower_bound (map.map, map.map + map.size, from, __Uint16PairLessByFirst ()); if (it != map.map + map.size && it->first == from) return it->second; return from; } KeyEvent KeyEvent::map_to_layout (KeyboardLayout new_layout) const { if (layout == SCIM_KEYBOARD_Unknown || new_layout == SCIM_KEYBOARD_Unknown || layout == new_layout || layout >= SCIM_KEYBOARD_NUM_LAYOUTS || new_layout >= SCIM_KEYBOARD_NUM_LAYOUTS || new_layout < 0 || code > 0xFFFF) return *this; KeyEvent evt (code, mask, new_layout); uint16 new_code = (uint16) code; switch (mask & (SCIM_KEY_CapsLockMask | SCIM_KEY_ShiftMask)) { case 0: new_code = __remap_keycode (new_code, __normal_map [layout]); new_code = __remap_keycode (new_code, __normal_invert_map [new_layout]); break; case SCIM_KEY_CapsLockMask: new_code = __remap_keycode (new_code, __caps_map [layout]); new_code = __remap_keycode (new_code, __caps_invert_map [new_layout]); break; case SCIM_KEY_ShiftMask: new_code = __remap_keycode (new_code, __shift_map [layout]); new_code = __remap_keycode (new_code, __shift_invert_map [new_layout]); break; case (SCIM_KEY_ShiftMask | SCIM_KEY_CapsLockMask): new_code = __remap_keycode (new_code, __caps_shift_map [layout]); new_code = __remap_keycode (new_code, __caps_shift_invert_map [new_layout]); break; } evt.code = (uint32) new_code; return evt; } bool scim_key_to_string (String &str, const KeyEvent & key) { str = key.get_key_string (); return str.length () != 0; } bool scim_string_to_key (KeyEvent &key, const String & str) { std::vector list; bool skip; size_t i; key.code = 0; key.mask = 0; scim_split_string_list (list, str, '+'); for (std::vector ::iterator it=list.begin (); it!=list.end (); ++it) { skip = false; for (i = 0; i < SCIM_NUM_KEY_MASKS; ++i) { if (*it == String (__scim_key_mask_names [i].name)) { key.mask |= __scim_key_mask_names [i].value; skip = true; break; } } if (skip) continue; __KeyName *p = std::lower_bound (__scim_keys_by_name, __scim_keys_by_name + SCIM_NUM_KEY_NAMES, it->c_str (), __KeyNameLessByName ()); if (p != __scim_keys_by_name + SCIM_NUM_KEY_NAMES && strcmp (p->name, it->c_str ()) == 0) { key.code = p->value; } else if (it->length () >= 6 && (*it)[0] == '0' && ((*it)[1] == 'x' || (*it)[1] == 'X')){ key.code = strtol (it->c_str () + 2, NULL, 16); } else if (strcmp (p->name, "VoidSymbol") == 0) { key.code = SCIM_KEY_VoidSymbol; } } return key.code != 0; } bool scim_key_list_to_string (String &str, const std::vector & keylist) { std::vector strlist; for (std::vector::const_iterator it = keylist.begin (); it != keylist.end (); ++it) { if (scim_key_to_string (str, *it)) strlist.push_back (str); } str = scim_combine_string_list (strlist, ','); return str.length () != 0; } bool scim_string_to_key_list (std::vector &keylist, const String &str) { std::vector strlist; scim_split_string_list (strlist, str, ','); keylist.clear (); for (std::vector ::iterator it = strlist.begin (); it != strlist.end (); ++it) { KeyEvent key; if (scim_string_to_key (key, *it)) keylist.push_back (key); } return keylist.size () > 0; } String scim_keyboard_layout_to_string (KeyboardLayout layout) { if (layout >= 0 && layout < SCIM_KEYBOARD_NUM_LAYOUTS) return String (__scim_keyboard_layout_ids_by_code [layout].name); return String (__scim_keyboard_layout_ids_by_code [0].name); } KeyboardLayout scim_string_to_keyboard_layout (const String &str) { if (str == __scim_keyboard_layout_ids_by_code [0].name) return SCIM_KEYBOARD_Unknown; if (str == __scim_keyboard_layout_ids_by_code [1].name || str == String ("US") || str == String ("Default")) return SCIM_KEYBOARD_Default; __KeyName *it = std::lower_bound (__scim_keyboard_layout_ids_by_name + 2, __scim_keyboard_layout_ids_by_name + SCIM_KEYBOARD_NUM_LAYOUTS, str.c_str (), __KeyNameLessByName()); if (it != __scim_keyboard_layout_ids_by_name + SCIM_KEYBOARD_NUM_LAYOUTS && strcmp (it->name, str.c_str ()) == 0) return static_cast (it->value); return SCIM_KEYBOARD_Unknown; } String scim_keyboard_layout_get_display_name (KeyboardLayout layout) { if (layout >= 0 && layout < SCIM_KEYBOARD_NUM_LAYOUTS) return String (_(__scim_keyboard_layout_names [layout])); return String (_(__scim_keyboard_layout_names [0])); } KeyboardLayout scim_get_default_keyboard_layout () { String layout_name (__scim_keyboard_layout_ids_by_code [0].name); layout_name = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_KEYBOARD_LAYOUT, layout_name); return scim_string_to_keyboard_layout (layout_name); } void scim_set_default_keyboard_layout (KeyboardLayout layout) { String layout_name = scim_keyboard_layout_to_string (layout); scim_global_config_write (SCIM_GLOBAL_CONFIG_DEFAULT_KEYBOARD_LAYOUT, layout_name); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_debug.h0000644000175000017500000001403312422143415015201 0ustar tzhuantzhuan/** * @file scim_debug.h * @brief Defines class scim::DebugOutput and related MACROS. * * All of the debug information should be output via scim::DebugOutput class. * This class provides message filter and redirection ability. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_debug.h,v 1.18 2005/08/05 01:54:24 suzhe Exp $ */ #ifndef __SCIM_DEBUG_H #define __SCIM_DEBUG_H #define SCIM_DEBUG_MAX_VERBOSE 7 namespace scim { /** * @name The mask for debug messages filtering. * @{ */ #define SCIM_DEBUG_AllMask (~0) /**< Show all messages. */ #define SCIM_DEBUG_MainMask 1 /**< Show messages of main application. */ #define SCIM_DEBUG_ConfigMask 2 /**< Show messages of Config objects */ #define SCIM_DEBUG_IMEngineMask 4 /**< Show messages of IMEngine objects */ #define SCIM_DEBUG_BackEndMask 8 /**< Show messages of BackEnd objects */ #define SCIM_DEBUG_FrontEndMask 16 /**< Show messages of FrontEnd objects */ #define SCIM_DEBUG_ModuleMask 32 /**< Show messages of Module objects */ #define SCIM_DEBUG_UtilityMask 64 /**< Show messages of utility functions */ #define SCIM_DEBUG_IConvMask 128 /**< Show messages of IConvert objects */ #define SCIM_DEBUG_LookupTableMask 256 /**< Show messages of LookupTable objects */ #define SCIM_DEBUG_SocketMask 512 /**< Show messages of Socket objects */ /** * @} */ /** * @name The macros to simplify the debug message print method. * * You can output debug messages by this way: * SCIM_DEBUG_IMENGINE(1) << "Hello World!\n"; * * @{ */ #define SCIM_DEBUG(mask,level) (scim::DebugOutput(mask,level) << scim::DebugOutput::serial_number () << __FILE__ << ":" << __LINE__ << " > ") #define SCIM_DEBUG_MAIN(level) SCIM_DEBUG(SCIM_DEBUG_MainMask,level) #define SCIM_DEBUG_CONFIG(level) SCIM_DEBUG(SCIM_DEBUG_ConfigMask,level) #define SCIM_DEBUG_IMENGINE(level) SCIM_DEBUG(SCIM_DEBUG_IMEngineMask,level) #define SCIM_DEBUG_BACKEND(level) SCIM_DEBUG(SCIM_DEBUG_BackEndMask,level) #define SCIM_DEBUG_FRONTEND(level) SCIM_DEBUG(SCIM_DEBUG_FrontEndMask,level) #define SCIM_DEBUG_MODULE(level) SCIM_DEBUG(SCIM_DEBUG_ModuleMask,level) #define SCIM_DEBUG_UTILITY(level) SCIM_DEBUG(SCIM_DEBUG_UtilityMask,level) #define SCIM_DEBUG_ICONV(level) SCIM_DEBUG(SCIM_DEBUG_IConvMask,level) #define SCIM_DEBUG_LOOKUPTABLE(level) SCIM_DEBUG(SCIM_DEBUG_LookupTableMask,level) #define SCIM_DEBUG_SOCKET(level) SCIM_DEBUG(SCIM_DEBUG_SocketMask,level) /** * @} */ /** * @brief The class to filter and redirect the debug messages. */ class DebugOutput { private: static uint32 current_verbose; static uint32 current_mask; static uint32 verbose_level; static uint32 output_mask; static std::ostream *output_stream; public: /** * @brief Constructor. * @param mask - the debug filter mask. * @param verbose - the verbose level of the debug message. */ DebugOutput (uint32 mask = SCIM_DEBUG_AllMask, uint32 verbose = 1); /** * @brief A template stream output operator. * * All kinds of data and variables can be output via DebugOutput by * this operator. */ #if ENABLE_DEBUG template const DebugOutput& operator << (const T& t) const { if (output_stream && (current_mask & output_mask) && (current_verbose <= verbose_level)) (*output_stream) << t; return *this; } #else template const DebugOutput& operator << (const T&) const { return *this; } #endif public: /** * @brief The global method to enable the debug output. * @param debug - the mask to indicate which kind of * debug should be enabled. */ static void enable_debug (uint32 debug); /** * @brief The global method to enable the debug output by their names. * @param debug - the name of the debug type to be enabled. The valid * names are: all, main, config, imengine, backend, frontend, * module, utility, iconv, lookuptable, socket. */ static void enable_debug_by_name (const String &debug); /** * @brief Disable the debug type indicated by the given mask. * @param debug - the mask of the debug type to be disabled. */ static void disable_debug (uint32 debug); /** * @brief Disable the debug type indicated by the given name. * @param debug - the name of the debug type to be disabled. */ static void disable_debug_by_name (const String &debug); /** * @brief Set the debug verbose level. * @param verbose - the debug verbose level, 0 means no debug output. */ static void set_verbose_level (uint32 verbose); /** * @brief Set the debug output file. * * @param file - the file to store the debug output. * If equal to "stderr" or "cerr" then the debug * output will be set to std:cerr. * If equal to "stdout" or "cout" then the debug * output will be set to std::cout. */ static void set_output (const String &file); static String serial_number (); }; } // namespace scim #endif //__SCIM_DEBUG_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_debug.cpp0000644000175000017500000000745512422143415015546 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_debug.cpp,v 1.10 2005/08/05 01:54:24 suzhe Exp $ * */ #define Uses_SCIM_DEBUG #include "scim_private.h" #include "scim.h" #include namespace scim { struct _DebugMaskName { uint32 mask; const char *name; }; static _DebugMaskName _debug_mask_names [] = { {SCIM_DEBUG_AllMask, "all"}, {SCIM_DEBUG_MainMask, "main"}, {SCIM_DEBUG_ConfigMask, "config"}, {SCIM_DEBUG_IMEngineMask, "imengine"}, {SCIM_DEBUG_BackEndMask, "backend"}, {SCIM_DEBUG_FrontEndMask, "frontend"}, {SCIM_DEBUG_ModuleMask, "module"}, {SCIM_DEBUG_UtilityMask, "utility"}, {SCIM_DEBUG_IConvMask, "iconv"}, {SCIM_DEBUG_LookupTableMask,"lookuptable"}, {SCIM_DEBUG_SocketMask, "socket"}, {0, 0} }; uint32 DebugOutput::current_verbose = 0; uint32 DebugOutput::current_mask = 0; uint32 DebugOutput::verbose_level = 0; uint32 DebugOutput::output_mask = ~0; std::ostream * DebugOutput::output_stream = &std::cerr; static std::ofstream __debug_output_file; #if ENABLE_DEBUG DebugOutput::DebugOutput (uint32 mask, uint32 verbose) { current_mask = mask; current_verbose = verbose; } #else DebugOutput::DebugOutput (uint32 mask, uint32 verbose) { } #endif void DebugOutput::set_verbose_level (uint32 verbose) { verbose_level = (verbose > SCIM_DEBUG_MAX_VERBOSE) ? SCIM_DEBUG_MAX_VERBOSE : verbose; } void DebugOutput::enable_debug (uint32 debug) { output_mask |= debug; } void DebugOutput::enable_debug_by_name (const String &debug) { _DebugMaskName *p = _debug_mask_names; while (p->mask && p->name) { if (String (p->name) == debug) { output_mask |= p->mask; return; } ++ p; } } void DebugOutput::disable_debug (uint32 debug) { output_mask &= (~debug); } void DebugOutput::disable_debug_by_name (const String &debug) { _DebugMaskName *p = _debug_mask_names; while (p->mask && p->name) { if (String (p->name) == debug) { output_mask &= (~(p->mask)); return; } ++ p; } } void DebugOutput::set_output (const String &file) { DebugOutput::output_stream = &std::cerr; if (file.length ()) { if (file == String ("stderr") || file == String ("cerr")) DebugOutput::output_stream = &std::cerr; else if (file == String ("stdout") || file == String ("cout")) DebugOutput::output_stream = &std::cout; else if (file == String ("none") || file == String ("off")) DebugOutput::output_stream = 0; else { __debug_output_file.open (file.c_str ()); if (__debug_output_file.is_open ()) DebugOutput::output_stream = &__debug_output_file; } } } String DebugOutput::serial_number () { static unsigned int serial = 0; char buf [40]; snprintf (buf, 40, "<%08u>:", serial ++); return String (buf); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_connection.h0000644000175000017500000000702612422143415016256 0ustar tzhuantzhuan/** @file scim_connection.h * @brief C++ signal-slot connection interface. * * Most code of this file are came from Inti project. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * Copyright (c) 2002 The Inti Development Team. * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_connection.h,v 1.10 2005/01/10 08:30:53 suzhe Exp $ */ #ifndef __SCIM_CONNECTION_H #define __SCIM_CONNECTION_H namespace scim { /** * @addtogroup SignalSlot * @{ */ class Slot; /** * @class Node * @brief Base class for classes managing slots. * * A node connects a slot to its Connection class, the class returned * from a signal's connect() method. */ class Node : public ReferencedObject { Pointer slot_; protected: Node(Slot *slot); //!< Constructor. virtual ~Node(); //!< Destructor. public: Slot* slot() { return slot_.get (); } //!< Returns a pointer to the slot held by this node. virtual void block() = 0; //!< Block signal emission to the slot until unblock is called. virtual void unblock() = 0; //!< Unblock the slot so signal emmissions can be received. virtual void disconnect() = 0; //!< Disconnect the slot. The slot will no longer receive signal emissions. }; /** * @class Connection * @brief A signal connection class. * * A Connection class is returned by value from a signal's connect() * method. Using this class you can block, unblock and disconnect * a signal connection. */ class Connection { mutable Pointer node_; public: //! @name Constructors //! @{ Connection(); //!< Default constructor. Connection(Node *node); //!< Construct a connection object for node. //!< @param node - a pointer to the Node class for this connection. Connection(const Connection& src); //!< Copy constructor. ~Connection(); //!< Destructor. Connection& operator=(const Connection& src); //!< Assignment operator. //! @} //! @name Methods //! @{ void block(); //!< Block signal transmission to a slot. //!< The slot will not be called during any signal emissions unless it is unblocked again. void unblock(); //!< Unblock a previously blocked slot. //!< A blocked slot is skipped during signal emissions and will not be invoked, unblocking //!< it (for exactly the number of times it has been blocked before) reverts its "blocked" //!< state, so the slot will be recognized by the signal system and is called upon future //!< or currently ongoing signal emissions. void disconnect(); //!< Disconnect a slot. //!< The slot will not be called during any future or currently ongoing //!< emissions of the signal it has been connected to. //! @} }; /** @} */ } // namespace scim #endif //__SCIM_CONNECTION_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_connection.cpp0000644000175000017500000000401212422143415016601 0ustar tzhuantzhuan/* * Most code of this file are came from Inti project. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * Copyright (c) 2002 The Inti Development Team. * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_connection.cpp,v 1.7 2005/01/10 08:30:53 suzhe Exp $ */ #define Uses_SCIM_OBJECT #define Uses_SCIM_CONNECTION #define Uses_SCIM_SLOT #include "scim_private.h" #include "scim.h" namespace scim { /* Node */ Node::Node(Slot *slot) : slot_(slot) { } Node::~Node() { } void Node::disconnect() { if (!slot_.null ()) slot_.reset (); } /* Connection */ Connection::Connection() : node_(0) { } Connection::Connection(Node *node) : node_(node) { } Connection::Connection(const Connection& src) : node_(src.node_) { } Connection::~Connection() { } Connection& Connection::operator=(const Connection& src) { if (src.node_ == node_) return *this; node_ = src.node_; src.node_.reset (); return *this; } void Connection::block() { if (!node_.null ()) node_->block(); } void Connection::unblock() { if (!node_.null ()) node_->unblock(); } void Connection::disconnect() { if (!node_.null ()) { node_->disconnect(); node_.reset (); } } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_config_path.h0000644000175000017500000000751012422143415016376 0ustar tzhuantzhuan/** * @file scim_config_path.h * @brief This file defines some common used configuration keys. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_config_path.h,v 1.35 2005/06/26 16:35:33 suzhe Exp $ */ #ifndef __SCIM_CONFIG_PATH_H #define __SCIM_CONFIG_PATH_H namespace scim { /** * @addtogroup Config * @{ */ #define SCIM_CONFIG_UPDATE_TIMESTAMP "/UpdateTimeStamp" #define SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY "/DefaultIMEngineFactory" #define SCIM_CONFIG_FRONTEND_ON_THE_SPOT "/FrontEnd/OnTheSpot" #define SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD "/FrontEnd/SharedInputMethod" #define SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT "/FrontEnd/IMOpenedByDefault" #define SCIM_CONFIG_HOTKEYS_FRONTEND "/Hotkeys/FrontEnd" #define SCIM_CONFIG_HOTKEYS_FRONTEND_TRIGGER "/Hotkeys/FrontEnd/Trigger" #define SCIM_CONFIG_HOTKEYS_FRONTEND_ON "/Hotkeys/FrontEnd/On" #define SCIM_CONFIG_HOTKEYS_FRONTEND_OFF "/Hotkeys/FrontEnd/Off" #define SCIM_CONFIG_HOTKEYS_FRONTEND_NEXT_FACTORY "/Hotkeys/FrontEnd/NextFactory" #define SCIM_CONFIG_HOTKEYS_FRONTEND_PREVIOUS_FACTORY "/Hotkeys/FrontEnd/PreviousFactory" #define SCIM_CONFIG_HOTKEYS_FRONTEND_SHOW_FACTORY_MENU "/Hotkeys/FrontEnd/ShowFactoryMenu" #define SCIM_CONFIG_HOTKEYS_FRONTEND_VALID_KEY_MASK "/Hotkeys/FrontEnd/ValidKeyMask" #define SCIM_CONFIG_HOTKEYS_IMENGINE "/Hotkeys/IMEngine" #define SCIM_CONFIG_HOTKEYS_IMENGINE_LIST "/Hotkeys/IMEngine/List" #define SCIM_CONFIG_FILTER_FILTERED_IMENGINES "/Filter/FilteredIMEngines" #define SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST "/Filter/FilteredIMEngines/List" #define SCIM_GLOBAL_CONFIG_DISABLED_IMENGINE_FACTORIES "/DisabledIMEngineFactories" #define SCIM_GLOBAL_CONFIG_SUPPORTED_UNICODE_LOCALES "/SupportedUnicodeLocales" #define SCIM_GLOBAL_CONFIG_DEFAULT_KEYBOARD_LAYOUT "/DefaultKeyboardLayout" #define SCIM_GLOBAL_CONFIG_DEFAULT_PANEL_PROGRAM "/DefaultPanelProgram" #define SCIM_GLOBAL_CONFIG_DEFAULT_CONFIG_MODULE "/DefaultConfigModule" #define SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_FRONTEND_ADDRESS "/DefaultSocketFrontEndAddress" #define SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_IMENGINE_ADDRESS "/DefaultSocketIMEngineAddress" #define SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_CONFIG_ADDRESS "/DefaultSocketConfigAddress" #define SCIM_GLOBAL_CONFIG_DEFAULT_PANEL_SOCKET_ADDRESS "/DefaultPanelSocketAddress" #define SCIM_GLOBAL_CONFIG_DEFAULT_HELPER_MANAGER_SOCKET_ADDRESS "/DefaultHelperManagerSocketAddress" #define SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_TIMEOUT "/DefaultSocketTimeout" /** @} */ } // namespace scim #endif //__SCIM_CONFIG_PATH_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_config_module.h0000644000175000017500000000750712422143415016735 0ustar tzhuantzhuan/** @file scim_config_module.h * @brief Define scim::ConfigModule class for manipulating the config modules. * * Class scim::ConfigModule is a wrapper of class scim::Module, * which is for manipulating the configuration modules. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_config_module.h,v 1.15 2005/04/09 15:38:39 suzhe Exp $ */ #ifndef __SCIM_CONFIG_MODULE_H #define __SCIM_CONFIG_MODULE_H namespace scim { /** * @addtogroup Config * @{ */ /** * @brief The prototype of initialization function in config modules. * * There must be a function called "scim_config_module_init" * which complies with this prototype. * This function name can have a prefix like simple_LTX_, * in which "simple" is the module's name. */ typedef void (*ConfigModuleInitFunc) (void); /** * @brief The prototype of configure object creation function in config modules. * * There must be a function called "scim_config_module_create_config" * which complies with this prototype. * This function name can have a prefix like simple_LTX_, * in which "simple" is the module's name. */ typedef ConfigPointer (*ConfigModuleCreateConfigFunc) (); /** * @brief The class to manipulate the config modules. * * This is a wrapper of scim::Module class, which is specially * for manipulating the config modules. */ class ConfigModule { Module m_module; ConfigModuleInitFunc m_config_init; ConfigModuleCreateConfigFunc m_config_create_config; ConfigModule (const ConfigModule &); ConfigModule & operator= (const ConfigModule &); public: /** * @brief Default constructor. */ ConfigModule (); /** * @brief Constructor. * @param name - the module's name, eg. "simple". */ ConfigModule (const String &name); /** * @brief Load a module by its name. * * Load a module into memory. * If another module has been loaded into this object, * then the old module will be unloaded first. * If the old module is resident, false will be returned, * and the old module will be untouched. * * @param name - the module's name, eg. "simple". * @return true if success. */ bool load (const String &name); /** * @brief Check if a module is loaded and initialized successfully. * @return true if a module is already loaded and initialized successfully. */ bool valid () const; /** * @brief Create a configuration object from this module. * * The type of newly created configuration object * must be a derived class of scim::ConfigBase. * * @return a smart pointer points to the configuration object. */ ConfigPointer create_config () const; }; /** * @brief Get a name list of currently available configuration modules. * @param mod_list - the result list will be stored here. * @return the number of the modules, equal to mod_list.size (). */ int scim_get_config_module_list (std::vector & mod_list); /** @} */ } // namespace scim #endif //__SCIM_CONFIG_MODULE_H /* vi:ts=4:ai:nowrap:expandtab */ scim-1.4.15/src/scim_config_module.cpp0000644000175000017500000000457312422143415017270 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_config_module.cpp,v 1.15 2005/04/09 15:38:39 suzhe Exp $ * */ #define Uses_SCIM_CONFIG_MODULE #define Uses_SCIM_MODULE #include "scim_private.h" #include "scim.h" namespace scim { ConfigModule::ConfigModule () : m_config_init (0), m_config_create_config (0) { } ConfigModule::ConfigModule (const String &name) : m_config_init (0), m_config_create_config (0) { load (name); } bool ConfigModule::load (const String &name) { try { if (!m_module.load (name, "Config")) return false; m_config_init = (ConfigModuleInitFunc) m_module.symbol ("scim_config_module_init"); m_config_create_config = (ConfigModuleCreateConfigFunc) m_module.symbol ("scim_config_module_create_config"); if (!m_config_init || !m_config_create_config) { m_module.unload (); m_config_init = 0; m_config_create_config = 0; return false; } m_config_init (); } catch (...) { m_module.unload (); m_config_init = 0; m_config_create_config = 0; return false; } return true; } bool ConfigModule::valid () const { return (m_module.valid () && m_config_init && m_config_create_config); } ConfigPointer ConfigModule::create_config () const { if (valid ()) return m_config_create_config (); return ConfigPointer (); } int scim_get_config_module_list (std::vector & mod_list) { return scim_get_module_list (mod_list, "Config"); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_config_base.h0000644000175000017500000003171412422143415016357 0ustar tzhuantzhuan/** @file scim_config_base.h * @brief scim::ConfigBase Interface. * * Provide a unified interface to access the configuration data. * All of SCIM objects should use this interface if they have any * configuration data. */ /* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_config_base.h,v 1.22 2005/04/09 15:38:39 suzhe Exp $ */ #ifndef __SCIM_CONFIG_BASE_H #define __SCIM_CONFIG_BASE_H namespace scim { /** * @addtogroup Config * The base classes for config modules * @{ */ /** * @brief An exception class to hold Config related errors. * * scim::ConfigBase and its derived classes must throw * scim::ConfigError object when error. */ class ConfigError: public Exception { public: ConfigError (const String& what_arg) : Exception (String("scim::Config: ") + what_arg) { } }; class ConfigBase; /** * @typedef typedef Pointer ConfigPointer; * * A smart pointer for scim::ConfigBase and its derived classes. */ typedef Pointer ConfigPointer; /** * @typedef typedef Slot1 ConfigSlotVoid; * * The slot type to connect to the coresponding signal. */ typedef Slot1 ConfigSlotVoid; /** * @typedef typedef Signal1 ConfigSignalVoid; * * The signal type to connect with the ConfigSlotVoid slot type. */ typedef Signal1 ConfigSignalVoid; /** * @brief The interface class to access the configuration data. * * This is an interface class to access the configuration data. * All of the SCIM objects which have configuration data should * use this interface to store and load them. */ class ConfigBase : public ReferencedObject { ConfigSignalVoid m_signal_reload; public: /** * @name Constructor and Destructor. * @{ */ /** * @brief Contrustor */ ConfigBase (); /** * @brief Virtual destructor * empty but ensures that dtor of all derived classes is virtual */ virtual ~ConfigBase (); /** * @} */ /** * @name Pure virtual methods which should be implemented in derived classes. * @{ */ /** * @brief Check if this Config object is valid. * @return true if its valid and ready to work. */ virtual bool valid () const = 0; /** * @brief Return the name of this configuration module. * * This name must be same as the config module's name. */ virtual String get_name () const = 0; /** * @brief Read a string from the given key. * @param key - the key to be read. * @param ret - the result will be stored into *ret. * @return true if the string is read successfully, otherwise return false. */ virtual bool read (const String& key, String *ret) const = 0; /** * @brief Read an int value from the given key. * @param key - the key to be read. * @param ret - the result will be stored into *ret. * @return true if the value is read successfully, otherwise return false. */ virtual bool read (const String& key, int *ret) const = 0; /** * @brief Read a double value from the given key. * @param key - the key to be read. * @param ret - the result will be stored into *ret. * @return true if the value is read successfully, otherwise return false. */ virtual bool read (const String& key, double *ret) const = 0; /** * @brief Read a bool value from the given key. * @param key - the key to be read. * @param ret - the result will be stored into *ret. * @return true if the value is read successfully, otherwise return false. */ virtual bool read (const String& key, bool *ret) const = 0; /** * @brief Read a string list from the given key. * @param key - the key to be read. * @param ret - the result will be stored into *ret. * @return true if the string list is read successfully, otherwise return false. */ virtual bool read (const String& key, std::vector *ret) const = 0; /** * @brief Read an int list from the given key. * @param key - the key to be read. * @param ret - the result will be stored into *ret. * @return true if the int list is read successfully, otherwise return false. */ virtual bool read (const String& key, std::vector *ret) const = 0; /** * @brief Write a string to the given key. * @param key - the key to be written. * @param value - the string to be written to the key. * @return true if success, otherwise false. */ virtual bool write (const String& key, const String& value) = 0; /** * @brief Write an int value to the given key. * @param key - the key to be written. * @param value - the int value to be written to the key. * @return true if success, otherwise false. */ virtual bool write (const String& key, int value) = 0; /** * @brief Write a double value to the given key. * @param key - the key to be written. * @param value - the double value to be written to the key. * @return true if success, otherwise false. */ virtual bool write (const String& key, double value) = 0; /** * @brief Write a bool value to the given key. * @param key - the key to be written. * @param value - the bool value to be written to the key. * @return true if success, otherwise false. */ virtual bool write (const String& key, bool value) = 0; /** * @brief Write a string list to the given key. * @param key - the key to be written. * @param value - the string list to be written to the key. * @return true if success, otherwise false. */ virtual bool write (const String& key, const std::vector & value) = 0; /** * @brief Write an int list to the given key. * @param key - the key to be written. * @param value - the int list to be written to the key. * @return true if success, otherwise false. */ virtual bool write (const String& key, const std::vector & value) = 0; /** * @brief Permanently writes all changes. * @return true if success. */ virtual bool flush() = 0; /** * @brief Erase a key and its value * @param key - the key to be erased. * @return true if success. */ virtual bool erase (const String& key) = 0; /** * @brief Reload the configurations from storage. * * All modified keys after the last flush maybe lost. * * The derived method should call this base method * after reload the configurations successfully, * in order to emit the reload signal. * * The derived method should have some machanism to avoid * reload again if there is no update after * the previous reload. * * @return true if success. */ virtual bool reload () = 0; /** * @} */ /** * @name Other helper methods. * @{ */ /** * @brief Read a string from the given key with a default fallback value. * * If failed to read from the given key, then return the given default value. * * @param key - the key to be read. * @param defVal - the default value to be return if failed to read. * @return The result string. */ String read (const String& key, const String& defVal = String ()) const; /** * @brief Read an int value from the given key with a default fallback value. * * If failed to read from the given key, then return the given default value. * * @param key - the key to be read. * @param defVal - the default value to be return if failed to read. * @return The result int value. */ int read (const String& key, int defVal) const; /** * @brief Read a double value from the given key with a default fallback value. * * If failed to read from the given key, then return the given default value. * * @param key - the key to be read. * @param defVal - the default value to be return if failed to read. * @return The result double value. */ double read (const String& key, double defVal) const; /** * @brief Read a bool value from the given key with a default fallback value. * * If failed to read from the given key, then return the given default value. * * @param key - the key to be read. * @param defVal - the default value to be return if failed to read. * @return The result bool value. */ bool read (const String& key, bool defVal) const; /** * @brief Read a string list from the given key with a default fallback value. * * If failed to read from the given key, then return the given default value. * * @param key - the key to be read. * @param defVal - the default value to be return if failed to read. * @return The result string list. */ std::vector read (const String& key, const std::vector & defVal) const; /** * @brief Read an int list from the given key with a default fallback value. * * If failed to read from the given key, then return the given default value. * * @param key - the key to be read. * @param defVal - the default value to be return if failed to read. * @return The result int list. */ std::vector read (const String& key, const std::vector & defVal) const; /** * @brief connect the given slot to the reload signal. * @param slot - the given slot to be connected. * @return the Connection object, can be used to disconnect this slot. */ Connection signal_connect_reload (ConfigSlotVoid *slot); /** @} */ public: /** * @brief Set the default global Config object. * * There is only one global Config object in an application. * All other objects should use it by default. * * @param p_config - a smart pointer to the Config object. * @return a smart pointer to the old default Config object. */ static ConfigPointer set (const ConfigPointer &p_config); /** * @brief Get the default global Config object. * * The default global Config object can be set with function ConfigBase::set. * If there is no default object set, a new object can be created if needed. * * @param create_on_demand - if it's true then a new object will be created, * if there is no one available. * @param default_module - the Config module should be used to create the * default Config object. If omitted, then use the * default module defined in global config file. * @return a smart pointer to the default global Config object. */ static ConfigPointer get (bool create_on_demand = true, const String &default_module = String ("")); }; /** * @brief A dummy implementation of interface class scim::ConfigBase. * * The read methods will just return false and the default value (if available). * The write methods will do nothing. */ class DummyConfig : public ConfigBase { public: DummyConfig (); virtual ~DummyConfig (); virtual bool valid () const; virtual String get_name () const; virtual bool read (const String& key, String *ret) const; virtual bool read (const String& key, int *ret) const; virtual bool read (const String& key, double *ret) const; virtual bool read (const String& key, bool *ret) const; virtual bool read (const String& key, std::vector *ret) const; virtual bool read (const String& key, std::vector *ret) const; virtual bool write (const String& key, const String& value); virtual bool write (const String& key, int value); virtual bool write (const String& key, double value); virtual bool write (const String& key, bool value); virtual bool write (const String& key, const std::vector & value); virtual bool write (const String& key, const std::vector & value); virtual bool flush(); virtual bool erase (const String& key ); virtual bool reload (); }; /** @} */ } // namespace scim #endif //__SCIM_CONFIG_BASE_H /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_config_base.cpp0000644000175000017500000001411012422143415016701 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_config_base.cpp,v 1.19 2005/04/09 15:38:39 suzhe Exp $ */ #define Uses_SCIM_CONFIG_BASE #define Uses_SCIM_CONFIG_PATH #define Uses_SCIM_CONFIG_MODULE #include "scim_private.h" #include "scim.h" namespace scim { ConfigPointer _scim_default_config (0); ConfigModule _scim_default_config_module; static ConfigPointer _create_config (const String &default_module) { if (!_scim_default_config_module.valid ()) { String module; if (!default_module.length ()) module = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_CONFIG_MODULE, String ("simple")); else module = default_module; _scim_default_config_module.load (module); } if (_scim_default_config_module.valid ()) { _scim_default_config = _scim_default_config_module.create_config (); return _scim_default_config; } return ConfigPointer (0); } ConfigBase::ConfigBase () { } ConfigBase::~ConfigBase () { } bool ConfigBase::valid () const { return true; } String ConfigBase::read (const String& key, const String& defVal) const { String tmp; if (!read (key, &tmp)) { SCIM_DEBUG_CONFIG(1) << "Warning : No default scim::String value for key \"" << key << "\", " << "using default value.\n"; return defVal; } return tmp; } int ConfigBase::read (const String& key, int defVal) const { int tmp = 0; if (!read (key, &tmp)) { SCIM_DEBUG_CONFIG(1) << "Warning : No default int value for key \"" << key << "\", " << "using default value.\n"; return defVal; } return tmp; } double ConfigBase::read (const String& key, double defVal) const { double tmp = 0; if (!read (key, &tmp)) { SCIM_DEBUG_CONFIG(1) << "Warning : No default float value for key \"" << key << "\", " << "using default value.\n"; return defVal; } return tmp; } bool ConfigBase::read (const String& key, bool defVal) const { bool tmp = false; if (!read (key, &tmp)) { SCIM_DEBUG_CONFIG(1) << "Warning : No default bool value for key \"" << key << "\", " << "using default value.\n"; return defVal; } return tmp; } std::vector ConfigBase::read (const String& key, const std::vector & defVal) const { std::vector tmp; if (!read (key, &tmp)) { SCIM_DEBUG_CONFIG(1) << "Warning : No default scim::String list value for key \"" << key << "\", " << "using default value.\n"; return defVal; } return tmp; } std::vector ConfigBase::read (const String& key, const std::vector & defVal) const { std::vector tmp; if (!read (key, &tmp)) { SCIM_DEBUG_CONFIG(1) << "Warning : No default int list value for key \"" << key << "\", " << "using default value.\n"; return defVal; } return tmp; } bool ConfigBase::reload () { if (!ConfigBase::valid ()) return false; m_signal_reload.emit (this); return true; } Connection ConfigBase::signal_connect_reload (ConfigSlotVoid *slot) { return m_signal_reload.connect (slot); } ConfigPointer ConfigBase::set (const ConfigPointer &p_config) { ConfigPointer old = _scim_default_config; _scim_default_config = p_config; return old; } ConfigPointer ConfigBase::get (bool create_on_demand, const String &default_module) { if (create_on_demand && _scim_default_config.null ()) _create_config (default_module); return _scim_default_config; } /* * Implementation of DummyConfig */ DummyConfig::DummyConfig () { } DummyConfig::~DummyConfig () { } bool DummyConfig::valid () const { return ConfigBase::valid(); } String DummyConfig::get_name () const { return "dummy"; } // String bool DummyConfig::read (const String& key, String *pStr) const { return false; } // int bool DummyConfig::read (const String& key, int *pl) const { return false; } // double bool DummyConfig::read (const String& key, double* val) const { return false; } // bool bool DummyConfig::read (const String& key, bool* val) const { return false; } //String list bool DummyConfig::read (const String& key, std::vector * val) const { return false; } //int list bool DummyConfig::read (const String& key, std::vector * val) const { return false; } // write the value (return true on success) bool DummyConfig::write (const String& key, const String& value) { return true; } bool DummyConfig::write (const String& key, int value) { return true; } bool DummyConfig::write (const String& key, double value) { return true; } bool DummyConfig::write (const String& key, bool value) { return true; } bool DummyConfig::write (const String& key, const std::vector & value) { return true; } bool DummyConfig::write (const String& key, const std::vector & value) { return true; } // permanently writes all changes bool DummyConfig::flush() { return true; } // delete entries bool DummyConfig::erase (const String& key) { return true; } // reload the configurations. bool DummyConfig::reload () { return ConfigBase::reload (); } } // namespace scim /* vi:ts=4:nowrap:ai:expandtab */ scim-1.4.15/src/scim_config_agent.cpp0000644000175000017500000003552312422143415017100 0ustar tzhuantzhuan/* * Smart Common Input Method * * Copyright (c) 2002-2005 James Su * * * 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 program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: scim_config_agent.cpp,v 1.10 2005/07/03 08:36:42 suzhe Exp $ * */ #define Uses_STL_IOSTREAM #define Uses_C_LOCALE #define Uses_SCIM_CONFIG_MODULE #define Uses_SCIM_HELPER #define Uses_SCIM_CONFIG_PATH #include "scim_private.h" #include #include using namespace scim; using std::cout; using std::cerr; using std::endl; enum DataType { DATA_TYPE_STRING, DATA_TYPE_INT, DATA_TYPE_DOUBLE, DATA_TYPE_BOOL, DATA_TYPE_STRING_LIST, DATA_TYPE_INT_LIST }; enum Command { DO_NOTHING, GET_DATA, SET_DATA, DEL_KEY }; static String trim_blank (const String &str) { String::size_type begin, len; begin = str.find_first_not_of (" \t\n\v"); if (begin == String::npos) return String (); len = str.find_last_not_of (" \t\n\v") - begin + 1; return str.substr (begin, len); } static String get_param_portion (const String &str) { String::size_type begin = str.find_first_of (" \t\n\v="); if (begin == String::npos) return str; return str.substr (0, begin); } static String get_value_portion (const String &str) { String::size_type begin = str.find_first_of ("="); if (begin == String::npos || (begin + 1) == str.length ()) return String (""); return trim_blank (str.substr (begin + 1, String::npos)); } int main (int argc, char *argv []) { static ConfigModule config_module; ConfigPointer config; std::vector config_list; String def_config; String key; String value; String display; DataType type = DATA_TYPE_STRING; Command cmd = DO_NOTHING; bool reload = false; bool global = false; int i; char *p = getenv ("DISPLAY"); if (p) display = String (p); //get modules list scim_get_config_module_list (config_list); //Use simple Config module as default if available. if (config_list.size ()) { def_config = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_CONFIG_MODULE, String ("simple")); if (std::find (config_list.begin (), config_list.end (), def_config) == config_list.end ()) def_config = config_list [0]; } else { cerr << "No config module found.\n"; return -1; } // parse command options i = 0; while (i= argc) break; if (String ("-h") == argv [i] || String ("--help") == argv [i]) { cout << "Usage: " << argv [0] << "