X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=example%2Fmedit.c;h=cb24ddab7e2d18c6f167f9235165807ee03d2574;hb=78b5889d3fd2949bc636133956d6f3e54d6181e2;hp=233f7cf9d53b3181e81652bcfd793bf3f4f77a7e;hpb=57bac66b0e23ea5f96ecc6357952950f623fdcf4;p=m17n%2Fm17n-lib.git diff --git a/example/medit.c b/example/medit.c index 233f7cf..cb24dda 100644 --- a/example/medit.c +++ b/example/medit.c @@ -116,7 +116,7 @@ #include #include -#define VERSION "1.0.1" +#define VERSION "1.2" /* Global variables. */ @@ -176,10 +176,12 @@ 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. */ typedef struct { @@ -216,6 +218,7 @@ struct FaceRec {"times", &face_times}, {"dv-ttyogesh", &face_dv_ttyogesh}, {"freesans", &face_freesans}, + {"freeserif", &face_freeserif}, {"freemono", &face_freemono}, {"Menu Style", NULL}, @@ -331,8 +334,8 @@ update_top (int pos) 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; } @@ -379,21 +382,21 @@ redraw (int y0, int y1, int clear, int scroll_bar) 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) @@ -405,10 +408,10 @@ redraw (int y0, int y1, int clear, int scroll_bar) 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); } @@ -422,16 +425,19 @@ set_input_method_spot () 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) @@ -455,12 +461,12 @@ redraw_cursor (int clear) 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; @@ -474,8 +480,8 @@ redraw_cursor (int clear) 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); } @@ -495,7 +501,7 @@ 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) { @@ -503,7 +509,7 @@ update_cursor (int pos, int full) 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) { @@ -512,13 +518,13 @@ update_cursor (int pos, int full) 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; } @@ -544,34 +550,28 @@ update_selection () 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; } @@ -738,59 +738,60 @@ show_cursor (XtPointer client_data) 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) { @@ -936,7 +937,7 @@ delete_char (int n) /* 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); @@ -983,8 +984,9 @@ insert_chars (MText *newtext) } -/* 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, @@ -994,14 +996,52 @@ covert_selection (Widget w, Atom *selection_atom, 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; } @@ -1030,12 +1070,20 @@ get_selection (Widget w, XtPointer cliend_data, Atom *selection, Atom *type, 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 (); @@ -1079,6 +1127,19 @@ ExposeProc (Widget w, XEvent *event, String *str, Cardinal *num) 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 @@ -1285,9 +1346,9 @@ ScrollProc (Widget w, XtPointer client_data, XtPointer position) { 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) @@ -1297,9 +1358,9 @@ ScrollProc (Widget w, XtPointer client_data, XtPointer position) 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; } @@ -1313,10 +1374,10 @@ ScrollProc (Widget w, XtPointer client_data, XtPointer position) 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) @@ -1531,7 +1592,8 @@ KeyProc (Widget w, XEvent *event, String *str, Cardinal *num) { 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); @@ -1572,7 +1634,7 @@ SaveProc (Widget w, XtPointer client_data, XtPointer call_data) 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); @@ -1623,7 +1685,7 @@ read_file () 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); @@ -1726,6 +1788,7 @@ CursorProc (Widget w, XtPointer client_data, XtPointer call_data) XtSetValues (CursorMenus[i], arg, 1); } + update_cursor (cursor.from, 0); redraw (0, win_height, 1, 0); } @@ -1781,6 +1844,7 @@ FaceProc (Widget w, XtPointer client_data, XtPointer call_data) int from, to; int old_y1; + hide_cursor (); if (! SELECTEDP ()) { MPlist *plist; @@ -1905,7 +1969,7 @@ DumpImageProc (Widget w, XtPointer client_data, XtPointer call_data) 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); @@ -1957,12 +2021,22 @@ compare_input_method (const void *elt1, const void *elt2) } 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); @@ -2014,6 +2088,17 @@ setup_input_methods (int with_xim) (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; + } } @@ -2115,7 +2200,7 @@ FileDialogProc (Widget w, XtPointer client_data, XtPointer call_data) 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 (); @@ -2274,8 +2359,14 @@ help_exit (char *prog, int exit_code) 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); } @@ -2284,6 +2375,8 @@ main (int argc, char **argv) { Widget form, BodyWidget, w; char *fontset_name = NULL; + int fontsize = 0; + char *initial_input_method = NULL; int col = 80, row = 32; /* Translation table for TextWidget. */ String trans = ": Expose()\n\ @@ -2337,11 +2430,23 @@ main (int argc, char **argv) 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; @@ -2352,12 +2457,12 @@ main (int argc, char **argv) } 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 = "/dev/null"; mdatabase_dir = "."; /* Initialize the m17n library. */ @@ -2386,23 +2491,30 @@ main (int argc, char **argv) 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 > 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); 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 (); @@ -2444,6 +2556,8 @@ main (int argc, char **argv) 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")); @@ -2483,7 +2597,7 @@ main (int argc, char **argv) free (tib_font); } - setup_input_methods (with_xim); + setup_input_methods (with_xim, initial_input_method); gc = DefaultGC (display, screen); @@ -2830,6 +2944,7 @@ main (int argc, char **argv) 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); @@ -2838,13 +2953,6 @@ main (int argc, char **argv) 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); @@ -2853,6 +2961,13 @@ main (int argc, char **argv) XtDestroyWidget (ShellWidget); XtDestroyApplicationContext (context); + M17N_FINI (); + + free (fontset_name); + free (filename); + free (input_method_table); + free (InputMethodMenus); + exit (0); } #endif /* not FOR_DOXYGEN */