(moduledir): Use ${libdir} instead of ${exec_prefix}/lib.
[m17n/m17n-lib.git] / example / medit.c
index 6c4bf3f..fe6fad2 100644 (file)
@@ -1,5 +1,5 @@
 /* medit.c -- simple multilingual editor.              -*- coding: euc-jp; -*-
 /* medit.c -- simple multilingual editor.              -*- coding: euc-jp; -*-
-   Copyright (C) 2003, 2004, 2005
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
@@ -17,7 +17,7 @@
 
    You should have received a copy of the GNU Lesser General Public
    License along with the m17n library; if not, write to the Free
 
    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
    02111-1307, USA.  */
 
 /***en
@@ -49,7 +49,7 @@
 
     This program is to demonstrate how to use the m17n GUI API.
     Although m17n-edit directly uses the GUI API, the API is mainly
 
     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
     for direct use from application programs.
 */
 /***ja
@@ -81,7 +81,7 @@
 
     ¤³¤Î¥×¥í¥°¥é¥à¤Ï m17n GUI API ¤Î»È¤¤Êý¤ò¼¨¤¹¤â¤Î¤Ç¤¢¤ë¡£m17n-edit
     ¤ÏľÀÜ GUI API ¤ò»È¤Ã¤Æ¤¤¤ë¤¬¡¢¤³¤Î API ¤Ï¼ç¤Ë¥Ä¡¼¥ë¥­¥Ã¥È¥é¥¤¥Ö¥é
 
     ¤³¤Î¥×¥í¥°¥é¥à¤Ï 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>
 
 #include <X11/Xaw/SmeLine.h>
 #include <X11/Xaw/MenuButton.h>
 
-#define VERSION "1.2.0"
-
 /* Global variables.  */
 
 char *filename;
 /* Global variables.  */
 
 char *filename;
@@ -173,6 +171,7 @@ Pixmap CheckPixmap;
 MFrame *frame;
 MText *mt;
 int nchars;                    /* == mtext_len (mt) */
 MFrame *frame;
 MText *mt;
 int nchars;                    /* == mtext_len (mt) */
+int mt_modified;
 MDrawControl control, input_status_control;
 MTextProperty *selection;
 
 MDrawControl control, input_status_control;
 MTextProperty *selection;
 
@@ -200,7 +199,9 @@ InputMethodInfo *input_method_table;
 
 int num_input_methods;
 int current_input_method = -1; /* i.e. none */
 
 int num_input_methods;
 int current_input_method = -1; /* i.e. none */
+int unicode_input_method = -1;
 int auto_input_method = 0;
 int auto_input_method = 0;
+int saved_input_method = -3;
 MInputContext *current_input_context;
 
 struct FaceRec
 MInputContext *current_input_context;
 
 struct FaceRec
@@ -257,7 +258,7 @@ struct LineInfo
 {
   int from;                    /* BOL position of the line.  */
   int to;                      /* BOL position of the next line.  */
 {
   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.  */
 };
 
   int ascent;                  /* Height of the top Y position.  */
 };
 
@@ -352,12 +353,8 @@ update_scroll_bar (int from, int to)
 {
   float top = (float) from / nchars;
   float shown = (float) (to - from) / nchars;
 {
   float top = (float) from / nchars;
   float shown = (float) (to - from) / nchars;
-  XtArgVal *l_top = (XtArgVal *) &top;
-  XtArgVal *l_shown = (XtArgVal *) &shown;
 
 
-  XtSetArg (arg[0], XtNtopOfThumb, *l_top);
-  XtSetArg (arg[1], XtNshown, *l_shown);
-  XtSetValues (SbarWidget, arg, 2);
+  XawScrollbarSetThumb (SbarWidget, top, shown);
 }
 
 
 }
 
 
@@ -508,6 +505,7 @@ update_cursor (int pos, int full)
 {
   MDrawMetric rect;
 
 {
   MDrawMetric rect;
 
+  control.cursor_pos = pos;
   if (full)
     {
       /* CUR is inaccurate.  We can trust only TOP.  */
   if (full)
     {
       /* CUR is inaccurate.  We can trust only TOP.  */
@@ -864,8 +862,8 @@ show_cursor (XtPointer client_data)
       else
        {
          XtSetArg (arg[0], XtNborderWidth, 1);
       else
        {
          XtSetArg (arg[0], XtNborderWidth, 1);
-         XtSetArg (arg[1], XtNlabel,
-                   msymbol_name (msymbol_get (sym, Mlanguage)));
+         sym = mlanguage_name (sym);
+         XtSetArg (arg[1], XtNlabel, msymbol_name (sym));
          XtSetValues (CurLangWidget, arg, 2);
        }
       XtSetValues (CurLangWidget, arg, 2);
          XtSetValues (CurLangWidget, arg, 2);
        }
       XtSetValues (CurLangWidget, arg, 2);
@@ -1281,7 +1279,7 @@ ButtonProc (Widget w, XEvent *event, String *str, Cardinal *num)
     {
       MText *produced = mtext ();
 
     {
       MText *produced = mtext ();
 
-          minput_lookup (current_input_context, Mnil, NULL, produced);
+      minput_lookup (current_input_context, Mnil, NULL, produced);
       if (mtext_len (produced) > 0)
        {
          insert_chars (produced);
       if (mtext_len (produced) > 0)
        {
          insert_chars (produced);
@@ -1550,6 +1548,7 @@ JumpProc (Widget w, XtPointer client_data, XtPointer persent_ptr)
   update_cursor (pos1, 1);
 }
 
   update_cursor (pos1, 1);
 }
 
+static void InputMethodProc (Widget, XtPointer, XtPointer);
 
 static void
 KeyProc (Widget w, XEvent *event, String *str, Cardinal *num)
 
 static void
 KeyProc (Widget w, XEvent *event, String *str, Cardinal *num)
@@ -1561,15 +1560,26 @@ KeyProc (Widget w, XEvent *event, String *str, Cardinal *num)
   /* If set to 1, do not update target_x_position.  */
   int keep_target_x_position = 0;
   MText *produced;
   /* 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))
   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;
 
   if (event->type == KeyRelease)
     return;
 
-  hide_cursor ();
-
   produced = mtext ();
   ret = minput_lookup (current_input_context, Mnil, event, produced);
   if (mtext_len (produced) > 0)
   produced = mtext ();
   ret = minput_lookup (current_input_context, Mnil, event, produced);
   if (mtext_len (produced) > 0)
@@ -1578,6 +1588,12 @@ KeyProc (Widget w, XEvent *event, String *str, Cardinal *num)
     ret = XLookupString (key_event, buf, sizeof (buf), &keysym, NULL);
   m17n_object_unref (produced);
 
     ret = XLookupString (key_event, buf, sizeof (buf), &keysym, NULL);
   m17n_object_unref (produced);
 
+  if (saved_input_method > -3)
+    {
+      InputMethodProc (w, (XtPointer) saved_input_method, NULL);
+      saved_input_method = -3;
+    }
+
   switch (keysym)
     {
     case XK_Delete:
   switch (keysym)
     {
     case XK_Delete:
@@ -1746,6 +1762,14 @@ KeyProc (Widget w, XEvent *event, String *str, Cardinal *num)
              redraw (0, win_height, 1, 1);
              return;
            }
              redraw (0, win_height, 1, 1);
              return;
            }
+         else if (buf[0] == '='
+                  && (event->xkey.state & ControlMask)
+                  && unicode_input_method >= 0)
+           {
+             saved_input_method = current_input_method;
+             InputMethodProc (w, (XtPointer) unicode_input_method, NULL);
+             minput_filter (current_input_context, msymbol ("C-u"), NULL);
+           }
          else
            {
              MText *temp = mtext ();
          else
            {
              MText *temp = mtext ();
@@ -1917,7 +1941,7 @@ FilterProc (Widget w, XtPointer client_data, XtPointer call_data)
   handle = dlopen (filter_module, RTLD_NOW);
   if (! handle)
     return;
   handle = dlopen (filter_module, RTLD_NOW);
   if (! handle)
     return;
-  *(void **) (&func) = dlsym (handle, "filter");
+  func = (void (*) (MText *, int, int)) dlsym (handle, "filter");
   if (func)
     (*func) (mt, mtext_property_start (selection),
             mtext_property_end (selection));
   if (func)
     (*func) (mt, mtext_property_start (selection),
             mtext_property_end (selection));
@@ -2173,7 +2197,7 @@ surrounding_text_handler (MInputContext *ic, MSymbol command)
     {
       int len = (int) mplist_value (ic->plist);
       int pos;
     {
       int len = (int) mplist_value (ic->plist);
       int pos;
-      MText *surround = NULL;
+      MText *surround;
 
       if (len < 0)
        {
 
       if (len < 0)
        {
@@ -2189,11 +2213,10 @@ surrounding_text_handler (MInputContext *ic, MSymbol command)
            pos = nchars;
          surround = mtext_duplicate (mt, cursor.from, pos);
        }
            pos = nchars;
          surround = mtext_duplicate (mt, cursor.from, pos);
        }
-      if (surround)
-       {
-         mplist_set (ic->plist, Mtext, surround);
-         m17n_object_unref (surround);
-       }
+      else
+       surround = mtext ();
+      mplist_set (ic->plist, Mtext, surround);
+      m17n_object_unref (surround);
     }
   else if (command == Minput_delete_surrounding_text)
     {
     }
   else if (command == Minput_delete_surrounding_text)
     {
@@ -2204,13 +2227,19 @@ surrounding_text_handler (MInputContext *ic, MSymbol command)
          if (cursor.from + len < 0)
            len = - cursor.from;
          mtext_del (mt, cursor.from + len, cursor.from);
          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);
        }
       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;
     }
 }
 
     }
 }
 
@@ -2229,8 +2258,8 @@ compare_input_method (const void *elt1, const void *elt2)
     return 1;
   if (im2->language == Mt)
     return -1;
     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));
 }
 
   return strcmp (msymbol_name (lang1), msymbol_name (lang2));
 }
 
@@ -2240,6 +2269,7 @@ setup_input_methods (int with_xim, char *initial_input_method)
   MPlist *plist = mdatabase_list (msymbol ("input-method"), Mnil, Mnil, Mnil);
   MPlist *pl;
   int i;
   MPlist *plist = mdatabase_list (msymbol ("input-method"), Mnil, Mnil, Mnil);
   MPlist *pl;
   int i;
+  MSymbol Municode = msymbol ("unicode");
 
   num_input_methods = plist ? mplist_length (plist) : 0;
   if (with_xim)
 
   num_input_methods = plist ? mplist_length (plist) : 0;
   if (with_xim)
@@ -2273,16 +2303,23 @@ setup_input_methods (int with_xim, char *initial_input_method)
 
   qsort (input_method_table, num_input_methods, sizeof input_method_table[0],
         compare_input_method);
 
   qsort (input_method_table, num_input_methods, sizeof input_method_table[0],
         compare_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);
-  mplist_put (minput_driver->callback_list, Minput_get_surrounding_text,
-             (void *) surrounding_text_handler);
-  mplist_put (minput_driver->callback_list, Minput_delete_surrounding_text,
-             (void *) surrounding_text_handler);
+  for (i = 0; i < num_input_methods; i++)
+    if (input_method_table[i].language == Mt
+       && input_method_table[i].name == Municode)
+      {
+       unicode_input_method = i;
+       break;
+      }
+  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;
 
   current_input_context = NULL;
   current_input_method = -1;
@@ -2488,7 +2525,8 @@ create_menu_button (Widget top, Widget parent, Widget left, char *button_name,
   XtSetArg (arg[3], XtNhighlightThickness, 1);
   XtSetArg (arg[4], XtNleft, XawChainLeft);
   XtSetArg (arg[5], XtNright, XawChainLeft);
   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,
   if (left)
     XtSetArg (arg[i], XtNfromHoriz, left), i++;
   button = XtCreateManagedWidget (button_name, menuButtonWidgetClass, parent,
@@ -2584,6 +2622,7 @@ main (int argc, char **argv)
 {
   Widget form, BodyWidget, w;
   char *fontset_name = NULL;
 {
   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;
   int fontsize = 0;
   char *initial_input_method = NULL;
   int col = 80, row = 32;
@@ -2615,6 +2654,7 @@ main (int argc, char **argv)
   int with_xim = 0;
   int i, j;
   char *filter = NULL;
   int with_xim = 0;
   int i, j;
   char *filter = NULL;
+  MFont *font = NULL;
 
   setlocale (LC_ALL, "");
   /* Create the top shell.  */
 
   setlocale (LC_ALL, "");
   /* Create the top shell.  */
@@ -2632,8 +2672,8 @@ main (int argc, char **argv)
        help_exit (argv[0], 0);
       else if (! strcmp (argv[i], "--version"))
        {
        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, 2008 AIST, JAPAN\n");
          exit (0);
        }
       else if (! strcmp (argv[i], "--geometry"))
          exit (0);
        }
       else if (! strcmp (argv[i], "--geometry"))
@@ -2654,6 +2694,11 @@ main (int argc, char **argv)
          i++;
          fontset_name = strdup (argv[i]);
        }
          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++;
       else if (! strcmp (argv[i], "--im"))
        {
          i++;
@@ -2717,18 +2762,32 @@ main (int argc, char **argv)
 
   {
     MPlist *plist = mplist ();
 
   {
     MPlist *plist = mplist ();
-    MFace *face;
     MFont *font;
 
     mplist_put (plist, msymbol ("widget"), ShellWidget);
     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);
       }
        mplist_add (plist, Mface, face);
        m17n_object_unref (face);
       }
@@ -2924,7 +2983,7 @@ main (int argc, char **argv)
 
        if (im->language != Mnil && im->language != Mt)
          {
 
        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
            if (sym == Mnil)
              name1 = msymbol_name (im->language);
            else
@@ -3051,7 +3110,7 @@ main (int argc, char **argv)
            MSymbol fullname;
 
            if (sym != Mnil
            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];
              {
                char *name = msymbol_name (fullname);
                char c = name[0];
@@ -3182,6 +3241,8 @@ main (int argc, char **argv)
   m17n_object_unref (face_default);
   m17n_object_unref (default_face_list);
   m17n_object_unref (selection);
   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);
 
   XFreeGC (display, mono_gc);
   XFreeGC (display, mono_gc_inv);
@@ -3193,6 +3254,7 @@ main (int argc, char **argv)
 
   M17N_FINI ();
 
 
   M17N_FINI ();
 
+  free (font_name);
   free (fontset_name);
   free (filename);
   free (input_method_table);
   free (fontset_name);
   free (filename);
   free (input_method_table);