diff -c ../xfig.3.2.2/Fig.ad ./Fig.ad
*** ../xfig.3.2.2/Fig.ad	Thu Jul  2 09:10:28 1998
--- ./Fig.ad	Sun Jun  6 15:36:56 1999
***************
*** 142,147 ****
--- 142,158 ----
  !
  !Fig*keyFile:	~/.xfig.Compose-key
  
+ ! If xfig is compiled with I18N option, you may want to uncomment following line.
+ ! Note that you shouldn't remove "Fig*international: false".
+ !
+ !Fig.international: true
+ Fig*international: false
+ 
+ Fig.translations: #override \n\
+          <Key>: \n\
+          <KeyUp>: \n
+ 
+ 
  ! keyboard accelerators
  
  
diff -c ../xfig.3.2.2/d_arc.c ./d_arc.c
*** ../xfig.3.2.2/d_arc.c	Sat Jun 13 01:19:07 1998
--- ./d_arc.c	Sat May 29 12:23:46 1999
***************
*** 32,37 ****
--- 32,38 ----
  #include "w_cursor.h"
  #include "w_msgpanel.h"
  #include "w_mousefun.h"
+ #include "u_geom.h"
  
  /* EXPORT */
  
***************
*** 43,57 ****
  static void	get_arcpoint();
  static void	init_arc_drawing();
  static void	cancel_arc();
  
  void
  arc_drawing_selected()
  {
!     set_mousefun("first point", "", "", "", "", "");
      canvas_kbd_proc = null_proc;
      canvas_locmove_proc = null_proc;
      canvas_leftbut_proc = init_arc_drawing;
!     canvas_middlebut_proc = null_proc;
      canvas_rightbut_proc = null_proc;
      set_cursor(arrow_cursor);
      reset_action_on();
--- 44,63 ----
  static void	get_arcpoint();
  static void	init_arc_drawing();
  static void	cancel_arc();
+ static void	init_arc_c_drawing();
+ 
+ static Boolean	center_marked;
+ F_pos	center_point;
  
  void
  arc_drawing_selected()
  {
!     center_marked = FALSE;
!     set_mousefun("first point", "center point", "", "", "", "");
      canvas_kbd_proc = null_proc;
      canvas_locmove_proc = null_proc;
      canvas_leftbut_proc = init_arc_drawing;
!     canvas_middlebut_proc = init_arc_c_drawing;
      canvas_rightbut_proc = null_proc;
      set_cursor(arrow_cursor);
      reset_action_on();
***************
*** 61,73 ****
  init_arc_drawing(x, y)
      int		    x, y;
  {
!     set_mousefun("mid point", "", "cancel", "", "", "");
      draw_mousefun_canvas();
      canvas_rightbut_proc = cancel_arc;
      num_point = 0;
      point[num_point].x = fix_x = cur_x = x;
      point[num_point++].y = fix_y = cur_y = y;
!     canvas_locmove_proc = unconstrained_line;
      canvas_leftbut_proc = get_arcpoint;
      canvas_middlebut_proc = null_proc;
      elastic_line();
--- 67,85 ----
  init_arc_drawing(x, y)
      int		    x, y;
  {
!     if (center_marked) {
!       elastic_line();
!       set_mousefun("mid angle", "", "cancel", "", "", "");
!     } else {
!       set_mousefun("mid point", "", "cancel", "", "", "");
!     }
      draw_mousefun_canvas();
      canvas_rightbut_proc = cancel_arc;
      num_point = 0;
      point[num_point].x = fix_x = cur_x = x;
      point[num_point++].y = fix_y = cur_y = y;
!     if (!center_marked)
!       canvas_locmove_proc = unconstrained_line;
      canvas_leftbut_proc = get_arcpoint;
      canvas_middlebut_proc = null_proc;
      elastic_line();
***************
*** 78,83 ****
--- 90,99 ----
  static void
  cancel_arc()
  {
+     if (center_marked) {
+       center_marked = FALSE;
+       center_marker(center_point.x, center_point.y);  /* clear center marker */
+     }
      elastic_line();
      /* erase any length info if appres.showlengths is true */
      erase_lengths();
***************
*** 99,105 ****
  	return;
  
      if (num_point == 1) {
! 	set_mousefun("final point", "", "cancel", "", "", "");
  	draw_mousefun_canvas();
      }
      if (num_point == 2) {
--- 115,124 ----
  	return;
  
      if (num_point == 1) {
! 	if (center_marked)
!   	  set_mousefun("final angle", "", "cancel", "", "", "");
! 	else
! 	  set_mousefun("final point", "", "cancel", "", "", "");
  	draw_mousefun_canvas();
      }
      if (num_point == 2) {
***************
*** 140,145 ****
--- 159,184 ----
  	x = point[i].x;
  	y = point[i].y;
      }
+ 
+     if (center_marked) {
+       double theta, r;
+ 
+       center_marker(center_point.x, center_point.y);  /* clear center marker */
+ 
+       r = sqrt((point[0].x - center_point.x) * (point[0].x - center_point.x)
+ 	       + (point[0].y - center_point.y) * (point[0].y - center_point.y));
+ 
+       theta = compute_angle((double)(point[1].x - center_point.x),
+ 			    (double)(point[1].y - center_point.y));
+       point[1].x = center_point.x + r * cos(theta);
+       point[1].y = center_point.y + r * sin(theta);
+       
+       theta = compute_angle((double)(point[2].x - center_point.x),
+ 			    (double)(point[2].y - center_point.y));
+       point[2].x = center_point.x + r * cos(theta);
+       point[2].y = center_point.y + r * sin(theta);
+     }
+ 
      if (!compute_arccenter(point[0], point[1], point[2], &xx, &yy)) {
  	put_msg("Invalid ARC geometry");
  	arc_drawing_selected();
***************
*** 187,189 ****
--- 226,246 ----
      arc_drawing_selected();
      draw_mousefun_canvas();
  }
+ 
+ 
+ static void
+ init_arc_c_drawing(x, y)
+     int		    x, y;
+ {
+     set_mousefun("first point", "", "cancel", "", "", "");
+     draw_mousefun_canvas();
+     canvas_locmove_proc = arc_point;
+     canvas_middlebut_proc = null_proc;
+     canvas_rightbut_proc = cancel_arc;
+     center_point.x = fix_x = cur_x = x;
+     center_point.y = fix_y = cur_y = y;
+     center_marked = TRUE;
+     center_marker(center_point.x, center_point.y);
+     num_point = 0;
+ }
+ 
diff -c ../xfig.3.2.2/d_arc.h ./d_arc.h
*** ../xfig.3.2.2/d_arc.h	Fri Jun 12 09:01:20 1998
--- ./d_arc.h	Sat May 29 12:23:46 1999
***************
*** 16,18 ****
--- 16,19 ----
   */
  
  extern F_pos		point[3];
+ extern F_pos		center_point;
diff -c ../xfig.3.2.2/d_spline.c ./d_spline.c
*** ../xfig.3.2.2/d_spline.c	Fri Jun 12 09:25:03 1998
--- ./d_spline.c	Sat May 29 12:23:49 1999
***************
*** 141,147 ****
  	spline->type = (cur_mode == F_APPROX_SPLINE) ? T_OPEN_APPROX : T_OPEN_INTERP;
      }
      if (!make_sfactors(spline)) {
! 	free_spline(spline);
      } else {
  	add_spline(spline);
      }
--- 141,147 ----
  	spline->type = (cur_mode == F_APPROX_SPLINE) ? T_OPEN_APPROX : T_OPEN_INTERP;
      }
      if (!make_sfactors(spline)) {
! 	free_spline(&spline);
      } else {
  	add_spline(spline);
      }
diff -c ../xfig.3.2.2/d_subspline.c ./d_subspline.c
*** ../xfig.3.2.2/d_subspline.c	Sat Jun  6 06:27:07 1998
--- ./d_subspline.c	Sat May 29 12:23:49 1999
***************
*** 65,71 ****
       F_spline   **spline;
  {
    if (num_pts > MIN_NUMPOINTS_FOR_QUICK_REDRAW)
!       free_spline(spline);
  }
  
  void
--- 65,71 ----
       F_spline   **spline;
  {
    if (num_pts > MIN_NUMPOINTS_FOR_QUICK_REDRAW)
!       free_spline(&spline);
  }
  
  void
***************
*** 152,158 ****
  
    if (!first_spline_point(prev2->x, prev2->y, sfactor_cursor->s, subspline))
      {
!       free_spline(subspline);
        return NULL;
      }
    
--- 152,158 ----
  
    if (!first_spline_point(prev2->x, prev2->y, sfactor_cursor->s, subspline))
      {
!       free_spline(&subspline);
        return NULL;
      }
    
***************
*** 162,168 ****
    if (!(add_subspline_point(spline, &last_point, &last_sfactor, prev1)
  	&&  add_subspline_point(spline, &last_point, &last_sfactor, cursor)))
      {
!       free_spline(subspline);
        return NULL;
      }
  
--- 162,168 ----
    if (!(add_subspline_point(spline, &last_point, &last_sfactor, prev1)
  	&&  add_subspline_point(spline, &last_point, &last_sfactor, cursor)))
      {
!       free_spline(&subspline);
        return NULL;
      }
  
***************
*** 175,181 ****
        
        if (!add_subspline_point(spline, &last_point, &last_sfactor, cursor))
  	{
! 	  free_spline(subspline);
  	  subspline = NULL;
  	  break;
  	}
--- 175,181 ----
        
        if (!add_subspline_point(spline, &last_point, &last_sfactor, cursor))
  	{
! 	  free_spline(&subspline);
  	  subspline = NULL;
  	  break;
  	}
diff -c ../xfig.3.2.2/d_text.c ./d_text.c
*** ../xfig.3.2.2/d_text.c	Sat Jun 13 01:27:52 1998
--- ./d_text.c	Sun Jun 13 15:26:29 1999
***************
*** 108,119 ****
  static int i18n_prefix_tail(), i18n_suffix_head();
  extern Boolean is_i18n_font();
  
! #ifndef I18N_NO_PREEDIT
  static pid_t preedit_pid = -1;
  static char preedit_filename[PATH_MAX] = "";
  static open_preedit_proc(), close_preedit_proc(), paste_preedit_proc();
  static Boolean is_preedit_running();
! #endif  /* I18N_NO_PREEDIT */
  #endif  /* I18N */
  
  void
--- 108,119 ----
  static int i18n_prefix_tail(), i18n_suffix_head();
  extern Boolean is_i18n_font();
  
! #ifdef I18N_USE_PREEDIT
  static pid_t preedit_pid = -1;
  static char preedit_filename[PATH_MAX] = "";
  static open_preedit_proc(), close_preedit_proc(), paste_preedit_proc();
  static Boolean is_preedit_running();
! #endif  /* I18N_USE_PREEDIT */
  #endif  /* I18N */
  
  void
***************
*** 126,132 ****
      canvas_rightbut_proc = null_proc;
      set_mousefun("position cursor", "", "", "", "", "");
  #ifdef I18N
! #ifndef I18N_NO_PREEDIT
      if (appres.international && strlen(appres.text_preedit) != 0) {
        if (is_preedit_running()) {
  	canvas_middlebut_proc = paste_preedit_proc;
--- 126,132 ----
      canvas_rightbut_proc = null_proc;
      set_mousefun("position cursor", "", "", "", "", "");
  #ifdef I18N
! #ifdef I18N_USE_PREEDIT
      if (appres.international && strlen(appres.text_preedit) != 0) {
        if (is_preedit_running()) {
  	canvas_middlebut_proc = paste_preedit_proc;
***************
*** 137,144 ****
  	set_mousefun("position cursor", "", "open pre-edit", "", "", "");
        }
      }
! #endif  /* I18N_NO_PREEDIT */
  #endif  /* I18N */
      clear_mousefun_kbd();
      set_cursor(pencil_cursor);
      is_newline = 0;
--- 137,145 ----
  	set_mousefun("position cursor", "", "open pre-edit", "", "", "");
        }
      }
! #endif  /* I18N_USE_PREEDIT */
  #endif  /* I18N */
+     reset_action_on();
      clear_mousefun_kbd();
      set_cursor(pencil_cursor);
      is_newline = 0;
***************
*** 1074,1083 ****
    if (xim_style & XIMStatusArea) {
      GetPreferredGeomerty(ic, XNStatusAttributes, &status_area_ptr);
      status_area.width = status_area_ptr->width;
      status_area.height = status_area_ptr->height;
      status_area.x = 0;
      status_area.y = height - status_area.height;
!     SetGeometry(ic, XNStatusAttributes, &status_area);
      if (appres.DEBUG) fprintf(stderr, "status geometry: %dx%d+%d+%d\n",
  			      status_area.width, status_area.height,
  			      status_area.x, status_area.y);
--- 1075,1085 ----
    if (xim_style & XIMStatusArea) {
      GetPreferredGeomerty(ic, XNStatusAttributes, &status_area_ptr);
      status_area.width = status_area_ptr->width;
+     if (width / 2 < status_area.width) status_area.width = width / 2;
      status_area.height = status_area_ptr->height;
      status_area.x = 0;
      status_area.y = height - status_area.height;
!     SetGeometry(xim_ic, XNStatusAttributes, &status_area);
      if (appres.DEBUG) fprintf(stderr, "status geometry: %dx%d+%d+%d\n",
  			      status_area.width, status_area.height,
  			      status_area.x, status_area.y);
***************
*** 1085,1094 ****
    if (xim_style & XIMPreeditArea) {
      GetPreferredGeomerty(ic, XNPreeditAttributes, &preedit_area_ptr);
      preedit_area.width = preedit_area_ptr->width;
      preedit_area.height = preedit_area_ptr->height;
      preedit_area.x = width - preedit_area.width;
      preedit_area.y = height - preedit_area.height;
!     SetGeometry(ic, XNPreeditAttributes, &preedit_area);
      if (appres.DEBUG) fprintf(stderr, "preedit geometry: %dx%d+%d+%d\n",
  			      preedit_area.width, preedit_area.height,
  			      preedit_area.x, preedit_area.y);
--- 1087,1100 ----
    if (xim_style & XIMPreeditArea) {
      GetPreferredGeomerty(ic, XNPreeditAttributes, &preedit_area_ptr);
      preedit_area.width = preedit_area_ptr->width;
+     if (preedit_area.width < width - status_area.width)
+       preedit_area.width = width - status_area.width;
+     if (width < preedit_area.width)
+       preedit_area.width = width;
      preedit_area.height = preedit_area_ptr->height;
      preedit_area.x = width - preedit_area.width;
      preedit_area.y = height - preedit_area.height;
!     SetGeometry(xim_ic, XNPreeditAttributes, &preedit_area);
      if (appres.DEBUG) fprintf(stderr, "preedit geometry: %dx%d+%d+%d\n",
  			      preedit_area.width, preedit_area.height,
  			      preedit_area.x, preedit_area.y);
***************
*** 1099,1105 ****
       Widget w;
  {
    const XIMStyle style_notuseful = 0;
!   const XIMStyle style_over_the_spot = XIMPreeditPosition | XIMStatusNothing;
    const XIMStyle style_off_the_spot = XIMPreeditArea | XIMStatusArea;
    const XIMStyle style_root = XIMPreeditNothing | XIMStatusNothing;
    static long int im_event_mask = 0;
--- 1105,1112 ----
       Widget w;
  {
    const XIMStyle style_notuseful = 0;
!   const XIMStyle style_over_the_spot = XIMPreeditPosition | XIMStatusArea;
!   const XIMStyle style_old_over_the_spot = XIMPreeditPosition | XIMStatusNothing;
    const XIMStyle style_off_the_spot = XIMPreeditArea | XIMStatusArea;
    const XIMStyle style_root = XIMPreeditNothing | XIMStatusNothing;
    static long int im_event_mask = 0;
***************
*** 1112,1117 ****
--- 1119,1126 ----
    preferred_style = style_notuseful;
    if (strncasecmp(appres.xim_input_style, "OverTheSpot", 3) == 0)
      preferred_style = style_over_the_spot;
+   else if (strncasecmp(appres.xim_input_style, "OldOverTheSpot", 6) == 0)
+     preferred_style = style_old_over_the_spot;
    else if (strncasecmp(appres.xim_input_style, "OffTheSpot", 3) == 0)
      preferred_style = style_off_the_spot;
    else if (strncasecmp(appres.xim_input_style, "Root", 3) == 0)
***************
*** 1196,1207 ****
        y1 = ZOOMY(y);
        if (x1 < 0) x1 = 0;
        if (y1 < 0) y1 = 0;
-       if (x1 == spot.x && y1 == spot.y) {
- 	/* XSetICValues() may be ignored if spot.x/y is not changed */
- 	spot.x = 0;
- 	spot.y = 0;
- 	XSetICValues(xim_ic, XNPreeditAttributes, preedit_att, NULL);
-       }
        spot.x = x1;
        spot.y = y1;
        XSetICValues(xim_ic, XNPreeditAttributes, preedit_att, NULL);
--- 1205,1210 ----
***************
*** 1255,1268 ****
  {
    int i;
    erase_char_string();	/* erase current string */
!   for (i = 0; str[i] != '\0'; i++) {
!     prefix[leng_prefix++] = str[i];
      prefix[leng_prefix] = '\0';
    }
-   draw_char_string();	/* draw new string */
  }
  
! #ifndef I18N_NO_PREEDIT
  static Boolean is_preedit_running()
  {
    pid_t pid;
--- 1258,1279 ----
  {
    int i;
    erase_char_string();	/* erase current string */
!   for (i = 0; str[i] != '\0'; i++) prefix_append_char(str[i]);
!   draw_char_string();	/* draw new string */
! }
! 
! prefix_append_char(ch)
!      char ch;
! {
!   if (leng_prefix + leng_suffix < BUF_SIZE) {
!     prefix[leng_prefix++] = ch;
      prefix[leng_prefix] = '\0';
+   } else {
+     put_msg("Text buffer is full, character is ignored");
    }
  }
  
! #ifdef I18N_USE_PREEDIT
  static Boolean is_preedit_running()
  {
    pid_t pid;
***************
*** 1348,1353 ****
    text_drawing_selected();
    draw_mousefun_canvas();
  }
! #endif  /* I18N_NO_PREEDIT */
  
  #endif /* I18N */
--- 1359,1364 ----
    text_drawing_selected();
    draw_mousefun_canvas();
  }
! #endif  /* I18N_USE_PREEDIT */
  
  #endif /* I18N */
diff -c ../xfig.3.2.2/d_text.h ./d_text.h
*** ../xfig.3.2.2/d_text.h	Sat Jun 13 00:52:17 1998
--- ./d_text.h	Tue Jun  8 22:09:40 1999
***************
*** 26,30 ****
--- 26,33 ----
  extern XIC	xim_ic;
  extern Boolean	xim_active;
  extern		i18n_char_handler();
+ extern		prefix_append_char();
+ #ifdef I18N_USE_PREEDIT
  extern		kill_preedit();
+ #endif  /* I18N_USE_PREEDIT */
  #endif  /* I18N */
diff -c ../xfig.3.2.2/e_convert.c ./e_convert.c
*** ../xfig.3.2.2/e_convert.c	Sat Jun  6 06:28:11 1998
--- ./e_convert.c	Sat May 29 12:23:49 1999
***************
*** 184,190 ****
      }
      /* A spline must have an s parameter for each point */
      if (!make_sfactors(s)) {
! 	free_spline(s);
  	return;
      }
  
--- 184,190 ----
      }
      /* A spline must have an s parameter for each point */
      if (!make_sfactors(s)) {
! 	free_spline(&s);
  	return;
      }
  
diff -c ../xfig.3.2.2/e_edit.c ./e_edit.c
*** ../xfig.3.2.2/e_edit.c	Sat Jun 13 01:33:07 1998
--- ./e_edit.c	Sat May 29 12:23:45 1999
***************
*** 3733,3745 ****
      XtPointer	    event;
  {
      pid_t pid;
!     char *s;
      struct stat original_stat;
      int err;
  
      /* get the filename for the picture object */
!     s = panel_get_value(pic_name_panel);
!     if (s == NULL || *s == '\0')	/* no name, return */
  	return;
  
      /* uncompress the image file if it is compressed (new name returns in s) */
--- 3733,3745 ----
      XtPointer	    event;
  {
      pid_t pid;
!     char s[PATH_MAX];
      struct stat original_stat;
      int err;
  
      /* get the filename for the picture object */
!     strcpy(s,panel_get_value(pic_name_panel));
!     if (*s == '\0')	/* no name, return */
  	return;
  
      /* uncompress the image file if it is compressed (new name returns in s) */
diff -c ../xfig.3.2.2/e_flip.c ./e_flip.c
*** ../xfig.3.2.2/e_flip.c	Sat Jun  6 06:28:49 1998
--- ./e_flip.c	Sat May 29 12:23:45 1999
***************
*** 341,346 ****
--- 341,351 ----
  	break;
      case LR_FLIP:		/* y axis  */
  	t->base_x = x + (x - t->base_x);
+ 	/* must flip right/left justification too */
+ 	if (t->type == T_LEFT_JUSTIFIED)
+ 	    t->type =T_RIGHT_JUSTIFIED;
+ 	else if (t->type == T_RIGHT_JUSTIFIED)
+ 	    t->type =T_LEFT_JUSTIFIED;
  	break;
      }
  }
diff -c ../xfig.3.2.2/e_update.c ./e_update.c
*** ../xfig.3.2.2/e_update.c	Sat Jun  6 06:29:16 1998
--- ./e_update.c	Sat May 29 12:23:48 1999
***************
*** 368,374 ****
      up_part(text->font, using_ps ? cur_ps_font : cur_latex_font, I_FONT);
      old_psfont_flag = (text->flags & PSFONT_TEXT);
      new_psfont_flag = (cur_textflags & PSFONT_TEXT);
!     up_part(text->flags, cur_textflags & ~PSFONT_TEXT, I_TEXTFLAGS);
      if (cur_updatemask & I_FONT)
  	text->flags |= new_psfont_flag;
      else
--- 368,374 ----
      up_part(text->font, using_ps ? cur_ps_font : cur_latex_font, I_FONT);
      old_psfont_flag = (text->flags & PSFONT_TEXT);
      new_psfont_flag = (cur_textflags & PSFONT_TEXT);
!     text->flags &= ~PSFONT_TEXT;
      if (cur_updatemask & I_FONT)
  	text->flags |= new_psfont_flag;
      else
diff -c ../xfig.3.2.2/f_read.c ./f_read.c
*** ../xfig.3.2.2/f_read.c	Tue Jun 30 02:05:32 1998
--- ./f_read.c	Sat May 29 12:23:50 1999
***************
*** 648,655 ****
  	    return (NULL);
  	}
  	skip_line(fp);
! 	convert_arrow(&wd, &ht);
! 	a->for_arrow = new_arrow(type, style, thickness, wd, ht);
  	skip_comment(fp);
      }
      skip_comment(fp);
--- 648,658 ----
  	    return (NULL);
  	}
  	skip_line(fp);
! 	/* throw away any arrow heads on pie-wedge arcs */
! 	if (a->type == T_OPEN_ARC) {
! 	    convert_arrow(&wd, &ht);
! 	    a->for_arrow = new_arrow(type, style, thickness, wd, ht);
! 	}
  	skip_comment(fp);
      }
      skip_comment(fp);
***************
*** 660,667 ****
  	    return (NULL);
  	}
  	skip_line(fp);
! 	convert_arrow(&wd, &ht);
! 	a->back_arrow = new_arrow(type, style, thickness, wd, ht);
      }
      return (a);
  }
--- 663,673 ----
  	    return (NULL);
  	}
  	skip_line(fp);
! 	/* throw away any arrow heads on pie-wedge arcs */
! 	if (a->type == T_OPEN_ARC) {
! 	    convert_arrow(&wd, &ht);
! 	    a->for_arrow = new_arrow(type, style, thickness, wd, ht);
! 	}
      }
      return (a);
  }
***************
*** 1538,1564 ****
  	return;				/* no, ok */
  
      /* ask the user */
!     if (popup_query(QUERY_YESNO, shift_msg)==RESULT_NO)
  	return;
  
      /* shift the whole figure to keep it "on the page" */
      dx = dy = 0;
      rnd = posn_rnd[cur_pointposn];
!     if (lowx < 0)
! 	{
  	dx = -lowx+rnd;	/* and round up to small grid */
! 	if (rnd != 0)
! 	    dx--;
! 	}
!     if (lowy < 0)
! 	{
  	dy = -lowy+rnd;
! 	if (rnd != 0)
! 	    dy--;
! 	}
!     file_msg(
! 	"Shifting entire figure %d units right and %d units down to keep on page.",
! 	dx,dy);
      for (e = obj->ellipses; e != NULL; e = e->next)
  	translate_ellipse(e, dx, dy);
      for (a = obj->arcs; a != NULL; a = a->next)
--- 1544,1565 ----
  	return;				/* no, ok */
  
      /* ask the user */
!     if (!preview_in_progress && (popup_query(QUERY_YESNO, shift_msg)==RESULT_NO))
  	return;
  
      /* shift the whole figure to keep it "on the page" */
      dx = dy = 0;
      rnd = posn_rnd[cur_pointposn];
!     if (lowx < 0) {
  	dx = -lowx+rnd;	/* and round up to small grid */
!     }
!     if (lowy < 0) {
  	dy = -lowy+rnd;
!     }
!     if (!preview_in_progress)
! 	file_msg(
! 	    "Shifting entire figure %d units right and %d units down to keep on page.",
! 	    dx,dy);
      for (e = obj->ellipses; e != NULL; e = e->next)
  	translate_ellipse(e, dx, dy);
      for (a = obj->arcs; a != NULL; a = a->next)
diff -c ../xfig.3.2.2/fig.h ./fig.h
*** ../xfig.3.2.2/fig.h	Sat Jun  6 05:51:01 1998
--- ./fig.h	Sat May 29 12:23:48 1999
***************
*** 341,347 ****
  #define		signof(a)	(((a) < 0) ? -1 : 1)
  
  #ifdef USE_INLINE
! #define INLINE inline
  #else
  #define INLINE
  #endif /* USE_INLINE */
--- 341,347 ----
  #define		signof(a)	(((a) < 0) ? -1 : 1)
  
  #ifdef USE_INLINE
! #define INLINE __inline
  #else
  #define INLINE
  #endif /* USE_INLINE */
diff -c ../xfig.3.2.2/main.c ./main.c
*** ../xfig.3.2.2/main.c	Tue Jun 30 05:25:55 1998
--- ./main.c	Sat Jun 12 13:08:50 1999
***************
*** 56,61 ****
--- 56,62 ----
  #endif
  
  #ifdef I18N
+ #include <X11/keysym.h>
  #include <locale.h>
  #endif  /* I18N */
  
***************
*** 169,175 ****
      {"userunit", "UserUnit",   XtRString, sizeof(char *),
        XtOffset(appresPtr, user_unit), XtRString, (caddr_t) ""},
      {"but_per_row", "But_per_row",   XtRInt, sizeof(int),
!       XtOffset(appresPtr, but_per_row), XtRImmediate, (caddr_t) 2},
      {"max_image_colors", "Max_image_colors", XtRInt, sizeof(int),
        XtOffset(appresPtr, max_image_colors), XtRImmediate, (caddr_t) 0},
      {"dont_switch_cmap", "Dont_switch_cmap", XtRBoolean, sizeof(Boolean),
--- 170,176 ----
      {"userunit", "UserUnit",   XtRString, sizeof(char *),
        XtOffset(appresPtr, user_unit), XtRString, (caddr_t) ""},
      {"but_per_row", "But_per_row",   XtRInt, sizeof(int),
!       XtOffset(appresPtr, but_per_row), XtRImmediate, (caddr_t) 0},
      {"max_image_colors", "Max_image_colors", XtRInt, sizeof(int),
        XtOffset(appresPtr, max_image_colors), XtRImmediate, (caddr_t) 0},
      {"dont_switch_cmap", "Dont_switch_cmap", XtRBoolean, sizeof(Boolean),
***************
*** 216,221 ****
--- 217,228 ----
         XtOffset(appresPtr, japanese), XtRBoolean, (caddr_t) & true},
      {"eucEncoding", "EucEncoding", XtRBoolean, sizeof(Boolean),
         XtOffset(appresPtr, euc_encoding), XtRBoolean, (caddr_t) & true},
+     {"alwaysUseFontSet", "AlwaysUseFontSet", XtRBoolean, sizeof(Boolean),
+        XtOffset(appresPtr, always_use_fontset), XtRBoolean, (caddr_t) & false},
+     {"fixedFontSet", "FontSet", XtRFontSet, sizeof(XFontSet),
+        XtOffset(appresPtr, fixed_fontset), XtRString,
+        (caddr_t) "-*-times-medium-r-normal--16-*-*-*-*-*-*-*,"
+ 	 "-*-*-medium-r-normal--16-*-*-*-*-*-*-*,*--16-*" },
      {"normalFontSet", "NormalFontSet", XtRFontSet, sizeof(XFontSet),
         XtOffset(appresPtr, normal_fontset), XtRString,
         (caddr_t) "-*-times-medium-r-normal--16-*-*-*-*-*-*-*,"
***************
*** 227,243 ****
  	 "-*-*-bold-r-normal--16-*-*-*-*-*-*-*,"
  	 "-*-*-*-r-*--16-*-*-*-*-*-*-*" },
      {"fontSetSize", "FontSetSize", XtRInt, sizeof(int),
!        XtOffset(appresPtr, fontset_size), XtRImmediate, (caddr_t)16 },
      {"inputStyle", "InputStyle", XtRString, sizeof(char *),
         XtOffset(appresPtr, xim_input_style), XtRString, (caddr_t) "OffTheSpot"},
-     {"fixedFontSet", "FontSet", XtRFontSet, sizeof(XFontSet),
-        XtOffset(appresPtr, fixed_fontset), XtRString,
-        (caddr_t) "-*-times-medium-r-normal--16-*-*-*-*-*-*-*,"
- 	 "-*-*-medium-r-normal--16-*-*-*-*-*-*-*,*--16-*" },
-     {"textPreedit", "TextPreedit", XtRString, sizeof(char *),
-        XtOffset(appresPtr, text_preedit), XtRString, (caddr_t) ""},
      {"fig2devLocalizeOption", "Fig2devLocalizeOption", XtRString, sizeof(char *),
         XtOffset(appresPtr, fig2dev_localize_option), XtRString, (caddr_t) "-j"},
  #endif  /* I18N */
  };
  
--- 234,248 ----
  	 "-*-*-bold-r-normal--16-*-*-*-*-*-*-*,"
  	 "-*-*-*-r-*--16-*-*-*-*-*-*-*" },
      {"fontSetSize", "FontSetSize", XtRInt, sizeof(int),
!        XtOffset(appresPtr, fontset_size), XtRImmediate, (caddr_t)0 },
      {"inputStyle", "InputStyle", XtRString, sizeof(char *),
         XtOffset(appresPtr, xim_input_style), XtRString, (caddr_t) "OffTheSpot"},
      {"fig2devLocalizeOption", "Fig2devLocalizeOption", XtRString, sizeof(char *),
         XtOffset(appresPtr, fig2dev_localize_option), XtRString, (caddr_t) "-j"},
+ #ifdef I18N_USE_PREEDIT
+     {"textPreedit", "TextPreedit", XtRString, sizeof(char *),
+        XtOffset(appresPtr, text_preedit), XtRString, (caddr_t) ""},
+ #endif
  #endif  /* I18N */
  };
  
***************
*** 818,823 ****
--- 823,875 ----
      }
  	
      setup_sizes(init_canv_wd, init_canv_ht);
+ 
+     /* if canvas size was not specified explicitly, shrink the
+        canvas so that xfig window can fit can fit into the screen */
+     if (appres.but_per_row <= 0
+ 	|| appres.tmp_height <= 0 || appres.tmp_width <= 0) {
+       int IND_SW_HT = 32;  /* this should defined in w_icons.h */
+       int message_ht = CMDPANEL_HT;  /* assume all height are same... */
+       int scrollbar_ht = CMDPANEL_HT;
+       int margin_ht = 30;  /* margin for window decoration */
+       int margin_wd = 20;
+       int max_ht, max_wd, min_sw_per_row;
+       Boolean resize = FALSE;
+ 
+       if (appres.tmp_height <= 0) {
+ 	max_ht = HeightOfScreen(XtScreen(tool))
+ 	  - CMDPANEL_HT - message_ht - TOPRULER_HT - IND_SW_HT
+ 	    - scrollbar_ht - INTERNAL_BW * 4 - margin_ht;
+ 	CANVAS_HT_LAND = min2(max_ht, CANVAS_HT_LAND);
+ 	CANVAS_HT_PORT = min2(max_ht, CANVAS_HT_PORT);
+ 	if (max_ht < init_canv_ht) {
+ 	  init_canv_ht = max_ht;
+ 	  resize = TRUE;
+ 	}
+       }
+ 
+       if (appres.but_per_row <= 0) {
+ 	/* decide SW_PER_ROW so that they can fit into the window */
+ 	min_sw_per_row = (MODE_SW_HT + INTERNAL_BW) * 38 / init_canv_ht + 1;
+ 	SW_PER_ROW = max2(min_sw_per_row, SW_PER_ROW);
+       }
+ 
+       if (appres.tmp_width <= 0) {
+ 	max_wd = WidthOfScreen(XtScreen(tool))
+ 	  - INTERNAL_BW * 2 - (MODE_SW_WD + INTERNAL_BW) * SW_PER_ROW
+ 	    - SIDERULER_WD - margin_wd;
+ 	CANVAS_WD_LAND = min2(max_wd, CANVAS_WD_LAND);
+ 	CANVAS_WD_PORT = min2(max_wd, CANVAS_WD_PORT);
+ 	if (max_wd < init_canv_wd) {
+ 	  init_canv_wd = max_wd;
+ 	  resize = TRUE;
+ 	}
+       }
+ 
+       if (resize)
+ 	setup_sizes(init_canv_wd, init_canv_ht);
+     }
+ 
      (void) init_cmd_panel(form);
      (void) init_msg(form,arg_filename);
      (void) init_mousefun(form);
***************
*** 1304,1309 ****
--- 1356,1365 ----
      }
      else
  #ifdef I18N
+       /* I use this code instead of XtAppMainLoop(), bacause there was
+          a problem when used with kinput2.
+ 	 Probably, it is not good idea to mix call of XtDispatchEvent()
+ 	 and canvas_selected(), but I couldn't find better solution. -T.S. */
      if (xim_ic != NULL) {
        XEvent event;
        for (;;) {
***************
*** 1311,1320 ****
  	if (!xim_active) {
  	  XtDispatchEvent(&event);
  	} else if (!XFilterEvent(&event, XtWindow(canvas_sw))) {
! 	  if (event.type == KeyPress) {
! 	    canvas_selected(canvas_sw, &event, NULL, NULL);
! 	    /* call it directly because Window ID may different */
! 	    /* this is not good... */
  	  } else {
  	    XtDispatchEvent(&event);
  	  }
--- 1367,1380 ----
  	if (!xim_active) {
  	  XtDispatchEvent(&event);
  	} else if (!XFilterEvent(&event, XtWindow(canvas_sw))) {
! 	  if (event.type == KeyPress
! 	      && XtWindow(canvas_sw) == ((XKeyPressedEvent *)&event)->window) {
! 	    KeySym key = XLookupKeysym((XKeyPressedEvent *)&event, 0);
! 	    if (XK_F1 <= key && key <= XK_F35) {
! 	      XtDispatchEvent(&event);
! 	    } else {
! 	      canvas_selected(canvas_sw, &event, NULL, NULL);
! 	    }
  	  } else {
  	    XtDispatchEvent(&event);
  	  }
diff -c ../xfig.3.2.2/mode.h ./mode.h
*** ../xfig.3.2.2/mode.h	Thu Jul  2 09:04:58 1998
--- ./mode.h	Sat May 29 12:23:47 1999
***************
*** 37,42 ****
--- 37,43 ----
  #define		F_REGPOLY		15
  #define		F_PICOBJ		16
  #define		F_PLACE_LIB_OBJ		17
+ #define		F_PASTE			18
  
  #define	    FIRST_EDIT_MODE	    F_GLUE
  #define		F_GLUE			30
diff -c ../xfig.3.2.2/resources.h ./resources.h
*** ../xfig.3.2.2/resources.h	Sat Jun  6 07:40:14 1998
--- ./resources.h	Sat Jun 12 12:54:53 1999
***************
*** 184,196 ****
      Boolean international;
      Boolean japanese;
      Boolean euc_encoding;
      XFontSet normal_fontset;
      XFontSet bold_fontset;
      int fontset_size;
-     String fig2dev_localize_option;
      String xim_input_style;
!     XFontSet fixed_fontset;
      String text_preedit;
  #endif  /* I18N */
  }		appresStruct, *appresPtr;
  extern appresStruct appres;
--- 184,199 ----
      Boolean international;
      Boolean japanese;
      Boolean euc_encoding;
+     Boolean always_use_fontset;
+     XFontSet fixed_fontset;
      XFontSet normal_fontset;
      XFontSet bold_fontset;
      int fontset_size;
      String xim_input_style;
!     String fig2dev_localize_option;
! #ifdef I18N_USE_PREEDIT
      String text_preedit;
+ #endif
  #endif  /* I18N */
  }		appresStruct, *appresPtr;
  extern appresStruct appres;
diff -c ../xfig.3.2.2/u_draw.c ./u_draw.c
*** ../xfig.3.2.2/u_draw.c	Fri Jul  3 01:41:18 1998
--- ./u_draw.c	Sat May 29 12:23:42 1999
***************
*** 1280,1286 ****
      dx=x2-x1;
      r=sqrt(dx*dx+dy*dy);
  
!     h = (double) arrow->ht;
      /* lpt is the amount the arrowhead extends beyond the end of the line */
      lpt = arrow->thickness/2.0/(arrow->wd/h/2.0);
      /* add this to the length */
--- 1280,1286 ----
      dx=x2-x1;
      r=sqrt(dx*dx+dy*dy);
  
!     h = (double) arrow->ht*ZOOM_FACTOR;
      /* lpt is the amount the arrowhead extends beyond the end of the line */
      lpt = arrow->thickness/2.0/(arrow->wd/h/2.0);
      /* add this to the length */
diff -c ../xfig.3.2.2/u_elastic.c ./u_elastic.c
*** ../xfig.3.2.2/u_elastic.c	Fri Jun 12 09:09:23 1998
--- ./u_elastic.c	Sat May 29 12:23:46 1999
***************
*** 25,30 ****
--- 25,31 ----
  #include "w_canvas.h"
  #include "w_setup.h"
  #include "w_zoom.h"
+ #include "d_arc.h"
  
  /********************** EXPORTS **************/
  
***************
*** 708,713 ****
--- 709,725 ----
  }
  
  /*************************** ARCS *************************/
+ 
+ void
+ arc_point(x, y, numpoint)
+     int		    x, y, numpoint;
+ {
+     elastic_line();
+     cur_x = x;
+     cur_y = y;
+     altlength_msg(MSG_DIAM_ANGLE, center_point.x, center_point.y);
+     elastic_line();
+ }
  
  void
  reshaping_arc(x, y)
diff -c ../xfig.3.2.2/u_elastic.h ./u_elastic.h
*** ../xfig.3.2.2/u_elastic.h	Fri Jun 12 09:09:10 1998
--- ./u_elastic.h	Sat May 29 12:23:46 1999
***************
*** 30,35 ****
--- 30,36 ----
  #define		MSG_LENGTH	3
  #define		MSG_DIST	4
  #define		MSG_PNTS_LENGTH	5
+ #define		MSG_DIAM_ANGLE	6
  
  extern int	constrained;
  extern float	cur_angle;
***************
*** 73,78 ****
--- 74,80 ----
  extern void	elastic_scalepts();
  extern void	scaling_line();
  
+ extern void	arc_point();
  extern void	moving_arc();
  extern void	elastic_movearc();
  extern void	reshaping_arc();
diff -c ../xfig.3.2.2/u_markers.c ./u_markers.c
*** ../xfig.3.2.2/u_markers.c	Sat Jun  6 06:38:51 1998
--- ./u_markers.c	Sat May 29 12:23:48 1999
***************
*** 310,316 ****
      dy = (int) ((double) t->ascent * cos(t->angle));
      dx = (int) ((double) t->ascent * sin(t->angle));
      set_marker(canvas_win,t->base_x-dx-2,t->base_y-dy-2,MARK_SIZ,MARK_SIZ);
!     set_marker(canvas_win,t->base_x-2,t->base_y-2,MARK_SIZ,MARK_SIZ);
      if (t->tagged)
  	toggle_texthighlight(t);
  }
--- 310,319 ----
      dy = (int) ((double) t->ascent * cos(t->angle));
      dx = (int) ((double) t->ascent * sin(t->angle));
      set_marker(canvas_win,t->base_x-dx-2,t->base_y-dy-2,MARK_SIZ,MARK_SIZ);
!     /* only draw second marker if not on top of first (e.g. string with only
!        spaces has no height) */
!     if (dx != 0 || dy != 0)
! 	set_marker(canvas_win,t->base_x-2,t->base_y-2,MARK_SIZ,MARK_SIZ);
      if (t->tagged)
  	toggle_texthighlight(t);
  }
diff -c ../xfig.3.2.2/u_print.c ./u_print.c
*** ../xfig.3.2.2/u_print.c	Sat Jun  6 06:39:15 1998
--- ./u_print.c	Sat May 29 16:49:34 1999
***************
*** 262,281 ****
  	if (transparent) {
  	    /* escape the first character of the transparent color (#) for the shell */
  #ifdef I18N
! 	    sprintf(prcmd, "fig2dev -L%s %s -t \\%s -m %f %s %s", 
  		appres.international ? appres.fig2dev_localize_option : "",
  #else
! 	    sprintf(prcmd, "fig2dev -L%s -t \\%s -m %f %s %s", 
  #endif  /* I18N */
! 			lang, transparent, mag/100.0, tmp_fig_file, outfile);
  	} else {
  #ifdef I18N
! 	    sprintf(prcmd, "fig2dev -L%s %s -m %f %s %s", 
  		appres.international ? appres.fig2dev_localize_option : "",
  #else
! 	    sprintf(prcmd, "fig2dev -L%s -m %f %s %s", 
  #endif  /* I18N */
! 			lang, mag/100.0, tmp_fig_file, outfile);
  	}
  
      /* everything else */
--- 262,281 ----
  	if (transparent) {
  	    /* escape the first character of the transparent color (#) for the shell */
  #ifdef I18N
! 	    sprintf(prcmd, "fig2dev -L%s %s -t \\%s -m %f %s %s", lang,
  		appres.international ? appres.fig2dev_localize_option : "",
  #else
! 	    sprintf(prcmd, "fig2dev -L%s -t \\%s -m %f %s %s", lang,
  #endif  /* I18N */
! 			transparent, mag/100.0, tmp_fig_file, outfile);
  	} else {
  #ifdef I18N
! 	    sprintf(prcmd, "fig2dev -L%s %s -m %f %s %s", lang,
  		appres.international ? appres.fig2dev_localize_option : "",
  #else
! 	    sprintf(prcmd, "fig2dev -L%s -m %f %s %s", lang,
  #endif  /* I18N */
! 			mag/100.0, tmp_fig_file, outfile);
  	}
  
      /* everything else */
diff -c ../xfig.3.2.2/u_redraw.c ./u_redraw.c
*** ../xfig.3.2.2/u_redraw.c	Wed Jul  1 08:22:07 1998
--- ./u_redraw.c	Sat May 29 12:23:50 1999
***************
*** 25,34 ****
--- 25,40 ----
  #include "e_rotate.h"
  #include "u_draw.h"
  #include "w_canvas.h"
+ #include "w_file.h"
  #include "w_setup.h"
  #include "w_util.h"
  #include "w_zoom.h"
  
+ /* EXPORTS */
+ 
+ /* set in redisplay_region if called when preview_in_progress is true */
+ Boolean	request_redraw = False;
+ 
  /*
   * Support for rendering based on correct object depth.	 A simple depth based
   * caching scheme; anything more will require major surgery on the object
***************
*** 424,432 ****
  
      /* find which type of object we need to refresh */
  
!     if (cur_mode >= FIRST_EDIT_MODE && canvas_locmove_proc != null_proc) {
! 	(*canvas_locmove_proc)(last_x, last_y);
!     } else {
        switch (cur_mode) {
  	case F_PICOBJ:
  	case F_ARC_BOX:
--- 430,436 ----
  
      /* find which type of object we need to refresh */
  
!     if (cur_mode < FIRST_EDIT_MODE) {
        switch (cur_mode) {
  	case F_PICOBJ:
  	case F_ARC_BOX:
***************
*** 495,500 ****
--- 499,513 ----
  redisplay_region(xmin, ymin, xmax, ymax)
      int		    xmin, ymin, xmax, ymax;
  {
+     /* if we're generating a preview, don't redisplay the canvas 
+        but set request flag so preview will call us with full canvas 
+        after it is done generating the preview */
+ 
+     if (preview_in_progress) {
+ 	request_redraw = True;
+ 	return;
+     }
+ 
      set_temp_cursor(wait_cursor);
      /* kludge so that markers are redrawn */
      xmin -= 10;
diff -c ../xfig.3.2.2/u_redraw.h ./u_redraw.h
*** ../xfig.3.2.2/u_redraw.h	Sat Jun  6 06:17:15 1998
--- ./u_redraw.h	Sat May 29 12:23:50 1999
***************
*** 16,18 ****
--- 16,20 ----
   */
  
  extern void	redisplay_canvas();
+ extern Boolean	request_redraw;		/* set in redisplay_region if called when
+ 					   preview_in_progress is true */
diff -c ../xfig.3.2.2/w_canvas.c ./w_canvas.c
*** ../xfig.3.2.2/w_canvas.c	Wed Jul  1 07:32:53 1998
--- ./w_canvas.c	Tue Jun  8 22:09:52 1999
***************
*** 489,494 ****
--- 489,506 ----
  		event_time = paste_event->time;
  	   else
  		time((time_t *) &event_time);
+ 
+ #ifdef I18N
+ 	if (appres.international) {
+ 	  Atom atom_compound_text = XInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
+ 	  if (atom_compound_text) {
+ 	    XtGetSelectionValue(w, XA_PRIMARY, atom_compound_text,
+ 				get_canvas_clipboard, NULL, event_time);
+ 	    return;
+ 	  }
+ 	}
+ #endif  /* I18N */
+ 
  	XtGetSelectionValue(w, XA_PRIMARY,
  		XA_STRING, get_canvas_clipboard, NULL, event_time);
  }
***************
*** 505,510 ****
--- 517,553 ----
  {
  	unsigned char *c;
  	int i;
+ #ifdef I18N
+ 	if (appres.international) {
+ 	  Atom atom_compound_text = XInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
+ 	  char **tmp;
+ 	  XTextProperty prop;
+ 	  int num_values;
+ 	  int ret_status;
+ 
+ 	  if (*type == atom_compound_text) {
+ 	    prop.value = buf;
+ 	    prop.encoding = *type;
+ 	    prop.format = *format;
+ 	    prop.nitems = *length;
+ 	    num_values = 0;
+ 	    ret_status = XmbTextPropertyToTextList(XtDisplay(w), &prop, &tmp, &num_values);
+ 	    if (ret_status == Success || 0 < num_values) {
+ 	      for (i = 0; i < num_values; i++) {
+ 		for (c = tmp[i]; *c; c++) {
+ 		  if (canvas_kbd_proc == char_handler && ' ' <= *c && *(c + 1)) {
+ 		    prefix_append_char(*c);
+ 		  } else {
+ 		    canvas_kbd_proc((XKeyEvent *) 0, *c, (KeySym) 0);
+ 		  }
+ 		}
+ 	      }
+ 	      XtFree(buf);
+ 	      return;
+ 	    }
+ 	  }
+ 	}
+ #endif  /* I18N */
  
  	c = (unsigned char *) buf;
  	for (i=0; i<*length; i++) {
diff -c ../xfig.3.2.2/w_cmdpanel.c ./w_cmdpanel.c
*** ../xfig.3.2.2/w_cmdpanel.c	Tue Jun 30 02:20:15 1998
--- ./w_cmdpanel.c	Sat May 29 13:58:26 1999
***************
*** 59,64 ****
--- 59,71 ----
  void		new();
  void		delete_all_cmd();
  void		paste();
+ static void	init_move_object(),move_object();
+ static void	place_object(),cancel_paste();
+ static void	put_draw();
+ static void	place_object_orig_posn();
+ 
+ static int	cur_paste_x,cur_paste_y,off_paste_x,off_paste_y;
+ static int	orig_paste_x,orig_paste_y;
  
  /* popup message over button when mouse enters it */
  static void     cmd_balloon_trigger();
***************
*** 426,434 ****
      Boolean	    abortflag;
  {
  #ifdef I18N
! #ifndef I18N_NO_PREEDIT
    kill_preedit();
! #endif  /* I18N_NO_PREEDIT */
  #endif  /* I18N */
      /* delete the cut buffer only if it is in a temporary directory */
      if (strncmp(cut_buf_name, TMPDIR, strlen(TMPDIR)) == 0)
--- 433,441 ----
      Boolean	    abortflag;
  {
  #ifdef I18N
! #ifdef I18N_USE_PREEDIT
    kill_preedit();
! #endif  /* I18N_USE_PREEDIT */
  #endif  /* I18N */
      /* delete the cut buffer only if it is in a temporary directory */
      if (strncmp(cut_buf_name, TMPDIR, strlen(TMPDIR)) == 0)
***************
*** 453,463 ****
      exit(0);
  }
  
- static void	init_move_object(),move_object();
- static void	place_object(),cancel_paste();
- static void	put_draw();
- static int	cur_paste_x,cur_paste_y,off_paste_x,off_paste_y;
- 
  void
  paste(w)
      Widget	    w;
--- 460,465 ----
***************
*** 471,479 ****
  
  	set_cursor(wait_cursor);
  	turn_off_current();
! 	set_mousefun("place object","","cancel paste",
! 			"place object", "", "cancel paste");
  	set_action_on();
  	cur_c = create_compound();
  	cur_c->parent = NULL;
  	cur_c->GABPtr = NULL;
--- 473,484 ----
  
  	set_cursor(wait_cursor);
  	turn_off_current();
! 	set_mousefun("place object","place at orig posn","cancel paste",
! 			"place object", "place at orig posn", "cancel paste");
! 	/* set to paste mode */
  	set_action_on();
+ 	cur_mode = F_PASTE;
+ 
  	cur_c = create_compound();
  	cur_c->parent = NULL;
  	cur_c->GABPtr = NULL;
***************
*** 493,498 ****
--- 498,508 ----
  			     &cur_c->secorner.x,
  			     &cur_c->secorner.y);
  	  
+ 		/* save orig coords of object */
+ 		orig_paste_x = cur_c->nwcorner.x;
+ 		orig_paste_y = cur_c->nwcorner.y;
+ 
+ 		/* make it relative for mouse positioning */
  		translate_compound(cur_c, -cur_c->nwcorner.x, -cur_c->nwcorner.y);
  	} else {
  		/* an error reading a .fig file */
***************
*** 516,522 ****
  	off_paste_y=new_c->secorner.y;
  	canvas_locmove_proc = init_move_object;
  	canvas_leftbut_proc = place_object;
! 	canvas_middlebut_proc = null_proc;
  	canvas_rightbut_proc = cancel_paste;
  
  	/* set crosshair cursor */
--- 526,532 ----
  	off_paste_y=new_c->secorner.y;
  	canvas_locmove_proc = init_move_object;
  	canvas_leftbut_proc = place_object;
! 	canvas_middlebut_proc = place_object_orig_posn;
  	canvas_rightbut_proc = cancel_paste;
  
  	/* set crosshair cursor */
***************
*** 577,601 ****
  init_move_object(x, y)
      int		    x, y;
  {	
!     cur_paste_x=x;
!     cur_paste_y=y;
      translate_compound(new_c,x,y);
      
      put_draw(PAINT);
      canvas_locmove_proc = move_object;
  }
  
  static void
  place_object(x, y, shift)
      int		    x, y;
      unsigned int    shift;
  {
-     canvas_leftbut_proc = null_proc;
-     canvas_middlebut_proc = null_proc;
-     canvas_rightbut_proc = null_proc;
-     canvas_locmove_proc = null_proc;
      put_draw(ERASE);
      clean_up();
      add_compound(new_c);
      set_modifiedflag();
      redisplay_compound(new_c);
--- 587,630 ----
  init_move_object(x, y)
      int		    x, y;
  {	
!     cur_paste_x = x;
!     cur_paste_y = y;
      translate_compound(new_c,x,y);
      
      put_draw(PAINT);
      canvas_locmove_proc = move_object;
  }
  
+ /* button 1: paste object at current position of mouse */
+ 
  static void
  place_object(x, y, shift)
      int		    x, y;
      unsigned int    shift;
  {
      put_draw(ERASE);
      clean_up();
+     add_compound(new_c);
+     set_modifiedflag();
+     redisplay_compound(new_c);
+     cancel_paste();
+ }
+ 
+ /* button 2: paste object in original location whence it came */
+ 
+ static void
+ place_object_orig_posn(x, y, shift)
+     int		    x, y;
+     unsigned int    shift;
+ {
+     int dx,dy;
+ 
+     put_draw(ERASE);
+     clean_up();
+     /* move back to original position */
+     dx = orig_paste_x-x;
+     dy = orig_paste_y-y;
+     translate_compound(new_c,dx,dy);
      add_compound(new_c);
      set_modifiedflag();
      redisplay_compound(new_c);
diff -c ../xfig.3.2.2/w_color.c ./w_color.c
*** ../xfig.3.2.2/w_color.c	Thu Jun 25 07:42:07 1998
--- ./w_color.c	Sat May 29 12:23:48 1999
***************
*** 854,863 ****
  	    tool_vclass == DirectColor ||
  	    tool_vclass == TrueColor) {
  		XAllocColor(tool_d, tool_cm, &mixed_color[which]);
! 		if (colorMemory[which]) {
! 		    FirstArg(XtNbackground, mixed_color[which].pixel);
! 		    SetValues(mixedColor[which]);
! 		}
  	} else {
  		XStoreColor(tool_d, tool_cm, &mixed_color[which]);
  	}
--- 854,861 ----
  	    tool_vclass == DirectColor ||
  	    tool_vclass == TrueColor) {
  		XAllocColor(tool_d, tool_cm, &mixed_color[which]);
! 		FirstArg(XtNbackground, mixed_color[which].pixel);
! 		SetValues(mixedColor[which]);
  	} else {
  		XStoreColor(tool_d, tool_cm, &mixed_color[which]);
  	}
***************
*** 1075,1081 ****
  	    /* try to get a colorcell */
  	    if (!alloc_color_cells(pixels,1)) {
  		put_msg("Can't allocate user color, not enough colorcells");
! 		return 0;
  	    }
  	}
  	if (!use_exist) {
--- 1073,1079 ----
  	    /* try to get a colorcell */
  	    if (!alloc_color_cells(pixels,1)) {
  		put_msg("Can't allocate user color, not enough colorcells");
! 		return -1;
  	    }
  	}
  	if (!use_exist) {
diff -c ../xfig.3.2.2/w_drawprim.c ./w_drawprim.c
*** ../xfig.3.2.2/w_drawprim.c	Sat Jun  6 06:42:27 1998
--- ./w_drawprim.c	Sat May 29 12:23:44 1999
***************
*** 1251,1256 ****
--- 1251,1259 ----
      /* required to draw dashes for zero-width lines */
      if (width == 1 && style == SOLID_LINE)
  	width = 0;
+     /* conversely, if the width is calculated to 0 and this is a dashed line, make width 1 */
+     if (width == 0 && style != SOLID_LINE)
+ 	width = 1;
  
      /* if we're drawing to the bitmap instead of the canvas
         map colors white => white, all others => black */
diff -c ../xfig.3.2.2/w_file.c ./w_file.c
*** ../xfig.3.2.2/w_file.c	Sat Jun  6 09:09:49 1998
--- ./w_file.c	Sat May 29 12:23:50 1999
***************
*** 21,26 ****
--- 21,27 ----
  #include "mode.h"
  #include "e_edit.h"
  #include "f_read.h"
+ #include "u_redraw.h"
  #include "w_drawprim.h"		/* for max_char_height */
  #include "w_dir.h"
  #include "w_export.h"
***************
*** 1102,1110 ****
--- 1103,1120 ----
      if (file_load_request) {
  	cancel_preview = False;
  	do_load((Widget) 0, (XButtonEvent *) 0);
+ 	/* if redisplay_region was called don't bother because
+ 	   we're loading a file over it */
+ 	request_redraw = False;		
      }
      if (file_save_request) {
  	cancel_preview = False;
  	do_save((Widget) 0, (XButtonEvent *) 0);
+     }
+     /* if user requested a canvas redraw while preview was being generated
+        do that now for full canvas */
+     if (request_redraw) {
+ 	redisplay_region(0, 0, CANVAS_WD, CANVAS_HT);
+ 	request_redraw = False;
      }
  }
diff -c ../xfig.3.2.2/w_help.c ./w_help.c
*** ../xfig.3.2.2/w_help.c	Wed Jun 17 01:06:43 1998
--- ./w_help.c	Sat May 29 12:23:46 1999
***************
*** 23,28 ****
--- 23,37 ----
  char	cmd[400];
  Boolean check_docfile();
  
+ void	help_ok();
+ 
+ static String	about_translations =
+ 	"<Message>WM_PROTOCOLS: DismissAbout()\n";
+ static XtActionsRec	about_actions[] =
+ {
+     {"DismissAbout", (XtActionProc) help_ok},
+ };
+ 
  void
  launch_html(w, closure, call_data)
      Widget    w;
***************
*** 143,148 ****
--- 152,161 ----
  	NextArg(XtNy, y);
  	help_popup = XtCreatePopupShell("About Xfig",transientShellWidgetClass,
  				tool, Args, ArgCount);
+ 	XtOverrideTranslations(help_popup,
+ 			   XtParseTranslationTable(about_translations));
+ 	XtAppAddActions(tool_app, about_actions, XtNumber(about_actions));
+ 
  	FirstArg(XtNborderWidth, 0);
  	form = XtCreateManagedWidget("help_form", formWidgetClass, help_popup,
  				Args, ArgCount);
***************
*** 175,178 ****
--- 188,192 ----
  	XtAddCallback(ok, XtNcallback, help_ok, (XtPointer) NULL);
      }
      XtPopup(help_popup,XtGrabNone);
+     (void) XSetWMProtocols(tool_d, XtWindow(help_popup), &wm_delete_window, 1);
  }
diff -c ../xfig.3.2.2/w_i18n.c ./w_i18n.c
*** ../xfig.3.2.2/w_i18n.c	Sat Jun  6 06:44:23 1998
--- ./w_i18n.c	Sun Jun 13 15:18:47 1999
***************
*** 207,212 ****
--- 207,213 ----
       char *str;
  {
    int i;
+   if (appres.always_use_fontset) return TRUE;
    for (i = 0; str[i] != '\0'; i++) {
      if (str[i] & 0x80) return TRUE;
    }
***************
*** 221,233 ****
       int *size_ret;
  {
    extern struct _xfstruct x_fontinfo[]; /* X11 fontnames */
!   static font_types[] = { 0, 2 };  /* 0 = Times-Roman, 2 = Times-Bold */
    struct xfont *nf;
    int i;
    if (!appres.international) return FALSE;
    for (i = 0; i < XtNumber(font_types); i++) {
      nf = x_fontinfo[font_types[i]].xfontlist;
!     while (nf != NULL && nf->fstruct->fid != fid) nf = nf->next;
      if (nf != NULL) {
        *fontset = (font_types[i]==0) ? appres.normal_fontset : appres.bold_fontset;
        *size_ret = nf->size;
--- 222,235 ----
       int *size_ret;
  {
    extern struct _xfstruct x_fontinfo[]; /* X11 fontnames */
!   static int font_types[] = { 0, 2 };  /* 0 = Times-Roman, 2 = Times-Bold */
    struct xfont *nf;
    int i;
    if (!appres.international) return FALSE;
    for (i = 0; i < XtNumber(font_types); i++) {
      nf = x_fontinfo[font_types[i]].xfontlist;
!     while (nf != NULL && (nf->fstruct == NULL || nf->fstruct->fid != fid))
!       nf = nf->next;
      if (nf != NULL) {
        *fontset = (font_types[i]==0) ? appres.normal_fontset : appres.bold_fontset;
        *size_ret = nf->size;
***************
*** 262,277 ****
        || !seek_fontset(font->fid, &fontset, &font_size)) {
      XTextExtents(font, str, len, dir, asc, des, overall);
    } else {
-     scale = (double)font_size / (double)appres.fontset_size;
      XmbTextExtents(fontset, str, len, &ink, &logical);
!     overall->lbearing = 0;
!     overall->rbearing = logical.width * scale;
!     overall->width = logical.width * scale;
!     overall->ascent = (-logical.y + 1) * scale;
!     overall->descent = (logical.height + logical.y + 1) * scale;
    }
  }
  
  /* functions for bitmap scaling (AllocTextBitmapAndScaleBuf, ScaleUp, */
  /* and ScaleDown) are derived from tgif-2.13 */
  
--- 264,290 ----
        || !seek_fontset(font->fid, &fontset, &font_size)) {
      XTextExtents(font, str, len, dir, asc, des, overall);
    } else {
      XmbTextExtents(fontset, str, len, &ink, &logical);
!     if (appres.fontset_size <= 0)
!       scale = (double)font_size / (double)i18n_fontset_height(fontset);
!     else
!       scale = (double)font_size / (double)appres.fontset_size;
!     overall->width = max2(logical.width, ink.width + ink.x) * scale + 0.5;
!     overall->lbearing = -ink.x * scale;
!     overall->rbearing = overall->width;
!     overall->ascent = -logical.y * scale;
!     overall->descent = logical.height * scale - overall->ascent;
    }
  }
  
+ int i18n_fontset_height(fontset)
+      XFontSet fontset;
+ {
+   XFontSetExtents *extents;
+   extents = XExtentsOfFontSet(fontset);
+   return extents->max_logical_extent.height;
+ }
+ 
  /* functions for bitmap scaling (AllocTextBitmapAndScaleBuf, ScaleUp, */
  /* and ScaleDown) are derived from tgif-2.13 */
  
***************
*** 310,324 ****
       int height;
       double scale;
  {
    register int i, j;
    register int x1, y1, x2, y2;
  
    i = -1;
!   for (x2 = 0; x2 < width; x2++) {
      x1 = x2 / scale;
      if (x1 != i) {
        j = -1;
!       for (y2 = 0; y2 < height; y2++) {
  	y1 = y2 / scale;
  	if (y1 != j) {
  	  if (scale_buf[y2] = XGetPixel(from_image, x1, y1))
--- 323,339 ----
       int height;
       double scale;
  {
+   int wd = width * scale;
+   int ht = height * scale;
    register int i, j;
    register int x1, y1, x2, y2;
  
    i = -1;
!   for (x2 = 0; x2 < wd; x2++) {
      x1 = x2 / scale;
      if (x1 != i) {
        j = -1;
!       for (y2 = 0; y2 < ht; y2++) {
  	y1 = y2 / scale;
  	if (y1 != j) {
  	  if (scale_buf[y2] = XGetPixel(from_image, x1, y1))
***************
*** 331,337 ****
        }
        i = x1;
      } else {
!       for (y2 = 0; y2 < height; y2++) {
  	if (scale_buf[y2] == 1)
  	  XPutPixel(to_image, x2, y2, 1);
        }
--- 346,352 ----
        }
        i = x1;
      } else {
!       for (y2 = 0; y2 < ht; y2++) {
  	if (scale_buf[y2] == 1)
  	  XPutPixel(to_image, x2, y2, 1);
        }
***************
*** 346,360 ****
       int height;
       double scale;
  {
!   int ymax, y1, y2;
!   register int xmax, x1, x2, last_x2;
  
!   xmax = width / scale;
!   ymax = height / scale;
!   for (y1 = 0; y1 < ymax; y1++) {
      y2 = y1 * scale;
      last_x2 = -1;
!     for (x1 = 0; x1 < xmax; x1++) {
        x2 = x1 * scale;
        if (x2 != last_x2 && XGetPixel(from_image, x1, y1)) {
  	XPutPixel(to_image, x2, y2, 1);
--- 361,373 ----
       int height;
       double scale;
  {
!   int y1, y2;
!   register int x1, x2, last_x2;
  
!   for (y1 = 0; y1 < height; y1++) {
      y2 = y1 * scale;
      last_x2 = -1;
!     for (x1 = 0; x1 < width; x1++) {
        x2 = x1 * scale;
        if (x2 != last_x2 && XGetPixel(from_image, x1, y1)) {
  	XPutPixel(to_image, x2, y2, 1);
***************
*** 383,389 ****
    static Drawable last_drawable = None;
    static Font last_font = None;
    static char last_str[400] = "";
!   static int width, height, ascent;
    XImage *from_image;
    XFontSet fontset;
    int font_size;
--- 396,402 ----
    static Drawable last_drawable = None;
    static Font last_font = None;
    static char last_str[400] = "";
!   static int width, lbearing, height, ascent;
    XImage *from_image;
    XFontSet fontset;
    int font_size;
***************
*** 405,417 ****
        strncpy(last_str, str, sizeof(last_str));
  
        XmbTextExtents(fontset, str, len, &ink, &logical);
!       base_width = logical.width + 1;
!       base_height = max2(logical.height + 1, appres.fontset_size);
  
!       scale = (double)font_size / (double)appres.fontset_size;
        width = base_width * scale + 0.5;
        height = base_height * scale + 0.5;
!       ascent = (-logical.y + 1) * scale + 0.5;
        AllocTextBitmapAndScaleBuf(dpy, drawable,
  			 max2(base_width, width), max2(base_height, height));
        if (depth_one_gc == None) {
--- 418,434 ----
        strncpy(last_str, str, sizeof(last_str));
  
        XmbTextExtents(fontset, str, len, &ink, &logical);
!       base_width = ink.width + abs(ink.x) + 1;
!       base_height = ink.height + 1;
  
!       if (appres.fontset_size <= 0)
! 	scale = (double)font_size / (double)i18n_fontset_height(fontset);
!       else
! 	scale = (double)font_size / (double)appres.fontset_size;
        width = base_width * scale + 0.5;
+       lbearing = max2(-ink.x, 0) * scale + 0.5;
        height = base_height * scale + 0.5;
!       ascent = -ink.y * scale + 0.5;
        AllocTextBitmapAndScaleBuf(dpy, drawable,
  			 max2(base_width, width), max2(base_height, height));
        if (depth_one_gc == None) {
***************
*** 444,459 ****
  		     text_bitmap_width, text_bitmap_height);
        XSetForeground(dpy, depth_one_gc, 1);
        XmbDrawString(dpy, text_bitmap, fontset, depth_one_gc,
! 		    0, -logical.y + 1, str, len);
  
        from_image = XGetImage(dpy, text_bitmap, 0, 0,
  		     text_bitmap_width, text_bitmap_height, 1, ZPixmap);
  
        bzero(to_image_data, to_image_size);  /* clear to_image */
        if (1.0 < scale) {  /* scale up */
! 	ScaleUp(from_image, to_image, width, height, scale);
        } else {  /* scale down */
! 	ScaleDown(from_image, to_image, width, height, scale);
        }
        XDestroyImage(from_image);
  
--- 461,476 ----
  		     text_bitmap_width, text_bitmap_height);
        XSetForeground(dpy, depth_one_gc, 1);
        XmbDrawString(dpy, text_bitmap, fontset, depth_one_gc,
! 		    max2(-ink.x, 0), -ink.y, str, len);
  
        from_image = XGetImage(dpy, text_bitmap, 0, 0,
  		     text_bitmap_width, text_bitmap_height, 1, ZPixmap);
  
        bzero(to_image_data, to_image_size);  /* clear to_image */
        if (1.0 < scale) {  /* scale up */
! 	ScaleUp(from_image, to_image, base_width, base_height, scale);
        } else {  /* scale down */
! 	ScaleDown(from_image, to_image, base_width, base_height, scale);
        }
        XDestroyImage(from_image);
  
***************
*** 464,471 ****
      XCopyGC(dpy, gc, GCForeground|GCBackground|GCFunction|GCPlaneMask, my_gc);
      XSetFillStyle(dpy, my_gc, FillStippled);
      XSetStipple(dpy, my_gc, paint_bitmap);
!     XSetTSOrigin(dpy, my_gc, x, y - ascent);
!     XFillRectangle(dpy, drawable, my_gc, x, y - ascent, width, height);
    }
  }
  
--- 481,488 ----
      XCopyGC(dpy, gc, GCForeground|GCBackground|GCFunction|GCPlaneMask, my_gc);
      XSetFillStyle(dpy, my_gc, FillStippled);
      XSetStipple(dpy, my_gc, paint_bitmap);
!     XSetTSOrigin(dpy, my_gc, x - lbearing, y - ascent);
!     XFillRectangle(dpy, drawable, my_gc, x - lbearing, y - ascent, width, height);
    }
  }
  
diff -c ../xfig.3.2.2/w_library.c ./w_library.c
*** ../xfig.3.2.2/w_library.c	Thu Jun 25 07:50:29 1998
--- ./w_library.c	Sat May 29 12:23:51 1999
***************
*** 26,31 ****
--- 26,32 ----
  #include "e_placelib.h"
  #include "f_read.h"
  #include "u_create.h"
+ #include "u_redraw.h"
  #include "w_canvas.h"
  #include "w_drawprim.h"		/* for max_char_height */
  #include "w_dir.h"
***************
*** 919,924 ****
--- 920,932 ----
      /* reset cursor */
      XUndefineCursor(tool_d, XtWindow(library_panel));
      app_flush();
+ 
+     /* if user requested a canvas redraw while preview was being generated
+        do that now for full canvas */
+     if (request_redraw) {
+ 	redisplay_region(0, 0, CANVAS_WD, CANVAS_HT);
+ 	request_redraw = False;
+     }
  }
  
  /* fool the toolkit into drawing the new pixmap */
diff -c ../xfig.3.2.2/w_msgpanel.c ./w_msgpanel.c
*** ../xfig.3.2.2/w_msgpanel.c	Fri Jun 12 06:07:10 1998
--- ./w_msgpanel.c	Sat May 29 12:23:47 1999
***************
*** 600,605 ****
--- 600,615 ----
  		(float)dy*appres.user_scale, cur_fig_units,
  		ang );
  	break;
+     case MSG_DIAM_ANGLE:
+ 	if (num_point == 0)
+ 	  put_msg("Diameter = %.3f %s, Angle = %.1f deg",
+ 		  len*appres.user_scale, cur_fig_units,
+ 		  ang );
+ 	else
+ 	  put_msg("%d point%s, Angle = %.1f deg",
+ 		  num_point, ((num_point != 1)? "s": ""),
+ 		  ang );
+ 	break;
      default:
  	put_msg("%s = %.3f %s, dx = %.3lf %s, dy = %.3lf %s (%.1f) deg",
  		(type==MSG_LENGTH? "Length": "Distance"),
diff -c ../xfig.3.2.2/w_rottext.c ./w_rottext.c
*** ../xfig.3.2.2/w_rottext.c	Sat Jun  6 06:46:36 1998
--- ./w_rottext.c	Sat May 29 12:23:47 1999
***************
*** 1000,1008 ****
      while(str3!=NULL);
      
      free(str1);
! #ifdef I18N
!     if (item->max_width <= 0) return NULL;
! #endif  /* I18N */
      
      /* overall font height */
  #ifdef I18N
--- 1000,1007 ----
      while(str3!=NULL);
      
      free(str1);
!     if (item->max_width <= 0)
! 	return NULL;
      
      /* overall font height */
  #ifdef I18N
diff -c ../xfig.3.2.2/w_zoom.c ./w_zoom.c
*** ../xfig.3.2.2/w_zoom.c	Sat Jun  6 06:47:25 1998
--- ./w_zoom.c	Sat May 29 12:23:43 1999
***************
*** 54,59 ****
--- 54,176 ----
  static int	my_fix_x, my_fix_y;
  static int	my_cur_x, my_cur_y;
  
+ 
+ /* storage for conversion of data points to screen coords (zXDrawLines and zXFillPolygon) */
+ 
+ static XPoint	*_pp_ = (XPoint *) NULL;	/* data pointer itself */
+ static int	 _npp_ = 0;			/* number of points currently allocated */
+ static Boolean	 _noalloc_ = False;		/* signals previous failed alloc */
+ static Boolean	 chkalloc();
+ static void	 convert_sh();
+ 
+ zXDrawLines(d,w,gc,p,n,m)
+     Display	*d;
+     Window	 w;
+     GC		 gc;
+     zXPoint	*p;
+     int		 n;
+ {
+     /* make sure we have allocated data */
+     if (!chkalloc(n)) {
+ 	return;
+     }
+     /* now convert each point to short */
+     convert_sh(p,n);
+     XDrawLines(d,w,gc,_pp_,n,m);
+ }
+ 
+ zXFillPolygon(d,w,gc,p,n,m,o)
+     Display	*d;
+     Window	 w;
+     GC		 gc;
+     zXPoint	*p;
+     int		 n;
+     int		 m,o;
+ {
+     /* make sure we have allocated data */
+     if (!chkalloc(n)) {
+ 	return;
+     }
+     /* now convert each point to short */
+     convert_sh(p,n);
+     XFillPolygon(d,w,gc,_pp_,n,m,o);
+ }
+ 
+ /* convert each point to short */
+ 
+ void
+ convert_sh(p,n)
+     zXPoint	*p;
+     int		 n;
+ {
+     int 	 i;
+ 
+     for (i=0;i<n;i++) {
+ 	_pp_[i].x = SHZOOMX(p[i].x);
+ 	_pp_[i].y = SHZOOMY(p[i].y);
+     }
+ }
+ 
+ /* convert Fig units to pixels at current zoom AND convert to short, being
+    careful to convert large numbers (> 12000) to numbers the X library likes */
+ 
+ /* One for X coordinates */
+ 
+ short
+ SHZOOMX(x)
+     int		 x;
+ {
+     x = ZOOMX(x);
+     /* the X server or X11 Library doesn't like coords larger than about 12000 */
+     x = (x < -12000? -12000: (x > 12000? 12000: x));
+     return (short) x;
+ }
+ 
+ /* do the same using the ZOOMY transformation for a Y coordinate */
+ 
+ short
+ SHZOOMY(y)
+     int		 y;
+ {
+     y = ZOOMY(y);
+     /* the X server or X11 Library doesn't like coords larger than about 12000 */
+     y = (y < -12000? -12000: (y > 12000? 12000: y));
+     return (short) y;
+ }
+ 
+ static Boolean
+ chkalloc(n)
+     int		 n;
+ {
+     int		 i;
+     XPoint	*tpp;
+ 
+     /* see if we need to allocate some (more) memory */
+     if (n > _npp_) {
+ 	/* if previous allocation failed, return now */
+ 	if (_noalloc_)
+ 	    return False;
+ 	/* get either what we need +50 points or 500, whichever is larger */
+ 	i = max2(n+50, 500);	
+ 	if (_npp_ == 0) {
+ 	    if ((tpp = malloc(i * sizeof(XPoint))) == 0) {
+ 		fprintf(stderr,"\007Can't alloc memory for %d point array, exiting\n");
+ 		exit(1);
+ 	    }
+ 	} else {
+ 	    if ((tpp = realloc(_pp_, i * sizeof(XPoint))) == 0) {
+ 		file_msg("Can't alloc memory for %d point array",n);
+ 		_noalloc_ = True;
+ 		return False;
+ 	    }
+ 	}
+ 	/* everything ok, set global pointer and count */
+ 	_pp_ = tpp;
+ 	_npp_ = i;
+     }
+     return True;
+ }
+ 
  void
  zoom_selected(x, y, button)
      int		    x, y;
diff -c ../xfig.3.2.2/w_zoom.h ./w_zoom.h
*** ../xfig.3.2.2/w_zoom.h	Sat Jun  6 06:23:40 1998
--- ./w_zoom.h	Sat May 29 12:23:43 1999
***************
*** 27,70 ****
  typedef struct { int x,y; } zXPoint ;
  
  /* convert Fig units to pixels at current zoom */
  #define ZOOMX(x) round(zoomscale*((x)-zoomxoff))
  #define ZOOMY(y) round(zoomscale*((y)-zoomyoff))
  
  /* convert pixels to Fig units at current zoom */
  #define BACKX(x) round(x/zoomscale+zoomxoff)
  #define BACKY(y) round(y/zoomscale+zoomyoff)
  
! #define zXDrawArc(d,w,gc,x,y,d1,d2,a1,a2)\
!     XDrawArc(d,w,gc,(short)ZOOMX(x),(short)ZOOMY(y), \
  	     (short)round(zoomscale*(d1)),(short)round(zoomscale*(d2)),\
  	     a1,a2)
! #define zXFillArc(d,w,gc,x,y,d1,d2,a1,a2)\
!     XFillArc(d,w,gc,(short)ZOOMX(x),(short)ZOOMY(y), \
  	     (short)round(zoomscale*(d1)),(short)round(zoomscale*(d2)),\
  	     a1,a2)
! #define zXDrawLine(d,w,gc,x1,y1,x2,y2)\
!     XDrawLine(d,w,gc,(short)ZOOMX(x1),(short)ZOOMY(y1), \
! 	      (short)ZOOMX(x2),(short)ZOOMY(y2))
! #define zXRotDrawString(d,font,ang,w,gc,x,y,s)\
!     XRotDrawString(d,font,ang,w,gc,(short)ZOOMX(x),(short)ZOOMY(y),s)
! #define zXFillRectangle(d,w,gc,x1,y1,x2,y2)\
!     XFillRectangle(d,w,gc,(short)ZOOMX(x1),(short)ZOOMY(y1),\
! 		(short)round(zoomscale*(x2)),(short)round(zoomscale*(y2)))
! #define zXDrawRectangle(d,w,gc,x1,y1,x2,y2)\
!     XDrawRectangle(d,w,gc,(short)ZOOMX(x1),(short)ZOOMY(y1),\
  		(short)round(zoomscale*(x2)),(short)round(zoomscale*(y2)))
! #define zXDrawLines(d,w,gc,p,n,m)\
!     {int i;\
!      XPoint *pp=(XPoint *) malloc(n * sizeof(XPoint)); \
!      for(i=0;i<n;i++){pp[i].x=ZOOMX(p[i].x);pp[i].y=ZOOMY(p[i].y);}\
!      XDrawLines(d,w,gc,pp,n,m);\
!      free(pp); \
!     }
! #define zXFillPolygon(d,w,gc,p,n,m,o)\
!     {int i;\
!      XPoint *pp=(XPoint *) malloc(n * sizeof(XPoint)); \
!      for(i=0;i<n;i++){pp[i].x=ZOOMX(p[i].x);pp[i].y=ZOOMY(p[i].y);}\
!      XFillPolygon(d,w,gc,pp,n,m,o);\
!      free(pp); \
!     }
  #endif /* W_ZOOM_H */
--- 27,61 ----
  typedef struct { int x,y; } zXPoint ;
  
  /* convert Fig units to pixels at current zoom */
+ /* warning: if you need to convert these to short, use SHZOOMX/Y */
+ 
  #define ZOOMX(x) round(zoomscale*((x)-zoomxoff))
  #define ZOOMY(y) round(zoomscale*((y)-zoomyoff))
  
+ extern short	SHZOOMX();
+ extern short	SHZOOMY();
+ 
  /* convert pixels to Fig units at current zoom */
  #define BACKX(x) round(x/zoomscale+zoomxoff)
  #define BACKY(y) round(y/zoomscale+zoomyoff)
  
! #define zXDrawArc(disp,win,gc,x,y,d1,d2,a1,a2)\
!     XDrawArc(disp,win,gc,SHZOOMX(x),SHZOOMY(y), \
  	     (short)round(zoomscale*(d1)),(short)round(zoomscale*(d2)),\
  	     a1,a2)
! #define zXFillArc(disp,win,gc,x,y,d1,d2,a1,a2)\
!     XFillArc(disp,win,gc,SHZOOMX(x),SHZOOMY(y), \
  	     (short)round(zoomscale*(d1)),(short)round(zoomscale*(d2)),\
  	     a1,a2)
! #define zXDrawLine(disp,win,gc,x1,y1,x2,y2)\
!     XDrawLine(disp,win,gc,SHZOOMX(x1),SHZOOMY(y1), \
! 	      SHZOOMX(x2),SHZOOMY(y2))
! #define zXRotDrawString(disp,font,ang,win,gc,x,y,s)\
!     XRotDrawString(disp,font,ang,win,gc,SHZOOMX(x),SHZOOMY(y),s)
! #define zXFillRectangle(disp,win,gc,x1,y1,x2,y2)\
!     XFillRectangle(disp,win,gc,SHZOOMX(x1),SHZOOMY(y1),\
  		(short)round(zoomscale*(x2)),(short)round(zoomscale*(y2)))
! #define zXDrawRectangle(disp,win,gc,x1,y1,w,h)\
!     XDrawRectangle(disp,win,gc,SHZOOMX(x1),SHZOOMY(y1),\
! 		(short)round(zoomscale*(w)),(short)round(zoomscale*(h)))
  #endif /* W_ZOOM_H */
