#include <m17n-misc.h>
#include <m17n-X.h>
-#define VERSION "1.0.1"
+#define VERSION "1.1"
/* Global variables. */
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. */
typedef struct {
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;
}
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 (from < nchars && y + info.metrics.height <= y0)
{
- y += info.this.height;
+ y += info.metrics.height;
from = info.line_to;
GLYPH_INFO (from, from, info);
}
- y0 = y - info.this.y;
+ 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;
if (control.orientation_reversed)
x += win_width - cursor.logical_width;
- CLEAR_AREA (x, cur.y0, cursor.logical_width, cursor.this.height);
+ CLEAR_AREA (x, cur.y0, cursor.logical_width, cursor.metrics.height);
}
DRAW_TEXT (cursor.x, cur.y0 + cur.ascent, cursor.from, cursor.to);
}
{
/* 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;
}
sel_start.ascent = - rect.y;
GLYPH_INFO (pos, from, info);
if (pos < info.line_from)
- sel_start.y0 += - rect.y + info.y + info.this.y;
+ 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.y0 = top.ascent + info.y + info.metrics.y;
}
- sel_start.ascent = -info.this.y;
- sel_start.y1 = sel_start.y0 + info.this.height;
+ 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;
- 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
{
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;
}
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);
- 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);
+ 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)
{
/* 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);
}
-/* Convert the currently selected text to COMPOUND-TEXT. It is called
- when someone requests the current value of the selection. */
+/* 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;
+ 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)
+ select_input_method (idx);
+ else
+ input_method_table[idx].available = -1;
+ }
show_cursor (NULL);
}
else
{
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)
XtSetValues (CursorMenus[i], arg, 1);
}
+ update_cursor (cursor.from, 0);
redraw (0, win_height, 1, 0);
}
}
void
-setup_input_methods (int with_xim)
+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;
+ }
num_input_methods = mplist_length (plist);
(void *) input_status);
mplist_put (minput_driver->callback_list, Minput_status_done,
(void *) input_status);
+
+ 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;
+ }
}
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;
+ int fontsize = 120;
+ char *initial_input_method = NULL;
int col = 80, row = 32;
/* Translation table for TextWidget. */
String trans = "<Expose>: Expose()\n\
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], "--im"))
+ {
+ i++;
+ initial_input_method = strdup (argv[i]);
+ }
else if (! strcmp (argv[i], "--with-xim"))
{
with_xim = 1;
}
else
{
- fprintf (stderr, "Unknown option: %s", argv[i]);
+ fprintf (stderr, "Unknown option: %s\n", argv[i]);
help_exit (argv[0], 1);
}
}
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 || fontsize != 120)
{
MFontset *fontset = mfontset (fontset_name);
face = mface ();
mface_put_prop (face, Mfontset, fontset);
+ mface_put_prop (face, Msize, (void *) fontsize);
m17n_object_unref (fontset);
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_copy ((MFace *) mframe_get_prop (frame, Mface));
default_face_list = mplist ();
free (tib_font);
}
- setup_input_methods (with_xim);
+ setup_input_methods (with_xim, initial_input_method);
gc = DefaultGC (display, screen);
m17n_object_unref (default_face_list);
m17n_object_unref (selection);
- M17N_FINI ();
-
- free (fontset_name);
- free (filename);
- free (input_method_table);
- free (InputMethodMenus);
-
XFreeGC (display, mono_gc);
XFreeGC (display, mono_gc_inv);
XFreeGC (display, gc_inv);
XtDestroyWidget (ShellWidget);
XtDestroyApplicationContext (context);
+ M17N_FINI ();
+
+ free (fontset_name);
+ free (filename);
+ free (input_method_table);
+ free (InputMethodMenus);
+
exit (0);
}
#endif /* not FOR_DOXYGEN */