From 13004b54a2083501565e500a4962cad443550ddb Mon Sep 17 00:00:00 2001 From: Jing-Tang Keith Jang Date: Fri, 1 Dec 2000 04:49:28 +0000 Subject: [PATCH] Initial version. A L10N Emacs that can act as an XIM client. PR: ports/23198 --- chinese/emacs20/Makefile | 38 + chinese/emacs20/files/Emacs | 2 + chinese/emacs20/files/dot.emacs | 9 + .../emacs20/files/emacs20-xim-20000713.diff | 746 ++++++++++++++++++ chinese/emacs20/pkg-message | 11 + 5 files changed, 806 insertions(+) create mode 100644 chinese/emacs20/Makefile create mode 100644 chinese/emacs20/files/Emacs create mode 100644 chinese/emacs20/files/dot.emacs create mode 100644 chinese/emacs20/files/emacs20-xim-20000713.diff create mode 100644 chinese/emacs20/pkg-message 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 +# +# $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' +