summaryrefslogtreecommitdiff
path: root/chinese
diff options
context:
space:
mode:
authorJing-Tang Keith Jang <keith@FreeBSD.org>2000-12-01 04:49:28 +0000
committerJing-Tang Keith Jang <keith@FreeBSD.org>2000-12-01 04:49:28 +0000
commit13004b54a2083501565e500a4962cad443550ddb (patch)
tree95d5d5323039d4f890d68418ec9e1fd8047852e7 /chinese
parentFix machine/console.h -> sys/{consio,kbio}.h change. (diff)
Initial version. A L10N Emacs that can act as an XIM client.
PR: ports/23198
Notes
Notes: svn path=/head/; revision=35570
Diffstat (limited to 'chinese')
-rw-r--r--chinese/emacs20/Makefile38
-rw-r--r--chinese/emacs20/files/Emacs2
-rw-r--r--chinese/emacs20/files/dot.emacs9
-rw-r--r--chinese/emacs20/files/emacs20-xim-20000713.diff746
-rw-r--r--chinese/emacs20/pkg-message11
5 files changed, 806 insertions, 0 deletions
diff --git a/chinese/emacs20/Makefile b/chinese/emacs20/Makefile
new file mode 100644
index 000000000000..a8b5afe4ebbc
--- /dev/null
+++ b/chinese/emacs20/Makefile
@@ -0,0 +1,38 @@
+# ex:ts=8
+# Ports collection makefile for: emacs20 with XIM and a little zh-l10n
+# Date created: Sat Nov 11, 2000
+# Whom: Clive Lin <clive@CirX.ORG>
+#
+# $FreeBSD$
+#
+
+MASTERDIR= ${.CURDIR}/../../editors/emacs20
+
+MAINTAINER= clive@CirX.ORG
+
+.if !defined(WITHOUT_X11)
+RUN_DEPENDS+= ${X11BASE}/lib/X11/fonts/local/kc15f.pcf.gz:${PORTSDIR}/chinese/kcfonts \
+ xcin2.5:${PORTSDIR}/chinese/xcin25
+.endif
+
+WITH_XPG4= yes
+
+PKGMESSAGE= ${.CURDIR}/pkg-message
+
+PLIST= ${WRKDIR}/pkg-plist
+
+pre-patch:
+ @( cd ${WRKSRC}; \
+ ${PATCH} -sp1 < ${.CURDIR}/files/emacs20-xim-20000713.diff ; )
+
+post-patch:
+ @${ECHO} "share/emacs/%%EMACS_VER%%/etc/Emacs" >> ${WRKDIR}/pkg-plist
+ @${ECHO} "share/emacs/%%EMACS_VER%%/etc/dot.emacs" >> ${WRKDIR}/pkg-plist
+ @${CAT} ${MASTERDIR}/pkg-plist >> ${WRKDIR}/pkg-plist
+
+post-install:
+ ${INSTALL} -c ${.CURDIR}/files/Emacs ${PREFIX}/share/emacs/${PORTVERSION}/etc
+ ${INSTALL} -c ${.CURDIR}/files/dot.emacs ${PREFIX}/share/emacs/${PORTVERSION}/etc
+ @${CAT} ${PKGMESSAGE}
+
+.include "${MASTERDIR}/Makefile"
diff --git a/chinese/emacs20/files/Emacs b/chinese/emacs20/files/Emacs
new file mode 100644
index 000000000000..6e162b334fe0
--- /dev/null
+++ b/chinese/emacs20/files/Emacs
@@ -0,0 +1,2 @@
+Emacs.Font: fontset-16
+Emacs.Fontset-0: -*-*-medium-r-normal-*-16-*-*-*-*-*-fontset-16
diff --git a/chinese/emacs20/files/dot.emacs b/chinese/emacs20/files/dot.emacs
new file mode 100644
index 000000000000..2fb65f502f59
--- /dev/null
+++ b/chinese/emacs20/files/dot.emacs
@@ -0,0 +1,9 @@
+;; Set environment to Chinese-Big5
+(set-language-environment 'chinese-big5)
+(set-keyboard-coding-system 'chinese-big5)
+(set-terminal-coding-system 'chinese-big5)
+(set-buffer-file-coding-system 'chinese-big5)
+(set-selection-coding-system 'chinese-big5)
+(modify-coding-system-alist 'process "*" 'chinese-big5)
+;; Do not conflicts with xcin hook
+(global-set-key (kbd "M-SPC") 'set-mark-command)
diff --git a/chinese/emacs20/files/emacs20-xim-20000713.diff b/chinese/emacs20/files/emacs20-xim-20000713.diff
new file mode 100644
index 000000000000..60ea83bfb5f1
--- /dev/null
+++ b/chinese/emacs20/files/emacs20-xim-20000713.diff
@@ -0,0 +1,746 @@
+diff -Naurw emacs-20.7.orig/src/xfns.c emacs-20.7/src/xfns.c
+--- emacs-20.7.orig/src/xfns.c Thu Jul 1 09:09:39 1999
++++ emacs-20.7/src/xfns.c Sat Jun 17 00:18:36 2000
+@@ -2719,6 +2719,259 @@
+ }
+ #endif
+
++/* Support routines for XIC (X Input Context). */
++#ifdef HAVE_X_I18N
++
++/* Create X fontset. */
++static XFontSet
++xic_create_xfontset (f, base_fontname)
++ struct frame *f;
++ char *base_fontname;
++{
++ XFontSet xfs;
++ char **missing_list;
++ int missing_count;
++ char *def_string;
++
++ xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
++ base_fontname, &missing_list,
++ &missing_count, &def_string);
++ if (missing_list)
++ XFreeStringList (missing_list);
++ /* Don't need to free def_string. */
++
++ return xfs;
++}
++
++/* Supported XIM styles, ordered in preferences. */
++static XIMStyle supported_styles[] =
++{
++ XIMPreeditPosition | XIMStatusArea,
++ XIMPreeditPosition | XIMStatusNothing,
++ XIMPreeditPosition | XIMStatusNone,
++ XIMPreeditNothing | XIMStatusArea,
++ XIMPreeditNothing | XIMStatusNothing,
++ XIMPreeditNothing | XIMStatusNone,
++ XIMPreeditNone | XIMStatusArea,
++ XIMPreeditNone | XIMStatusNothing,
++ XIMPreeditNone | XIMStatusNone,
++ 0,
++};
++
++/* Choose the best style, given:
++ * - user preferences (already checked to be supported by Emacs)
++ * - styles supported by the input method */
++#define DEFAULTStyle (XIMPreeditNothing | XIMStatusNothing)
++static XIMStyle
++best_style (user, xim)
++ XIMStyles *user;
++ XIMStyles *xim;
++{
++ int i, j;
++
++ for (i = 0; i < user->count_styles; i++)
++ {
++ for (j = 0; j < xim->count_styles; j++)
++ {
++ if (user->supported_styles[i] == xim->supported_styles[j])
++ return user->supported_styles[i];
++ }
++ }
++ return DEFAULTStyle; /* Default Style */
++}
++
++/* Create XIC for a frame. */
++void
++xic_create_frame (f)
++ struct frame *f;
++{
++#ifndef X_I18N_INHIBITED
++ XIM xim;
++ XIC xic = NULL;
++ XFontSet xfs = NULL;
++ static XIMStyle xic_style;
++
++ if (FRAME_XIC (f))
++ return;
++ xim = FRAME_X_XIM (f);
++
++ if (xim)
++ {
++ XRectangle s_area = {0, 0, 1, 1};
++ XPoint spot = {0, 1};
++ XVaNestedList preedit_attr;
++ XVaNestedList status_attr;
++ static const char DEFAULT_FONT[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
++ char *base_fontname;
++ int fontset;
++
++ /* Create X fontset. */
++ fontset = FRAME_FONTSET (f);
++ if (fontset < 0)
++ base_fontname = DEFAULT_FONT;
++ else
++ {
++ struct fontset_info *fontsetp;
++ int len = 0;
++ int i;
++
++ fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
++ for (i = 0; i <= MAX_CHARSET; i++)
++ if (fontsetp->fontname[i])
++ len += strlen (fontsetp->fontname[i]) + 1;
++ base_fontname = alloca (len);
++ strcpy (base_fontname, fontsetp->fontname[CHARSET_ASCII]);
++ for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
++ if (fontsetp->fontname[i])
++ {
++ strcat (base_fontname, ",");
++ strcat (base_fontname, fontsetp->fontname[i]);
++ }
++ }
++ xfs = xic_create_xfontset (f, base_fontname);
++
++ /* Determine XIC style. */
++ if (xic_style == 0)
++ {
++ XIMStyles supported_list;
++ supported_list.count_styles = sizeof (supported_styles) / sizeof (supported_styles[0]);
++ supported_list.supported_styles = supported_styles;
++ xic_style = best_style (&supported_list, FRAME_X_XIM_STYLES (f));
++ }
++
++ preedit_attr = XVaCreateNestedList (0,
++ XNFontSet, xfs,
++ XNForeground, FRAME_FOREGROUND_PIXEL (f),
++ XNBackground, FRAME_BACKGROUND_PIXEL (f),
++ xic_style & XIMPreeditPosition ? XNSpotLocation : NULL, &spot,
++ NULL);
++ status_attr = XVaCreateNestedList (0,
++ XNArea, &s_area,
++ XNFontSet, xfs,
++ XNForeground, FRAME_FOREGROUND_PIXEL (f),
++ XNBackground, FRAME_BACKGROUND_PIXEL (f),
++ NULL);
++
++ xic = XCreateIC (xim,
++ XNInputStyle, xic_style,
++ XNClientWindow, FRAME_X_WINDOW(f),
++ XNFocusWindow, FRAME_X_WINDOW(f),
++ XNStatusAttributes, status_attr,
++ XNPreeditAttributes, preedit_attr,
++ NULL);
++ XFree (preedit_attr);
++ XFree (status_attr);
++ }
++
++ FRAME_XIC (f) = xic;
++ FRAME_XIC_STYLE (f) = xic_style;
++ FRAME_XIC_FONTSET (f) = xfs;
++#else /* X_I18N_INHIBITED */
++ FRAME_XIC (f) = NULL;
++ FRAME_XIC_STYLE (f) = 0;
++ FRAME_XIC_FONTSET (f) = NULL;
++#endif /* X_I18N_INHIBITED */
++}
++
++/* Destroy XIC for a frame. */
++void
++xic_destroy_frame (f)
++ struct frame *f;
++{
++ if (FRAME_XIC (f) == NULL)
++ return;
++
++ XDestroyIC (FRAME_XIC (f));
++ if (FRAME_XIC_FONTSET (f))
++ XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
++
++ FRAME_XIC (f) = NULL;
++ FRAME_XIC_FONTSET (f) = NULL;
++}
++
++/* Place preedit area for XIC in cursor position. */
++void
++xic_set_preeditarea (f, x, y)
++ struct frame *f;
++ int x, y;
++{
++ XVaNestedList attr;
++ XPoint spot;
++
++ spot.x = CHAR_TO_PIXEL_COL (f, x);
++ spot.y = CHAR_TO_PIXEL_ROW (f, y) + FONT_BASE (FRAME_FONT (f));
++ attr = XVaCreateNestedList (0,
++ XNSpotLocation, &spot,
++ NULL);
++ XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
++ XFree (attr);
++}
++
++/* Place status area for XIC in bottom right corner. */
++void
++xic_set_statusarea (f)
++ struct frame *f;
++{
++ XIC xic = FRAME_XIC (f);
++ XVaNestedList attr;
++ XRectangle area;
++ XRectangle *needed;
++
++ /* Basically, I follow the way of XEmacs20.4. */
++ /* Negotiate geometry of status area. */
++ /* If input method has existing status area, use its current size */
++ area.x = area.y = area.width = area.height = 0;
++ attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
++ XSetICValues (xic, XNStatusAttributes, attr, NULL);
++ XFree (attr);
++
++ attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
++ XGetICValues (xic, XNStatusAttributes, attr, NULL);
++ XFree (attr);
++
++ if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
++ {
++ attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
++ XGetICValues (xic, XNStatusAttributes, attr, NULL);
++ XFree (attr);
++ }
++
++ area.width = needed->width;
++ area.height = needed->height;
++ area.x = PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
++ area.y = PIXEL_HEIGHT (f) - area.height - FRAME_MENUBAR_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
++ XFree(needed);
++
++ attr = XVaCreateNestedList (0, XNArea, &area, NULL);
++ XSetICValues(xic, XNStatusAttributes, attr, NULL);
++ XFree(attr);
++}
++
++/* Set X fontset for XIC, called when a new Emacs fontset is chosen. */
++void
++xic_set_xfontset (f, base_fontname)
++ struct frame *f;
++ char *base_fontname;
++{
++ XVaNestedList attr;
++ XFontSet xfs;
++
++ xfs = xic_create_xfontset (f, base_fontname);
++
++ attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
++ if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
++ XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
++ if (FRAME_XIC_STYLE (f) & XIMStatusArea)
++ XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
++ XFree (attr);
++
++ if (FRAME_XIC_FONTSET (f))
++ XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
++ FRAME_XIC_FONTSET (f) = xfs;
++}
++#endif /* HAVE_X_I18N */
++
++
+ #ifdef USE_X_TOOLKIT
+
+ /* Create and set up the X widget for frame F. */
+@@ -2876,34 +3129,8 @@
+ XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
+
+ #ifdef HAVE_X_I18N
+-#ifndef X_I18N_INHIBITED
+- {
+- XIM xim;
+- XIC xic = NULL;
+-
+- xim = XOpenIM (FRAME_X_DISPLAY (f), NULL, NULL, NULL);
+-
+- if (xim)
+- {
+- xic = XCreateIC (xim,
+- XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+- XNClientWindow, FRAME_X_WINDOW(f),
+- XNFocusWindow, FRAME_X_WINDOW(f),
+- NULL);
+-
+- if (xic == 0)
+- {
+- XCloseIM (xim);
+- xim = NULL;
+- }
+- }
+- FRAME_XIM (f) = xim;
+- FRAME_XIC (f) = xic;
+- }
+-#else /* X_I18N_INHIBITED */
+- FRAME_XIM (f) = 0;
+- FRAME_XIC (f) = 0;
+-#endif /* X_I18N_INHIBITED */
++ FRAME_XIC (f) = NULL;
++ xic_create_frame (f);
+ #endif /* HAVE_X_I18N */
+
+ f->output_data.x->wm_hints.input = True;
+@@ -2928,6 +3155,16 @@
+
+ /* Make all the standard events reach the Emacs frame. */
+ attributes.event_mask = STANDARD_EVENT_SET;
++#ifdef HAVE_X_I18N
++ if (FRAME_XIC (f))
++ {
++ /* XIM server might require some X events. */
++ unsigned long fevent = NoEventMask;
++
++ XGetICValues(FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
++ attributes.event_mask |= fevent;
++ }
++#endif /* HAVE_X_I18N */
+ attribute_mask = CWEventMask;
+ XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
+ attribute_mask, &attributes);
+@@ -2998,38 +3235,21 @@
+ InputOutput, /* class */
+ FRAME_X_DISPLAY_INFO (f)->visual,
+ attribute_mask, &attributes);
+-#ifdef HAVE_X_I18N
+-#ifndef X_I18N_INHIBITED
+- {
+- XIM xim;
+- XIC xic = NULL;
+
+- xim = XOpenIM (FRAME_X_DISPLAY(f), NULL, NULL, NULL);
+-
+- if (xim)
+- {
+- xic = XCreateIC (xim,
+- XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+- XNClientWindow, FRAME_X_WINDOW(f),
+- XNFocusWindow, FRAME_X_WINDOW(f),
+- NULL);
+-
+- if (!xic)
++#ifdef HAVE_X_I18N
++ xic_create_frame (f);
++ if (FRAME_XIC (f))
+ {
+- XCloseIM (xim);
+- xim = NULL;
+- }
+- }
++ /* XIM server might require some X events. */
++ unsigned long fevent = NoEventMask;
+
+- FRAME_XIM (f) = xim;
+- FRAME_XIC (f) = xic;
++ XGetICValues(FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
++ attributes.event_mask |= fevent;
++ attribute_mask = CWEventMask;
++ XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
++ attribute_mask, &attributes);
+ }
+-#else /* X_I18N_INHIBITED */
+- FRAME_XIM (f) = 0;
+- FRAME_XIC (f) = 0;
+-#endif /* X_I18N_INHIBITED */
+ #endif /* HAVE_X_I18N */
+-
+ validate_x_resource_name ();
+
+ class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;
+diff -Naurw emacs-20.7.orig/src/xterm.c emacs-20.7/src/xterm.c
+--- emacs-20.7.orig/src/xterm.c Mon Aug 2 09:16:43 1999
++++ emacs-20.7/src/xterm.c Wed Jul 12 23:28:40 2000
+@@ -3791,9 +3791,6 @@
+ int prefix;
+ Lisp_Object part;
+ struct x_display_info *dpyinfo;
+-#ifdef HAVE_X_I18N
+- Status status_return;
+-#endif
+
+ if (interrupt_input_blocked)
+ {
+@@ -3862,7 +3859,7 @@
+ event.xclient.window);
+ /* The necessity of the following line took me
+ a full work-day to decipher from the docs!! */
+- if (f1 != 0 && FRAME_XIC (f1) && XFilterEvent (&event, None))
++ if (XFilterEvent (&event, f1 ? FRAME_X_WINDOW(f1) : None))
+ break;
+ }
+ #endif
+@@ -4235,18 +4232,30 @@
+ #ifdef HAVE_X_I18N
+ if (FRAME_XIC (f))
+ {
+- /* The necessity of the following line took me
+- a full work-day to decipher from the docs!! */
+- if (XFilterEvent (&event, None))
+- break;
++ unsigned char *copy_bufptr = copy_buffer;
++ int copy_bufsiz = sizeof (copy_buffer);
++ Status status_return;
++
++ nbytes = XmbLookupString (FRAME_XIC (f),
++ &event.xkey, copy_bufptr,
++ copy_bufsiz, &keysym,
++ &status_return);
++ if (status_return == XBufferOverflow)
++ {
++ copy_bufsiz = nbytes + 1;
++ copy_bufptr = (char *) alloca (copy_bufsiz);
+ nbytes = XmbLookupString (FRAME_XIC (f),
+- &event.xkey, copy_buffer,
+- 80, &keysym,
++ &event.xkey, copy_bufptr,
++ copy_bufsiz, &keysym,
+ &status_return);
++ }
+ if (status_return == XLookupNone)
+ break;
+ else if (status_return == XLookupChars)
++ {
+ keysym = NoSymbol;
++ modifiers = 0;
++ }
+ else if (status_return != XLookupKeySym
+ && status_return != XLookupBoth)
+ abort ();
+@@ -4378,7 +4387,10 @@
+ else
+ abort ();
+ }
+- goto OTHER;
++ break;
++
++ case KeyRelease:
++ break;
+
+ /* Here's a possible interpretation of the whole
+ FocusIn-EnterNotify FocusOut-LeaveNotify mess. If you get a
+@@ -4515,6 +4527,13 @@
+ x_real_positions (f, &f->output_data.x->left_pos,
+ &f->output_data.x->top_pos);
+
++#ifdef HAVE_X_I18N
++ if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
++ {
++ xic_set_statusarea (f);
++ }
++#endif
++
+ if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
+ {
+ /* Since the WM decorations come below top_pos now,
+@@ -4992,6 +5011,13 @@
+ /* Those are the only two we have implemented! */
+ abort ();
+
++#ifdef HAVE_X_I18N
++ if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMPreeditPosition))
++ {
++ xic_set_preeditarea (f, x, y);
++ }
++#endif
++
+ UNBLOCK_INPUT;
+ }
+
+@@ -5463,9 +5489,176 @@
+ FS_LOAD_FONT (f, FRAME_X_FONT_TABLE (f),
+ CHARSET_ASCII, fontsetp->fontname[CHARSET_ASCII], fontset);
+
++#ifdef HAVE_X_I18N
++ if (FRAME_XIC (f)
++ && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
++ {
++ xic_set_xfontset (f, fontsetp->fontname[CHARSET_ASCII]);
++ }
++#endif /* HAVE_X_I18N */
+ return build_string (fontsetname);
+ }
+
++
++/* Support routines for XIM (X Input Method). */
++#ifdef HAVE_X_I18N
++
++#ifdef HAVE_X11R6
++/* XIM destroy callback function,
++ which is called whenever the connected XIM server dies.
++ Clear XIM information. */
++static void
++xim_destroy_callback (xim, client_data, call_data)
++ XIM xim;
++ XPointer client_data;
++ XPointer call_data;
++{
++ struct x_display_info *dpyinfo = (struct x_display_info *)client_data;
++ Lisp_Object frame, tail;
++
++ BLOCK_INPUT;
++ /* Don't need to call XDestroyIC. */
++ FOR_EACH_FRAME (tail, frame)
++ if (FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
++ {
++ FRAME_XIC (XFRAME (frame)) = NULL;
++ if (FRAME_XIC_FONTSET (XFRAME (frame)))
++ {
++ XFreeFontSet (FRAME_X_DISPLAY (XFRAME (frame)), FRAME_XIC_FONTSET (XFRAME (frame)));
++ FRAME_XIC_FONTSET (XFRAME (frame)) = NULL;
++ }
++ }
++
++ /* Don't need to call XCloseIM. */
++ dpyinfo->xim = NULL;
++ XFree (dpyinfo->xim_styles);
++ UNBLOCK_INPUT;
++}
++#endif /* HAVE_X11R6 */
++
++/* Open the connection with XIM server. */
++static void
++xim_open_dpy (dpyinfo, resource_name)
++ struct x_display_info *dpyinfo;
++ char *resource_name;
++{
++ XIM xim;
++
++ xim = XOpenIM (dpyinfo->display, dpyinfo->xrdb, resource_name, EMACS_CLASS);
++ dpyinfo->xim = xim;
++
++ if (xim)
++ {
++ XIMValuesList *xim_values_list;
++#ifdef HAVE_X11R6
++ XIMCallback destroy;
++#endif
++
++ /* Get supported styles and XIM values */
++ XGetIMValues (xim,
++ XNQueryInputStyle, &dpyinfo->xim_styles,
++ NULL);
++#ifdef HAVE_X11R6
++ destroy.callback = xim_destroy_callback;
++ destroy.client_data = (XPointer)dpyinfo;
++ XSetIMValues (xim, XNDestroyCallback, &destroy, NULL);
++#endif
++ }
++}
++
++#ifdef HAVE_X11R6
++struct xim_inst_t
++{
++ struct x_display_info *dpyinfo;
++ char *resource_name;
++};
++
++/* XIM instantiate callback function,
++ which is called whenever an XIM server is available. */
++static void
++xim_instantiate_callback(display, client_data, call_data)
++ Display *display;
++ XPointer client_data;
++ XPointer call_data;
++{
++ struct xim_inst_t *xim_inst = (struct xim_inst_t *)client_data;
++ struct x_display_info *dpyinfo = xim_inst->dpyinfo;
++
++ /* We don't support multiple XIM connections. */
++ if (dpyinfo->xim)
++ return;
++
++ xim_open_dpy (dpyinfo, xim_inst->resource_name);
++
++ /* Create XIC for the existing frames on the same display,
++ as long as they have no XIC. */
++ if (dpyinfo->xim && dpyinfo->reference_count > 0)
++ {
++ Lisp_Object tail, frame;
++
++ BLOCK_INPUT;
++ FOR_EACH_FRAME (tail, frame)
++ if (FRAME_X_DISPLAY_INFO (XFRAME (frame)) == xim_inst->dpyinfo)
++ if (FRAME_XIC (XFRAME (frame)) == NULL)
++ {
++ xic_create_frame (XFRAME (frame));
++ if (FRAME_XIC_STYLE (XFRAME (frame)) & XIMStatusArea)
++ xic_set_statusarea (XFRAME (frame));
++ if (FRAME_XIC_STYLE (XFRAME (frame)) & XIMPreeditPosition)
++ xic_set_preeditarea (XFRAME (frame),
++ FRAME_CURSOR_X (XFRAME (frame)),
++ FRAME_CURSOR_Y (XFRAME (frame)));
++ }
++ UNBLOCK_INPUT;
++ }
++}
++#endif /* HAVE_X11R6 */
++
++/* It's dependent on X11R5 or X11R6 to open the connection with XIM server.
++ On X11R5, open the connection only at the first time.
++ On X11R6, open the connection in XIM instantiate callback function. */
++static void
++xim_initialize (dpyinfo, resource_name)
++ struct x_display_info *dpyinfo;
++ char *resource_name;
++{
++#ifdef HAVE_X11R6
++ struct xim_inst_t *xim_inst;
++ int len;
++
++ dpyinfo->xim = NULL;
++ xim_inst = (struct xim_inst_t *) xmalloc (sizeof (struct xim_inst_t));
++ xim_inst->dpyinfo = dpyinfo;
++ len = strlen (resource_name);
++ xim_inst->resource_name = (char *) xmalloc (len + 1);
++ bcopy (resource_name, xim_inst->resource_name, len + 1);
++ XRegisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
++ resource_name, EMACS_CLASS,
++ xim_instantiate_callback, (XPointer)xim_inst);
++#else /* not HAVE_X11R6 */
++ dpyinfo->xim = NULL;
++ xim_open_dpy (dpyinfo, resource_name);
++#endif /* not HAVE_X11R6 */
++}
++
++/* Close the connection with XIM server. */
++static void
++xim_close_dpy (dpyinfo)
++ struct x_display_info *dpyinfo;
++{
++#ifdef HAVE_X11R6
++ XUnregisterIMInstantiateCallback(dpyinfo->display, dpyinfo->xrdb,
++ NULL, EMACS_CLASS,
++ xim_instantiate_callback, NULL);
++#endif /* HAVE_X11R6 */
++ XCloseIM (dpyinfo->xim);
++ dpyinfo->xim = NULL;
++
++ XFree (dpyinfo->xim_styles);
++}
++#endif /* HAVE_X_I18N */
++
++
+ /* Calculate the absolute position in frame F
+ from its current recorded position values and gravity. */
+
+@@ -6175,15 +6368,9 @@
+ if (f->output_data.x->icon_desc != 0)
+ XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
+ #ifdef HAVE_X_I18N
+- if (FRAME_XIM (f))
++ if (FRAME_XIC (f))
+ {
+- XDestroyIC (FRAME_XIC (f));
+-#if ! defined (SOLARIS2) || defined (HAVE_X11R6)
+- /* This line causes crashes on Solaris with Openwin,
+- due to an apparent bug in XCloseIM.
+- X11R6 seems not to have the bug. */
+- XCloseIM (FRAME_XIM (f));
+-#endif
++ xic_destroy_frame (f);
+ }
+ #endif
+ XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->window_desc);
+@@ -7335,6 +7522,10 @@
+ 1);
+ }
+
++#ifdef HAVE_X_I18N
++ xim_initialize (dpyinfo, resource_name);
++#endif
++
+ #ifdef subprocesses
+ /* This is only needed for distinguishing keyboard and process input. */
+ if (connection != 0)
+@@ -7440,6 +7631,11 @@
+ if (--dpyinfo->kboard->reference_count == 0)
+ delete_kboard (dpyinfo->kboard);
+ #endif
++#ifdef HAVE_X_I18N
++ if (dpyinfo->xim)
++ xim_close_dpy (dpyinfo);
++#endif
++
+ xfree (dpyinfo->font_table);
+ xfree (dpyinfo->x_id_name);
+ xfree (dpyinfo);
+diff -Naurw emacs-20.7.orig/src/xterm.h emacs-20.7/src/xterm.h
+--- emacs-20.7.orig/src/xterm.h Sun Aug 16 07:58:10 1998
++++ emacs-20.7/src/xterm.h Sat Jun 17 00:18:37 2000
+@@ -297,6 +297,12 @@
+ /* The null pixel used for filling a character background with
+ background color of a gc. */
+ Pixmap null_pixel;
++
++#ifdef HAVE_X_I18N
++ /* XIM(X Input method) */
++ XIM xim;
++ XIMStyles *xim_styles;
++#endif
+ };
+
+ /* This is a chain of structures for all the X displays currently in use. */
+@@ -492,10 +498,11 @@
+ char has_been_visible;
+
+ #ifdef HAVE_X_I18N
+- /* Input method. */
+- XIM xim;
++ /* XIM(X Input method) */
+ /* Input context (currently, this means Compose key handler setup). */
+ XIC xic;
++ XIMStyle xic_style;
++ XFontSet xic_xfs;
+ #endif
+ };
+
+@@ -526,6 +533,7 @@
+ #define FRAME_FONT(f) ((f)->output_data.x->font)
+ #define FRAME_FONTSET(f) ((f)->output_data.x->fontset)
+ #define FRAME_INTERNAL_BORDER_WIDTH(f) ((f)->output_data.x->internal_border_width)
++#define FRAME_MENUBAR_HEIGHT(f) ((f)->output_data.x->menubar_height)
+ #define FRAME_LINE_HEIGHT(f) ((f)->output_data.x->line_height)
+
+ /* This gives the x_display_info structure for the display F is on. */
+@@ -546,8 +554,11 @@
+
+ #define FRAME_DESIRED_CURSOR(f) ((f)->output_data.x->desired_cursor)
+
+-#define FRAME_XIM(f) ((f)->output_data.x->xim)
++#define FRAME_X_XIM(f) (FRAME_X_DISPLAY_INFO (f)->xim)
++#define FRAME_X_XIM_STYLES(f) (FRAME_X_DISPLAY_INFO (f)->xim_styles)
+ #define FRAME_XIC(f) ((f)->output_data.x->xic)
++#define FRAME_XIC_STYLE(f) ((f)->output_data.x->xic_style)
++#define FRAME_XIC_FONTSET(f) ((f)->output_data.x->xic_xfs)
+
+ /* X-specific scroll bar stuff. */
+
+@@ -877,6 +888,11 @@
+ extern void x_set_border_pixel P_ ((struct frame *, int));
+ extern void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
+ extern void x_implicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
++extern void xic_create_frame P_ ((struct frame *));
++extern void xic_destroy_frame P_ ((struct frame *));
++extern void xic_set_preeditarea P_ ((struct frame *, int, int));
++extern void xic_set_statusarea P_ ((struct frame *));
++extern void xic_set_xfontset P_ ((struct frame *, char *));
+ extern int x_pixel_width P_ ((struct frame *));
+ extern int x_pixel_height P_ ((struct frame *));
+ extern int x_char_width P_ ((struct frame *));
diff --git a/chinese/emacs20/pkg-message b/chinese/emacs20/pkg-message
new file mode 100644
index 000000000000..ad35bfcc3157
--- /dev/null
+++ b/chinese/emacs20/pkg-message
@@ -0,0 +1,11 @@
+
+!!!! Notice !!!!
+
+1) You have to copy Emacs and dot.emacs within
+ ${PREFIX}/share/emacs/${EMACS_VER}/etc/
+ into your home directory, and rename dot.emacs to .emacs,
+ in order to make it work.
+2) Remember to set environment varible XMODIFIERS !
+ csh/tcsh: setenv XMODIFIERS @im=xcin
+ sh/bash: export XMODIFIERS='@im=xcin'
+