X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=example%2Fmedit.c;h=63701cae3a03c6a50de22d15e164690580097173;hb=25f86deb0d70cf889849019fa18adfc76573ee22;hp=37ced117cc29c522823acc792b6057de94496016;hpb=73d4dd23b8a0e408c5d5287bd8b0bfa8beb12924;p=m17n%2Fm17n-lib.git diff --git a/example/medit.c b/example/medit.c index 37ced11..63701ca 100644 --- a/example/medit.c +++ b/example/medit.c @@ -21,13 +21,13 @@ 02111-1307, USA. */ /***en - @enpage 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. @@ -48,18 +48,18 @@ 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 Outout Method), not + for direct use from application programs. */ /***ja - @japage medit ¿¸À¸ì¥Æ¥­¥¹¥È¤ÎÊÔ½¸ + @japage m17n-edit ¿¸À¸ì¥Æ¥­¥¹¥È¤ÎÊÔ½¸ - @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 FILE ¤ò¥¦¥£¥ó¥É¥¦¤Ëɽ¼¨¤·¡¢¥æ¡¼¥¶¤¬ÊÔ½¸¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë¡£ @@ -79,10 +79,10 @@ - ¤³¤Î¥×¥í¥°¥é¥à¤Ï m17n GUI API ¤Î»È¤¤Êý¤ò¼¨¤¹¤â¤Î¤Ç¤¢¤ë¡£medit ¤Ïľ - ÀÜ GUI API ¤ò»È¤Ã¤Æ¤¤¤ë¤¬¡¢¤³¤Î API ¤Ï¼ç¤Ë¥Ä¡¼¥ë¥­¥Ã¥È¥é¥¤¥Ö¥é¥ê¤ä - XOM (X Outout Method) ¤Î¼ÂÁõÍѤǤ¢¤ê¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é ¥à - ¤«¤é¤ÎľÀܤÎÍøÍѤò°Õ¿Þ¤·¤Æ¤¤¤Ê¤¤¡£ + ¤³¤Î¥×¥í¥°¥é¥à¤Ï m17n GUI API ¤Î»È¤¤Êý¤ò¼¨¤¹¤â¤Î¤Ç¤¢¤ë¡£m17n-edit + ¤ÏľÀÜ GUI API ¤ò»È¤Ã¤Æ¤¤¤ë¤¬¡¢¤³¤Î API ¤Ï¼ç¤Ë¥Ä¡¼¥ë¥­¥Ã¥È¥é¥¤¥Ö¥é + ¥ê¤äXOM (X Outout Method) ¤Î¼ÂÁõÍѤǤ¢¤ê¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é + ¥à¤«¤é¤ÎľÀܤÎÍøÍѤò°Õ¿Þ¤·¤Æ¤¤¤Ê¤¤¡£ */ #ifndef FOR_DOXYGEN @@ -95,12 +95,22 @@ #include #include #include +#include #include #include #include #include #include + +#include +#include +#include + +#include + +#ifdef HAVE_X11_XAW_COMMAND_H + #include #include #include @@ -112,11 +122,7 @@ #include #include -#include -#include -#include - -#define VERSION "1.1" +#define VERSION "1.2.0" /* Global variables. */ @@ -172,6 +178,8 @@ int nchars; /* == mtext_len (mt) */ MDrawControl control, input_status_control; MTextProperty *selection; +MSymbol Mword; + MFace *face_default; MFace *face_xxx_large; MFace *face_box; @@ -490,7 +498,7 @@ redraw_cursor (int clear) /* 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) @@ -795,14 +803,8 @@ show_cursor (XtPointer client_data) 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); @@ -902,8 +904,9 @@ delete_char (int n) { 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; @@ -942,6 +945,10 @@ delete_char (int n) 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; @@ -956,6 +963,7 @@ insert_chars (MText *newtext) int n = mtext_len (newtext); MDrawMetric rect; int y0, old_y1, new_y1; + int line_from; if (SELECTEDP ()) { @@ -966,9 +974,15 @@ insert_chars (MText *newtext) } 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; @@ -984,6 +998,57 @@ insert_chars (MText *newtext) } +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. */ @@ -1184,6 +1249,20 @@ ButtonProc (Widget w, XEvent *event, String *str, Cardinal *num) redraw (sel_start.y0, sel_end.y1, 1, 0); } hide_cursor (); + if (current_input_context) + { + MText *produced = mtext (); + + minput_reset_ic (current_input_context); + 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); } @@ -1575,6 +1654,22 @@ KeyProc (Widget w, XEvent *event, String *str, Cardinal *num) 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) { @@ -1721,8 +1816,6 @@ BidiProc (Widget w, XtPointer client_data, XtPointer call_data) 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) { @@ -1734,7 +1827,7 @@ 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++) { @@ -1750,6 +1843,25 @@ LineBreakProc (Widget w, XtPointer client_data, XtPointer call_data) } 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; @@ -2038,7 +2150,7 @@ setup_input_methods (int with_xim, char *initial_input_method) method_name = initial_input_method; } - num_input_methods = mplist_length (plist); + num_input_methods = plist ? mplist_length (plist) : 0; if (with_xim) { @@ -2063,20 +2175,23 @@ setup_input_methods (int with_xim, char *initial_input_method) i++; } - for (pl = plist; mplist_key (pl) != Mnil; pl = mplist_next (pl)) + if (plist) { - MDatabase *mdb = mplist_value (pl); - MSymbol *tag = mdatabase_tag (mdb); - - if (tag[1] != Mnil) + for (pl = plist; mplist_key (pl) != Mnil; pl = mplist_next (pl)) { - input_method_table[i].language = tag[1]; - input_method_table[i].name = tag[2]; - i++; + MDatabase *mdb = mplist_value (pl); + MSymbol *tag = mdatabase_tag (mdb); + + if (tag[1] != Mnil) + { + input_method_table[i].language = tag[1]; + input_method_table[i].name = tag[2]; + i++; + } } - } - m17n_object_unref (plist); + m17n_object_unref (plist); + } num_input_methods = i; qsort (input_method_table, num_input_methods, sizeof input_method_table[0], compare_input_method); @@ -2403,11 +2518,12 @@ main (int argc, char **argv) int font_width, font_ascent, font_descent; int with_xim = 0; int i, j; + char *filter = 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)); @@ -2420,7 +2536,7 @@ main (int argc, char **argv) help_exit (argv[0], 0); else if (! strcmp (argv[i], "--version")) { - printf ("medit (m17n library) %s\n", VERSION); + printf ("m17n-edit (m17n library) %s\n", VERSION); printf ("Copyright (C) 2003 AIST, JAPAN\n"); exit (0); } @@ -2451,6 +2567,11 @@ main (int argc, char **argv) { with_xim = 1; } + else if (! strcmp (argv[i], "--filter")) + { + i++; + filter = argv[i]; + } else if (argv[i][0] != '-') { filename = strdup (argv[i]); @@ -2462,19 +2583,22 @@ main (int argc, char **argv) } } 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 (); @@ -2732,6 +2856,14 @@ main (int argc, char **argv) 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), @@ -2826,9 +2958,9 @@ main (int argc, char **argv) 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) @@ -2970,4 +3102,17 @@ main (int argc, char **argv) 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 */