Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 1 Dec 2000 04:18:06 +0800 (CST)
From:      Clive Lin <clive@CirX.ORG>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   ports/23198: New port: chinese/emacs20
Message-ID:  <200011302018.eAUKI6v25833@cartier.cirx.org>

next in thread | raw e-mail | index | archive | help

>Number:         23198
>Category:       ports
>Synopsis:       New port: chinese/emacs20
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Nov 30 12:20:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Clive Lin <clive@CirX.ORG>
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
This site doesnt' exist
>Environment:
System: FreeBSD cartier.cirx.org 5.0-CURRENT FreeBSD 5.0-CURRENT #1: Tue Nov 28 02:07:36 CST 2000 root@cartier.cirx.org:/home/nexus/obj/home/nexus/src/sys/GENE i386

>Description:
	New port: chinese/emacs20. Slave port of editors/emacs20.
	This makes Chinese characters input via XIM or simply terminal
	possible, mean while editors/emacs20 can't.

>How-To-Repeat:
	
>Fix:

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


>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ports" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200011302018.eAUKI6v25833>