/* medit.c -- simple multilingual editor. -*- coding: euc-jp; -*-
- Copyright (C) 2003, 2004
+ Copyright (C) 2003, 2004, 2005, 2006, 2007
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H15PRO112
You should have received a copy of the GNU Lesser General Public
License along with the m17n library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
02111-1307, USA. */
/***en
This program is to demonstrate how to use the m17n GUI API.
Although m17n-edit directly uses the GUI API, the API is mainly
- for toolkit libraries or to implement XOM (X Outout Method), not
+ for toolkit libraries or to implement XOM (X Output Method), not
for direct use from application programs.
*/
/***ja
¤³¤Î¥×¥í¥°¥é¥à¤Ï m17n GUI API ¤Î»È¤¤Êý¤ò¼¨¤¹¤â¤Î¤Ç¤¢¤ë¡£m17n-edit
¤ÏľÀÜ GUI API ¤ò»È¤Ã¤Æ¤¤¤ë¤¬¡¢¤³¤Î API ¤Ï¼ç¤Ë¥Ä¡¼¥ë¥¥Ã¥È¥é¥¤¥Ö¥é
- ¥ê¤äXOM (X Outout Method) ¤Î¼ÂÁõÍѤǤ¢¤ê¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
+ ¥ê¤äXOM (X Output Method) ¤Î¼ÂÁõÍѤǤ¢¤ê¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
¥à¤«¤é¤ÎľÀܤÎÍøÍѤò°Õ¿Þ¤·¤Æ¤¤¤Ê¤¤¡£
*/
#include <X11/Xaw/SmeLine.h>
#include <X11/Xaw/MenuButton.h>
-#define VERSION "1.2.0"
-
/* Global variables. */
char *filename;
MFrame *frame;
MText *mt;
int nchars; /* == mtext_len (mt) */
+int mt_modified;
MDrawControl control, input_status_control;
MTextProperty *selection;
{
int from; /* BOL position of the line. */
int to; /* BOL position of the next line. */
- int y0, y1; /* Top and bottom Y position of the line. */
+ int y0, y1; /* Top and bottom Y position of the line. */
int ascent; /* Height of the top Y position. */
};
void
select_input_method (idx)
{
+ int previous_input_method = current_input_method;
+
if (idx == current_input_method)
return;
- if (current_input_context)
+ if (current_input_method >= 0)
{
minput_destroy_ic (current_input_context);
current_input_context = NULL;
current_input_method = -1;
}
- if (idx >= 0)
+
+ if (idx >= 0
+ && input_method_table[idx].available >= 0)
{
InputMethodInfo *im = input_method_table + idx;
- if (im->language == Mnil)
+ if (im->available == 0)
{
- MInputXIMArgIC arg_xic;
- Window win = XtWindow (TextWidget);
-
- arg_xic.input_style = 0;
- arg_xic.client_win = arg_xic.focus_win = win;
- arg_xic.preedit_attrs = arg_xic.status_attrs = NULL;
- current_input_context = minput_create_ic (im->im, &arg_xic);
+ if (im->language)
+ im->im = minput_open_im (im->language, im->name, NULL);
+ else
+ {
+ MInputXIMArgIM arg_xim;
+
+ arg_xim.display = display;
+ arg_xim.db = NULL;
+ arg_xim.res_name = arg_xim.res_class = NULL;
+ arg_xim.locale = NULL;
+ arg_xim.modifier_list = NULL;
+ im->im = minput_open_im (Mnil, im->name, &arg_xim);
+ }
+ im->available = im->im ? 1 : -1;
}
- else
+ if (im->im)
{
- MInputGUIArgIC arg_ic;
+ if (im->language == Mnil)
+ {
+ MInputXIMArgIC arg_xic;
+ Window win = XtWindow (TextWidget);
- arg_ic.frame = frame;
- arg_ic.client = (MDrawWindow) XtWindow (ShellWidget);
- arg_ic.focus = (MDrawWindow) XtWindow (TextWidget);
- current_input_context = minput_create_ic (im->im, &arg_ic);
- }
+ arg_xic.input_style = 0;
+ arg_xic.client_win = arg_xic.focus_win = win;
+ arg_xic.preedit_attrs = arg_xic.status_attrs = NULL;
+ current_input_context = minput_create_ic (im->im, &arg_xic);
+ }
+ else
+ {
+ MInputGUIArgIC arg_ic;
- if (current_input_context)
- {
- set_input_method_spot ();
- current_input_method = idx;
+ arg_ic.frame = frame;
+ arg_ic.client = (MDrawWindow) XtWindow (ShellWidget);
+ arg_ic.focus = (MDrawWindow) XtWindow (TextWidget);
+ current_input_context = minput_create_ic (im->im, &arg_ic);
+ }
+
+ if (current_input_context)
+ {
+ current_input_method = idx;
+ set_input_method_spot ();
+ }
+ else
+ {
+ minput_close_im (im->im);
+ im->im = NULL;
+ im->available = -1;
+ current_input_method = -1;
+ }
}
}
+ if (! auto_input_method)
+ {
+ XtSetArg (arg[0], XtNleftBitmap, None);
+ if (previous_input_method >= 0)
+ XtSetValues (InputMethodMenus[previous_input_method + 2], arg, 1);
+ else
+ XtSetValues (InputMethodMenus[0], arg, 1);
+ XtSetArg (arg[0], XtNleftBitmap, CheckPixmap);
+ if (current_input_method >= 0)
+ XtSetValues (InputMethodMenus[current_input_method + 2], arg, 1);
+ else
+ XtSetValues (InputMethodMenus[0], arg, 1);
+ }
+
if (current_input_method >= 0)
{
char *label;
+
XtSetArg (arg[0], XtNlabel, &label);
XtGetValues (InputMethodMenus[current_input_method + 2], arg, 1);
XtSetArg (arg[0], XtNlabel, label);
}
else
- XtSetArg (arg[0], XtNlabel, "");
+ {
+ XtSetArg (arg[0], XtNlabel, "");
+ }
XtSetValues (CurIMLang, arg, 1);
}
else
{
XtSetArg (arg[0], XtNborderWidth, 1);
- XtSetArg (arg[1], XtNlabel,
- msymbol_name (msymbol_get (sym, Mlanguage)));
+ XtSetArg (arg[1], XtNlabel, mlanguage_name (sym));
XtSetValues (CurLangWidget, arg, 2);
}
XtSetValues (CurLangWidget, arg, 2);
int i;
for (i = 0; i < num_input_methods; i++)
- if (input_method_table[i].language == sym)
+ if (input_method_table[i].language == sym
+ && input_method_table[i].available >= 0)
break;
- if (i < num_input_methods
- && input_method_table[i].available >= 0)
- {
- if (! input_method_table[i].im)
- {
- input_method_table[i].im =
- minput_open_im (input_method_table[i].language,
- input_method_table[i].name, NULL);
- if (! input_method_table[i].im)
- input_method_table[i].available = -1;
- }
- if (input_method_table[i].im)
- select_input_method (i);
- else
- select_input_method (-1);
- }
+ if (i < num_input_methods)
+ select_input_method (i);
else
select_input_method (-1);
}
from = cursor.from, to = from + n;
else
{
+ from = cursor.from + n;
+ to = cursor.from;
if (cursor.from == cur.from)
{
/* We are at the beginning of line. */
reseat (info.line_from);
}
update_cursor (pos, 1);
- from = cursor.from;
- to = cursor.to;
- }
- else
- {
- from = cursor.from - 1;
- to = cursor.from;
}
}
update_cursor (0, 1);
redraw (0, win_height, 0, 1);
if (current_input_method >= 0)
- {
- int idx = current_input_method;
+ {
+ int idx = current_input_method;
- current_input_method = -1;
- input_method_table[idx].im =
- minput_open_im (input_method_table[idx].language,
- input_method_table[idx].name, NULL);
- if (input_method_table[idx].im)
+ current_input_method = -1;
select_input_method (idx);
- else
- input_method_table[idx].available = -1;
- }
+ }
show_cursor (NULL);
}
else
redraw (sel_start.y0, sel_end.y1, 1, 0);
}
hide_cursor ();
- if (current_input_context)
+ if (current_input_context
+ && minput_filter (current_input_context, Minput_focus_move, NULL) == 0)
{
MText *produced = mtext ();
- minput_reset_ic (current_input_context);
minput_lookup (current_input_context, Mnil, NULL, produced);
if (mtext_len (produced) > 0)
{
}
void
+FocusInProc (Widget w, XEvent *event, String *str, Cardinal *num)
+{
+ if (current_input_context
+ && minput_filter (current_input_context, Minput_focus_in, NULL) == 0)
+ {
+ MText *produced = mtext ();
+
+ minput_lookup (current_input_context, Mnil, NULL, produced);
+ if (mtext_len (produced) > 0)
+ {
+ hide_cursor ();
+ insert_chars (produced);
+ }
+ m17n_object_unref (produced);
+ }
+}
+
+void
+FocusOutProc (Widget w, XEvent *event, String *str, Cardinal *num)
+{
+ if (current_input_context
+ && minput_filter (current_input_context, Minput_focus_out, NULL) == 0)
+ {
+ MText *produced = mtext ();
+
+ minput_lookup (current_input_context, Mnil, NULL, produced);
+ if (mtext_len (produced) > 0)
+ {
+ hide_cursor ();
+ insert_chars (produced);
+ }
+ m17n_object_unref (produced);
+ }
+}
+
+void
ScrollProc (Widget w, XtPointer client_data, XtPointer position)
{
int from;
/* If set to 1, do not update target_x_position. */
int keep_target_x_position = 0;
MText *produced;
+ int y0, old_y1, new_y1;
+
+ hide_cursor ();
+ mt_modified = 0;
+ y0 = cur.y0;
+ old_y1 = cur.y1;
if (current_input_context
&& minput_filter (current_input_context, Mnil, event))
- return;
+ {
+ if (mt_modified)
+ {
+ new_y1 = cur.y1;
+ update_region (y0, old_y1, new_y1);
+ }
+ return;
+ }
if (event->type == KeyRelease)
return;
- hide_cursor ();
-
produced = mtext ();
ret = minput_lookup (current_input_context, Mnil, event, produced);
if (mtext_len (produced) > 0)
{
int idx = (int) client_data;
- if (idx == -2 ? current_input_method < 0
+ if (idx == -2 ? (! auto_input_method && current_input_method < 0)
: idx == -1 ? auto_input_method
: idx == current_input_method)
return;
- XtSetArg (arg[0], XtNleftBitmap, None);
if (auto_input_method)
{
+ select_input_method (-1);
+ XtSetArg (arg[0], XtNleftBitmap, None);
XtSetValues (InputMethodMenus[1], arg, 1);
auto_input_method = 0;
}
- else if (current_input_method < 0)
- XtSetValues (InputMethodMenus[0], arg, 1);
- else
- XtSetValues (InputMethodMenus[current_input_method + 2], arg, 1);
if (idx == -1)
{
+ select_input_method (-1);
+ XtSetArg (arg[0], XtNleftBitmap, None);
+ XtSetValues (InputMethodMenus[0], arg, 1);
+ XtSetArg (arg[0], XtNleftBitmap, CheckPixmap);
+ XtSetValues (InputMethodMenus[1], arg, 1);
auto_input_method = 1;
hide_cursor ();
}
- else if (input_method_table[idx].available >= 0)
+ else
{
- if (! input_method_table[idx].im)
- {
- input_method_table[idx].im =
- minput_open_im (input_method_table[idx].language,
- input_method_table[idx].name, NULL);
- if (! input_method_table[idx].im)
- input_method_table[idx].available = -1;
- }
- if (input_method_table[idx].im)
- select_input_method (idx);
+ select_input_method (idx);
}
- XtSetArg (arg[0], XtNleftBitmap, CheckPixmap);
- XtSetValues (InputMethodMenus[idx + 2], arg, 1);
}
MPlist *default_face_list;
XtSetValues (CurIMStatus, arg, 1);
}
+void
+surrounding_text_handler (MInputContext *ic, MSymbol command)
+{
+ if (command == Minput_get_surrounding_text)
+ {
+ int len = (int) mplist_value (ic->plist);
+ int pos;
+ MText *surround;
+
+ if (len < 0)
+ {
+ pos = cursor.from + len;
+ if (pos < 0)
+ pos = 0;
+ surround = mtext_duplicate (mt, pos, cursor.from);
+ }
+ else if (len > 0)
+ {
+ pos = cursor.from + len;
+ if (pos > nchars)
+ pos = nchars;
+ surround = mtext_duplicate (mt, cursor.from, pos);
+ }
+ else
+ surround = mtext ();
+ mplist_set (ic->plist, Mtext, surround);
+ m17n_object_unref (surround);
+ }
+ else if (command == Minput_delete_surrounding_text)
+ {
+ int len = (int) mplist_value (ic->plist);
+
+ if (len < 0)
+ {
+ if (cursor.from + len < 0)
+ len = - cursor.from;
+ mtext_del (mt, cursor.from + len, cursor.from);
+ nchars += len;
+ update_cursor (cursor.from + len, 1);
+ }
+ else if (len > 0)
+ {
+ if (cursor.from + len > nchars)
+ len = nchars - cursor.from;
+ mtext_del (mt, cursor.from, cursor.from + len);
+ nchars -= len;
+ update_cursor (cursor.from, 1);
+ }
+ if (len)
+ mt_modified = 1;
+ }
+}
+
int
compare_input_method (const void *elt1, const void *elt2)
{
return 1;
if (im2->language == Mt)
return -1;
- lang1 = msymbol_get (im1->language, Mlanguage);
- lang2 = msymbol_get (im2->language, Mlanguage);
+ lang1 = mlanguage_name (im1->language);
+ lang2 = mlanguage_name (im2->language);
return strcmp (msymbol_name (lang1), msymbol_name (lang2));
}
void
setup_input_methods (int with_xim, char *initial_input_method)
{
- MInputMethod *im = NULL;
MPlist *plist = mdatabase_list (msymbol ("input-method"), Mnil, Mnil, Mnil);
MPlist *pl;
- int i = 0;
- char *lang_name = NULL, *method_name = NULL;
-
- if (initial_input_method)
- {
- char *p = strchr (initial_input_method, '-');
- if (p)
- lang_name = initial_input_method, method_name = p + 1, *p = '\0';
- else
- method_name = initial_input_method;
- }
+ int i;
num_input_methods = plist ? mplist_length (plist) : 0;
-
if (with_xim)
- {
- MInputXIMArgIM arg_xim;
-
- arg_xim.display = display;
- arg_xim.db = NULL;
- arg_xim.res_name = arg_xim.res_class = NULL;
- arg_xim.locale = NULL;
- arg_xim.modifier_list = NULL;
- im = minput_open_im (Mnil, msymbol ("xim"), &arg_xim);
- if (im)
- num_input_methods++;
- }
+ num_input_methods++;
input_method_table = calloc (num_input_methods, sizeof (InputMethodInfo));
- if (im)
- {
- input_method_table[i].available = 1;
- input_method_table[i].language = Mnil;
- input_method_table[i].name = im->name;
- input_method_table[i].im = im;
- i++;
- }
+ i = 0;
if (plist)
{
- for (pl = plist; mplist_key (pl) != Mnil; pl = mplist_next (pl))
+ for (pl = plist; mplist_key (pl) != Mnil; pl = mplist_next (pl), i++)
{
MDatabase *mdb = mplist_value (pl);
MSymbol *tag = mdatabase_tag (mdb);
- if (tag[1] != Mnil)
+ if (tag[2] == Mnil)
+ i--, num_input_methods--;
+ else
{
input_method_table[i].language = tag[1];
input_method_table[i].name = tag[2];
- i++;
}
}
-
m17n_object_unref (plist);
}
- num_input_methods = i;
+ if (with_xim)
+ {
+ input_method_table[i].language = Mnil;
+ input_method_table[i].name = msymbol ("xim");
+ i++;
+ }
+
qsort (input_method_table, num_input_methods, sizeof input_method_table[0],
compare_input_method);
+ mplist_put_func (minput_driver->callback_list, Minput_status_start,
+ M17N_FUNC (input_status));
+ mplist_put_func (minput_driver->callback_list, Minput_status_draw,
+ M17N_FUNC (input_status));
+ mplist_put_func (minput_driver->callback_list, Minput_status_done,
+ M17N_FUNC (input_status));
+ mplist_put_func (minput_driver->callback_list, Minput_get_surrounding_text,
+ M17N_FUNC (surrounding_text_handler));
+ mplist_put_func (minput_driver->callback_list, Minput_delete_surrounding_text,
+ M17N_FUNC (surrounding_text_handler));
+
current_input_context = NULL;
+ current_input_method = -1;
- mplist_put (minput_driver->callback_list, Minput_status_start,
- (void *) input_status);
- mplist_put (minput_driver->callback_list, Minput_status_draw,
- (void *) input_status);
- mplist_put (minput_driver->callback_list, Minput_status_done,
- (void *) input_status);
+ if (initial_input_method)
+ {
+ char *lang_name, *method_name;
+ char *p = strchr (initial_input_method, '-');
- if (method_name)
- for (i = 0; i < num_input_methods; i++)
- if (strcmp (method_name, msymbol_name (input_method_table[i].name)) == 0
- && (lang_name
- ? strcmp (lang_name, msymbol_name (input_method_table[i].language)) == 0
- : input_method_table[i].language == Mt))
- {
- current_input_method = i;
- break;
- }
+ if (p && p[1])
+ lang_name = initial_input_method, *p = '\0', method_name = p + 1;
+ else
+ lang_name = "t", method_name = initial_input_method;
+
+ for (i = 0; i < num_input_methods; i++)
+ if ((strcmp (method_name, msymbol_name (input_method_table[i].name))
+ == 0)
+ && (strcmp (lang_name, msymbol_name (input_method_table[i].language)) == 0))
+ {
+ current_input_method = i;
+ break;
+ }
+ }
}
XtSetArg (arg[3], XtNhighlightThickness, 1);
XtSetArg (arg[4], XtNleft, XawChainLeft);
XtSetArg (arg[5], XtNright, XawChainLeft);
- i = 6;
+ XtSetArg (arg[6], XtNinternational, True);
+ i = 7;
if (left)
XtSetArg (arg[i], XtNfromHoriz, left), i++;
button = XtCreateManagedWidget (button_name, menuButtonWidgetClass, parent,
{"ButtonRelease", ButtonReleaseProc},
{"ButtonMotion", ButtonMoveProc},
{"Button2Press", Button2Proc},
- {"MenuHelp", MenuHelpProc}
+ {"MenuHelp", MenuHelpProc},
+ {"FocusIn", FocusInProc},
+ {"FocusOut", FocusOutProc}
};
{
Widget form, BodyWidget, w;
char *fontset_name = NULL;
+ char *font_name = NULL;
int fontsize = 0;
char *initial_input_method = NULL;
int col = 80, row = 32;
<Btn2Down>: Button2Press()";
/* Translation table for the top form widget. */
String trans2 = "<Key>: Key()\n\
- <KeyUp>: Key()";
+ <KeyUp>: Key()\n\
+ <FocusIn>: FocusIn()\n\
+ <FocusOut>: FocusOut()";
String pop_face_trans
= "<EnterWindow>: MenuHelp(Pop face property) highlight()\n\
<LeaveWindow>: MenuHelp() reset()\n\
int with_xim = 0;
int i, j;
char *filter = NULL;
+ MFont *font = NULL;
setlocale (LC_ALL, "");
/* Create the top shell. */
help_exit (argv[0], 0);
else if (! strcmp (argv[i], "--version"))
{
- printf ("m17n-edit (m17n library) %s\n", VERSION);
- printf ("Copyright (C) 2003 AIST, JAPAN\n");
+ printf ("m17n-edit (m17n library) %s\n", M17NLIB_VERSION_NAME);
+ printf ("Copyright (C) 2003, 2004, 2005, 2006, 2007 AIST, JAPAN\n");
exit (0);
}
else if (! strcmp (argv[i], "--geometry"))
i++;
fontset_name = strdup (argv[i]);
}
+ else if (! strcmp (argv[i], "--font"))
+ {
+ i++;
+ font_name = strdup (argv[i]);
+ }
else if (! strcmp (argv[i], "--im"))
{
i++;
{
MPlist *plist = mplist ();
- MFace *face;
MFont *font;
mplist_put (plist, msymbol ("widget"), ShellWidget);
- if (fontset_name || fontsize > 0)
+ if (fontset_name || font_name || fontsize > 0)
{
- MFontset *fontset = mfontset (fontset_name);
-
- face = mface ();
- mface_put_prop (face, Mfontset, fontset);
- mface_put_prop (face, Msize, (void *) fontsize);
- m17n_object_unref (fontset);
+ MFace *face;
+
+ if (font_name)
+ {
+ font = mfont_parse_name (font_name, Mnil);
+ if (font)
+ face = mface_from_font (font);
+ else
+ face = mface ();
+ }
+ else
+ face = mface ();
+ if (fontset_name)
+ {
+ MFontset *fontset = mfontset (fontset_name);
+
+ mface_put_prop (face, Mfontset, fontset);
+ m17n_object_unref (fontset);
+ }
+ if (fontsize > 0)
+ mface_put_prop (face, Msize, (void *) fontsize);
mplist_add (plist, Mface, face);
m17n_object_unref (face);
}
MFont *dev_font = mfont ();
MFont *thai_font = mfont ();
MFont *tib_font = mfont ();
- MFontset *fontset;
+ MFontset *fontset, *fontset_no_ctl;
MSymbol unicode_bmp = msymbol ("unicode-bmp");
MSymbol no_ctl = msymbol ("no-ctl");
mfont_put_prop (tib_font, Mfamily, msymbol ("mtib"));
mfont_put_prop (tib_font, Mregistry, unicode_bmp);
- fontset = mfontset_copy (mfontset (fontset_name), "no-ctl");
- mfontset_modify_entry (fontset, msymbol ("latin"), Mnil, Mnil,
+ fontset = mfontset (fontset_name);
+ fontset_no_ctl = mfontset_copy (fontset, "no-ctl");
+ m17n_object_unref (fontset);
+ mfontset_modify_entry (fontset_no_ctl, msymbol ("latin"), Mnil, Mnil,
latin_font, Mnil, 0);
- mfontset_modify_entry (fontset, msymbol ("devanagari"), Mnil, Mnil,
+ mfontset_modify_entry (fontset_no_ctl, msymbol ("devanagari"), Mnil, Mnil,
dev_font, no_ctl, 0);
- mfontset_modify_entry (fontset, msymbol ("thai"), Mnil, Mnil,
+ mfontset_modify_entry (fontset_no_ctl, msymbol ("thai"), Mnil, Mnil,
thai_font, no_ctl, 0);
- mfontset_modify_entry (fontset, msymbol ("tibetan"), Mnil, Mnil,
+ mfontset_modify_entry (fontset_no_ctl, msymbol ("tibetan"), Mnil, Mnil,
tib_font, no_ctl, 0);
face_no_ctl_fontset = mface ();
- mface_put_prop (face_no_ctl_fontset, Mfontset, fontset);
- m17n_object_unref (fontset);
+ mface_put_prop (face_no_ctl_fontset, Mfontset, fontset_no_ctl);
+ m17n_object_unref (fontset_no_ctl);
free (dev_font);
free (thai_font);
if (im->language != Mnil && im->language != Mt)
{
- MSymbol sym = msymbol_get (im->language, Mlanguage);
+ MSymbol sym = mlanguage_name (im->language);
if (sym == Mnil)
name1 = msymbol_name (im->language);
else
MSymbol fullname;
if (sym != Mnil
- && ((fullname = msymbol_get (sym, Mlanguage)) != Mnil))
+ && ((fullname = mlanguage_name (sym)) != Mnil))
{
char *name = msymbol_name (fullname);
char c = name[0];
m17n_object_unref (face_default);
m17n_object_unref (default_face_list);
m17n_object_unref (selection);
+ if (font)
+ free (font);
XFreeGC (display, mono_gc);
XFreeGC (display, mono_gc_inv);
M17N_FINI ();
+ free (font_name);
free (fontset_name);
free (filename);
free (input_method_table);