-/* medit.c -- simple multilingual editor.
- Copyright (C) 2003, 2004
+/* medit.c -- simple multilingual editor. -*- coding: euc-jp; -*-
+ 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
- @page medit edit multilingual text
+ @enpage m17n-edit edit multilingual text
- @section medit-synopsis SYNOPSIS
+ @section m17n-edit-synopsis SYNOPSIS
- medit [ XT-OPTION ...] [ OPTION ... ] FILE
+ m17n-edit [ XT-OPTION ...] [ OPTION ... ] FILE
- @section medit-description DESCRIPTION
+ @section m17n-edit-description DESCRIPTION
Display FILE on a window and allow users to edit it.
</ul>
This program is to demonstrate how to use the m17n GUI API.
- Although medit directly uses the GUI API, the API is mainly for
- toolkit libraries or to implement XOM (X Outout Method), not for
- direct use from application programs.
+ Although m17n-edit directly uses the GUI API, the API is mainly
+ for toolkit libraries or to implement XOM (X Output Method), not
+ for direct use from application programs.
+*/
+/***ja
+ @japage m17n-edit ¿¸À¸ì¥Æ¥¥¹¥È¤ÎÊÔ½¸
+
+ @section m17n-edit-synopsis SYNOPSIS
+
+ m17n-edit [ XT-OPTION ...] [ OPTION ... ] FILE
+
+ @section m17n-edit-description DESCRIPTION
+
+ FILE ¤ò¥¦¥£¥ó¥É¥¦¤Ëɽ¼¨¤·¡¢¥æ¡¼¥¶¤¬ÊÔ½¸¤Ç¤¤ë¤è¤¦¤Ë¤¹¤ë¡£
+
+ XT-OPTIONs ¤Ï Xt ¤Îɸ½à¤Î°ú¿ô¤Ç¤¢¤ë¡£ (e.g. -fn, -fg).
+
+ °Ê²¼¤Î¥ª¥×¥·¥ç¥ó¤¬ÍøÍѤǤ¤ë¡£
+
+ <ul>
+
+ <li> --version
+
+ ¥Ð¡¼¥¸¥ç¥óÈÖ¹æ¤òɽ¼¨¤¹¤ë¡£
+
+ <li> -h, --help
+
+ ¤³¤Î¥á¥Ã¥»¡¼¥¸¤òɽ¼¨¤¹¤ë¡£
+
+ </ul>
+
+ ¤³¤Î¥×¥í¥°¥é¥à¤Ï m17n GUI API ¤Î»È¤¤Êý¤ò¼¨¤¹¤â¤Î¤Ç¤¢¤ë¡£m17n-edit
+ ¤ÏľÀÜ GUI API ¤ò»È¤Ã¤Æ¤¤¤ë¤¬¡¢¤³¤Î API ¤Ï¼ç¤Ë¥Ä¡¼¥ë¥¥Ã¥È¥é¥¤¥Ö¥é
+ ¥ê¤äXOM (X Output Method) ¤Î¼ÂÁõÍѤǤ¢¤ê¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
+ ¥à¤«¤é¤ÎľÀܤÎÍøÍѤò°Õ¿Þ¤·¤Æ¤¤¤Ê¤¤¡£
*/
#ifndef FOR_DOXYGEN
#include <unistd.h>
#include <libgen.h>
#include <locale.h>
+#include <dlfcn.h>
+
+#ifdef HAVE_X11_XAW_COMMAND_H
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
+
+#include <m17n-gui.h>
+#include <m17n-misc.h>
+#include <m17n-X.h>
+
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/SmeLine.h>
#include <X11/Xaw/MenuButton.h>
-#include <m17n-gui.h>
-#include <m17n-misc.h>
-#include <m17n-X.h>
-
-#define VERSION "1.0"
-
/* Global variables. */
char *filename;
MFrame *frame;
MText *mt;
int nchars; /* == mtext_len (mt) */
-MDrawControl control;
+int mt_modified;
+MDrawControl control, input_status_control;
MTextProperty *selection;
+MSymbol Mword;
+
MFace *face_default;
MFace *face_xxx_large;
MFace *face_box;
MFace *face_courier, *face_helvetica, *face_times;
-MFace *face_dv_ttyogesh, *face_freesans, *face_freemono;
+MFace *face_dv_ttyogesh, *face_freesans, *face_freeserif, *face_freemono;
MFace *face_default_fontset, *face_no_ctl_fontset;
MFace *face_input_status;
+MSymbol Mcoding_compound_text;
+
int logical_move = 1; /* If 0, move cursor visually. */
-MInputMethod **input_method_table;
+typedef struct {
+ int available;
+ MSymbol language, name;
+ MInputMethod *im;
+} InputMethodInfo;
+
+InputMethodInfo *input_method_table;
+
int num_input_methods;
int current_input_method = -1; /* i.e. none */
int auto_input_method = 0;
{"times", &face_times},
{"dv-ttyogesh", &face_dv_ttyogesh},
{"freesans", &face_freesans},
+ {"freeserif", &face_freeserif},
{"freemono", &face_freemono},
{"Menu Style", NULL},
{
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. */
};
top.from = info.line_from;
top.to = info.line_to;
top.y0 = 0;
- top.y1 = info.this.height;
- top.ascent = - info.this.y;
+ top.y1 = info.metrics.height;
+ top.ascent = - info.metrics.y;
}
int sel_y0 = SELECTEDP () ? sel_start.y0 : 0;
struct LineInfo *line;
- if (clear)
+ if (clear || control.anti_alias)
CLEAR_AREA (0, y0, win_width, y1 - y0);
- /* Find a line closest to y0. The lihe is a cursor line if the
- cursor is at the position above Y0, otherwise the top line. */
+ /* Find a line closest to y0. It is a cursor line if the cursor is
+ Y0, otherwise the top line. */
if (y0 >= cur.y0)
line = &cur;
else
from = line->from;
y = line->y0;
- info.this.height = line->y1 - y;
- info.this.y = - line->ascent;
+ info.metrics.height = line->y1 - y;
+ info.metrics.y = - line->ascent;
info.line_to = line->to;
- while (from < nchars && y + info.this.height <= y0)
+ while (y + info.metrics.height <= y0)
{
- y += info.this.height;
+ y += info.metrics.height;
from = info.line_to;
+ if (from >= nchars)
+ break;
GLYPH_INFO (from, from, info);
}
- y0 = y - info.this.y;
+ if (y + info.metrics.height <= y0)
+ return;
+
+ y0 = y - info.metrics.y;
to = from;
while (to < nchars && y < y1)
{
GLYPH_INFO (to, to, info);
- y += info.this.height;
+ y += info.metrics.height;
to = info.line_to;
}
if (to == nchars)
while (to < nchars)
{
GLYPH_INFO (to, to, info);
- if (y + info.this.height >= win_height)
+ if (y + info.metrics.height >= win_height)
break;
to = info.line_to;
- y += info.this.height;
+ y += info.metrics.height;
}
update_scroll_bar (top.from, to);
}
int x = cursor.x + (control.orientation_reversed ? win_width : 0);
int pos = cursor.from > 0 ? cursor.from - 1 : 0;
MFace *faces[256];
- int n = mtext_get_prop_values (mt, pos, Mface, (void **) faces, 256);
+ int n = 0;
int size = 0, ratio = 0, i;
- for (i = n - 1; i >= 0; i--)
- {
- if (! size)
- size = (int) mface_get_prop (faces[i], Msize);
- if (! ratio)
- ratio = (int) mface_get_prop (faces[i], Mratio);
- }
+ if (nchars > 0)
+ n = mtext_get_prop_values (mt, pos, Mface, (void **) faces, 256);
+ if (n > 0)
+ for (i = n - 1; i >= 0; i--)
+ {
+ if (! size)
+ size = (int) mface_get_prop (faces[i], Msize);
+ if (! ratio)
+ ratio = (int) mface_get_prop (faces[i], Mratio);
+ }
if (! size)
size = default_font_size;
if (ratio)
MDrawMetric rect;
int y0 = cur.y0, y1 = cur.y1;
- if (beg != cur.from)
+ if (beg < cur.from)
{
TEXT_EXTENTS (beg, cur.from, rect);
y0 -= rect.height;
}
- if (end != cur.to)
+ if (end > cur.to)
{
TEXT_EXTENTS (cur.to, end, rect);
y1 += rect.height;
int x = cursor.x;
if (control.orientation_reversed)
- x += win_width - cursor.this.width;
- CLEAR_AREA (x, cur.y0, cursor.this.width, cursor.this.height);
+ x += win_width - cursor.logical_width;
+ CLEAR_AREA (x, cur.y0, cursor.logical_width, cursor.metrics.height);
}
DRAW_TEXT (cursor.x, cur.y0 + cur.ascent, cursor.from, cursor.to);
}
/* Update the information about the location of cursor to the position
$POS. If $FULL is nonzero, update the information fully only from
- the information about the top line. Otherwise, truct the current
+ the information about the top line. Otherwise, trust the current
information in the structure $CUR. */
void
update_cursor (int pos, int full)
{
/* CUR is inaccurate. We can trust only TOP. */
GLYPH_INFO (top.from, pos, cursor);
- cur.y0 = top.ascent + cursor.y + cursor.this.y;
+ cur.y0 = top.ascent + cursor.y + cursor.metrics.y;
}
else if (pos < cur.from)
{
TEXT_EXTENTS (from, cur.from, rect);
GLYPH_INFO (from, pos, cursor);
- cur.y0 -= (rect.height + rect.y) - (cursor.y + cursor.this.y);
+ cur.y0 -= (rect.height + rect.y) - (cursor.y + cursor.metrics.y);
}
else if (pos < cur.to)
{
else
{
GLYPH_INFO (cur.from, pos, cursor);
- cur.y0 += cur.ascent + cursor.y + cursor.this.y;
+ cur.y0 += cur.ascent + cursor.y + cursor.metrics.y;
}
cur.from = cursor.line_from;
cur.to = cursor.line_to;
- cur.y1 = cur.y0 + cursor.this.height;
- cur.ascent = - cursor.this.y;
+ cur.y1 = cur.y0 + cursor.metrics.height;
+ cur.ascent = - cursor.metrics.y;
}
if (from < top.from)
{
- GLYPH_INFO (bol (from, 0), from, info);
- sel_start.ascent = -info.this.y;
- sel_start.from = info.line_from;
- sel_start.to = info.line_to;
- TEXT_EXTENTS (from, top.from, rect);
- sel_start.y0 = - rect.height;
- sel_start.y1 = sel_start.y0 + info.this.height;
+ int pos = bol (from, 0);
+
+ TEXT_EXTENTS (pos, top.from, rect);
+ sel_start.y0 = top.y0 - rect.height;
+ sel_start.ascent = - rect.y;
+ GLYPH_INFO (pos, from, info);
+ if (pos < info.line_from)
+ sel_start.y0 += - rect.y + info.y + info.metrics.y;
}
else
{
GLYPH_INFO (top.from, from, info);
- sel_start.y0 = top.ascent + info.y + info.this.y;
- sel_start.y1 = sel_start.y0 + info.this.height;
- sel_start.ascent = -info.this.y;
- sel_start.from = info.line_from;
- sel_start.to = info.line_to;
+ sel_start.y0 = top.ascent + info.y + info.metrics.y;
}
+ sel_start.ascent = -info.metrics.y;
+ sel_start.y1 = sel_start.y0 + info.metrics.height;
+ sel_start.from = info.line_from;
+ sel_start.to = info.line_to;
if (to <= sel_start.to)
{
sel_end = sel_start;
- to = bol (to - 1, 1) - 1;
- if (to >= sel_end.to)
- {
- GLYPH_INFO (sel_start.from, to, info);
- sel_end.y1 = sel_end.y0 + info.y + info.this.height;
- sel_end.to = info.line_to;
- }
}
else
{
- to = bol (to - 1, 1) - 1;
GLYPH_INFO (sel_start.from, to, info);
- sel_end.y0 = sel_start.y0 + sel_start.ascent + info.y + info.this.y;
- sel_end.y1 = sel_end.y0 + info.this.height;
- sel_end.ascent = - info.this.y;
+ sel_end.y0 = sel_start.y0 + sel_start.ascent + info.y + info.metrics.y;
+ sel_end.y1 = sel_end.y0 + info.metrics.height;
+ sel_end.ascent = - info.metrics.y;
sel_end.from = info.line_from;
sel_end.to = info.line_to;
}
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)
{
- MInputMethod *im = input_method_table[idx];
+ 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, &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, &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);
}
Boolean
show_cursor (XtPointer client_data)
{
+ MFaceHLineProp *hline;
+ MFaceBoxProp *box;
+
if (cur.y0 < 0)
{
reseat (cur.from);
if (current_input_context)
set_input_method_spot ();
- {
- int pos = (SELECTEDP () ? mtext_property_start (selection)
- : cursor.from > 0 ? cursor.from - 1
- : cursor.from);
- MFace *face = mface ();
- MTextProperty *props[256];
- int n = mtext_get_properties (mt, pos, Mface, props, 256);
- int i;
- char buf[256], *p = buf;
- MSymbol sym;
-
- buf[0] = '\0';
- if (cursor.font)
- {
- int size = (int) mfont_get_prop (cursor.font, Msize);
- MSymbol family = mfont_get_prop (cursor.font, Mfamily);
- MSymbol weight = mfont_get_prop (cursor.font, Mweight);
- MSymbol style = mfont_get_prop (cursor.font, Mstyle);
- MSymbol registry = mfont_get_prop (cursor.font, Mregistry);
-
- sprintf (p, "%dpt", size / 10), p += strlen (p);
- if (family)
- strcat (p, ","), strcat (p, msymbol_name (family)), p += strlen (p);
- if (weight)
- strcat (p, ","), strcat (p, msymbol_name (weight)), p += strlen (p);
- if (style)
- strcat (p, ","), strcat (p, msymbol_name (style)), p += strlen (p);
- if (registry)
- strcat (p, ","), strcat (p, msymbol_name (registry)), p += strlen (p);
- p += strlen (p);
- }
+ if (nchars > 0)
+ {
+ int pos = (SELECTEDP () ? mtext_property_start (selection)
+ : cursor.from > 0 ? cursor.from - 1
+ : cursor.from);
+ MFace *face = mface ();
+ MTextProperty *props[256];
+ int n = mtext_get_properties (mt, pos, Mface, props, 256);
+ int i;
+ char buf[256], *p = buf;
+ MSymbol sym;
- mface_merge (face, face_default);
- for (i = 0; i < n; i++)
- if (props[i] != selection)
- mface_merge (face, (MFace *) mtext_property_value (props[i]));
- sym = (MSymbol) mface_get_prop (face, Mforeground);
- if (sym != Mnil)
- strcat (p, ","), strcat (p, msymbol_name (sym)), p += strlen (p);
- if ((MSymbol) mface_get_prop (face, Mvideomode) == Mreverse)
- strcat (p, ",rev"), p += strlen (p);
- if (mface_get_prop (face, Mhline))
- strcat (p, ",ul"), p += strlen (p);
- if (mface_get_prop (face, Mbox))
- strcat (p, ",box"), p += strlen (p);
- m17n_object_unref (face);
+ buf[0] = '\0';
+ if (cursor.font)
+ {
+ int size = (int) mfont_get_prop (cursor.font, Msize);
+ MSymbol family = mfont_get_prop (cursor.font, Mfamily);
+ MSymbol weight = mfont_get_prop (cursor.font, Mweight);
+ MSymbol style = mfont_get_prop (cursor.font, Mstyle);
+ MSymbol registry = mfont_get_prop (cursor.font, Mregistry);
+
+ sprintf (p, "%dpt", size / 10), p += strlen (p);
+ if (family)
+ strcat (p, ","), strcat (p, msymbol_name (family)), p += strlen (p);
+ if (weight)
+ strcat (p, ","), strcat (p, msymbol_name (weight)), p += strlen (p);
+ if (style)
+ strcat (p, ","), strcat (p, msymbol_name (style)), p += strlen (p);
+ if (registry)
+ strcat (p, ","), strcat (p, msymbol_name (registry)), p += strlen (p);
+ p += strlen (p);
+ }
- XtSetArg (arg[0], XtNborderWidth, 1);
- XtSetArg (arg[1], XtNlabel, buf);
- XtSetValues (CurFaceWidget, arg, 2);
- }
+ mface_merge (face, face_default);
+ for (i = 0; i < n; i++)
+ if (props[i] != selection)
+ mface_merge (face, (MFace *) mtext_property_value (props[i]));
+ sym = (MSymbol) mface_get_prop (face, Mforeground);
+ if (sym != Mnil)
+ strcat (p, ","), strcat (p, msymbol_name (sym)), p += strlen (p);
+ if ((MSymbol) mface_get_prop (face, Mvideomode) == Mreverse)
+ strcat (p, ",rev"), p += strlen (p);
+ hline = mface_get_prop (face, Mhline);
+ if (hline && hline->width > 0)
+ strcat (p, ",ul"), p += strlen (p);
+ box = mface_get_prop (face, Mbox);
+ if (box && box->width > 0)
+ strcat (p, ",box"), p += strlen (p);
+ m17n_object_unref (face);
+
+ XtSetArg (arg[0], XtNborderWidth, 1);
+ XtSetArg (arg[1], XtNlabel, buf);
+ XtSetValues (CurFaceWidget, arg, 2);
+ }
if (control.cursor_pos < nchars)
{
- MSymbol sym = Mnil;
+ MSymbol sym = mtext_get_prop (mt, control.cursor_pos, Mlanguage);
- if (control.cursor_pos > 0
- && mtext_ref_char (mt, control.cursor_pos - 1) != '\n')
- sym = mtext_get_prop (mt, control.cursor_pos - 1, Mlanguage);
- if (sym == Mnil)
- sym = mtext_get_prop (mt, control.cursor_pos, Mlanguage);
-
if (sym == Mnil)
{
XtSetArg (arg[0], XtNborderWidth, 0);
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)
select_input_method (i);
{
MDrawMetric rect;
MDrawGlyphInfo info;
- int old_y1, new_y1;
+ int y0, old_y1, new_y1;
int from, to;
+ int line_from = cursor.line_from;
if (n > 0)
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;
}
}
/* Now delete a character. */
mtext_del (mt, from, to);
- nchars--;
+ nchars -= to - from;
if (from >= top.from && from < top.to)
update_top (top.from);
update_cursor (from, 1);
+ y0 = cur.y0;
+ if (line_from != cursor.line_from)
+ y0 -= 1;
+
TEXT_EXTENTS (cur.from, bol (to, 1), rect);
new_y1 = cur.y0 + rect.height;
int n = mtext_len (newtext);
MDrawMetric rect;
int y0, old_y1, new_y1;
+ int line_from;
if (SELECTEDP ())
{
}
y0 = cur.y0;
+ if (cursor.line_from > 0
+ && mtext_ref_char (mt, cursor.line_from - 1) != '\n')
+ y0 -= control.min_line_descent;
+
TEXT_EXTENTS (cur.from, bol (cur.to - 1, 1), rect);
old_y1 = y0 + rect.height;
+ line_from = cursor.line_from;
+
/* Now insert chars. */
mtext_ins (mt, cursor.from, newtext);
nchars += n;
}
-/* Convert the currently selected text to COMPOUND-TEXT. It is called
- when someone requests the current value of the selection. */
+int
+word_constituent_p (int c)
+{
+ MSymbol category = (MSymbol) mchar_get_prop (c, Mcategory);
+ char *name = category != Mnil ? msymbol_name (category) : NULL;
+
+ return (name && (name[0] == 'L' || name[0] == 'M'));
+}
+
+
+void
+forward_word ()
+{
+ int pos = cursor.from;
+
+ while (pos < nchars && ! word_constituent_p (mtext_ref_char (mt, pos)))
+ pos++;
+ if (pos < nchars)
+ {
+ MTextProperty *prop = mtext_get_property (mt, pos, Mword);
+
+ if (prop)
+ pos = mtext_property_end (prop);
+ else
+ while (pos < nchars && word_constituent_p (mtext_ref_char (mt, pos)))
+ pos++;
+ }
+ update_cursor (pos, 0);
+}
+
+void
+backward_word ()
+{
+ int pos = cursor.from;
+
+ while (pos > 0 && ! word_constituent_p (mtext_ref_char (mt, pos - 1)))
+ pos--;
+ if (pos > 0)
+ {
+ MTextProperty *prop = mtext_get_property (mt, pos - 1, Mword);
+
+ if (prop)
+ pos = mtext_property_start (prop);
+ else
+ while (pos > 0 && word_constituent_p (mtext_ref_char (mt, pos - 1)))
+ pos--;
+ }
+ update_cursor (pos, 0);
+}
+
+
+/* Convert the currently selected text to UTF8-STRING or
+ COMPOUND-TEXT. It is called when someone requests the current
+ value of the selection. */
Boolean
covert_selection (Widget w, Atom *selection_atom,
Atom *target, Atom *return_type,
MText *this_mt = mtext ();
int from = mtext_property_start (selection);
int to = mtext_property_end (selection);
+ MSymbol coding;
+ int len;
mtext_copy (this_mt, 0, mt, from, to);
- *length = mconv_encode_buffer (msymbol ("compound-text"),
- this_mt, buf, 4096);
- *return_type = XA_COMPOUND_TEXT;
+ if (*target == XA_TEXT)
+ {
+#ifdef X_HAVE_UTF8_STRING
+ coding = Mcoding_utf_8;
+ *return_type = XA_UTF8_STRING;
+#else
+ coding = Mcoding_compound_text;
+ *return_type = XA_COMPOUND_TEXT;
+#endif
+ }
+ else if (*target == XA_UTF8_STRING)
+ {
+ coding = Mcoding_utf_8;
+ *return_type = XA_UTF8_STRING;
+ }
+ else if (*target == XA_STRING)
+ {
+ int i;
+
+ len = to - from;
+ for (i = 0; i < len; i++)
+ if (mtext_ref_char (this_mt, i) >= 0x100)
+ /* Can't encode in XA_STRING */
+ return False;
+ coding = Mcoding_iso_8859_1;
+ *return_type = XA_STRING;
+ }
+ else if (*target == XA_COMPOUND_TEXT)
+ {
+ coding = Mcoding_compound_text;
+ *return_type = XA_COMPOUND_TEXT;
+ }
+ else
+ return False;
+
+ len = mconv_encode_buffer (coding, this_mt, buf, 4096);
+ m17n_object_unref (this_mt);
+ if (len < 0)
+ return False;
+ *length = len;
*value = (XtPointer) buf;
*format = 8;
- m17n_object_unref (this_mt);
return True;
}
coding = Mnil;
else if (*type == XA_COMPOUND_TEXT)
coding = msymbol ("compound-text");
+#ifdef X_HAVE_UTF8_STRING
else if (*type == XA_UTF8_STRING)
coding = msymbol ("utf-8");
+#endif
else
goto err;
this_mt = mconv_decode_buffer (coding, (unsigned char *) value, *length);
+ if (! this_mt && *type != XA_UTF8_STRING)
+ {
+ XtGetSelectionValue (w, XA_PRIMARY, XA_UTF8_STRING, get_selection, NULL,
+ CurrentTime);
+ goto err;
+ }
if (this_mt)
{
hide_cursor ();
update_top (0);
update_cursor (0, 1);
redraw (0, win_height, 0, 1);
+ if (current_input_method >= 0)
+ {
+ int idx = current_input_method;
+
+ current_input_method = -1;
+ select_input_method (idx);
+ }
show_cursor (NULL);
}
else
redraw (sel_start.y0, sel_end.y1, 1, 0);
}
hide_cursor ();
+ if (current_input_context
+ && minput_filter (current_input_context, Minput_focus_move, NULL) == 0)
+ {
+ MText *produced = mtext ();
+
+ minput_lookup (current_input_context, Mnil, NULL, produced);
+ if (mtext_len (produced) > 0)
+ {
+ insert_chars (produced);
+ if (pos >= cursor.from)
+ pos += mtext_len (produced);
+ }
+ m17n_object_unref (produced);
+ }
update_cursor (pos, 0);
}
if (cursor.from == from)
{
- /* Start position of selection changed. */
- select_region (pos, to);
- if (pos > from)
- /* Shrunken. Previous selection face must be cleared. */
- redraw (start_y0, sel_start.y1, 1, 0);
+ /* Starting position changed. */
+ if (pos <= from)
+ {
+ /* Enlarged. We can simply overdraw. */
+ select_region (pos, to);
+ redraw (sel_start.y0, start_y1, 0, 0);
+ }
+ else if (pos < to)
+ {
+ /* Shrunken. Previous selection face must be cleared. */
+ select_region (pos, to);
+ redraw (start_y0, sel_start.y1, 1, 0);
+ }
+ else if (pos == to)
+ {
+ /* Shrunken to zero. */
+ XtDisownSelection (w, XA_PRIMARY, CurrentTime);
+ mtext_detach_property (selection);
+ redraw (start_y0, end_y1, 1, 0);
+ }
else
- /* Enlarged. We can simply overdraw. */
- redraw (sel_start.y0, start_y1, 0, 0);
+ {
+ /* Full update is necessary. */
+ select_region (to, pos);
+ redraw (start_y0, sel_end.y1, 1, 0);
+ }
}
else
{
- /* End position of selection changed. */
- select_region (from, pos);
- if (pos < to)
- /* Shrunken. Previous selection face must be cleared. */
- redraw (sel_end.y0, end_y1, 1, 0);
+ /* Ending position changed. */
+ if (pos < from)
+ {
+ /* Full update is necessary. */
+ select_region (pos, from);
+ redraw (sel_start.y0, end_y1, 1, 0);
+ }
+ else if (pos == from)
+ {
+ /* Shrunken to zero. */
+ XtDisownSelection (w, XA_PRIMARY, CurrentTime);
+ mtext_detach_property (selection);
+ redraw (start_y0, end_y1, 1, 0);
+ }
+ else if (pos < to)
+ {
+ /* Shrunken. Previous selection face must be cleared. */
+ select_region (from, pos);
+ redraw (sel_end.y0, end_y1, 1, 0);
+ }
else
- /* Enlarged. We can simply overdraw. */
- redraw (end_y0, sel_end.y1, 0, 0);
+ {
+ /* Enlarged. We can simply overdraw. */
+ select_region (from, pos);
+ redraw (end_y0, sel_end.y1, 0, 0);
+ }
}
}
else
}
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;
{
pos = bol (from - 1, 0);
GLYPH_INFO (pos, from - 1, info);
- if (height + info.this.height > win_height)
+ if (height + info.metrics.height > win_height)
break;
- height += info.this.height;
+ height += info.metrics.height;
from = info.line_from;
}
if (cursor_pos >= top.to)
while (cursor_pos < nchars)
{
GLYPH_INFO (pos, pos, info);
- if (height + info.this.height > win_height)
+ if (height + info.metrics.height > win_height)
break;
- height += info.this.height;
+ height += info.metrics.height;
cursor_pos = pos;
pos = info.line_to;
}
while (from < nchars)
{
GLYPH_INFO (from, from, info);
- if (height + info.this.height > win_height
+ if (height + info.metrics.height > win_height
|| info.line_to >= nchars)
break;
- height += info.this.height;
+ height += info.metrics.height;
from = info.line_to;
}
if (from == nchars)
/* 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)
ScrollProc (w, NULL, (XtPointer) -1);
break;
+ case XK_b:
+ if (key_event->state >= Mod1Mask)
+ {
+ lose_selection (NULL, NULL);
+ backward_word ();
+ break;
+ }
+
+ case XK_f:
+ if (key_event->state >= Mod1Mask)
+ {
+ lose_selection (NULL, NULL);
+ forward_word ();
+ break;
+ }
+
default:
if (ret > 0)
{
{
MText *temp = mtext ();
- mtext_cat_char (temp, buf[0] == '\r' ? '\n' : buf[0]);
+ mtext_cat_char (temp, buf[0] == '\r' ? '\n'
+ : ((unsigned char *) buf)[0]);
if (current_input_context)
mtext_put_prop (temp, 0, 1, Mlanguage,
current_input_context->im->language);
mtext_detach_property (selection);
}
- mconv_encode_stream (Mcoding_utf_8, mt, fp);
+ mconv_encode_stream (Mcoding_utf_8_full, mt, fp);
fclose (fp);
if (from >= 0)
select_region (from, to);
if (! fp)
FATAL_ERROR ("Can't read \"%s\"!\n", filename);
- mt = mconv_decode_stream (Mcoding_utf_8, fp);
+ mt = mconv_decode_stream (Mcoding_utf_8_full, fp);
fclose (fp);
if (! mt)
FATAL_ERROR ("Can't decode \"%s\" by UTF-8!\n", filename);
redraw (0, win_height, 1, 0);
}
-extern int line_break (MText *mt, int pos, int from, int to, int line, int y);
-
void
LineBreakProc (Widget w, XtPointer client_data, XtPointer call_data)
{
else
{
control.max_line_width = win_width;
- control.line_break = (data == 1 ? NULL : line_break);
+ control.line_break = (data == 1 ? NULL : mdraw_default_line_break);
}
for (i = 0; i < 3; i++)
{
}
void
+FilterProc (Widget w, XtPointer client_data, XtPointer call_data)
+{
+ char *filter_module = (char *) client_data;
+ void *handle;
+ void (*func) (MText *, int, int);
+
+ if (! SELECTEDP ())
+ return;
+ handle = dlopen (filter_module, RTLD_NOW);
+ if (! handle)
+ return;
+ *(void **) (&func) = dlsym (handle, "filter");
+ if (func)
+ (*func) (mt, mtext_property_start (selection),
+ mtext_property_end (selection));
+ dlclose (handle);
+}
+
+void
CursorProc (Widget w, XtPointer client_data, XtPointer call_data)
{
int data = (int) client_data;
XtSetValues (CursorMenus[i], arg, 1);
}
+ update_cursor (cursor.from, 0);
redraw (0, win_height, 1, 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
- select_input_method (idx);
- XtSetArg (arg[0], XtNleftBitmap, CheckPixmap);
- XtSetValues (InputMethodMenus[idx + 2], arg, 1);
+ {
+ select_input_method (idx);
+ }
}
+MPlist *default_face_list;
+
void
FaceProc (Widget w, XtPointer client_data, XtPointer call_data)
{
int from, to;
int old_y1;
+ hide_cursor ();
if (! SELECTEDP ())
- return;
+ {
+ MPlist *plist;
+
+ if (idx >= 0)
+ {
+ MFace *face = mframe_get_prop (frame, Mface);
+
+ for (plist = default_face_list; mplist_key (plist) != Mnil;
+ plist = mplist_next (plist))
+ mface_merge (face, mplist_value (plist));
+ mplist_add (plist, Mt, *face_table[idx].face);
+ mface_merge (face, *face_table[idx].face);
+ }
+ else if (mplist_key (mplist_next (default_face_list)) != Mnil)
+ {
+ MFace *face = mframe_get_prop (frame, Mface);
+
+ for (plist = default_face_list;
+ mplist_key (mplist_next (plist)) != Mnil;
+ plist = mplist_next (plist))
+ mface_merge (face, mplist_value (plist));
+ mplist_pop (plist);
+ }
+ update_top (0);
+ update_cursor (0, 1);
+ redraw (0, win_height, 1, 1);
+ show_cursor (NULL);
+ return;
+ }
XtAppAddWorkProc (context, show_cursor, NULL);
from = mtext_property_start (selection);
mdump = popen ("mdump -q", "w");
if (! mdump)
return;
- converter = mconv_stream_converter (Mcoding_utf_8, mdump);
+ converter = mconv_stream_converter (Mcoding_utf_8_full, mdump);
mconv_encode_range (converter, mt, from, to);
mconv_free_converter (converter);
fclose (mdump);
mtext_put_prop (ic->status, 0, mtext_len (ic->status),
Mlanguage, ic->im->language);
mdraw_text_extents (frame, ic->status, 0, mtext_len (ic->status),
- NULL, NULL, NULL, &rect);
- mdraw_text (frame, (MDrawWindow) input_status_pixmap,
- input_status_width - rect.width - 2, - rect.y,
- ic->status, 0, mtext_len (ic->status));
+ &input_status_control, NULL, NULL, &rect);
+ mdraw_text_with_control (frame, (MDrawWindow) input_status_pixmap,
+ input_status_width - rect.width - 2, - rect.y,
+ ic->status, 0, mtext_len (ic->status),
+ &input_status_control);
}
XtSetArg (arg[0], XtNbitmap, input_status_pixmap);
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)
{
- const MInputMethod *im1 = *(MInputMethod **) elt1;
- const MInputMethod *im2 = *(MInputMethod **) elt2;
+ const InputMethodInfo *im1 = elt1;
+ const InputMethodInfo *im2 = elt2;
MSymbol lang1, lang2;
if (im1->language == Mnil)
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)
+setup_input_methods (int with_xim, char *initial_input_method)
{
- MInputMethod *im = NULL;
- MInputXIMArgIM arg_xim;
MPlist *plist = mdatabase_list (msymbol ("input-method"), Mnil, Mnil, Mnil);
MPlist *pl;
- int i = 0;
-
- num_input_methods = mplist_length (plist);
+ int i;
+ num_input_methods = plist ? mplist_length (plist) : 0;
if (with_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++;
- }
- input_method_table = calloc (num_input_methods, sizeof (MInputMethod *));
- if (im)
- input_method_table[i++] = im;
- for (pl = plist; mplist_key (pl) != Mnil; pl = mplist_next (pl))
- {
- MDatabase *mdb = mplist_value (pl);
- MSymbol *tag = mdatabase_tag (mdb);
+ num_input_methods++;
+ input_method_table = calloc (num_input_methods, sizeof (InputMethodInfo));
- if (tag[1] != Mnil)
+ i = 0;
+ if (plist)
+ {
+ for (pl = plist; mplist_key (pl) != Mnil; pl = mplist_next (pl), i++)
{
- im = minput_open_im (tag[1], tag[2], NULL);
- if (im)
- input_method_table[i++] = im;
+ MDatabase *mdb = mplist_value (pl);
+ MSymbol *tag = mdatabase_tag (mdb);
+
+ if (tag[2] == Mnil)
+ i--, num_input_methods--;
+ else
+ {
+ input_method_table[i].language = tag[1];
+ input_method_table[i].name = tag[2];
+ }
}
+ m17n_object_unref (plist);
+ }
+ if (with_xim)
+ {
+ input_method_table[i].language = Mnil;
+ input_method_table[i].name = msymbol ("xim");
+ i++;
}
- m17n_object_unref (plist);
- num_input_methods = 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;
+
+ if (initial_input_method)
+ {
+ char *lang_name, *method_name;
+ char *p = strchr (initial_input_method, '-');
+
+ if (p && p[1])
+ lang_name = initial_input_method, *p = '\0', method_name = p + 1;
+ else
+ lang_name = "t", method_name = initial_input_method;
- 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);
+ 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;
+ }
+ }
}
m17n_object_unref (mt);
if (fp)
{
- mt = mconv_decode_stream (Mcoding_utf_8, fp);
+ mt = mconv_decode_stream (Mcoding_utf_8_full, fp);
fclose (fp);
if (! mt)
mt = mtext ();
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}
};
printf ("Display FILE on a window and allow users to edit it.\n");
printf ("XT-OPTIONs are standard Xt arguments (e.g. -fn, -fg).\n");
printf ("The following OPTIONs are available.\n");
+ printf (" %-13s\n\t\t%s", "--fontset FONTSET",
+ "Use the specified fontset\n");
+ printf (" %-13s %s", "-s SIZE", "Font size in 1/10 point (default 120).\n");
+ printf (" %-13s\n\t\t%s", "--im INPUT-METHOD",
+ "Input method activated initially.\n");
printf (" %-13s %s", "--version", "print version number\n");
printf (" %-13s %s", "-h, --help", "print this message\n");
+
exit (exit_code);
}
{
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;
/* Translation table for TextWidget. */
String trans = "<Expose>: Expose()\n\
<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 font_width, font_ascent, font_descent;
int with_xim = 0;
int i, j;
+ char *filter = NULL;
+ MFont *font = NULL;
setlocale (LC_ALL, "");
/* Create the top shell. */
XtSetLanguageProc (NULL, NULL, NULL);
- ShellWidget = XtOpenApplication (&context, "MEdit", NULL, 0, &argc, argv,
+ ShellWidget = XtOpenApplication (&context, "M17NEdit", NULL, 0, &argc, argv,
NULL, sessionShellWidgetClass, NULL, 0);
display = XtDisplay (ShellWidget);
screen = XScreenNumberOfScreen (XtScreen (ShellWidget));
help_exit (argv[0], 0);
else if (! strcmp (argv[i], "--version"))
{
- printf ("medit (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"))
if (sscanf (argv[i], "%dx%d", &col, &row) != 2)
help_exit (argv[0], 1);
}
+ else if (! strcmp (argv[i], "-s"))
+ {
+ i++;
+ fontsize = atoi (argv[i]);
+ if (fontsize < 0)
+ fontsize = 120;
+ }
else if (! strcmp (argv[i], "--fontset"))
{
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++;
+ initial_input_method = strdup (argv[i]);
+ }
else if (! strcmp (argv[i], "--with-xim"))
{
with_xim = 1;
}
+ else if (! strcmp (argv[i], "--filter"))
+ {
+ i++;
+ filter = argv[i];
+ }
else if (argv[i][0] != '-')
{
filename = strdup (argv[i]);
}
else
{
- fprintf (stderr, "Unknown option: %s", argv[i]);
+ fprintf (stderr, "Unknown option: %s\n", argv[i]);
help_exit (argv[0], 1);
}
}
if (! filename)
- help_exit (argv[0], 1);
+ filename = strdup ("/dev/null");
mdatabase_dir = ".";
/* Initialize the m17n library. */
M17N_INIT ();
if (merror_code != MERROR_NONE)
FATAL_ERROR ("%s\n", "Fail to initialize the m17n library!");
+ minput_driver = &minput_gui_driver;
mt = read_file (filename);
serialized = 0;
nchars = mtext_len (mt);
+ Mword = msymbol ("word");
+
{
MFace *face = mface ();
- mface_put_prop (face, Mbackground, msymbol ("blue"));
- mface_put_prop (face, Mforeground, msymbol ("yellow"));
+ mface_put_prop (face, Mforeground, msymbol ("blue"));
+ mface_put_prop (face, Mbackground, msymbol ("yellow"));
+ mface_put_prop (face, Mvideomode, Mreverse);
selection = mtext_property (Mface, face, MTEXTPROP_NO_MERGE);
m17n_object_unref (face);
}
XA_TEXT = XInternAtom (display, "TEXT", False);
XA_COMPOUND_TEXT = XInternAtom (display, "COMPOUND_TEXT", False);
XA_UTF8_STRING = XInternAtom (display, "UTF8_STRING", False);
+ Mcoding_compound_text = mconv_resolve_coding (msymbol ("compound-text"));
+ if (Mcoding_compound_text == Mnil)
+ FATAL_ERROR ("%s\n", "Don't know about COMPOUND-TEXT encoding!");
+
{
MPlist *plist = mplist ();
- MFace *face;
MFont *font;
mplist_put (plist, msymbol ("widget"), ShellWidget);
- if (fontset_name)
+ if (fontset_name || font_name || fontsize > 0)
{
- MFontset *fontset = mfontset (fontset_name);
-
- face = mface ();
- mface_put_prop (face, Mfontset, fontset);
- 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);
}
frame = mframe (plist);
+ if (! frame)
+ FATAL_ERROR ("%s\n", "Fail to create a frame!");
m17n_object_unref (plist);
- face_default = (MFace *) mframe_get_prop (frame, Mface);
+ face_default = mface_copy ((MFace *) mframe_get_prop (frame, Mface));
+ default_face_list = mplist ();
+ mplist_add (default_face_list, Mt, face_default);
face_default_fontset = mface ();
mface_put_prop (face_default_fontset, Mfontset,
mface_get_prop (face_default, Mfontset));
mface_put_prop (face_dv_ttyogesh, Mfamily, msymbol ("dv-ttyogesh"));
face_freesans = mface ();
mface_put_prop (face_freesans, Mfamily, msymbol ("freesans"));
+ face_freeserif = mface ();
+ mface_put_prop (face_freeserif, Mfamily, msymbol ("freeserif"));
face_freemono = mface ();
mface_put_prop (face_freemono, Mfamily, msymbol ("freemono"));
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);
free (tib_font);
}
- setup_input_methods (with_xim);
+ setup_input_methods (with_xim, initial_input_method);
gc = DefaultGC (display, screen);
SetMenu (menus[1], 0, "auto", NULL, InputMethodProc, -1, 0);
for (i = 0; i < num_input_methods; i++)
{
- MInputMethod *im = input_method_table[i];
+ InputMethodInfo *im = input_method_table + i;
char *name1, *name2;
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
for (i = 0; i < num_input_methods + 2; i++)
InputMethodMenus[i] = menus[i].w;
+ if (filter)
+ {
+ SetMenu (menus[0], 0, filter, NULL, FilterProc, filter, 0);
+ w = create_menu_button (ShellWidget, HeadWidget, w, "Filter",
+ "Filter Menu", menus, 1,
+ "Select filter to run");
+ }
+
input_status_width = font_width * 8;
input_status_height = (font_ascent + font_descent) * 2.4;
input_status_pixmap = XCreatePixmap (display, RootWindow (display, screen),
= prop.color_left = prop.color_right = Mnil;
prop.inner_hmargin = prop.inner_vmargin = 1;
prop.outer_hmargin = prop.outer_vmargin = 0;
- face_input_status = mface ();
+ face_input_status = mface_copy (face_default);
mface_put_prop (face_input_status, Mbox, &prop);
}
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];
- if (c >= 'A' && c <= 'Z')
+ if (c >= 'a' && c <= 'z')
{
- int idx = (c < 'U') ? (c - 'A') / 2 : 10;
+ int idx = (c < 'u') ? (c - 'a') / 2 : 10;
pl = plist[idx];
if (! pl)
for (i = 0; i < 11; i++)
if (plist[i])
{
- char *name = malloc (9);
+ char *name = alloca (9);
sprintf (name, "Menu %c-%c", 'A' + i * 2, 'A' + i * 2 + 1);
if (i == 10)
memset (&control, 0, sizeof control);
control.two_dimensional = 1;
control.enable_bidi = 1;
+ control.anti_alias = 1;
control.min_line_ascent = font_ascent;
control.min_line_descent = font_descent;
control.max_line_width = win_width;
control.partial_update = 1;
control.ignore_formatting_char = 1;
+ memset (&input_status_control, 0, sizeof input_status_control);
+ input_status_control.enable_bidi = 1;
+
XtAppAddActions (context, actions, XtNumber (actions));
XtRealizeWidget (ShellWidget);
if (current_input_context)
minput_destroy_ic (current_input_context);
for (i = 0; i < num_input_methods; i++)
- minput_close_im (input_method_table[i]);
+ if (input_method_table[i].im)
+ minput_close_im (input_method_table[i].im);
m17n_object_unref (frame);
-
m17n_object_unref (mt);
m17n_object_unref (face_xxx_large);
m17n_object_unref (face_box);
m17n_object_unref (face_times);
m17n_object_unref (face_dv_ttyogesh);
m17n_object_unref (face_freesans);
+ m17n_object_unref (face_freeserif);
m17n_object_unref (face_freemono);
m17n_object_unref (face_default_fontset);
m17n_object_unref (face_no_ctl_fontset);
m17n_object_unref (face_input_status);
+ m17n_object_unref (face_default);
+ m17n_object_unref (default_face_list);
m17n_object_unref (selection);
+ if (font)
+ free (font);
- M17N_FINI ();
-
- free (fontset_name);
-
+ XFreeGC (display, mono_gc);
+ XFreeGC (display, mono_gc_inv);
+ XFreeGC (display, gc_inv);
XtUninstallTranslations (form);
XtUninstallTranslations (TextWidget);
XtDestroyWidget (ShellWidget);
XtDestroyApplicationContext (context);
+ M17N_FINI ();
+
+ free (font_name);
+ free (fontset_name);
+ free (filename);
+ free (input_method_table);
+ free (InputMethodMenus);
+
exit (0);
}
+
+#else /* not HAVE_X11_XAW_COMMAND_H */
+
+int
+main (int argc, char **argv)
+{
+ fprintf (stderr,
+ "Building of this program failed (lack of some header files)\n");
+ exit (1);
+}
+
+#endif /* not HAVE_X11_XAW_COMMAND_H */
+
#endif /* not FOR_DOXYGEN */