*** arc.c.orig	Sun Apr 11 10:46:34 1999
--- arc.c	Sun Apr 11 10:46:34 1999
***************
*** 1260,1265 ****
  }
  
! struct ObjRec *CreateArcObj(xc,yc,x1,y1,x2,y2,dir,ltx,lty,w,h,angle1,angle2)
     int xc, yc, x1, y1, x2, y2, dir, ltx, lty, w, h, angle1, angle2;
  {
     struct ArcRec *arc_ptr;
--- 1260,1267 ----
  }
  
! struct ObjRec *CreateArcObj(xc, yc, x1, y1, x2, y2, dir, ltx, lty, w, h,
!       angle1, angle2, CreateAbsolute)
     int xc, yc, x1, y1, x2, y2, dir, ltx, lty, w, h, angle1, angle2;
+    int CreateAbsolute;
  {
     struct ArcRec *arc_ptr;
***************
*** 1283,1295 ****
     arc_ptr->style = lineStyle;
  
!    arc_ptr->xc = ABS_X(xc);
!    arc_ptr->yc = ABS_Y(yc);
!    arc_ptr->x1 = ABS_X(x1);
!    arc_ptr->y1 = ABS_Y(y1);
!    arc_ptr->x2 = ABS_X(x2);
!    arc_ptr->y2 = ABS_Y(y2);
     arc_ptr->dir = dir;
-    arc_ptr->ltx = ABS_X(xc-w/2);
-    arc_ptr->lty = ABS_Y(yc-h/2);
     arc_ptr->w = (arc_ptr->xc-arc_ptr->ltx)<<1;
     arc_ptr->h = (arc_ptr->yc-arc_ptr->lty)<<1;
--- 1285,1308 ----
     arc_ptr->style = lineStyle;
  
!    if (CreateAbsolute) {
!       arc_ptr->xc = xc;
!       arc_ptr->yc = yc;
!       arc_ptr->x1 = x1;
!       arc_ptr->y1 = y1;
!       arc_ptr->x2 = x2;
!       arc_ptr->y2 = y2;
!       arc_ptr->ltx = xc-(w>>1);
!       arc_ptr->lty = yc-(h>>1);
!    } else {
!       arc_ptr->xc = ABS_X(xc);
!       arc_ptr->yc = ABS_Y(yc);
!       arc_ptr->x1 = ABS_X(x1);
!       arc_ptr->y1 = ABS_Y(y1);
!       arc_ptr->x2 = ABS_X(x2);
!       arc_ptr->y2 = ABS_Y(y2);
!       arc_ptr->ltx = ABS_X(xc-(w>>1));
!       arc_ptr->lty = ABS_Y(yc-(h>>1));
!    }
     arc_ptr->dir = dir;
     arc_ptr->w = (arc_ptr->xc-arc_ptr->ltx)<<1;
     arc_ptr->h = (arc_ptr->yc-arc_ptr->lty)<<1;
***************
*** 1780,1787 ****
        if (curChoice == DRAWEDGEARC) {
           obj_ptr = CreateArcObj(cx, cy, OrigX, OrigY, first_x, first_y,
!                dir, ltx, lty, w, h, angle1, angle2);
        } else {
           obj_ptr = CreateArcObj(OrigX, OrigY, first_x, first_y, saved_x,
!                saved_y, dir, ltx, lty, w, h, angle1, angle2);
        }
        RecordNewObjCmd();
--- 1793,1800 ----
        if (curChoice == DRAWEDGEARC) {
           obj_ptr = CreateArcObj(cx, cy, OrigX, OrigY, first_x, first_y,
!                dir, ltx, lty, w, h, angle1, angle2, FALSE);
        } else {
           obj_ptr = CreateArcObj(OrigX, OrigY, first_x, first_y, saved_x,
!                saved_y, dir, ltx, lty, w, h, angle1, angle2, FALSE);
        }
        RecordNewObjCmd();
***************
*** 2348,2352 ****
     }
     obj_ptr = CreateArcObj(0, 0, x1, y1, x2, y2, dir, -r, -r, r*2, r*2,
!          theta1*64, angle2*64);
  
     PlaceTopObj(obj_ptr);
--- 2361,2365 ----
     }
     obj_ptr = CreateArcObj(0, 0, x1, y1, x2, y2, dir, -r, -r, r*2, r*2,
!          theta1*64, angle2*64, FALSE);
  
     PlaceTopObj(obj_ptr);
*** chinput.c.orig	Sun Apr 11 10:46:35 1999
--- chinput.c	Sun Apr 11 10:46:35 1999
***************
*** 34,39 ****
  #include "tgifdefs.h"
  
- #include <X11/Xos.h>
- 
  #include "chinput.e"
  
--- 34,37 ----
*** choice.c.orig	Sun Apr 11 10:46:36 1999
--- choice.c	Sun Apr 11 10:46:36 1999
***************
*** 457,462 ****
              GCClipMask | GCClipXOrigin | GCClipYOrigin, &values);
  
!       XFillRectangle(mainDisplay, choiceWindow, choiceGC, x, y,
!             stTextExtents.bbox_h, stTextExtents.bbox_w);
  
        values.clip_mask = None;
--- 457,464 ----
              GCClipMask | GCClipXOrigin | GCClipYOrigin, &values);
  
!       XFillRectangle(mainDisplay, choiceWindow, choiceGC,
!             (x>image_x ? x : image_x), (y>image_y ? y: image_y),
!             (x>image_x ? stTextExtents.bbox_w : choiceImageW),
!             (y>image_y ? stTextExtents.bbox_h : choiceImageH));
  
        values.clip_mask = None;
***************
*** 993,997 ****
        break;
     case DRAWTEXT:
!       CreateTextObj(TRUE);
        if (NeedSelectTopObject(NewChoice, FALSE) && textDrawn) {
           HighLightJustDrawnText();
--- 995,999 ----
        break;
     case DRAWTEXT:
!       CreateTextObj(TRUE, TRUE);
        if (NeedSelectTopObject(NewChoice, FALSE) && textDrawn) {
           HighLightJustDrawnText();
*** choose.c.orig	Sun Apr 11 10:46:38 1999
--- choose.c	Sun Apr 11 10:46:38 1999
***************
*** 75,83 ****
  
     DspList *dsp_ptr;
!    char *title_str;
  
     struct CheckArrayRec *p_check_array;
  
!    int a_btn_w, title_w, graph_w, btn_start, title_start, graph_start;
     int btn_w, btn_gap, btn_selected, exposed, screen_w, screen_h;
     int edit_style, loop_once, dont_free_entries, leading;
--- 75,84 ----
  
     DspList *dsp_ptr;
!    char *title_str, *formatted_title_str;
  
     struct CheckArrayRec *p_check_array;
  
!    int title_w, title_h, title_num_lines;
!    int a_btn_w, graph_w, btn_start, title_start, graph_start;
     int btn_w, btn_gap, btn_selected, exposed, screen_w, screen_h;
     int edit_style, loop_once, dont_free_entries, leading;
***************
*** 109,130 ****
     struct NamesRec *pni;
  {
!    int max_w=max(max(pni->title_w,pni->graph_w),pni->btn_w);
  
     pni->base_win_w = max_w + (defaultFontWidth<<2);
-    pni->title_start = ((pni->base_win_w-pni->title_w)>>1);
     pni->graph_start = ((pni->base_win_w-pni->graph_w)>>1);
     pni->btn_start = ((pni->base_win_w-pni->btn_w)>>1);
  
     pni->path_bbox.ltx = pni->graph_start;
!    if (boldMsgFontPtr == NULL) {
!       pni->path_bbox.lty = 3*ROW_HEIGHT;
!    } else {
!       pni->path_bbox.lty = ((ROW_HEIGHT<<1)+boldMsgFontHeight+1);
!    }
     pni->path_bbox.lty -= 2;
!    pni->path_bbox.rbx = pni->path_bbox.ltx +
!          ITEM_LEN*defaultFontWidth+6;
     pni->path_bbox.rby = pni->path_bbox.lty +
           (msgFontPtr==NULL ? defaultFontHeight : msgFontHeight)+1+4;
  }
  
--- 110,137 ----
     struct NamesRec *pni;
  {
!    int max_w=max(pni->graph_w,pni->btn_w);
  
     pni->base_win_w = max_w + (defaultFontWidth<<2);
     pni->graph_start = ((pni->base_win_w-pni->graph_w)>>1);
+    if (pni->title_num_lines <= 1) {
+       pni->title_start = ((pni->base_win_w-pni->title_w)>>1);
+    } else {
+       pni->title_start = pni->graph_start;
+    }
     pni->btn_start = ((pni->base_win_w-pni->btn_w)>>1);
  
     pni->path_bbox.ltx = pni->graph_start;
!    pni->path_bbox.lty = (ROW_HEIGHT<<1)+pni->title_h;
!    /* the path_bbox needs 2 pixels around it */
     pni->path_bbox.lty -= 2;
!    pni->path_bbox.rbx = pni->path_bbox.ltx + ITEM_LEN*defaultFontWidth+6;
     pni->path_bbox.rby = pni->path_bbox.lty +
           (msgFontPtr==NULL ? defaultFontHeight : msgFontHeight)+1+4;
+    if (boldMsgFontPtr == NULL) {
+       pni->base_win_h = (7+ITEM_DSPED)*ROW_HEIGHT + pni->title_h;
+    } else {
+       pni->base_win_h = (6+ITEM_DSPED)*ROW_HEIGHT + boldMsgFontHeight + 1 +
+             pni->title_h;
+    }
  }
  
***************
*** 199,214 ****
  {
     struct NamesRec *pni=(&namesInfo);
-    int len;
  
     if (pni->title_str != NULL) free(pni->title_str);
     pni->title_str = UtilStrDup(title_str);
     if (pni->title_str == NULL) FailAllocMessage();
-    len = strlen(pni->title_str);
  
!    if (boldMsgFontPtr == NULL) {
!       pni->title_w = defaultFontWidth * len;
!    } else {
!       pni->title_w = XTextWidth(boldMsgFontPtr, pni->title_str, len);
!    }
     CalcBaseWinWidth(pni);
  }
--- 206,220 ----
  {
     struct NamesRec *pni=(&namesInfo);
  
     if (pni->title_str != NULL) free(pni->title_str);
+    if (pni->formatted_title_str != NULL) free(pni->formatted_title_str);
+    pni->formatted_title_str = NULL;
     pni->title_str = UtilStrDup(title_str);
     if (pni->title_str == NULL) FailAllocMessage();
  
!    CalcFormatStringInBox(pni->title_str,
!          (boldMsgFontPtr==NULL ? defaultFontPtr : boldMsgFontPtr),
!          pni->graph_w, &pni->title_num_lines, &pni->title_w, &pni->title_h,
!          &pni->formatted_title_str);
     CalcBaseWinWidth(pni);
  }
***************
*** 222,225 ****
--- 228,235 ----
        pni->title_str = NULL;
     }
+    if (pni->formatted_title_str != NULL) {
+       free(pni->formatted_title_str);
+       pni->formatted_title_str = NULL;
+    }
     if (!pni->dont_free_entries) {
        if (pni->dsp_ptr != NULL) {
***************
*** 291,294 ****
--- 301,306 ----
     if (pni->title_str != NULL) free(pni->title_str);
     pni->title_str = NULL;
+    if (pni->formatted_title_str != NULL) free(pni->formatted_title_str);
+    pni->formatted_title_str = NULL;
     XFreeGC(mainDisplay, nameGC);
     XFreeGC(mainDisplay, revNameGC);
***************
*** 474,482 ****
     }
     x = pni->graph_start;
!    if (boldMsgFontPtr == NULL) {
!       y = 3*ROW_HEIGHT;
!    } else {
!       y = ((ROW_HEIGHT<<1)+boldMsgFontHeight+1);
!    }
     box_w = ITEM_LEN*defaultFontWidth+6+(windowPadding<<1);
     cursor_y = y;
--- 486,492 ----
     }
     x = pni->graph_start;
!    /* the path_bbox has 2 pixels around it */
!    y = pni->path_bbox.lty+2;
! 
     box_w = ITEM_LEN*defaultFontWidth+6+(windowPadding<<1);
     cursor_y = y;
***************
*** 556,562 ****
     /* draw the title */
     if (pni->tabbed_from_root) {
!       XDrawString(mainDisplay, pni->base_win, nameGC,
!             pni->title_start, base_line, pni->title_str,
!             strlen(pni->title_str));
     } else {
        int tmp_w, len, tmp_start;
--- 566,591 ----
     /* draw the title */
     if (pni->tabbed_from_root) {
!       if (pni->title_num_lines <= 1) {
!          XDrawString(mainDisplay, pni->base_win, nameGC, pni->title_start,
!                base_line, pni->title_str, strlen(pni->title_str));
!       } else {
!          char *psz_line=pni->formatted_title_str;
!          char *psz=strchr(pni->formatted_title_str, '\n');
! 
!          do {
!             if (psz != NULL) *psz = '\0';
!             XDrawString(mainDisplay, pni->base_win, nameGC, pni->title_start,
!                   base_line, psz_line, strlen(psz_line));
!             base_line += ((boldMsgFontPtr==NULL) ? defaultFontHeight :
!                   boldMsgFontHeight);
!             if (psz != NULL) {
!                *psz++ = '\n';
!                psz_line = psz;
!                psz = strchr(psz_line, '\n');
!             } else {
!                break;
!             }
!          } while (psz_line != NULL);
!       }
     } else {
        int tmp_w, len, tmp_start;
***************
*** 570,575 ****
        }
        tmp_start = ((pni->base_win_w-tmp_w)>>1);
!       XDrawString(mainDisplay, pni->base_win, nameGC,
!             tmp_start, base_line, gszMsgBox, len);
        if (pni->title_str != NULL && *pni->title_str != '\0') {
           SetStringStatus(pni->title_str);
--- 599,604 ----
        }
        tmp_start = ((pni->base_win_w-tmp_w)>>1);
!       XDrawString(mainDisplay, pni->base_win, nameGC, tmp_start, base_line,
!             gszMsgBox, len);
        if (pni->title_str != NULL && *pni->title_str != '\0') {
           SetStringStatus(pni->title_str);
***************
*** 592,604 ****
  
        if (boldMsgFontPtr == NULL) {
-          pni->btn_bbox[i].lty = (6+ITEM_DSPED)*ROW_HEIGHT;
           button_h = defaultFontHeight + 4;
        } else {
-          pni->btn_bbox[i].lty = (5+ITEM_DSPED)*ROW_HEIGHT +
-                (boldMsgFontHeight+1);
           button_h = boldMsgFontHeight + 4;
        }
        pni->btn_bbox[i].ltx = left;
!       pni->btn_bbox[i].lty -= 2;
        pni->btn_bbox[i].rbx = pni->btn_bbox[i].ltx+button_w;
        pni->btn_bbox[i].rby = pni->btn_bbox[i].lty+button_h;
--- 621,631 ----
  
        if (boldMsgFontPtr == NULL) {
           button_h = defaultFontHeight + 4;
        } else {
           button_h = boldMsgFontHeight + 4;
        }
        pni->btn_bbox[i].ltx = left;
!       pni->btn_bbox[i].lty = (5+ITEM_DSPED)*ROW_HEIGHT + pni->title_h;
!       pni->btn_bbox[i].lty -= 1;
        pni->btn_bbox[i].rbx = pni->btn_bbox[i].ltx+button_w;
        pni->btn_bbox[i].rby = pni->btn_bbox[i].lty+button_h;
***************
*** 684,692 ****
     XDefineCursor(mainDisplay, pni->base_win, defaultCursor);
  
!    if (boldMsgFontPtr == NULL) {
!       y = 5*ROW_HEIGHT;
!    } else {
!       y = ((ROW_HEIGHT<<2)+boldMsgFontHeight+1);
!    }
     if ((pni->dsp_base_win=XCreateSimpleWindow(mainDisplay, pni->base_win,
           pni->graph_start, y, pni->dsp_base_win_w, pni->dsp_base_win_h,
--- 711,715 ----
     XDefineCursor(mainDisplay, pni->base_win, defaultCursor);
  
!    y = (ROW_HEIGHT<<2)+pni->title_h;
     if ((pni->dsp_base_win=XCreateSimpleWindow(mainDisplay, pni->base_win,
           pni->graph_start, y, pni->dsp_base_win_w, pni->dsp_base_win_h,
***************
*** 1679,1685 ****
        }
     } else if (CharIsTAB(key_ev, buf, key_sym, &has_ch)) {
!       TabInNames();
!       *pn_changing = FALSE;
!       *pn_selected_btn_index = INVALID;
     } else if ((!pni->tabbed_from_root || pni->num_entries != 0) &&
           ((key_sym>'\040' && key_sym<='\177' &&
--- 1702,1710 ----
        }
     } else if (CharIsTAB(key_ev, buf, key_sym, &has_ch)) {
!       if (pni->edit_style == NAMES_SELECT_FILE && pni->change_to_root) {
!          TabInNames();
!          *pn_changing = FALSE;
!          *pn_selected_btn_index = INVALID;
!       }
     } else if ((!pni->tabbed_from_root || pni->num_entries != 0) &&
           ((key_sym>'\040' && key_sym<='\177' &&
*** cli_xcin.c.orig	Sun Apr 11 10:46:39 1999
--- cli_xcin.c	Sun Apr 11 10:46:39 1999
***************
*** 164,169 ****
  }
  
- #include <X11/Xutil.h>
- 
  static XComposeStatus compose_status = {NULL, 0};
  
--- 164,167 ----
*** cmd.c.orig	Sun Apr 11 10:46:40 1999
--- cmd.c	Sun Apr 11 10:46:40 1999
***************
*** 1481,1485 ****
  
  #ifdef _TGIF_WB2
!    if (!gstWBInfo.listening && gstWBInfo.do_whiteboard) {
        char *psz_wb_data=NULL;
  
--- 1481,1485 ----
  
  #ifdef _TGIF_WB2
!    if (gstWBInfo.do_whiteboard) {
        char *psz_wb_data=NULL;
  
*** convxim.c.orig	Sun Apr 11 10:46:42 1999
--- convxim.c	Sun Apr 11 10:46:42 1999
***************
*** 30,42 ****
  #include "tgifdefs.h"
  
- #ifndef _NO_LOCALE_SUPPORT
- #include <X11/Xlocale.h>
- #else /* _NO_LOCALE_SUPPORT */
- #include <locale.h>
- #endif /* ~_NO_LOCALE_SUPPORT */
- 
  #include "convkinput.e"
  #include "convxim.e"
  #include "font.e"
  #include "msg.e"
  #include "setup.e"
--- 30,37 ----
  #include "tgifdefs.h"
  
  #include "convkinput.e"
  #include "convxim.e"
  #include "font.e"
+ #include "miniline.e"
  #include "msg.e"
  #include "setup.e"
***************
*** 63,66 ****
--- 58,62 ----
  static MYIOErrHandler	*oldhandler = NULL;
  static Bool		_XIMErrorFlag = False;
+ static Bool		overthespot = False;
  
  #ifndef _NO_XIMP
***************
*** 92,95 ****
--- 88,101 ----
  }
  
+ #define ROOT 1
+ #define OVERTHESPOT 2
+ static int style_type;
+ XFontSet XIMfs;
+ XFontSetExtents * fs_ext;
+ char** missing_list;
+ int missing_count;
+ char* def_string;
+ char* XIMFontSetStr="-misc-fixed-medium-r-normal--14-*";
+ 
  void XIMSetICFocus(dpy, win)
      Display *dpy;
***************
*** 100,103 ****
--- 106,112 ----
      Bool	style_flag;
      int	i;
+     XPoint spot;
+     XRectangle s_rect;
+     XVaNestedList preedit_attr, status_attr;
  
      if(oldhandler == NULL)
***************
*** 105,108 ****
--- 114,118 ----
  
      if(locale == NULL) {
+ #ifndef _NO_LOCALE_SUPPORT
  	char *c_ptr=(char*)getenv("LANG");
  
***************
*** 120,123 ****
--- 130,134 ----
  	sprintf(buf, "locale is \"%s\".\n", locale==NULL ? "(null)" : locale);
  	Msg(buf);
+ #endif /* ~_NO_LOCALE_SUPPORT */
      }
      if(modifiers == NULL) {
***************
*** 153,162 ****
  		NULL, NULL);
  	style_flag = False;
! 	for(i = 0; i < (int)(styles->count_styles); i ++)
  	    if(styles->supported_styles[i] ==
! 		    (XIMPreeditNothing | XIMStatusNothing))
! 		style_flag = True;
  	if(!style_flag) {
! 	    Msg("This IM don't support  \"Root\" input style.\n");
  	    XCloseIM(im);
  	    im = NULL;
--- 164,188 ----
  		NULL, NULL);
  	style_flag = False;
! 	if (overthespot) {
! 	  for(i = 0; i < (int)(styles->count_styles); i ++){
  	    if(styles->supported_styles[i] ==
! 	       (XIMPreeditPosition | XIMStatusArea)){
! 	      style_flag = True;
! 	      style_type = OVERTHESPOT;
! 	      Msg("OverTheSpot conversion\n");
! 	    }
! 	  }
! 	}else{
! 	  for(i = 0; i < (int)(styles->count_styles); i ++){
! 	    if(styles->supported_styles[i] ==
! 	       (XIMPreeditNothing | XIMStatusNothing)){
! 	      style_flag = True;
! 	      style_type = ROOT;
! 	      Msg("Root conversion\n");
! 	    }
! 	  }
! 	}
  	if(!style_flag) {
! 	    Msg("This IM don't support  \"Root\",\"OverTheSpot\" input style.\n");
  	    XCloseIM(im);
  	    im = NULL;
***************
*** 163,166 ****
--- 189,194 ----
  	    return;
  	}
+ 	switch (style_type){
+ 	case ROOT:
  	ic = XCreateIC(im,
  		XNInputStyle , XIMPreeditNothing | XIMStatusNothing,
***************
*** 168,171 ****
--- 196,226 ----
  		XNFocusWindow, win,
  		NULL, NULL);
+ 	break;
+ 	case OVERTHESPOT:
+ 	XIMfs=XCreateFontSet(dpy, XIMFontSetStr,
+ 			  &missing_list, &missing_count, &def_string);
+ 	fs_ext=XExtentsOfFontSet(XIMfs);
+ 	spot.x=0; spot.y=fs_ext->max_logical_extent.height;
+ 	s_rect.x=0; s_rect.y=fs_ext->max_logical_extent.height;
+ 	s_rect.width=640; s_rect.height=fs_ext->max_logical_extent.height;
+ 	preedit_attr=XVaCreateNestedList(0,
+ 					 XNSpotLocation, &spot,
+ 					 XNFontSet, XIMfs,
+ 					 NULL);
+ 	status_attr=XVaCreateNestedList(0,
+ 					XNArea, &s_rect,
+ 					XNFontSet, XIMfs,
+ 					NULL);
+ 	ic = XCreateIC(im,
+ 	        XNInputStyle , XIMPreeditPosition | XIMStatusArea,
+ 		XNClientWindow, win,
+ 		XNFocusWindow, win,
+ 		XNPreeditAttributes, preedit_attr,
+ 		XNStatusAttributes, status_attr,
+ 		NULL, NULL);
+ 	XFree(preedit_attr);
+ 	XFree(status_attr);
+ 	break;
+ 	}
  	if(ic == NULL) {
  	    printf("Can't create InputContext.\n");
***************
*** 226,229 ****
--- 281,329 ----
      }
  }
+ 
+ void XIMSetConvOverSpot(gnOverTheSpot)
+ Bool gnOverTheSpot;
+ {
+   overthespot=gnOverTheSpot;
+ }
+ 
+ void XIMTellCursorPosition(dpy, win, x, y)
+ Display* dpy;
+ Window win;
+ int x;
+ int y;
+ {
+   XPoint spot;
+   XRectangle s_rect;
+   XVaNestedList preedit_attr,status_attr;
+   char     gszAttemptedFontName[MAXSTRING+1];
+ 
+   if (!overthespot) return;
+ 
+   if (XIMfs) XFreeFontSet(dpy, XIMfs);
+   GetCurFontInfoStr(gszAttemptedFontName);
+   XIMfs=XCreateFontSet(dpy, gszAttemptedFontName,
+ 		    &missing_list, &missing_count, &def_string);
+   fs_ext=XExtentsOfFontSet(XIMfs);
+   spot.x=textCurX; spot.y=textCurBaselineY;
+   s_rect.x=textCurX; s_rect.y=textCurBaselineY+3;
+   /*s_rect.width=200; s_rect.height=fs_ext->max_logical_extent.height;*/
+   s_rect.width=50; s_rect.height=16;
+ 
+   preedit_attr=XVaCreateNestedList(0,
+ 				   XNSpotLocation, &spot,
+ 				   XNFontSet, XIMfs,
+ 				   NULL);
+   status_attr=XVaCreateNestedList(0,
+ 				  XNArea, &s_rect,
+ 				  NULL);
+   XSetICValues(ic,
+ 	       XNPreeditAttributes, preedit_attr,
+ 	       XNStatusAttributes, status_attr,
+ 	       NULL);
+   XFree(preedit_attr);
+   XFree(status_attr);
+   XSetICFocus(ic);
+ }
  #endif /* ~_NO_XIM */
  
*** cutpaste.c.orig	Sun Apr 11 10:46:43 1999
--- cutpaste.c	Sun Apr 11 10:46:43 1999
***************
*** 118,122 ****
  }
  
- static
  int WriteBufToCutBuffer(buf, bytes_to_write)
     char *buf;
--- 118,121 ----
***************
*** 1247,1251 ****
           for (obj_ptr=ObjPtr->detail.r->first; obj_ptr != NULL;
                 obj_ptr=obj_ptr->next) {
!             SetPropMask(ObjPtr, plMask, plSkip, pProp);
           }
           break;
--- 1246,1250 ----
           for (obj_ptr=ObjPtr->detail.r->first; obj_ptr != NULL;
                 obj_ptr=obj_ptr->next) {
!             SetPropMask(obj_ptr, plMask, plSkip, pProp);
           }
           break;
***************
*** 1564,1570 ****
                 if (ppir->bit == PROP_MASK_CTM) {
                    sprintf(gszMsgBox, "Cannot paste '%s' %s.  %s, '%s' %s.",
!                         ppir->desc, "for compound objects",
!                         "Therefore", ppir->desc,
!                         "cannot be selected");
                    MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
                    break;
--- 1563,1568 ----
                 if (ppir->bit == PROP_MASK_CTM) {
                    sprintf(gszMsgBox, "Cannot paste '%s' %s.  %s, '%s' %s.",
!                         ppir->desc, "for compound objects", "Therefore",
!                         ppir->desc, "cannot be selected");
                    MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
                    break;
***************
*** 2595,2599 ****
     int *pnEntries;
  {
!    DspList *dsp_ptr=NULL, *pdl=NULL;
     char *pszKeys=NULL;
     int num_entries=0;
--- 2593,2597 ----
     int *pnEntries;
  {
!    DspList *dsp_ptr=NULL;
     char *pszKeys=NULL;
     int num_entries=0;
***************
*** 2601,2604 ****
--- 2599,2603 ----
     *pnEntries = 0;
     if ((pszKeys=tgGetProfileString(pszSection, NULL, pszIniFile)) != NULL) {
+       DspList *pdl=NULL;
        char *pszKey=NULL;
  
***************
*** 2716,2719 ****
--- 2715,2719 ----
        sprintf(gszMsgBox, "The [%s] section of '%s' is empty.\n\n%s.",
              pszSection, pszIniFile, "Nothing to edit");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
        return FALSE;
     }
***************
*** 2748,2750 ****
--- 2748,2846 ----
  
     return ok_pressed;
+ }
+ 
+ static
+ DspList *IniSectionKeysListing(pszSection, pszIniFile, pnEntries)
+    char *pszSection, *pszIniFile;
+    int *pnEntries;
+ {
+    DspList *dsp_ptr=NULL;
+    char *pszKeys=NULL;
+    int num_entries=0;
+ 
+    *pnEntries = 0;
+    if ((pszKeys=tgGetProfileString(pszSection, NULL, pszIniFile)) != NULL) {
+       DspList *pdl=NULL;
+       char *pszKey=NULL;
+ 
+       for (pszKey=pszKeys; *pszKey != '\0'; pszKey++) {
+          num_entries++;
+          pszKey += strlen(pszKey);
+       }
+       dsp_ptr = (DspList*)malloc(num_entries*sizeof(DspList));
+       if (dsp_ptr == NULL) FailAllocMessage();
+       memset(dsp_ptr, 0, num_entries*sizeof(DspList));
+       for (pszKey=pszKeys, pdl=dsp_ptr; *pszKey != '\0'; pszKey++, pdl++) {
+          UtilStrCpyN(pdl->itemstr, sizeof(pdl->itemstr), pszKey);
+          /* use the directory field for inherited */
+          pdl->next = (&pdl[1]);
+ 
+          pszKey += strlen(pszKey);
+       }
+       tgFreeProfileString(pszKeys);
+    }
+    if (num_entries == 0) return NULL;
+ 
+    dsp_ptr[num_entries-1].next = NULL;
+    *pnEntries = num_entries;
+ 
+    return dsp_ptr;
+ }
+ 
+ static
+ int SelectFromIniSectionStrings(psz_title, dsp_ptr, entries, num_entries,
+       selected_str, selected_str_sz)
+    char *psz_title, **entries, *selected_str;
+    DspList *dsp_ptr;
+    int num_entries, selected_str_sz;
+ {
+    char win_name[128];
+ 
+    sprintf(win_name, "%s - Edit Ini Section", TOOL_NAME);
+    ResetNamesInfo();
+    NamesSetTitle(psz_title);
+    NamesAddButton("Ok", BUTTON_OK);
+    NamesAddButton("Cancel", BUTTON_CANCEL);
+    /* ignore double-click and <CR> */
+    NamesSetDefaultBtnId(BUTTON_OK, BUTTON_OK);
+    NamesSetStyle(NAMES_SIMPLE_SELECT_NAME, NAMES_LOOP_ONCE);
+    NamesSetEntries(dsp_ptr, entries, num_entries, NULL, TRUE, INVALID, 0);
+    return (Names(win_name, NULL, selected_str, selected_str_sz,
+          NULL)==BUTTON_OK);
+ }
+ 
+ char *SelectFromIniSection(pszTitle, pszSection, pszIniFile)
+    char *pszTitle, *pszSection, *pszIniFile;
+ {
+    int num_entries=0;
+    DspList *dsp_ptr=NULL;
+    char sz_title[MAXSTRING], **entries=NULL, selected_str[MAXSTRING];
+ 
+    MakeQuiescent();
+ 
+    dsp_ptr = IniSectionKeysListing(pszSection, pszIniFile, &num_entries);
+    if (dsp_ptr == NULL) {
+       sprintf(gszMsgBox, "The [%s] section of '%s' is empty.\n\n%s.",
+             pszSection, pszIniFile, "Nothing to select from");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       return FALSE;
+    }
+    ignoreDirectoryFlag = TRUE;
+    entries = MakeNameDspItemArray(num_entries, dsp_ptr);
+    ignoreDirectoryFlag = FALSE;
+    if (pszTitle == NULL) {
+       sprintf(sz_title, "Select a value from [%s]...", pszSection);
+    } else {
+       UtilStrCpyN(sz_title, sizeof(sz_title), pszTitle);
+    }
+    *selected_str = '\0';
+    if (!SelectFromIniSectionStrings(sz_title, dsp_ptr, entries, num_entries,
+          selected_str, sizeof(selected_str))) {
+       *selected_str = '\0';
+    }
+    free(dsp_ptr);
+    free(*entries);
+    free(entries);
+ 
+    return (*selected_str=='\0' ? NULL : UtilStrDup(selected_str));
  }
*** dialog.c.orig	Sun Apr 11 10:46:44 1999
--- dialog.c	Sun Apr 11 10:46:44 1999
***************
*** 278,353 ****
  }
  
! static
! void CalcSimpleGeometry(MBInfoPtr, Message)
!    struct MBRec *MBInfoPtr;
!    char *Message;
  {
!    int len=strlen(Message), max_len=0, max_h=0, left, inc, i, a_btn_w, a_btn_h;
!    char *dest_ptr, *c_ptr;
!    int font_height=0, font_asc=0, font_des=0, y=0;
  
!    font_height = defaultFontHeight;
!    font_asc = defaultFontAsc;
!    font_des = defaultFontDes;
  
!    MBInfoPtr->msg_copy = (char*)malloc(((len<<1)+1)*sizeof(char));
!    if (MBInfoPtr->msg_copy == NULL) FailAllocMessage();
  
!    dest_ptr = MBInfoPtr->msg_copy;
     *dest_ptr = '\0';
!    c_ptr = Message;
     while (c_ptr != NULL) {
        /* a line at a time */
        char *lf_ptr=strchr(c_ptr, '\n');
!       int full_str_len;
  
        if (lf_ptr != NULL) *lf_ptr = '\0';
        full_str_len = strlen(c_ptr);
!       if (full_str_len > max_len) {
!          if (full_str_len > MBInfoPtr->max_msg_str_len) {
              /* line too long for the message box */
              char *line=c_ptr;
  
!             max_len = MBInfoPtr->max_msg_str_len;
              while (line != NULL && *line != '\0') {
!                int line_len;
  
                 while (*line == ' ') line++;
                 line_len = strlen(line);
!                if (line_len > MBInfoPtr->max_msg_str_len) {
!                   int index=MBInfoPtr->max_msg_str_len;
  
!                   if (line[index] == ' ') {
!                      int saved_index=index--;
  
!                      while (index >=0 && line[index] == ' ') index--;
!                      line[++index] = '\0';
!                      sprintf(dest_ptr, "%s\n", line);
!                      dest_ptr = &dest_ptr[strlen(dest_ptr)];
!                      max_h += font_height+SPACING;
!                      line = &line[saved_index+1];
!                   } else {
!                      int saved_index=index;
! 
!                      while (index >=0 && line[index] != ' ') index--;
!                      if (index < 0) {
                          /* very long word */
-                         char saved_ch=line[saved_index];
- 
-                         line[saved_index] = '\0';
                          sprintf(dest_ptr, "%s\n", line);
                          dest_ptr = &dest_ptr[strlen(dest_ptr)];
!                         max_h += font_height+SPACING;
!                         line[saved_index] = saved_ch;
!                         line = &line[saved_index];
                       } else {
                          /* find a good space */
!                         saved_index = index--;
!                         while (index >=0 && line[index] == ' ') index--;
!                         line[++index] = '\0';
                          sprintf(dest_ptr, "%s\n", line);
                          dest_ptr = &dest_ptr[strlen(dest_ptr)];
!                         max_h += font_height+SPACING;
!                         line = &line[saved_index+1];
                       }
                    }
--- 278,378 ----
  }
  
! void CalcFormatStringInBox(buf, xfs, format_box_w, pn_num_lines, pn_max_w,
!       pn_max_h, ppsz_formated_buf)
!    char *buf, **ppsz_formated_buf;
!    XFontStruct *xfs;
!    int format_box_w, *pn_num_lines, *pn_max_w, *pn_max_h;
  {
!    char *dest_ptr=NULL, *c_ptr=NULL, *msg_copy=NULL;
!    int len=strlen(buf), max_len=0, max_w=0, max_h=0, total=0;
!    int num_lines=1, spacing=SPACING;
!    int font_height=xfs->max_bounds.ascent+xfs->max_bounds.descent;
  
!    total = XTextWidth(xfs, buf, len);
  
!    msg_copy = (char*)malloc(((len<<1)+1)*sizeof(char));
!    if (msg_copy == NULL) FailAllocMessage();
  
!    dest_ptr = msg_copy;
     *dest_ptr = '\0';
!    c_ptr = buf;
     while (c_ptr != NULL) {
        /* a line at a time */
        char *lf_ptr=strchr(c_ptr, '\n');
!       int full_str_len, full_str_total;
  
        if (lf_ptr != NULL) *lf_ptr = '\0';
        full_str_len = strlen(c_ptr);
!       full_str_total = XTextWidth(xfs, c_ptr, full_str_len);
!       if (full_str_total > max_w) {
!          if (full_str_total > format_box_w) {
              /* line too long for the message box */
              char *line=c_ptr;
  
!             max_w = format_box_w;
              while (line != NULL && *line != '\0') {
!                int line_len, line_total;
  
                 while (*line == ' ') line++;
                 line_len = strlen(line);
!                line_total = XTextWidth(xfs, line, line_len);
!                if (line_total > format_box_w) {
!                   char *lead_ptr=line, *last_ptr=NULL;
!                   int lead_index=0, last_index=0, still_going=TRUE;
  
!                   while (still_going && *lead_ptr != '\0') {
!                      char saved_ch;
!                      int w;
  
!                      while (*lead_ptr != ' ' && *lead_ptr != '\0') {
!                         lead_ptr++;
!                         lead_index++;
!                      }
!                      saved_ch = (*lead_ptr);
!                      *lead_ptr = '\0';
!                      w = XTextWidth(xfs, line, lead_index);
!                      if (w > format_box_w) {
!                         if (last_ptr == NULL) {
!                            /* very long word */
!                            sprintf(dest_ptr, "%s\n", line);
!                            dest_ptr = &dest_ptr[strlen(dest_ptr)];
!                            max_h += font_height+spacing;
!                            num_lines++;
!                            line = &line[lead_index];
!                         } else {
!                            /* find a good space */
!                            *last_ptr = '\0';
!                            sprintf(dest_ptr, "%s\n", line);
!                            *last_ptr = ' ';
!                            dest_ptr = &dest_ptr[strlen(dest_ptr)];
!                            max_h += font_height+spacing;
!                            num_lines++;
!                            line = &line[last_index+1];
!                         }
!                         still_going = FALSE;
!                      } else {
!                         last_ptr = lead_ptr;
!                         last_index = lead_index;
!                      }
!                      *lead_ptr++ = saved_ch;
!                      lead_index++;
!                   }
!                   if (still_going && *lead_ptr == '\0') {
!                      if (last_ptr == NULL) {
                          /* very long word */
                          sprintf(dest_ptr, "%s\n", line);
                          dest_ptr = &dest_ptr[strlen(dest_ptr)];
!                         max_h += font_height+spacing;
!                         num_lines++;
!                         line = &line[lead_index];
                       } else {
                          /* find a good space */
!                         *last_ptr = '\0';
                          sprintf(dest_ptr, "%s\n", line);
+                         *last_ptr = ' ';
                          dest_ptr = &dest_ptr[strlen(dest_ptr)];
!                         max_h += font_height+spacing;
!                         num_lines++;
!                         line = &line[last_index+1];
                       }
                    }
***************
*** 355,359 ****
                    sprintf(dest_ptr, "%s\n", line);
                    dest_ptr = &dest_ptr[strlen(dest_ptr)];
!                   max_h += font_height+SPACING;
                    break;
                 }
--- 380,384 ----
                    sprintf(dest_ptr, "%s\n", line);
                    dest_ptr = &dest_ptr[strlen(dest_ptr)];
!                   max_h += font_height+spacing;
                    break;
                 }
***************
*** 361,367 ****
           } else {
              max_len = full_str_len;
              sprintf(dest_ptr, "%s\n", c_ptr);
              dest_ptr = &dest_ptr[strlen(dest_ptr)];
!             max_h += font_height+SPACING;
           }
        } else {
--- 386,394 ----
           } else {
              max_len = full_str_len;
+             max_w = full_str_total;
              sprintf(dest_ptr, "%s\n", c_ptr);
              dest_ptr = &dest_ptr[strlen(dest_ptr)];
!             max_h += font_height+spacing;
!             if (lf_ptr != NULL) num_lines++;
           }
        } else {
***************
*** 368,374 ****
           sprintf(dest_ptr, "%s\n", c_ptr);
           dest_ptr = &dest_ptr[strlen(dest_ptr)];
!          max_h += font_height+SPACING;
        }
!       max_h -= SPACING;
        if (lf_ptr != NULL) {
           *lf_ptr = '\n';
--- 395,402 ----
           sprintf(dest_ptr, "%s\n", c_ptr);
           dest_ptr = &dest_ptr[strlen(dest_ptr)];
!          max_h += font_height+spacing;
!          if (lf_ptr != NULL) num_lines++;
        }
!       max_h -= spacing;
        if (lf_ptr != NULL) {
           *lf_ptr = '\n';
***************
*** 378,385 ****
        }
     }
     if (MBInfoPtr->is_dialog) {
        MBInfoPtr->msg_win_w = MBInfoPtr->max_msg_str_total;
     } else {
!       MBInfoPtr->msg_win_w = max_len*defaultFontWidth;
     }
     MBInfoPtr->msg_win_h = max_h;
--- 406,433 ----
        }
     }
+    if (pn_num_lines != NULL) *pn_num_lines = num_lines;
+    if (pn_max_w != NULL) *pn_max_w = max_w;
+    if (pn_max_h != NULL) *pn_max_h = max_h;
+    if (ppsz_formated_buf == NULL) {
+       free(msg_copy);
+    } else {
+       *ppsz_formated_buf = msg_copy;
+    }
+ }
+ 
+ static
+ void CalcSimpleGeometry(MBInfoPtr, Message)
+    struct MBRec *MBInfoPtr;
+    char *Message;
+ {
+    int i=0, max_h=0, left=0, inc=0, a_btn_w=0, a_btn_h=0, y=0, max_w=0;;
+ 
+    CalcFormatStringInBox(Message, boldMsgFontPtr, MBInfoPtr->max_msg_str_total,
+          NULL, &max_w, &max_h, &MBInfoPtr->msg_copy);
+ 
     if (MBInfoPtr->is_dialog) {
        MBInfoPtr->msg_win_w = MBInfoPtr->max_msg_str_total;
     } else {
!       MBInfoPtr->msg_win_w = max_w;
     }
     MBInfoPtr->msg_win_h = max_h;
***************
*** 450,576 ****
     char *Message;
  {
!    int len=strlen(Message), max_h=0, left, inc, i, a_btn_w, a_btn_h;
!    int max_len=0, max_total=0;
!    char *dest_ptr, *c_ptr;
!    int font_height, font_asc, font_des, total, y=0;
  
!    font_height = boldMsgFontHeight;
!    font_asc = boldMsgFontAsc;
!    font_des = boldMsgFontDes;
!    total = XTextWidth(boldMsgFontPtr, Message, len);
  
-    MBInfoPtr->msg_copy = (char*)malloc(((len<<1)+1)*sizeof(char));
-    if (MBInfoPtr->msg_copy == NULL) FailAllocMessage();
- 
-    dest_ptr = MBInfoPtr->msg_copy;
-    *dest_ptr = '\0';
-    c_ptr = Message;
-    while (c_ptr != NULL) {
-       /* a line at a time */
-       char *lf_ptr=strchr(c_ptr, '\n');
-       int full_str_len, full_str_total;
- 
-       if (lf_ptr != NULL) *lf_ptr = '\0';
-       full_str_len = strlen(c_ptr);
-       full_str_total = XTextWidth(boldMsgFontPtr, c_ptr, full_str_len);
-       if (full_str_total > max_total) {
-          if (full_str_total > MBInfoPtr->max_msg_str_total) {
-             /* line too long for the message box */
-             char *line=c_ptr;
- 
-             max_total = MBInfoPtr->max_msg_str_total;
-             while (line != NULL && *line != '\0') {
-                int line_len, line_total;
- 
-                while (*line == ' ') line++;
-                line_len = strlen(line);
-                line_total = XTextWidth(boldMsgFontPtr, line, line_len);
-                if (line_total > MBInfoPtr->max_msg_str_total) {
-                   char *lead_ptr=line, *last_ptr=NULL;
-                   int lead_index=0, last_index=0, still_going=TRUE;
- 
-                   while (still_going && *lead_ptr != '\0') {
-                      char saved_ch;
-                      int w;
- 
-                      while (*lead_ptr != ' ' && *lead_ptr != '\0') {
-                         lead_ptr++;
-                         lead_index++;
-                      }
-                      saved_ch = (*lead_ptr);
-                      *lead_ptr = '\0';
-                      w = XTextWidth(boldMsgFontPtr, line, lead_index);
-                      if (w > MBInfoPtr->max_msg_str_total) {
-                         if (last_ptr == NULL) {
-                            /* very long word */
-                            sprintf(dest_ptr, "%s\n", line);
-                            dest_ptr = &dest_ptr[strlen(dest_ptr)];
-                            max_h += font_height+SPACING;
-                            line = &line[lead_index];
-                         } else {
-                            /* find a good space */
-                            *last_ptr = '\0';
-                            sprintf(dest_ptr, "%s\n", line);
-                            *last_ptr = ' ';
-                            dest_ptr = &dest_ptr[strlen(dest_ptr)];
-                            max_h += font_height+SPACING;
-                            line = &line[last_index+1];
-                         }
-                         still_going = FALSE;
-                      } else {
-                         last_ptr = lead_ptr;
-                         last_index = lead_index;
-                      }
-                      *lead_ptr++ = saved_ch;
-                      lead_index++;
-                   }
-                   if (still_going && *lead_ptr == '\0') {
-                      if (last_ptr == NULL) {
-                         /* very long word */
-                         sprintf(dest_ptr, "%s\n", line);
-                         dest_ptr = &dest_ptr[strlen(dest_ptr)];
-                         max_h += font_height+SPACING;
-                         line = &line[lead_index];
-                      } else {
-                         /* find a good space */
-                         *last_ptr = '\0';
-                         sprintf(dest_ptr, "%s\n", line);
-                         *last_ptr = ' ';
-                         dest_ptr = &dest_ptr[strlen(dest_ptr)];
-                         max_h += font_height+SPACING;
-                         line = &line[last_index+1];
-                      }
-                   }
-                } else if (line_len > 0) {
-                   sprintf(dest_ptr, "%s\n", line);
-                   dest_ptr = &dest_ptr[strlen(dest_ptr)];
-                   max_h += font_height+SPACING;
-                   break;
-                }
-             }
-          } else {
-             max_len = full_str_len;
-             max_total = full_str_total;
-             sprintf(dest_ptr, "%s\n", c_ptr);
-             dest_ptr = &dest_ptr[strlen(dest_ptr)];
-             max_h += font_height+SPACING;
-          }
-       } else {
-          sprintf(dest_ptr, "%s\n", c_ptr);
-          dest_ptr = &dest_ptr[strlen(dest_ptr)];
-          max_h += font_height+SPACING;
-       }
-       max_h -= SPACING;
-       if (lf_ptr != NULL) {
-          *lf_ptr = '\n';
-          c_ptr = &lf_ptr[1];
-       } else {
-          break;
-       }
-    }
     if (MBInfoPtr->is_dialog) {
        MBInfoPtr->msg_win_w = MBInfoPtr->max_msg_str_total;
     } else {
!       MBInfoPtr->msg_win_w = max_total;
     }
     MBInfoPtr->msg_win_h = max_h;
--- 498,511 ----
     char *Message;
  {
!    int i=0, max_h=0, left=0, inc=0, a_btn_w=0, a_btn_h=0;
!    int font_height=boldMsgFontHeight, y=0, max_w=0;
  
!    CalcFormatStringInBox(Message, boldMsgFontPtr, MBInfoPtr->max_msg_str_total,
!          NULL, &max_w, &max_h, &MBInfoPtr->msg_copy);
  
     if (MBInfoPtr->is_dialog) {
        MBInfoPtr->msg_win_w = MBInfoPtr->max_msg_str_total;
     } else {
!       MBInfoPtr->msg_win_w = max_w;
     }
     MBInfoPtr->msg_win_h = max_h;
*** drawing.c.orig	Sun Apr 11 10:46:46 1999
--- drawing.c	Sun Apr 11 10:46:46 1999
***************
*** 121,124 ****
--- 121,125 ----
  int		userDisableRedraw=FALSE;
  int		executingCommands=FALSE;
+ int		gnDisableShortcuts=FALSE;
  
  static Pixmap	execAnimatePixmap=None;
***************
*** 404,407 ****
--- 405,445 ----
  }
  
+ #include "xbm/run.xbm"
+ 
+ static
+ void ShowRunning(dpy, win, win_w, win_h)
+    Display *dpy;
+    Window win;
+    int win_w, win_h;
+ {
+    GC gc;
+    XGCValues values;
+    int bg_pixel=(threeDLook ? myLtGryPixel : myBgPixel);
+ 
+    values.foreground = myFgPixel;
+    values.background = bg_pixel;
+    values.fill_style = FillOpaqueStippled;
+    values.stipple = runBitmap;
+    values.ts_x_origin = 0;
+    values.ts_y_origin = 0;
+    gc = XCreateGC(dpy, win,
+          GCForeground | GCBackground | GCFillStyle | GCStipple |
+          GCTileStipXOrigin | GCTileStipYOrigin, &values);
+    if (gc != NULL) {
+       if (threeDLook) {
+          values.foreground = bg_pixel;
+          values.fill_style = FillSolid;
+          XChangeGC(dpy, gc, GCForeground | GCFillStyle, &values);
+          XFillRectangle(dpy, win, gc, 0, 0, win_w, win_h);
+          values.foreground = myFgPixel;
+          values.fill_style = FillOpaqueStippled;
+          XChangeGC(dpy, gc, GCForeground | GCFillStyle, &values);
+       }
+       XFillRectangle(dpy, win, gc, 0, 0, run_width, run_height);
+       XFreeGC(dpy, gc);
+    }
+    if (run_bits) { } /* do nothing but reference the variable */
+ }
+ 
  void RedrawDummyWindow2()
  {
***************
*** 408,412 ****
--- 446,454 ----
     XEvent ev;
  
+    XClearWindow(mainDisplay, dummyWindow2);
     while (XCheckWindowEvent(mainDisplay, dummyWindow2, ExposureMask, &ev)) ;
+    if (gnDisableShortcuts) {
+       ShowRunning(mainDisplay, dummyWindow2, scrollBarW, scrollBarW);
+    }
     if (threeDLook) {
        struct BBRec bbox;
***************
*** 414,418 ****
        SetBBRec(&bbox, 0, 0, scrollBarW, scrollBarW);
        TgDrawThreeDButton(mainDisplay, dummyWindow2, textMenuGC, &bbox,
!             TGBS_LOWRED, 2, TRUE);
     }
  }
--- 456,460 ----
        SetBBRec(&bbox, 0, 0, scrollBarW, scrollBarW);
        TgDrawThreeDButton(mainDisplay, dummyWindow2, textMenuGC, &bbox,
!             gnDisableShortcuts ? TGBS_RAISED : TGBS_LOWRED, 2, TRUE);
     }
  }
***************
*** 1799,1802 ****
--- 1841,1851 ----
     /* returns INVALID if the key event can be caught by other windows */
  {
+    if (gnDisableShortcuts) {
+       sprintf(gszMsgBox, "%s %s!",
+             TOOL_NAME,
+             "is not finished with the previous ExecCmdsFromFile() yet");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       return BAD;
+    }
     if ((state & ControlMask) && (!(state & Mod1Mask))) {
        int rc=BAD;
*** edit.c.orig	Sun Apr 11 10:46:48 1999
--- edit.c	Sun Apr 11 10:46:48 1999
***************
*** 583,587 ****
     int changed=FALSE, read_only_text_exists=FALSE;
     int into_words=INVALID;
-    ObjListInfo oli;
  
     if (topSel == NULL) {
--- 583,586 ----
***************
*** 592,597 ****
     if ((into_words=GetBreakSpec()) == INVALID) return;
  
-    memset(&oli, 0, sizeof(ObjListInfo));
- 
     HighLightReverse();
     sel_ltx = selLtX; sel_lty = selLtY;
--- 591,594 ----
***************
*** 603,606 ****
--- 600,605 ----
        obj_ptr = sel_ptr->obj;
        if (obj_ptr->type == OBJ_TEXT && !obj_ptr->locked) {
+          ObjListInfo oli;
+ 
           if (obj_ptr->detail.t->read_only) {
              read_only_text_exists = TRUE;
***************
*** 607,610 ****
--- 606,611 ----
              continue;
           }
+          memset(&oli, 0, sizeof(ObjListInfo));
+ 
           changed = TRUE;
  
*** exec.c.orig	Sun Apr 11 10:46:50 1999
--- exec.c	Sun Apr 11 10:46:50 1999
***************
*** 40,45 ****
--- 40,47 ----
  
  #include "align.e"
+ #include "arc.e"
  #include "attr.e"
  #include "auxtext.e"
+ #include "box.e"
  #include "cmd.e"
  #include "color.e"
***************
*** 67,73 ****
--- 69,79 ----
  #include "navigate.e"
  #include "obj.e"
+ #include "oval.e"
  #include "pattern.e"
  #include "poly.e"
+ #include "polygon.e"
  #include "raster.e"
+ #include "rcbox.e"
+ #include "rect.e"
  #include "remote.e"
  #include "select.e"
***************
*** 136,139 ****
--- 142,147 ----
  int ExecAppendAttrIntoFile ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecSelectObjByName ARGS_DECL((char**, struct ObjRec *, char*));
+ void ExecSelectTopObj ARGS_DECL((struct ObjRec *, char*));
+ void ExecDelAllSelObj ARGS_DECL((struct ObjRec *, char*));
  void ExecUnSelectAllObj ARGS_DECL((struct ObjRec *, char*));
  int ExecMoveSelObjRel ARGS_DECL((char**, struct ObjRec *, char*));
***************
*** 154,157 ****
--- 162,171 ----
  int ExecSetSelObjDash ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecSetSelObjTransPat ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecSetSelObjRCBRadius ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecSetSelTextVSpace ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecSetSelTextJust ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecSetSelTextFont ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecSetSelTextSize ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecSetSelTextUnderline ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecInc ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecDec ARGS_DECL((char**, struct ObjRec *, char*));
***************
*** 165,168 ****
--- 179,183 ----
  int ExecStrCpy ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecStrCat ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecCopyStrToCutBuffer ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecWhile ARGS_DECL((char**, char**, struct ObjRec *, char*));
  int ExecIf ARGS_DECL((char**, struct ObjRec *, char*));
***************
*** 188,191 ****
--- 203,207 ----
  int ExecGetUserInput ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecAddAttrToSelObj ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecDelAttrFromSelObj ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecUserEndAnEdge ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecUserDrawAnEdge ARGS_DECL((char**, struct ObjRec *, char*));
***************
*** 242,248 ****
--- 258,278 ----
  int ExecSetXpmOutputVersion ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecEditIniSection ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecSelectFromIniSection ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecAppendLineIntoAttr ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecInsertLineIntoAttr ARGS_DECL((char**, struct ObjRec *, char*));
  int ExecClearAttr ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecCreateText ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecCreateBox ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecCreateCornerOval ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecCreateCenterOval ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecCreateEdgeOval ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecCreateRCBox ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecCreateArc ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecCreateFirstVertex ARGS_DECL((char**, struct ObjRec *, char*));
+ int ExecCreateNextVertex ARGS_DECL((char**, struct ObjRec *, char*));
+ void ExecCreatePoly ARGS_DECL((struct ObjRec *, char*));
+ void ExecCreatePolygon ARGS_DECL((struct ObjRec *, char*));
+ void ExecStartCreateGroup ARGS_DECL((struct ObjRec *, char*));
+ void ExecCreateGroup ARGS_DECL((struct ObjRec *, char*));
  
  static
***************
*** 260,263 ****
--- 290,295 ----
     { (NLFN*)ExecAppendAttrIntoFile,  "append_attr_into_file",             2, 0},
     { (NLFN*)ExecSelectObjByName,     "select_obj_by_name",                1, 0},
+    { (NLFN*)ExecSelectTopObj,        "select_top_obj",                    0, 0},
+    { (NLFN*)ExecDelAllSelObj,        "delete_selected_obj",               0, 0},
     { (NLFN*)ExecUnSelectAllObj,      "unselect_all_obj",                  0, 0},
     { (NLFN*)ExecMoveSelObjRel,       "move_selected_obj_relative",        2, 0},
***************
*** 278,281 ****
--- 310,319 ----
     { (NLFN*)ExecSetSelObjDash,       "set_selected_obj_dash",             1, 0},
     { (NLFN*)ExecSetSelObjTransPat,   "set_selected_obj_trans_pat",        1, 0},
+    { (NLFN*)ExecSetSelObjRCBRadius,  "set_selected_obj_rcb_radius",       1, 0},
+    { (NLFN*)ExecSetSelTextVSpace,    "set_selected_text_vspace",          1, 0},
+    { (NLFN*)ExecSetSelTextJust,      "set_selected_text_just",            1, 0},
+    { (NLFN*)ExecSetSelTextFont,      "set_selected_text_font",            1, 0},
+    { (NLFN*)ExecSetSelTextSize,      "set_selected_text_size",            1, 0},
+    { (NLFN*)ExecSetSelTextUnderline, "set_selected_text_underline",       1, 0},
     { (NLFN*)ExecInc,                 "inc",                               2, 0},
     { (NLFN*)ExecDec,                 "dec",                               2, 0},
***************
*** 289,292 ****
--- 327,331 ----
     { (NLFN*)ExecStrCpy,              "strcpy",                            2, 0},
     { (NLFN*)ExecStrCat,              "strcat",                            2, 0},
+    { (NLFN*)ExecCopyStrToCutBuffer,  "copy_string_to_cut_buffer",         1, 0},
     { (NLFN*)ExecWhile,               "while",                            -2, 1},
     { (NLFN*)ExecIf,                  "if",                                3, 1},
***************
*** 312,315 ****
--- 351,355 ----
     { (NLFN*)ExecGetUserInput,        "get_user_input",                    3, 0},
     { (NLFN*)ExecAddAttrToSelObj,     "add_attr_to_selected_obj",          4, 1},
+    { (NLFN*)ExecDelAttrFromSelObj,   "delete_attr_from_selected_obj",     1, 0},
     { (NLFN*)ExecUserEndAnEdge,       "user_end_an_edge",                  3, 1},
     { (NLFN*)ExecUserDrawAnEdge,      "user_draw_an_edge",                 2, 0},
***************
*** 366,372 ****
--- 406,426 ----
     { (NLFN*)ExecSetXpmOutputVersion, "set_xpm_output_version",            1, 0},
     { (NLFN*)ExecEditIniSection,      "edit_ini_section",                  4, 0},
+    { (NLFN*)ExecSelectFromIniSection,"select_from_ini_section",           4, 0},
     { (NLFN*)ExecAppendLineIntoAttr,  "append_line_into_attr",             2, 0},
     { (NLFN*)ExecInsertLineIntoAttr,  "insert_line_into_attr",             3, 0},
     { (NLFN*)ExecClearAttr,           "clear_attr",                        1, 0},
+    { (NLFN*)ExecCreateText,          "create_text_obj",                   3, 0},
+    { (NLFN*)ExecCreateBox,           "create_box_obj",                    4, 0},
+    { (NLFN*)ExecCreateCornerOval,    "create_corner_oval_obj",            4, 0},
+    { (NLFN*)ExecCreateCenterOval,    "create_center_oval_obj",            3, 0},
+    { (NLFN*)ExecCreateEdgeOval,      "create_edge_oval_obj",              4, 0},
+    { (NLFN*)ExecCreateRCBox,         "create_rcbox_obj",                  4, 0},
+    { (NLFN*)ExecCreateArc,           "create_arc_obj",                    6, 0},
+    { (NLFN*)ExecCreateFirstVertex,   "create_first_vertex",               2, 0},
+    { (NLFN*)ExecCreateNextVertex,    "create_next_vertex",                2, 0},
+    { (NLFN*)ExecCreatePoly,          "create_poly_obj",                   0, 0},
+    { (NLFN*)ExecCreatePolygon,       "create_polygon_obj",                0, 0},
+    { (NLFN*)ExecStartCreateGroup,    "start_create_group_obj",            0, 0},
+    { (NLFN*)ExecCreateGroup,         "create_group_obj",                  0, 0},
     { NULL, NULL, 0, 0 }
  };
***************
*** 1476,1479 ****
--- 1530,1557 ----
  
  static
+ int FloatExpression(expr, p_dval, orig_cmd)
+    char *expr, *orig_cmd;
+    double *p_dval;
+ {
+    struct VRec v;
+ 
+    if (EvalExpr(expr, &v)) {
+       switch (v.vtype) {
+       case NULL_VAL: break;
+       case INT_VAL: if (p_dval != NULL) *p_dval = (double)v.val.i; return TRUE;
+       case DBL_VAL: if (p_dval != NULL) *p_dval = v.val.d; return TRUE;
+       case STR_VAL: break;
+       default: break;
+       }
+    }
+    sprintf(gszMsgBox, "%s '%s' %s '%s' %s.",
+          "Invalid evaluation", expr,
+          "used (floating pointer number expected) when executing the",
+          orig_cmd, "command");
+    MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+    return FALSE;
+ }
+ 
+ static
  void SelectAnObj(sub_obj, owner_obj, top_owner, pp_saved_top_sel,
        pp_saved_bot_sel)
***************
*** 2460,2463 ****
--- 2538,2573 ----
  }
  
+ void ExecSelectTopObj(obj_ptr, orig_cmd)
+    char *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* select_top_obj(); */
+ {
+    if (topObj == NULL) {
+       sprintf(execDummyStr, "%s '%s' %s.",
+             "No object found while executing the", orig_cmd, "command");
+       MsgBox(execDummyStr, TOOL_NAME, INFO_MB);
+       gnAbortExec = TRUE;
+    } else {
+       if (topSel != NULL) RemoveAllSel();
+ 
+       SelectTopObj();
+    }
+ }
+ 
+ void ExecDelAllSelObj(obj_ptr, orig_cmd)
+    char *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* delete_selected_obj(); */
+ {
+    if (topSel == NULL) {
+       sprintf(execDummyStr, "%s '%s' %s.",
+             "No object selected while executing the", orig_cmd, "command");
+       MsgBox(execDummyStr, TOOL_NAME, INFO_MB);
+       gnAbortExec = TRUE;
+    } else {
+       DelAllSelObj();
+    }
+ }
+ 
  void ExecUnSelectAllObj(obj_ptr, orig_cmd)
     struct ObjRec *obj_ptr;
***************
*** 2590,2594 ****
     struct ObjRec *dest_attr_owner_obj=NULL;
     MiniLineInfo *pMiniLine=NULL;
!    char *buf=NULL, *c_ptr, *tmp_buf=NULL;
     int buf_sz=0, buf_len=0, tmp_sz=0, num_attrs=0;
     int found_name=FALSE, seen_first_attr=FALSE, null_url=FALSE;
--- 2700,2704 ----
     struct ObjRec *dest_attr_owner_obj=NULL;
     MiniLineInfo *pMiniLine=NULL;
!    char *buf=NULL, *c_ptr, *attr_names_buf=NULL;
     int buf_sz=0, buf_len=0, tmp_sz=0, num_attrs=0;
     int found_name=FALSE, seen_first_attr=FALSE, null_url=FALSE;
***************
*** 2627,2632 ****
        if (need_to_free_tmp_buf) UtilFree(tmp_buf);
     }
!    tmp_buf = (char*)malloc((tmp_sz+2)*sizeof(char));
!    if (tmp_buf == NULL) {
        free(buf);
        return FailAllocMessage();
--- 2737,2742 ----
        if (need_to_free_tmp_buf) UtilFree(tmp_buf);
     }
!    attr_names_buf = (char*)malloc((tmp_sz+2)*sizeof(char));
!    if (attr_names_buf == NULL) {
        free(buf);
        return FailAllocMessage();
***************
*** 2633,2637 ****
     }
     tmp_sz = 0;
!    found_name = FALSE;
     for (pMiniLine=list_attr->obj->detail.t->minilines.first;
           pMiniLine != NULL; pMiniLine=pMiniLine->next) {
--- 2743,2747 ----
     }
     tmp_sz = 0;
!    found_name = (!list_attr->nameshown);
     for (pMiniLine=list_attr->obj->detail.t->minilines.first;
           pMiniLine != NULL; pMiniLine=pMiniLine->next) {
***************
*** 2640,2648 ****
  
        if (found_name) {
!          strcpy(&tmp_buf[tmp_sz], tmp_buf);
           tmp_sz += strlen(tmp_buf);
        } else if ((c_ptr=strchr(tmp_buf, '=')) != NULL) {
           found_name = TRUE;
!          strcpy(&tmp_buf[tmp_sz], ++c_ptr);
           tmp_sz += strlen(c_ptr);
        } else {
--- 2750,2758 ----
  
        if (found_name) {
!          strcpy(&attr_names_buf[tmp_sz], tmp_buf);
           tmp_sz += strlen(tmp_buf);
        } else if ((c_ptr=strchr(tmp_buf, '=')) != NULL) {
           found_name = TRUE;
!          strcpy(&attr_names_buf[tmp_sz], ++c_ptr);
           tmp_sz += strlen(c_ptr);
        } else {
***************
*** 2651,2658 ****
        if (need_to_free_tmp_buf) UtilFree(tmp_buf);
  
!       tmp_buf[tmp_sz++] = '\n';
     }
!    tmp_buf[tmp_sz] = '\0';
!    for (num_attrs=0, c_ptr=strtok(tmp_buf, " ,\t\n\r"); c_ptr != NULL;
           num_attrs++, c_ptr=strtok(NULL, " ,\t\n\r")) {
        struct AttrRec *attr_ptr;
--- 2761,2768 ----
        if (need_to_free_tmp_buf) UtilFree(tmp_buf);
  
!       attr_names_buf[tmp_sz++] = '\n';
     }
!    attr_names_buf[tmp_sz] = '\0';
!    for (num_attrs=0, c_ptr=strtok(attr_names_buf, " ,\t\n\r"); c_ptr != NULL;
           num_attrs++, c_ptr=strtok(NULL, " ,\t\n\r")) {
        struct AttrRec *attr_ptr;
***************
*** 2664,2668 ****
        if (attr_ptr == NULL) {
           free(buf);
!          free(tmp_buf);
           return BadAttr(execDummyStr, orig_cmd);
        }
--- 2774,2778 ----
        if (attr_ptr == NULL) {
           free(buf);
!          free(attr_names_buf);
           return BadAttr(execDummyStr, orig_cmd);
        }
***************
*** 2693,2697 ****
        if (buf1 == NULL) {
           free(buf);
!          free(tmp_buf);
           return FailAllocMessage();
        }
--- 2803,2807 ----
        if (buf1 == NULL) {
           free(buf);
!          free(attr_names_buf);
           return FailAllocMessage();
        }
***************
*** 2733,2737 ****
        if ((buf=(char*)realloc(buf, buf1_index+buf_sz+1)) == NULL) {
           free(buf);
!          free(tmp_buf);
           free(buf1);
           return FailAllocMessage();
--- 2843,2847 ----
        if ((buf=(char*)realloc(buf, buf1_index+buf_sz+1)) == NULL) {
           free(buf);
!          free(attr_names_buf);
           free(buf1);
           return FailAllocMessage();
***************
*** 2751,2755 ****
     ReplaceAttrFirstValue(dest_attr_owner_obj, dest_attr, buf);
     free(buf);
!    free(tmp_buf);
     return TRUE;
  }
--- 2861,2865 ----
     ReplaceAttrFirstValue(dest_attr_owner_obj, dest_attr, buf);
     free(buf);
!    free(attr_names_buf);
     return TRUE;
  }
***************
*** 3006,3010 ****
  
     UtilRemoveQuotes(color_str);
!    if (topSel == NULL) return BadSelectedObj(orig_cmd);
  
     if ((index=QuickFindColorIndex(NULL, color_str, &new_alloc, FALSE)) ==
--- 3116,3120 ----
  
     UtilRemoveQuotes(color_str);
!    UtilTrimBlanks(color_str);
  
     if ((index=QuickFindColorIndex(NULL, color_str, &new_alloc, FALSE)) ==
***************
*** 3033,3037 ****
  
     UtilRemoveQuotes(index_str);
-    if (topSel == NULL) return BadSelectedObj(orig_cmd);
  
     if (!IntExpression(index_str, &index, orig_cmd)) {
--- 3143,3146 ----
***************
*** 3058,3062 ****
  
     UtilRemoveQuotes(index_str);
-    if (topSel == NULL) return BadSelectedObj(orig_cmd);
  
     if (!IntExpression(index_str, &index, orig_cmd)) {
--- 3167,3170 ----
***************
*** 3080,3085 ****
  {
     char *width_str=argv[0], *aw_str=argv[1], *ah_str=argv[2];
!    char width_spec[40], aw_spec[40], ah_spec[40];
!    int width, aw, ah;
  
     UtilRemoveQuotes(width_str);
--- 3188,3192 ----
  {
     char *width_str=argv[0], *aw_str=argv[1], *ah_str=argv[2];
!    int width=0, aw=0, ah=0;
  
     UtilRemoveQuotes(width_str);
***************
*** 3086,3091 ****
     UtilRemoveQuotes(aw_str);
     UtilRemoveQuotes(ah_str);
-    if (topSel == NULL) return BadSelectedObj(orig_cmd);
- 
     if (!IntExpression(width_str, &width, orig_cmd) ||
           !IntExpression(aw_str, &aw, orig_cmd) ||
--- 3193,3196 ----
***************
*** 3100,3108 ****
        return FALSE;
     }
!    sprintf(width_spec, "%1d", width);
!    sprintf(aw_spec, "%1d", aw);
!    sprintf(ah_spec, "%1d", ah);
!    ChangeAllSelRealLineWidth(CHANGE_LINE_ALL, width, aw, ah,
!          width_spec, aw_spec, ah_spec, FALSE);
     return TRUE;
  }
--- 3205,3221 ----
        return FALSE;
     }
!    if (topSel == NULL) {
!       int index=GetBestLineWidthIndex(width, aw, ah);
! 
!       ChangeAllSelLineWidth(index, FALSE);
!    } else {
!       char width_spec[40], aw_spec[40], ah_spec[40];
! 
!       sprintf(width_spec, "%1d", width);
!       sprintf(aw_spec, "%1d", aw);
!       sprintf(ah_spec, "%1d", ah);
!       ChangeAllSelRealLineWidth(CHANGE_LINE_ALL, width, aw, ah,
!             width_spec, aw_spec, ah_spec, FALSE);
!    }
     return TRUE;
  }
***************
*** 3117,3121 ****
  
     UtilRemoveQuotes(spline_spec);
!    if (topSel == NULL) return BadSelectedObj(orig_cmd);
  
     if (strcmp(spline_spec,"straight") == 0) {
--- 3230,3234 ----
  
     UtilRemoveQuotes(spline_spec);
!    UtilTrimBlanks(spline_spec);
  
     if (strcmp(spline_spec,"straight") == 0) {
***************
*** 3145,3149 ****
  
     UtilRemoveQuotes(arrow_spec);
!    if (topSel == NULL) return BadSelectedObj(orig_cmd);
  
     if (strcmp(arrow_spec,"none") == 0) {
--- 3258,3262 ----
  
     UtilRemoveQuotes(arrow_spec);
!    UtilTrimBlanks(arrow_spec);
  
     if (strcmp(arrow_spec,"none") == 0) {
***************
*** 3175,3179 ****
  
     UtilRemoveQuotes(index_str);
-    if (topSel == NULL) return BadSelectedObj(orig_cmd);
  
     if (!IntExpression(index_str, &index, orig_cmd)) {
--- 3288,3291 ----
***************
*** 3200,3204 ****
  
     UtilRemoveQuotes(trans_pat_str);
-    if (topSel == NULL) return BadSelectedObj(orig_cmd);
  
     if (!IntExpression(trans_pat_str, &trans_pat, orig_cmd)) {
--- 3312,3315 ----
***************
*** 3214,3217 ****
--- 3325,3478 ----
  }
  
+ int ExecSetSelObjRCBRadius(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* set_selected_obj_rcb_radius(rcb_radius); */
+ {
+    char *rcb_radius_str=argv[0];
+    int rcb_radius=0;
+ 
+    UtilRemoveQuotes(rcb_radius_str);
+ 
+    if (!IntExpression(rcb_radius_str, &rcb_radius, orig_cmd)) {
+       return FALSE;
+    }
+    if (rcb_radius < 4) {
+       sprintf(gszMsgBox, "%s '%s' %s '%s' %s.",
+             "Rcbox radius of", rcb_radius_str,
+             "is out of range when executing the", orig_cmd, "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       return FALSE;
+    }
+    ChangeAllSelRCBRadius(rcb_radius);
+    return TRUE;
+ }
+ 
+ int ExecSetSelTextVSpace(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* set_selected_text_vspace(v_space); */
+ {
+    char *v_space_str=argv[0];
+    int v_space=0;
+ 
+    UtilRemoveQuotes(v_space_str);
+ 
+    if (!IntExpression(v_space_str, &v_space, orig_cmd)) {
+       return FALSE;
+    }
+    ChangeVSpace(v_space);
+    return TRUE;
+ }
+ 
+ int ExecSetSelTextJust(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* set_selected_text_just(just_type); */
+ {
+    char *just_spec=argv[0];
+    int just=JUST_L;
+ 
+    UtilRemoveQuotes(just_spec);
+    UtilTrimBlanks(just_spec);
+ 
+    if (strcmp(just_spec,"left") == 0) {
+       just = JUST_L;
+    } else if (strcmp(just_spec,"center") == 0) {
+       just = JUST_C;
+    } else if (strcmp(just_spec,"right") == 0) {
+       just = JUST_R;
+    } else {
+       sprintf(gszMsgBox, "%s '%s' %s '%s' %s.",
+             "Text justification of", just_spec, "is unknown when executing the",
+             orig_cmd, "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       return FALSE;
+    }
+    ChangeFontJust(just);
+    return TRUE;
+ }
+ 
+ int ExecSetSelTextFont(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* set_selected_text_font(font_spec); */
+ {
+    char *font_spec=argv[0];
+    int font=0, style=0;
+ 
+    UtilRemoveQuotes(font_spec);
+    UtilTrimBlanks(font_spec);
+ 
+    if (!GetFontAndStyle(font_spec, &font, &style, TRUE)) {
+       sprintf(gszMsgBox, "%s '%s' %s '%s' %s.",
+             "Text font of", font_spec, "is unknown when executing the",
+             orig_cmd, "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       return FALSE;
+    }
+    ChangeFont(font, TRUE);
+    ChangeFontStyle(style);
+    return TRUE;
+ }
+ 
+ int ExecSetSelTextSize(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* set_selected_text_size(size); */
+ {
+    char *size_spec=argv[0], *psz=NULL;
+    int size=INVALID, sz_unit=INVALID, use_point_size=FALSE;
+    int size_index=0, min_diff=0, min_size_index=0;
+ 
+    UtilRemoveQuotes(size_spec);
+ 
+    if ((psz=strstr(size_spec, "point")) != NULL ||
+          (psz=strstr(size_spec, "pt")) != NULL) {
+       *psz = '\0';
+       use_point_size = TRUE;
+    }
+    if (!IntExpression(size_spec, &size, orig_cmd)) {
+       return FALSE;
+    }
+    if (use_point_size) {
+       sz_unit = PointSizeToSzUnit(size);
+    } else {
+       sz_unit = FontSizeToSzUnit(size);
+    }
+    if (topSel == NULL) {
+       min_diff = abs(fontSzUnits[0] - sz_unit);
+       for (size_index=1; size_index < numFontSizes; size_index++) {
+          int diff=abs(fontSzUnits[size_index]-sz_unit);
+ 
+          if (diff < min_diff) {
+             min_diff = diff;
+             min_size_index = size_index;
+          }
+       }
+       ChangeFontSize(min_size_index);
+    } else {
+       ChangeAllSelRealSzUnit(sz_unit, FALSE);
+    }
+    return TRUE;
+ }
+ 
+ int ExecSetSelTextUnderline(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* set_selected_text_underline(underline); */
+ {
+    char *underline_on_str=argv[0];
+    int underline_on=0;
+ 
+    UtilRemoveQuotes(underline_on_str);
+ 
+    if (!IntExpression(underline_on_str, &underline_on, orig_cmd)) {
+       return FALSE;
+    }
+    ChangeFontUnderline(underline_on != 0);
+    return TRUE;
+ }
+ 
  int ExecInc(argv, obj_ptr, orig_cmd)
     char **argv, *orig_cmd;
***************
*** 3543,3546 ****
--- 3804,3828 ----
  }
  
+ int ExecCopyStrToCutBuffer(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* copy_string_to_cut_buffer(str); */
+ {
+    char *the_str=argv[0];
+    int len=0;
+ 
+    UtilRemoveQuotes(the_str);
+ 
+    len = strlen(the_str);
+    if (!WriteBufToCutBuffer(the_str, strlen(the_str))) {
+       sprintf(gszMsgBox, "%s '%s' %s.",
+             "Writing to cut buffer failed while executing the", orig_cmd,
+             "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       return FALSE;
+    }
+    return TRUE;
+ }
+ 
  int ExecWhile(argv, raw_argv, obj_ptr, orig_cmd)
     char **argv, **raw_argv, *orig_cmd;
***************
*** 4302,4305 ****
--- 4584,4588 ----
        UpdTextBBox(attr_ptr->obj);
        AdjObjBBox(selected_obj);
+       UpdSelBBox();
        RecordReplaceAnObj(selected_obj);
        RedrawAreas(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
***************
*** 4316,4319 ****
--- 4599,4639 ----
  }
  
+ int ExecDelAttrFromSelObj(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* delete_attr_from_selected_obj(attr_name); */
+ {
+    char *attr_name=argv[0];
+    struct AttrRec *attr_ptr=NULL;
+    struct ObjRec *attr_owner_obj=NULL;
+    int ltx=0, lty=0, rbx=0, rby=0;
+ 
+    UtilRemoveQuotes(attr_name);
+    sprintf(execDummyStr, "%s=", attr_name);
+    attr_ptr = FindAttrWithName(obj_ptr, execDummyStr, &attr_owner_obj);
+    if (attr_ptr == NULL) return BadAttr(execDummyStr, orig_cmd);
+ 
+    ltx = attr_owner_obj->bbox.ltx;
+    lty = attr_owner_obj->bbox.lty;
+    rbx = attr_owner_obj->bbox.rbx;
+    rby = attr_owner_obj->bbox.rby;
+ 
+    PrepareToReplaceAnObj(attr_owner_obj);
+ 
+    UnlinkAttr(attr_ptr);
+    FreeTextObj(attr_ptr->obj);
+    FreeAttr(attr_ptr);
+    AdjObjBBox(attr_owner_obj);
+    if (outerSel != NULL) AdjAncestorsBBox();
+    UpdSelBBox();
+ 
+    RecordReplaceAnObj(attr_owner_obj);
+    RedrawAnArea(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
+          rbx+GRID_ABS_SIZE(1), rby+GRID_ABS_SIZE(1));
+ 
+    SetFileModified(TRUE);
+    return TRUE;
+ }
+ 
  int ExecUserEndAnEdge(argv, obj_ptr, orig_cmd)
     char **argv, *orig_cmd;
***************
*** 6495,6499 ****
     if (buf != NULL) UtilFree(buf);
  
-    SetFileModified(TRUE);
     return TRUE;
  }
--- 6815,6818 ----
***************
*** 6865,6869 ****
  {
     char *attr_name=argv[0], *title=argv[1], *section=argv[2], *ini_path=argv[3];
!    char buf[40];
     struct AttrRec *attr_ptr=NULL;
     struct ObjRec *attr_owner_obj=NULL;
--- 7184,7188 ----
  {
     char *attr_name=argv[0], *title=argv[1], *section=argv[2], *ini_path=argv[3];
!    char buf[40], *psz_keys=NULL;
     struct AttrRec *attr_ptr=NULL;
     struct ObjRec *attr_owner_obj=NULL;
***************
*** 6881,6884 ****
--- 7200,7213 ----
        title = NULL;
     }
+    if ((psz_keys=tgGetProfileString(section, NULL, ini_path)) == NULL) {
+       sprintf(gszMsgBox, "%s [%s] %s '%s' %s '%s' %s.",
+             "The", section, "section of", ini_path,
+             "is empty or non-existent while executing the", orig_cmd,
+             "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       return FALSE;
+    } else {
+       tgFreeProfileString(psz_keys);
+    }
     if (EditIniSection(title, section, ini_path, NULL)) {
        strcpy(buf, "OK");
***************
*** 6887,6893 ****
     }
     if (attr_ptr != NULL) {
        ReplaceAttrFirstValue(attr_owner_obj, attr_ptr, (buf==NULL ? "" : buf));
-       SetFileModified(TRUE);
     }
     return TRUE;
  }
--- 7216,7262 ----
     }
     if (attr_ptr != NULL) {
+       ReplaceAttrFirstValue(attr_owner_obj, attr_ptr, buf);
+    }
+    return TRUE;
+ }
+ 
+ int ExecSelectFromIniSection(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* select_from_ini_section(attr_name,title,section,ini_path); */
+ {
+    char *attr_name=argv[0], *title=argv[1], *section=argv[2], *ini_path=argv[3];
+    char *psz_keys=NULL, *buf=NULL;
+    struct AttrRec *attr_ptr=NULL;
+    struct ObjRec *attr_owner_obj=NULL;
+ 
+    UtilRemoveQuotes(attr_name);
+    UtilRemoveQuotes(title);
+    UtilRemoveQuotes(section);
+    UtilRemoveQuotes(ini_path);
+    if (strcmp(attr_name, "NULL") != 0) {
+       sprintf(execDummyStr, "%s=", attr_name);
+       attr_ptr = FindAttrWithName(obj_ptr, execDummyStr, &attr_owner_obj);
+       if (attr_ptr == NULL) return BadAttr(execDummyStr, orig_cmd);
+    }
+    if (strcmp(title, "NULL") == 0) {
+       title = NULL;
+    }
+    if ((psz_keys=tgGetProfileString(section, NULL, ini_path)) == NULL) {
+       sprintf(gszMsgBox, "%s [%s] %s '%s' %s '%s' %s.",
+             "The", section, "section of", ini_path,
+             "is empty or non-existent while executing the", orig_cmd,
+             "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       return FALSE;
+    } else {
+       tgFreeProfileString(psz_keys);
+    }
+    buf = SelectFromIniSection(title, section, ini_path);
+    if (attr_ptr != NULL) {
        ReplaceAttrFirstValue(attr_owner_obj, attr_ptr, (buf==NULL ? "" : buf));
     }
+    UtilFree(buf);
+ 
     return TRUE;
  }
***************
*** 6924,6928 ****
  
     RecordReplaceAnObj(attr_owner_obj);
!    RedrawAnArea(botObj, attr_ptr->obj->bbox.ltx-GRID_ABS_SIZE(1),
           attr_ptr->obj->bbox.lty-GRID_ABS_SIZE(1),
           attr_ptr->obj->bbox.rbx+GRID_ABS_SIZE(1),
--- 7293,7297 ----
  
     RecordReplaceAnObj(attr_owner_obj);
!    RedrawAnArea(attr_ptr->obj, topObj->bbox.ltx-GRID_ABS_SIZE(1),
           attr_ptr->obj->bbox.lty-GRID_ABS_SIZE(1),
           attr_ptr->obj->bbox.rbx+GRID_ABS_SIZE(1),
***************
*** 7077,7080 ****
--- 7446,7977 ----
  }
  
+ int ExecCreateText(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* create_text_obj(abs_x,abs_baseline_y,str); */
+ {
+    char *abs_x_str=argv[0], *abs_baseline_y_str=argv[1];
+    char *the_str=argv[2];
+    int abs_x=0, abs_baseline_y=0;
+ 
+    UtilRemoveQuotes(abs_x_str);
+    UtilRemoveQuotes(abs_baseline_y_str);
+    UtilRemoveQuotes(the_str);
+    if (!IntExpression(abs_x_str, &abs_x, orig_cmd) ||
+          !IntExpression(abs_baseline_y_str, &abs_baseline_y, orig_cmd)) {
+       return FALSE;
+    }
+    if (*the_str == '\0') {
+       sprintf(gszMsgBox, "%s '%s' %s.",
+             "Invalid string specified while executing the", orig_cmd,
+             "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       return FALSE;
+    }
+    MakeQuiescent();
+ 
+    NewCurText();
+    PrepareToReplaceAnObj(curTextObj);
+    DynStrSet(&topObj->detail.t->minilines.first->first_block->seg->dyn_str,
+          the_str);
+    curTextModified = TRUE;
+    CreateTextObj(TRUE, FALSE);
+    curTextModified = FALSE;
+    MoveObj(topObj, abs_x-topObj->x,
+          abs_baseline_y-topObj->detail.t->baseline_y);
+ 
+    RedrawAnArea(botObj, topObj->bbox.ltx-GRID_ABS_SIZE(1),
+          topObj->bbox.lty-GRID_ABS_SIZE(1),
+          topObj->bbox.rbx+GRID_ABS_SIZE(1),
+          topObj->bbox.rby+GRID_ABS_SIZE(1));
+ 
+    SetFileModified(TRUE);
+    return TRUE;
+ }
+ 
+ int ExecCreateBox(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* create_box_obj(abs_ltx,abs_lty,abs_rbx,abs_rby); */
+ {
+    char *abs_ltx_str=argv[0], *abs_lty_str=argv[1];
+    char *abs_rbx_str=argv[2], *abs_rby_str=argv[3];
+    int abs_ltx=0, abs_lty=0, abs_rbx=0, abs_rby=0;
+ 
+    UtilRemoveQuotes(abs_ltx_str);
+    UtilRemoveQuotes(abs_lty_str);
+    UtilRemoveQuotes(abs_rbx_str);
+    UtilRemoveQuotes(abs_rby_str);
+    if (!IntExpression(abs_ltx_str, &abs_ltx, orig_cmd) ||
+          !IntExpression(abs_lty_str, &abs_lty, orig_cmd) ||
+          !IntExpression(abs_rbx_str, &abs_rbx, orig_cmd) ||
+          !IntExpression(abs_rby_str, &abs_rby, orig_cmd)) {
+       return FALSE;
+    }
+    MakeQuiescent();
+ 
+    CreateBoxObj(abs_ltx, abs_lty, abs_rbx, abs_rby, TRUE);
+ 
+    RecordNewObjCmd();
+    RedrawAnArea(botObj, topObj->bbox.ltx-GRID_ABS_SIZE(1),
+          topObj->bbox.lty-GRID_ABS_SIZE(1),
+          topObj->bbox.rbx+GRID_ABS_SIZE(1),
+          topObj->bbox.rby+GRID_ABS_SIZE(1));
+ 
+    SetFileModified(TRUE);
+    return TRUE;
+ }
+ 
+ int ExecCreateCornerOval(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* create_corner_oval_obj(abs_ltx,abs_lty,abs_rbx,abs_rby); */
+ {
+    char *abs_ltx_str=argv[0], *abs_lty_str=argv[1];
+    char *abs_rbx_str=argv[2], *abs_rby_str=argv[3];
+    int abs_ltx=0, abs_lty=0, abs_rbx=0, abs_rby=0;
+    struct BBRec obbox;
+ 
+    UtilRemoveQuotes(abs_ltx_str);
+    UtilRemoveQuotes(abs_lty_str);
+    UtilRemoveQuotes(abs_rbx_str);
+    UtilRemoveQuotes(abs_rby_str);
+    if (!IntExpression(abs_ltx_str, &abs_ltx, orig_cmd) ||
+          !IntExpression(abs_lty_str, &abs_lty, orig_cmd) ||
+          !IntExpression(abs_rbx_str, &abs_rbx, orig_cmd) ||
+          !IntExpression(abs_rby_str, &abs_rby, orig_cmd)) {
+       return FALSE;
+    }
+    MakeQuiescent();
+ 
+    SetBBRec(&obbox, abs_ltx, abs_lty, abs_rbx, abs_rby);
+    CreateOvalObj(&obbox, TRUE);
+ 
+    RecordNewObjCmd();
+    RedrawAnArea(botObj, topObj->bbox.ltx-GRID_ABS_SIZE(1),
+          topObj->bbox.lty-GRID_ABS_SIZE(1),
+          topObj->bbox.rbx+GRID_ABS_SIZE(1),
+          topObj->bbox.rby+GRID_ABS_SIZE(1));
+ 
+    SetFileModified(TRUE);
+    return TRUE;
+ }
+ 
+ int ExecCreateCenterOval(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* create_center_oval_obj(abs_cx,abs_cy,radius); */
+ {
+    char *abs_cx_str=argv[0], *abs_cy_str=argv[1], *radius_str=argv[2];
+    int abs_cx=0, abs_cy=0, radius=0;
+    struct BBRec obbox;
+ 
+    UtilRemoveQuotes(abs_cx_str);
+    UtilRemoveQuotes(abs_cy_str);
+    UtilRemoveQuotes(radius_str);
+    if (!IntExpression(abs_cx_str, &abs_cx, orig_cmd) ||
+          !IntExpression(abs_cy_str, &abs_cy, orig_cmd) ||
+          !IntExpression(radius_str, &radius, orig_cmd)) {
+       return FALSE;
+    }
+    MakeQuiescent();
+ 
+    SetBBRec(&obbox, abs_cx-radius, abs_cy-radius, abs_cx+radius, abs_cy+radius);
+    CreateOvalObj(&obbox, TRUE);
+ 
+    RecordNewObjCmd();
+    RedrawAnArea(botObj, topObj->bbox.ltx-GRID_ABS_SIZE(1),
+          topObj->bbox.lty-GRID_ABS_SIZE(1),
+          topObj->bbox.rbx+GRID_ABS_SIZE(1),
+          topObj->bbox.rby+GRID_ABS_SIZE(1));
+ 
+    SetFileModified(TRUE);
+    return TRUE;
+ }
+ 
+ int ExecCreateEdgeOval(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* create_edge_oval_obj(abs_ltx,abs_lty,abs_rbx,abs_rby); */
+ {
+    char *abs_ltx_str=argv[0], *abs_lty_str=argv[1];
+    char *abs_rbx_str=argv[2], *abs_rby_str=argv[3];
+    int abs_ltx=0, abs_lty=0, abs_rbx=0, abs_rby=0, cx=0, cy=0, w=0;
+    double dx=(double)0, dy=(double)0, r=(double)0;
+    struct BBRec obbox;
+ 
+    UtilRemoveQuotes(abs_ltx_str);
+    UtilRemoveQuotes(abs_lty_str);
+    UtilRemoveQuotes(abs_rbx_str);
+    UtilRemoveQuotes(abs_rby_str);
+    if (!IntExpression(abs_ltx_str, &abs_ltx, orig_cmd) ||
+          !IntExpression(abs_lty_str, &abs_lty, orig_cmd) ||
+          !IntExpression(abs_rbx_str, &abs_rbx, orig_cmd) ||
+          !IntExpression(abs_rby_str, &abs_rby, orig_cmd)) {
+       return FALSE;
+    }
+    MakeQuiescent();
+ 
+    cx = ((abs_rbx + abs_ltx) >> 1);
+    cy = ((abs_rby + abs_lty) >> 1);
+    dx = (double)(cx - abs_ltx);
+    dy = (double)(cy - abs_lty);
+    r = (double)sqrt(dx*dx+dy*dy);
+    w = round(r);
+    SetBBRec(&obbox, cx-w, cy-w, cx+w, cy+w);
+    CreateOvalObj(&obbox, TRUE);
+ 
+    RecordNewObjCmd();
+    RedrawAnArea(botObj, topObj->bbox.ltx-GRID_ABS_SIZE(1),
+          topObj->bbox.lty-GRID_ABS_SIZE(1),
+          topObj->bbox.rbx+GRID_ABS_SIZE(1),
+          topObj->bbox.rby+GRID_ABS_SIZE(1));
+ 
+    SetFileModified(TRUE);
+    return TRUE;
+ }
+ 
+ int ExecCreateRCBox(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* create_rcbox_obj(abs_ltx,abs_lty,abs_rbx,abs_rby); */
+ {
+    char *abs_ltx_str=argv[0], *abs_lty_str=argv[1];
+    char *abs_rbx_str=argv[2], *abs_rby_str=argv[3];
+    int abs_ltx=0, abs_lty=0, abs_rbx=0, abs_rby=0;
+ 
+    UtilRemoveQuotes(abs_ltx_str);
+    UtilRemoveQuotes(abs_lty_str);
+    UtilRemoveQuotes(abs_rbx_str);
+    UtilRemoveQuotes(abs_rby_str);
+    if (!IntExpression(abs_ltx_str, &abs_ltx, orig_cmd) ||
+          !IntExpression(abs_lty_str, &abs_lty, orig_cmd) ||
+          !IntExpression(abs_rbx_str, &abs_rbx, orig_cmd) ||
+          !IntExpression(abs_rby_str, &abs_rby, orig_cmd)) {
+       return FALSE;
+    }
+    MakeQuiescent();
+ 
+    CreateRCBoxObj(abs_ltx, abs_lty, abs_rbx, abs_rby, TRUE);
+ 
+    RecordNewObjCmd();
+    RedrawAnArea(botObj, topObj->bbox.ltx-GRID_ABS_SIZE(1),
+          topObj->bbox.lty-GRID_ABS_SIZE(1),
+          topObj->bbox.rbx+GRID_ABS_SIZE(1),
+          topObj->bbox.rby+GRID_ABS_SIZE(1));
+ 
+    SetFileModified(TRUE);
+    return TRUE;
+ }
+ 
+ int ExecCreateArc(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* create_arc_obj(abs_cx,abs_cy,radius,dir,theta1,theta2); */
+ {
+    char *abs_cx_str=argv[0], *abs_cy_str=argv[1], *radius_str=argv[2];
+    char *dir_str=argv[3], *theta1_str=argv[4], *theta2_str=argv[5];
+    int abs_cx=0, abs_cy=0, radius=0, dir=0, x1=0, y1=0, x2=0, y2=0;
+    double theta1=(double)0, theta2=(double)0;
+    double angle_in_radian=(double)0, angle2=(double)0;
+ 
+    UtilRemoveQuotes(abs_cx_str);
+    UtilRemoveQuotes(abs_cy_str);
+    UtilRemoveQuotes(radius_str);
+    UtilRemoveQuotes(dir_str);
+    UtilRemoveQuotes(theta1_str);
+    UtilRemoveQuotes(theta2_str);
+    if (!IntExpression(abs_cx_str, &abs_cx, orig_cmd) ||
+          !IntExpression(abs_cy_str, &abs_cy, orig_cmd) ||
+          !IntExpression(radius_str, &radius, orig_cmd) ||
+          !FloatExpression(theta1_str, &theta1, orig_cmd) ||
+          !FloatExpression(theta2_str, &theta2, orig_cmd)) {
+       return FALSE;
+    }
+    UtilTrimBlanks(dir_str);
+    switch (*dir_str) {
+    case '+': dir = ARC_CW; break;
+    case '-': dir = ARC_CCW; break;
+    default:
+       sprintf(gszMsgBox, "%s '%s' %s '%s' %s.",
+             "Invalid direction", dir_str,
+             "specified while executing the", orig_cmd, "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       return FALSE;
+    }
+    MakeQuiescent();
+ 
+    switch (dir) {
+    case ARC_CCW:
+       theta1 += (double)90;
+       theta2 += (double)90;
+       break;
+    case ARC_CW:
+       theta1 = -theta1+((double)90);
+       theta2 = -theta2+((double)90);
+       break;
+    }
+    angle_in_radian = theta1 * M_PI / ((double)180);
+    x1 = round(((double)radius)*cos(angle_in_radian));
+    y1 = -round(((double)radius)*sin(angle_in_radian));
+    angle_in_radian = theta2 * M_PI / ((double)180);
+    x2 = round(((double)radius)*cos(angle_in_radian));
+    y2 = -round(((double)radius)*sin(angle_in_radian));
+ 
+    while (theta1 < (double)0) theta1 += (double)360;
+    while (theta2 > theta1) theta2 -= (double)360;
+    while (theta2 < theta1) theta2 += (double)360;
+ 
+    switch (dir) {
+    case ARC_CCW:
+       angle2 = theta2-theta1;
+       if (angle2 == 0) angle2 = (double)360;
+       break;
+    case ARC_CW:
+       angle2 = theta2-theta1-((double)360);
+       break;
+    }
+    CreateArcObj(abs_cx, abs_cx, abs_cx+x1, abs_cy+y1, abs_cx+x2, abs_cy+y2, dir,
+          -radius, -radius, (radius<<1), (radius<<1), round(theta1*((double)64)),
+          round(angle2*((double)64)), TRUE);
+ 
+    RecordNewObjCmd();
+    RedrawAnArea(botObj, topObj->bbox.ltx-GRID_ABS_SIZE(1),
+          topObj->bbox.lty-GRID_ABS_SIZE(1),
+          topObj->bbox.rbx+GRID_ABS_SIZE(1),
+          topObj->bbox.rby+GRID_ABS_SIZE(1));
+ 
+    SetFileModified(TRUE);
+    return TRUE;
+ }
+ 
+ static IntPoint firstVertexInCreate, lastVertexInCreate;
+ 
+ int ExecCreateFirstVertex(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* create_first_vertex(abs_x,abs_y); */
+ {
+    char *abs_x_str=argv[0], *abs_y_str=argv[1];
+    int abs_x=0, abs_y=0;
+ 
+    UtilRemoveQuotes(abs_x_str);
+    UtilRemoveQuotes(abs_y_str);
+    if (!IntExpression(abs_x_str, &abs_x, orig_cmd) ||
+          !IntExpression(abs_y_str, &abs_y, orig_cmd)) {
+       return FALSE;
+    }
+    MakeQuiescent();
+ 
+    ResetCreatePoly();
+    AddPtToCreatePoly(abs_x, abs_y);
+    firstVertexInCreate.x = abs_x;
+    firstVertexInCreate.y = abs_y;
+ 
+    return TRUE;
+ }
+ 
+ int ExecCreateNextVertex(argv, obj_ptr, orig_cmd)
+    char **argv, *orig_cmd;
+    struct ObjRec *obj_ptr;
+    /* create_next_vertex(abs_x,abs_y); */
+ {
+    char *abs_x_str=argv[0], *abs_y_str=argv[1];
+    int abs_x=0, abs_y=0;
+ 
+    UtilRemoveQuotes(abs_x_str);
+    UtilRemoveQuotes(abs_y_str);
+    if (!IntExpression(abs_x_str, &abs_x, orig_cmd) ||
+          !IntExpression(abs_y_str, &abs_y, orig_cmd)) {
+       return FALSE;
+    }
+    if (numPtsInPoly == 0) {
+       sprintf(gszMsgBox, "%s '%s' %s.",
+             "No starting vertex specified while executing the", orig_cmd,
+             "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       return FALSE;
+    }
+    AddPtToCreatePoly(abs_x, abs_y);
+    lastVertexInCreate.x = abs_x;
+    lastVertexInCreate.y = abs_y;
+ 
+    return TRUE;
+ }
+ 
+ void ExecCreatePoly(obj_ptr, orig_cmd)
+    struct ObjRec *obj_ptr;
+    char *orig_cmd;
+    /* create_poly_obj(); */
+ {
+    if (numPtsInPoly <= 1) {
+       sprintf(gszMsgBox, "%s %1d %s '%s' %s.",
+             "Too few vertices (", numPtsInPoly,
+             "vertex specified) while executing the", orig_cmd, "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       ResetCreatePoly();
+       gnAbortExec = TRUE;
+       return;
+    }
+    MakeQuiescent();
+ 
+    CreatePolyObj(numPtsInPoly, TRUE);
+ 
+    RecordNewObjCmd();
+    RedrawAnArea(botObj, topObj->bbox.ltx-GRID_ABS_SIZE(1),
+          topObj->bbox.lty-GRID_ABS_SIZE(1),
+          topObj->bbox.rbx+GRID_ABS_SIZE(1),
+          topObj->bbox.rby+GRID_ABS_SIZE(1));
+ 
+    SetFileModified(TRUE);
+ }
+ 
+ void ExecCreatePolygon(obj_ptr, orig_cmd)
+    struct ObjRec *obj_ptr;
+    char *orig_cmd;
+    /* create_polygon_obj(); */
+ {
+    if (numPtsInPoly <= 2) {
+       sprintf(gszMsgBox, "%s %1d %s %s '%s' %s.",
+             "Too few vertices (", numPtsInPoly,
+             (numPtsInPoly==2 ? "vertices" : "vertex"),
+             "specified) while executing the", orig_cmd, "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       ResetCreatePoly();
+    } else {
+       MakeQuiescent();
+ 
+       if (firstVertexInCreate.x != lastVertexInCreate.x ||
+             firstVertexInCreate.y != lastVertexInCreate.y) {
+          AddPtToCreatePoly(firstVertexInCreate.x, firstVertexInCreate.y);
+          lastVertexInCreate.x = firstVertexInCreate.x;
+          lastVertexInCreate.y = firstVertexInCreate.y;
+       }
+       CreatePolygonObj(numPtsInPoly, TRUE);
+ 
+       RecordNewObjCmd();
+       RedrawAnArea(botObj, topObj->bbox.ltx-GRID_ABS_SIZE(1),
+             topObj->bbox.lty-GRID_ABS_SIZE(1),
+             topObj->bbox.rbx+GRID_ABS_SIZE(1),
+             topObj->bbox.rby+GRID_ABS_SIZE(1));
+ 
+       SetFileModified(TRUE);
+    }
+ }
+ 
+ static struct SelRec *topSelBeforeCreateGroup=NULL;
+ static int createGroupDepth=0;
+ 
+ static
+ void ResetCreateGroup()
+ {
+    struct SelRec *next_sel=NULL;
+ 
+    while (topSelBeforeCreateGroup != NULL) {
+       next_sel = topSelBeforeCreateGroup->next;
+       free(topSelBeforeCreateGroup);
+       topSelBeforeCreateGroup = next_sel;
+    }
+    createGroupDepth = 0;
+ }
+ 
+ void ExecStartCreateGroup(obj_ptr, orig_cmd)
+    struct ObjRec *obj_ptr;
+    char *orig_cmd;
+    /* start_create_group_obj(); */
+ {
+    struct SelRec *sel_ptr=NULL;
+ 
+    MakeQuiescent();
+    sel_ptr = SelectThisObject(topObj);
+    sel_ptr->next = topSelBeforeCreateGroup;
+    topSelBeforeCreateGroup = sel_ptr;
+    createGroupDepth++;
+ }
+ 
+ void ExecCreateGroup(obj_ptr, orig_cmd)
+    struct ObjRec *obj_ptr;
+    char *orig_cmd;
+    /* create_group_obj(); */
+ {
+    struct SelRec *next_sel=NULL;
+    struct ObjRec *optr=NULL, *start_obj=NULL;
+    int num_objs=0;
+ 
+    if (createGroupDepth <= 0 || topSelBeforeCreateGroup == NULL) {
+       sprintf(gszMsgBox, "%s %s '%s' %s.",
+             "No starting object specified by 'start_create_group_obj'",
+             "while executing the", orig_cmd, "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       ResetCreateGroup();
+       gnAbortExec = TRUE;
+       return;
+    }
+    MakeQuiescent();
+ 
+    if (topSelBeforeCreateGroup->obj != NULL) {
+       for (optr=topObj; optr != NULL; optr=optr->next) {
+          if (optr == topSelBeforeCreateGroup->obj) {
+             break;
+          }
+       }
+       if (optr == NULL) {
+          sprintf(gszMsgBox, "%s %s '%s' %s.",
+                "Cannot find the object marker for 'start_create_group_obj'",
+                "while executing the", orig_cmd, "command");
+          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+          ResetCreateGroup();
+          gnAbortExec = TRUE;
+          return;
+       }
+    }
+    if (topSelBeforeCreateGroup->obj == NULL) {
+       start_obj = botObj;
+    } else {
+       start_obj = topSelBeforeCreateGroup->obj->prev;
+    }
+    for (optr=start_obj, num_objs=0; optr != NULL; optr=optr->prev, num_objs++) {
+    }
+    if (num_objs == 0) {
+       sprintf(gszMsgBox, "%s '%s' %s.",
+             "No objects to group while executing the", orig_cmd, "command");
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       ResetCreateGroup();
+       gnAbortExec = TRUE;
+       return;
+    } else if (num_objs == 1) {
+       if (start_obj->type != OBJ_POLY && start_obj->type != OBJ_POLYGON) {
+          sprintf(gszMsgBox, "%s '%s' %s.",
+                "Cannot group a single object while executing the", orig_cmd,
+                "command");
+          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+          ResetCreateGroup();
+          gnAbortExec = TRUE;
+          return;
+       }
+    }
+    for (optr=start_obj; optr != NULL; optr=optr->prev) {
+       struct SelRec *sel_ptr=SelectThisObject(optr);
+ 
+       sel_ptr->next = topSel;
+       sel_ptr->prev = NULL;
+       if (topSel == NULL) {
+          botSel = sel_ptr;
+       } else {
+          topSel->prev = sel_ptr;
+       }
+       topSel = sel_ptr;
+    }
+    UpdSelBBox();
+    GroupSelObj();
+    RemoveAllSel();
+    justDupped = FALSE;
+ 
+    next_sel = topSelBeforeCreateGroup->next;
+    free(topSelBeforeCreateGroup);
+    topSelBeforeCreateGroup = next_sel;
+    createGroupDepth--;
+ }
+ 
  /* --------------------- End of Exec Routines --------------------- */
  
***************
*** 7125,7128 ****
--- 8022,8026 ----
     }
     if (i == argc) {
+       if (argc == 0) execDummyStr[index++] = '(';
        execDummyStr[index++] = ')';
        execDummyStr[index] = '\0';
***************
*** 7416,7419 ****
--- 8314,8319 ----
        bottomExportPixelTrim = sTrimBBox.rby;
     }
+    ResetCreatePoly();
+    ResetCreateGroup();
  }
  
***************
*** 7504,7507 ****
--- 8404,8410 ----
           break;
        }
+       if (fp == stdin) {
+          gnDisableShortcuts = FALSE;
+       }
        warpToAttr = NULL;
        exec_rc = ExecuteCommands(buf, NULL);
***************
*** 7516,7519 ****
--- 8419,8423 ----
        if (fp == stdin) {
           XSync(mainDisplay, False);
+          gnDisableShortcuts = TRUE;
        }
        UtilFree(buf);
***************
*** 7575,7587 ****
        fp = stdin;
     }
!    stnExecutingCmdsFromFile = TRUE;
  
     ResetExec(TRUE);
     DoExecCmdsFromFile(fp, &quit);
  
!    if (fp != stdin) {
!       fclose(fp);
!    } else {
        printf("Finished executing commands from the standard input.\n");
     }
     stnExecutingCmdsFromFile = FALSE;
--- 8479,8498 ----
        fp = stdin;
     }
!    MakeQuiescent();
  
+    stnExecutingCmdsFromFile = TRUE;
+    if (fp == stdin) {
+       gnDisableShortcuts = TRUE;
+       RedrawDummyWindow2();
+    }
     ResetExec(TRUE);
     DoExecCmdsFromFile(fp, &quit);
  
!    if (fp == stdin) {
        printf("Finished executing commands from the standard input.\n");
+       gnDisableShortcuts = FALSE;
+       RedrawDummyWindow2();
+    } else {
+       fclose(fp);
     }
     stnExecutingCmdsFromFile = FALSE;
***************
*** 7598,7601 ****
--- 8509,8559 ----
  }
  
+ int BeginExecCommandsFromBuffer()
+ {
+    ResetExec(TRUE);
+ 
+    executingCommands = TRUE;
+    justDupped = FALSE;
+    execCurDepth++;
+ 
+    return TRUE;
+ }
+ 
+ int ExecACommandFromBuffer(buf, pn_quit)
+    char *buf;
+    int *pn_quit;
+ {
+    int exec_rc=INVALID;
+ 
+    warpToAttr = NULL;
+    exec_rc = ExecuteCommands(buf, NULL);
+    if (exec_rc == TRUE && warpToAttr != NULL) {
+       struct AttrRec *exec_attr=NULL;
+ 
+       DoTeleport(warpToAttr);
+       if ((exec_attr=FindFileAttrWithName("auto_exec=")) != NULL) {
+          DoExecLoop(NULL, exec_attr);
+       }
+    }
+    if (gnQuit) {
+       if (pn_quit != NULL) *pn_quit = TRUE;
+ 
+       execCurDepth--;
+       justDupped = FALSE;
+ 
+       SendCommandToSelf(CMDID_QUIT, 0);
+ 
+       return FALSE;
+    }
+    return TRUE;
+ }
+ 
+ void EndExecCommandsFromBuffer()
+ {
+    execCurDepth--;
+    justDupped = FALSE;
+    ShowCurChoiceMouseStatus(curChoice);
+ }
+ 
  void CleanUpExec()
  {
*** file.c.orig	Sun Apr 11 10:46:54 1999
--- file.c	Sun Apr 11 10:46:54 1999
***************
*** 602,610 ****
  }
  
! int FileNameHasExtension(file_name, file_type, pn_no_name)
     char *file_name;
!    int file_type, *pn_no_name;
  {
!    static char stszObjFileExt[20];
     static char stszSymFileExt[20];
     static char stszPinFileExt[20];
--- 602,610 ----
  }
  
! int FileNameHasExtension(file_name, file_type, pn_gzipped, pn_no_name)
     char *file_name;
!    int file_type, *pn_gzipped, *pn_no_name;
  {
!    static char stszObjFileExt[20], stszGzObjFileExt[20];
     static char stszSymFileExt[20];
     static char stszPinFileExt[20];
***************
*** 614,617 ****
--- 614,618 ----
     if (!initialized) {
        sprintf(stszObjFileExt, ".%s", OBJ_FILE_EXT);
+       sprintf(stszGzObjFileExt, ".%s.gz", OBJ_FILE_EXT);
        sprintf(stszSymFileExt, ".%s", SYM_FILE_EXT);
        sprintf(stszPinFileExt, ".%s", PIN_FILE_EXT);
***************
*** 618,621 ****
--- 619,623 ----
        initialized = TRUE;
     }
+    if (pn_gzipped != NULL) *pn_gzipped = FALSE;
     switch (file_type) {
     case OBJ_FILE_TYPE:
***************
*** 624,627 ****
--- 626,634 ----
           if (pn_no_name != NULL) *pn_no_name = (psz == file_name);
           return TRUE;
+       } else if ((psz=strstr(file_name, ".obj.gz")) != NULL &&
+             strcmp(psz, ".obj.gz") == 0) {
+          if (pn_no_name != NULL) *pn_no_name = (psz == file_name);
+          if (pn_gzipped != NULL) *pn_gzipped = TRUE;
+          return TRUE;
        } else if ((psz=strstr(file_name, ".tgo")) != NULL &&
              strcmp(psz, ".tgo") == 0) {
***************
*** 628,631 ****
--- 635,643 ----
           if (pn_no_name != NULL) *pn_no_name = (psz == file_name);
           return TRUE;
+       } else if ((psz=strstr(file_name, ".tgo.gz")) != NULL &&
+             strcmp(psz, ".tgo.gz") == 0) {
+          if (pn_no_name != NULL) *pn_no_name = (psz == file_name);
+          if (pn_gzipped != NULL) *pn_gzipped = TRUE;
+          return TRUE;
        } else if ((psz=strstr(file_name, stszObjFileExt)) != NULL &&
              strcmp(psz, stszObjFileExt) == 0) {
***************
*** 632,635 ****
--- 644,652 ----
           if (pn_no_name != NULL) *pn_no_name = (psz == file_name);
           return TRUE;
+       } else if ((psz=strstr(file_name, stszGzObjFileExt)) != NULL &&
+             strcmp(psz, stszGzObjFileExt) == 0) {
+          if (pn_no_name != NULL) *pn_no_name = (psz == file_name);
+          if (pn_gzipped != NULL) *pn_gzipped = TRUE;
+          return TRUE;
        }
        break;
***************
*** 673,677 ****
     char *file_name;
  {
!    static char stszObjFileExt[20];
     static char stszSymFileExt[20];
     static char stszPinFileExt[20];
--- 690,694 ----
     char *file_name;
  {
!    static char stszObjFileExt[20], stszGzObjFileExt[20];
     static char stszSymFileExt[20];
     static char stszPinFileExt[20];
***************
*** 682,685 ****
--- 699,703 ----
     if (!initialized) {
        sprintf(stszObjFileExt, ".%s", OBJ_FILE_EXT);
+       sprintf(stszGzObjFileExt, ".%s.gz", OBJ_FILE_EXT);
        sprintf(stszSymFileExt, ".%s", SYM_FILE_EXT);
        sprintf(stszPinFileExt, ".%s", PIN_FILE_EXT);
***************
*** 689,698 ****
--- 707,725 ----
           strcmp(psz, ".obj") == 0) {
        file_name[len-strlen(".obj")] = '\0';
+    } else if ((psz=strstr(file_name, ".obj.gz")) != NULL &&
+          strcmp(psz, ".obj.gz") == 0) {
+       file_name[len-strlen(".obj.gz")] = '\0';
     } else if ((psz=strstr(file_name, ".tgo")) != NULL &&
           strcmp(psz, ".tgo") == 0) {
        file_name[len-strlen(".tgo")] = '\0';
+    } else if ((psz=strstr(file_name, ".tgo.gz")) != NULL &&
+          strcmp(psz, ".tgo.gz") == 0) {
+       file_name[len-strlen(".tgo.gz")] = '\0';
     } else if ((psz=strstr(file_name, stszObjFileExt)) != NULL &&
           strcmp(psz, stszObjFileExt) == 0) {
        file_name[len-strlen(stszObjFileExt)] = '\0';
+    } else if ((psz=strstr(file_name, stszGzObjFileExt)) != NULL &&
+          strcmp(psz, stszGzObjFileExt) == 0) {
+       file_name[len-strlen(stszGzObjFileExt)] = '\0';
     } else if ((psz=strstr(file_name, ".sym")) != NULL &&
           strcmp(psz, ".sym") == 0) {
***************
*** 882,887 ****
     /* return TRUE if file successfully saved */
  {
!    char new_file_name[MAXPATHLENGTH+1], s[MAXPATHLENGTH+1];
!    char *rest=NULL;
     FILE *fp=NULL;
     int count=0, file_type=INVALID, short_name, watch_cursor=FALSE;
--- 909,913 ----
     /* return TRUE if file successfully saved */
  {
!    char new_file_name[MAXPATHLENGTH+1], *rest=NULL;
     FILE *fp=NULL;
     int count=0, file_type=INVALID, short_name, watch_cursor=FALSE;
***************
*** 948,956 ****
     if ((fp=fopen(new_file_name, "w")) == NULL) {
        if (short_name) {
!          sprintf(s, "Cannot open '%s', file not saved.", rest);
        } else {
!          sprintf(s, "Cannot open '%s', file not saved.", new_file_name);
        }
!       MsgBox(s, TOOL_NAME, INFO_MB);
        return INVALID;
     }
--- 974,982 ----
     if ((fp=fopen(new_file_name, "w")) == NULL) {
        if (short_name) {
!          sprintf(gszMsgBox, "Cannot open '%s', file not saved.", rest);
        } else {
!          sprintf(gszMsgBox, "Cannot open '%s', file not saved.", new_file_name);
        }
!       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
        return INVALID;
     }
***************
*** 957,965 ****
  
     if (short_name) {
!       sprintf(s, "Saving temporary file '%s' ...", rest);
     } else {
!       sprintf(s, "Saving temporary file '%s' ...", new_file_name);
     }
!    Msg(s);
  
     watch_cursor = watchCursorOnMainWindow;
--- 983,991 ----
  
     if (short_name) {
!       sprintf(gszMsgBox, "Saving temporary file '%s' ...", rest);
     } else {
!       sprintf(gszMsgBox, "Saving temporary file '%s' ...", new_file_name);
     }
!    Msg(gszMsgBox);
  
     watch_cursor = watchCursorOnMainWindow;
***************
*** 987,1000 ****
     if (writeFileFailed) {
        writeFileFailed = FALSE;
!       sprintf(s, "Fail to write to '%s'.\n\nFile system may be full.",
              new_file_name);
!       MsgBox(s, TOOL_NAME, INFO_MB);
     } else {
        if (short_name) {
!          sprintf(s, "Temporary file '%s' saved.", rest);
        } else {
!          sprintf(s, "Temporary file '%s' saved.", new_file_name);
        }
!       Msg(s);
     }
  
--- 1013,1026 ----
     if (writeFileFailed) {
        writeFileFailed = FALSE;
!       sprintf(gszMsgBox, "Fail to write to '%s'.\n\nFile system may be full.",
              new_file_name);
!       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
     } else {
        if (short_name) {
!          sprintf(gszMsgBox, "Temporary file '%s' saved.", rest);
        } else {
!          sprintf(gszMsgBox, "Temporary file '%s' saved.", new_file_name);
        }
!       Msg(gszMsgBox);
     }
  
***************
*** 1001,1009 ****
     if (tmpFileMode != 0 && chmod(new_file_name, tmpFileMode)) {
        if (short_name) {
!          sprintf(s, "Cannot chmod '%s' to 0%03o.", rest, tmpFileMode);
        } else {
!          sprintf(s, "Cannot chmod '%s' to 0%03o.", new_file_name, tmpFileMode);
        }
!       MsgBox(s, TOOL_NAME, INFO_MB);
     }
     return file_type;
--- 1027,1036 ----
     if (tmpFileMode != 0 && chmod(new_file_name, tmpFileMode)) {
        if (short_name) {
!          sprintf(gszMsgBox, "Cannot chmod '%s' to 0%03o.", rest, tmpFileMode);
        } else {
!          sprintf(gszMsgBox, "Cannot chmod '%s' to 0%03o.", new_file_name,
!                tmpFileMode);
        }
!       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
     }
     return file_type;
***************
*** 1014,1032 ****
     char *pszNewFile;
  {
!    char new_file_name[MAXPATHLENGTH+1], s[MAXPATHLENGTH+1];
     char new_full_name[MAXPATHLENGTH+1], tmp_str[MAXPATHLENGTH+1], *rest=NULL;
     char saved_cur_dir[MAXPATHLENGTH+1], saved_cur_file_name[MAXPATHLENGTH+1];
!    char obj_ext_str[MAXSTRING+1], sym_ext_str[MAXSTRING+1];
!    char pin_ext_str[MAXSTRING+1];
!    int saved_cur_file_defined=FALSE, no_name=FALSE;
!    FILE *fp=NULL;
!    int count=0, len, short_name, ok=TRUE, watch_cursor=FALSE;
!    struct ObjRec *obj_ptr, *saved_top_obj=NULL, *saved_bot_obj=NULL;
!    struct SelRec *top_sel_ptr=NULL, *bot_sel_ptr=NULL;
!    struct SelRec *sel_ptr, *next_sel;
!    struct PageRec *saved_cur_page;
     struct ObjRec *obj_ptr1=NULL, *obj_ptr2=NULL;
!    struct AttrRec *attr_ptr;
  
     if (SaveSelectedOnly && pszNewFile == NULL && topSel == NULL) {
        MsgBox("No objects selected!\n\nNothing saved!", TOOL_NAME, INFO_MB);
--- 1041,1062 ----
     char *pszNewFile;
  {
!    char new_file_name[MAXPATHLENGTH+1], gzipped_fname[MAXPATHLENGTH+1];
     char new_full_name[MAXPATHLENGTH+1], tmp_str[MAXPATHLENGTH+1], *rest=NULL;
     char saved_cur_dir[MAXPATHLENGTH+1], saved_cur_file_name[MAXPATHLENGTH+1];
!    char obj_ext_str[MAXSTRING+1], gz_obj_ext_str[MAXSTRING+1];
!    char sym_ext_str[MAXSTRING+1], pin_ext_str[MAXSTRING+1];
!    int saved_cur_file_defined=FALSE, no_name=FALSE, gzipped=FALSE, file_type=0;
!    int count=0, len, short_name=FALSE, ok=TRUE, watch_cursor=FALSE;
!    struct ObjRec *obj_ptr=NULL, *saved_top_obj=NULL, *saved_bot_obj=NULL;
     struct ObjRec *obj_ptr1=NULL, *obj_ptr2=NULL;
!    struct SelRec *top_sel_ptr=NULL, *bot_sel_ptr=NULL;
!    struct SelRec *sel_ptr=NULL, *next_sel=NULL;
!    struct PageRec *saved_cur_page=NULL;
!    struct AttrRec *attr_ptr=NULL;
!    FILE *fp=NULL;
  
+    file_type = OBJ_FILE_TYPE;
+    *gzipped_fname = '\0';
+ 
     if (SaveSelectedOnly && pszNewFile == NULL && topSel == NULL) {
        MsgBox("No objects selected!\n\nNothing saved!", TOOL_NAME, INFO_MB);
***************
*** 1037,1046 ****
     } else {
        if (curDirIsLocal) {
!          sprintf(s, "( working directory: %s )", curDir);
        } else {
!          sprintf(s, "( working directory: %s )", curLocalDir);
        }
        Dialog("Please enter new file name: ( <CR>: accept, <ESC>: cancel )",
!             s, new_file_name);
     }
     UtilTrimBlanks(new_file_name);
--- 1067,1076 ----
     } else {
        if (curDirIsLocal) {
!          sprintf(gszMsgBox, "( working directory: %s )", curDir);
        } else {
!          sprintf(gszMsgBox, "( working directory: %s )", curLocalDir);
        }
        Dialog("Please enter new file name: ( <CR>: accept, <ESC>: cancel )",
!             gszMsgBox, new_file_name);
     }
     UtilTrimBlanks(new_file_name);
***************
*** 1076,1079 ****
--- 1106,1110 ----
     }
     sprintf(obj_ext_str, ".%s", OBJ_FILE_EXT);
+    sprintf(gz_obj_ext_str, ".%s.gz", OBJ_FILE_EXT);
     sprintf(sym_ext_str, ".%s", SYM_FILE_EXT);
     sprintf(pin_ext_str, ".%s", PIN_FILE_EXT);
***************
*** 1091,1101 ****
     switch (count) {
     case 0:
!       if (FileNameHasExtension(new_file_name, OBJ_FILE_TYPE, &no_name)) {
           /* don't modify */
!       } else if (FileNameHasExtension(new_file_name, SYM_FILE_TYPE, &no_name)) {
           MsgBox("Cannot save as a symbol file.\n\nNo symbol defined.",
                 TOOL_NAME, INFO_MB);
           return;
!       } else if (FileNameHasExtension(new_file_name, PIN_FILE_TYPE, &no_name)) {
           MsgBox("Cannot save as a pin file.\n\nNo symbol defined.",
                 TOOL_NAME, INFO_MB);
--- 1122,1135 ----
     switch (count) {
     case 0:
!       if (FileNameHasExtension(new_file_name, OBJ_FILE_TYPE, &gzipped,
!             &no_name)) {
           /* don't modify */
!       } else if (FileNameHasExtension(new_file_name, SYM_FILE_TYPE, NULL,
!             &no_name)) {
           MsgBox("Cannot save as a symbol file.\n\nNo symbol defined.",
                 TOOL_NAME, INFO_MB);
           return;
!       } else if (FileNameHasExtension(new_file_name, PIN_FILE_TYPE, NULL,
!             &no_name)) {
           MsgBox("Cannot save as a pin file.\n\nNo symbol defined.",
                 TOOL_NAME, INFO_MB);
***************
*** 1104,1107 ****
--- 1138,1142 ----
           strcat(new_file_name, obj_ext_str);
        }
+       file_type = OBJ_FILE_TYPE;
        break;
     case 1:
***************
*** 1108,1116 ****
        if ((attr_ptr=FindAttrWithName(obj_ptr1, "type=", NULL)) != NULL &&
              strcmp(attr_ptr->attr_value.s, "tgif_pin") == 0) {
!          if (FileNameHasExtension(new_file_name, OBJ_FILE_TYPE, &no_name)) {
              MsgBox("Cannot save as an object file; one symbol defined.",
                    TOOL_NAME, INFO_MB);
              return;
!          } else if (FileNameHasExtension(new_file_name, SYM_FILE_TYPE,
                 &no_name)) {
              sprintf(gszMsgBox, "%s.\n\n%s.",
--- 1143,1152 ----
        if ((attr_ptr=FindAttrWithName(obj_ptr1, "type=", NULL)) != NULL &&
              strcmp(attr_ptr->attr_value.s, "tgif_pin") == 0) {
!          if (FileNameHasExtension(new_file_name, OBJ_FILE_TYPE, NULL,
!                &no_name)) {
              MsgBox("Cannot save as an object file; one symbol defined.",
                    TOOL_NAME, INFO_MB);
              return;
!          } else if (FileNameHasExtension(new_file_name, SYM_FILE_TYPE, NULL,
                 &no_name)) {
              sprintf(gszMsgBox, "%s.\n\n%s.",
***************
*** 1119,1123 ****
              MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
              return;
!          } else if (FileNameHasExtension(new_file_name, PIN_FILE_TYPE,
                 &no_name)) {
              /* don't modify */
--- 1155,1159 ----
              MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
              return;
!          } else if (FileNameHasExtension(new_file_name, PIN_FILE_TYPE, NULL,
                 &no_name)) {
              /* don't modify */
***************
*** 1125,1137 ****
              strcat(new_file_name, pin_ext_str);
           }
        } else {
!          if (FileNameHasExtension(new_file_name, OBJ_FILE_TYPE, &no_name)) {
              MsgBox("Cannot save as an object file; one symbol defined.",
                    TOOL_NAME, INFO_MB);
              return;
!          } else if (FileNameHasExtension(new_file_name, SYM_FILE_TYPE,
                 &no_name)) {
              /* don't modify */
!          } else if (FileNameHasExtension(new_file_name, PIN_FILE_TYPE,
                 &no_name)) {
              MsgBox("Cannot save as a pin file; only one symbol is defined.",
--- 1161,1175 ----
              strcat(new_file_name, pin_ext_str);
           }
+          file_type = PIN_FILE_TYPE;
        } else {
!          if (FileNameHasExtension(new_file_name, OBJ_FILE_TYPE, NULL,
!                &no_name)) {
              MsgBox("Cannot save as an object file; one symbol defined.",
                    TOOL_NAME, INFO_MB);
              return;
!          } else if (FileNameHasExtension(new_file_name, SYM_FILE_TYPE, NULL,
                 &no_name)) {
              /* don't modify */
!          } else if (FileNameHasExtension(new_file_name, PIN_FILE_TYPE, NULL,
                 &no_name)) {
              MsgBox("Cannot save as a pin file; only one symbol is defined.",
***************
*** 1141,1156 ****
              strcat(new_file_name, sym_ext_str);
           }
        }
        break;
     case 2:
!       if (FileNameHasExtension(new_file_name, OBJ_FILE_TYPE, &no_name)) {
           MsgBox("Cannot save as an object file; two symbols defined.",
                 TOOL_NAME, INFO_MB);
           return;
!       } else if (FileNameHasExtension(new_file_name, SYM_FILE_TYPE, &no_name)) {
           MsgBox("Cannot save as a symbol file; two symbols defined.",
                 TOOL_NAME, INFO_MB);
           return;
!       } else if (FileNameHasExtension(new_file_name, PIN_FILE_TYPE, &no_name)) {
           /* don't modify */
        } else {
--- 1179,1197 ----
              strcat(new_file_name, sym_ext_str);
           }
+          file_type = SYM_FILE_TYPE;
        }
        break;
     case 2:
!       if (FileNameHasExtension(new_file_name, OBJ_FILE_TYPE, NULL, &no_name)) {
           MsgBox("Cannot save as an object file; two symbols defined.",
                 TOOL_NAME, INFO_MB);
           return;
!       } else if (FileNameHasExtension(new_file_name, SYM_FILE_TYPE, NULL,
!             &no_name)) {
           MsgBox("Cannot save as a symbol file; two symbols defined.",
                 TOOL_NAME, INFO_MB);
           return;
!       } else if (FileNameHasExtension(new_file_name, PIN_FILE_TYPE, NULL,
!             &no_name)) {
           /* don't modify */
        } else {
***************
*** 1172,1175 ****
--- 1213,1217 ----
           return;
        }
+       file_type = PIN_FILE_TYPE;
        break;
     default: return;
***************
*** 1187,1200 ****
        sprintf(new_full_name, "%s%c%s", curLocalDir, DIR_SEP, new_file_name);
     }
!    if (!OkayToCreateFile(new_full_name)) return;
  
!    if ((short_name=IsPrefix(bootDir, new_full_name, &rest))) ++rest;
     if ((fp=fopen(new_full_name, "w")) == NULL) {
        if (short_name) {
!          sprintf(s, "Cannot open '%s', file not saved.", rest);
        } else {
!          sprintf(s, "Cannot open '%s', file not saved.", new_full_name);
        }
!       MsgBox(s, TOOL_NAME, INFO_MB);
        return;
     }
--- 1229,1265 ----
        sprintf(new_full_name, "%s%c%s", curLocalDir, DIR_SEP, new_file_name);
     }
!    if (file_type == OBJ_FILE_TYPE && gzipped) {
!       char tmp_fname[MAXPATHLENGTH];
  
!       sprintf(tmp_fname, "%sTgifXXXXXX", TMP_DIR);
!       mktemp(tmp_fname);
!       unlink(tmp_fname);
!       strcpy(gzipped_fname, new_full_name);
!       strcpy(new_full_name, tmp_fname);
!    }
!    if (!OkayToCreateFile((*gzipped_fname=='\0') ? new_full_name :
!          gzipped_fname)) {
!       if (*gzipped_fname != '\0') unlink(new_full_name);
!       return;
!    }
!    if (*gzipped_fname == '\0') {
!       if ((short_name=IsPrefix(bootDir, new_full_name, &rest))) ++rest;
!    } else {
!       if ((short_name=IsPrefix(bootDir, gzipped_fname, &rest))) ++rest;
!    }
     if ((fp=fopen(new_full_name, "w")) == NULL) {
        if (short_name) {
!          sprintf(gszMsgBox, "Cannot open '%s', file not saved.", rest);
        } else {
!          if (*gzipped_fname == '\0') {
!             sprintf(gszMsgBox, "Cannot open '%s', file not saved.",
!                   new_full_name);
!          } else {
!             sprintf(gszMsgBox, "Cannot open '%s', file not saved.",
!                   gzipped_fname);
!          }
        }
!       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
!       if (*gzipped_fname != '\0') unlink(new_full_name);
        return;
     }
***************
*** 1250,1254 ****
        strcpy(tmp_str, curLocalDir);
     }
!    SetCurDir(new_full_name);
     curFileDefined = TRUE;
  
--- 1315,1323 ----
        strcpy(tmp_str, curLocalDir);
     }
!    if (*gzipped_fname == '\0') {
!       SetCurDir(new_full_name);
!    } else {
!       SetCurDir(gzipped_fname);
!    }
     curFileDefined = TRUE;
  
***************
*** 1269,1277 ****
     }
     if (short_name) {
!       sprintf(s, "Saving '%s' ...", rest);
     } else {
!       sprintf(s, "Saving '%s' ...", new_full_name);
     }
!    Msg(s);
  
     if (!saveCommentsInSaveNew) CleanUpComments();
--- 1338,1350 ----
     }
     if (short_name) {
!       sprintf(gszMsgBox, "Saving '%s' ...", rest);
     } else {
!       if (*gzipped_fname == '\0') {
!          sprintf(gszMsgBox, "Saving '%s' ...", new_full_name);
!       } else {
!          sprintf(gszMsgBox, "Saving '%s' ...", gzipped_fname);
!       }
     }
!    Msg(gszMsgBox);
  
     if (!saveCommentsInSaveNew) CleanUpComments();
***************
*** 1299,1315 ****
     if (writeFileFailed) {
        writeFileFailed = FALSE;
!       sprintf(s, "Fail to write to '%s'.\n\nFile system may be full.",
!             new_full_name);
!       MsgBox(s, TOOL_NAME, INFO_MB);
        ok = FALSE;
     } else {
!       if (short_name) {
!          sprintf(s, "File '%s' saved.", rest);
        } else {
!          sprintf(s, "File '%s' saved.", new_full_name);
        }
-       Msg(s);
     }
- 
     if (SaveSelectedOnly) {
        CleanUpPage();
--- 1372,1406 ----
     if (writeFileFailed) {
        writeFileFailed = FALSE;
!       FailToWriteFileMessage(new_full_name);
        ok = FALSE;
     } else {
!       if (*gzipped_fname != '\0') {
!          if (!GzipFile(new_full_name, gzipped_fname)) {
!             sprintf(gszMsgBox, "%s '%s' to '%s'.\n\n%s '%s'.  %s.",
!                   "Problems encountered while (g)zipping", new_full_name,
!                   gzipped_fname, "The unzipped file is", new_full_name,
!                   "Please save a copy of it before proceeding");
!             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
!             ok = FALSE;
!          }
!          unlink(new_full_name);
!          strcpy(new_full_name, gzipped_fname);
!       }
!       if (ok) {
!          if (short_name) {
!             sprintf(gszMsgBox, "File '%s' saved.", rest);
!          } else {
!             sprintf(gszMsgBox, "File '%s' saved.", new_full_name);
!          }
!          Msg(gszMsgBox);
        } else {
!          if (short_name) {
!             sprintf(gszMsgBox, "File '%s' is NOT saved.", rest);
!          } else {
!             sprintf(gszMsgBox, "File '%s' is NOT saved.", new_full_name);
!          }
!          Msg(gszMsgBox);
        }
     }
     if (SaveSelectedOnly) {
        CleanUpPage();
***************
*** 1338,1342 ****
  void SaveSymInLibrary()
  {
!    char new_file_name[MAXPATHLENGTH+1], s[MAXPATHLENGTH+1];
     char new_full_name[MAXPATHLENGTH+1], dir_name[MAXPATHLENGTH+1];
     char saved_dir[MAXPATHLENGTH+1], saved_file[MAXPATHLENGTH+1];
--- 1429,1433 ----
  void SaveSymInLibrary()
  {
!    char new_file_name[MAXPATHLENGTH+1];
     char new_full_name[MAXPATHLENGTH+1], dir_name[MAXPATHLENGTH+1];
     char saved_dir[MAXPATHLENGTH+1], saved_file[MAXPATHLENGTH+1];
***************
*** 1425,1431 ****
        if (*new_file_name == '\0') return;
  
!       if (FileNameHasExtension(new_file_name, SYM_FILE_TYPE, &no_name)) {
           /* do nothing */
!       } else if (FileNameHasExtension(new_file_name, PIN_FILE_TYPE, &no_name)) {
           /* do nothing */
        } else if (count == 1) {
--- 1516,1523 ----
        if (*new_file_name == '\0') return;
  
!       if (FileNameHasExtension(new_file_name, SYM_FILE_TYPE, NULL, &no_name)) {
           /* do nothing */
!       } else if (FileNameHasExtension(new_file_name, PIN_FILE_TYPE, NULL,
!             &no_name)) {
           /* do nothing */
        } else if (count == 1) {
***************
*** 1463,1471 ****
     if ((fp=fopen(new_full_name, "w")) == NULL) {
        if (short_name) {
!          sprintf(s, "Cannot open '%s', file not saved.", rest);
        } else {
!          sprintf(s, "Cannot open '%s', file not saved.", new_full_name);
        }
!       MsgBox(s, TOOL_NAME, INFO_MB);
        return;
     }
--- 1555,1563 ----
     if ((fp=fopen(new_full_name, "w")) == NULL) {
        if (short_name) {
!          sprintf(gszMsgBox, "Cannot open '%s', file not saved.", rest);
        } else {
!          sprintf(gszMsgBox, "Cannot open '%s', file not saved.", new_full_name);
        }
!       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
        return;
     }
***************
*** 1482,1490 ****
  
     if (short_name) {
!       sprintf(s, "Saving '%s' ...", rest);
     } else {
!       sprintf(s, "Saving '%s' ...", new_full_name);
     }
!    Msg(s);
  
     if (!saveCommentsInSaveNew) CleanUpComments();
--- 1574,1582 ----
  
     if (short_name) {
!       sprintf(gszMsgBox, "Saving '%s' ...", rest);
     } else {
!       sprintf(gszMsgBox, "Saving '%s' ...", new_full_name);
     }
!    Msg(gszMsgBox);
  
     if (!saveCommentsInSaveNew) CleanUpComments();
***************
*** 1512,1525 ****
     if (writeFileFailed) {
        writeFileFailed = FALSE;
!       sprintf(s, "Fail to write to '%s'.\n\nFile system may be full.",
              new_full_name);
!       MsgBox(s, TOOL_NAME, INFO_MB);
     } else {
        if (short_name) {
!          sprintf(s, "File '%s' saved.", rest);
        } else {
!          sprintf(s, "File '%s' saved.", new_full_name);
        }
!       Msg(s);
     }
  
--- 1604,1617 ----
     if (writeFileFailed) {
        writeFileFailed = FALSE;
!       sprintf(gszMsgBox, "Fail to write to '%s'.\n\nFile system may be full.",
              new_full_name);
!       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
     } else {
        if (short_name) {
!          sprintf(gszMsgBox, "File '%s' saved.", rest);
        } else {
!          sprintf(gszMsgBox, "File '%s' saved.", new_full_name);
        }
!       Msg(gszMsgBox);
     }
  
***************
*** 1541,1551 ****
     struct ObjRec *obj_ptr=NULL;
     FILE *fp=NULL;
!    char ext[MAXPATHLENGTH+1], s[MAXPATHLENGTH+1];
!    char full_name[MAXPATHLENGTH+1], *rest=NULL, *psz;
     struct PageRec *saved_cur_page=NULL;
     struct ObjRec *obj_ptr1=NULL, *obj_ptr2=NULL;
     struct AttrRec *attr_ptr=NULL;
!    int watch_cursor=FALSE;
  
     if (!curFileDefined || !curDirIsLocal) {
        SaveNewFile(FALSE, NULL);
--- 1633,1644 ----
     struct ObjRec *obj_ptr=NULL;
     FILE *fp=NULL;
!    char ext[MAXPATHLENGTH+1], gzipped_fname[MAXPATHLENGTH+1];
!    char full_name[MAXPATHLENGTH+1], *rest=NULL, *psz=NULL;
     struct PageRec *saved_cur_page=NULL;
     struct ObjRec *obj_ptr1=NULL, *obj_ptr2=NULL;
     struct AttrRec *attr_ptr=NULL;
!    int watch_cursor=FALSE, gzipped=FALSE;
  
+    *gzipped_fname = '\0';
     if (!curFileDefined || !curDirIsLocal) {
        SaveNewFile(FALSE, NULL);
***************
*** 1556,1561 ****
        return;
     }
!    UtilStrCpyN(ext, sizeof(ext), psz);
  
     saved_cur_page = curPage;
     for (curPage=firstPage; curPage != NULL; curPage=curPage->next) {
--- 1649,1667 ----
        return;
     }
!    if (strcmp(psz, ".gz") == 0) {
!       char *dot_ptr=psz;
  
+       gzipped = TRUE;
+       *dot_ptr = '\0';
+       if ((psz=UtilStrRChr(curFileName, '.')) == NULL) {
+          TgAssert(FALSE, "Cannot find '.' in curFileName in SaveFile()", NULL);
+          *dot_ptr = '.';
+          return;
+       }
+       UtilStrCpyN(ext, sizeof(ext), psz);
+       *dot_ptr = '.';
+    } else {
+       UtilStrCpyN(ext, sizeof(ext), psz);
+    }
     saved_cur_page = curPage;
     for (curPage=firstPage; curPage != NULL; curPage=curPage->next) {
***************
*** 1575,1579 ****
     switch (count) {
     case 0:
!       if (FileNameHasExtension(ext, SYM_FILE_TYPE, &no_name)) {
           sprintf(gszMsgBox, "%s.\n\n%s.",
                 "No symbol defined in a symbol file", "Symbol file not saved");
--- 1681,1685 ----
     switch (count) {
     case 0:
!       if (FileNameHasExtension(ext, SYM_FILE_TYPE, NULL, &no_name)) {
           sprintf(gszMsgBox, "%s.\n\n%s.",
                 "No symbol defined in a symbol file", "Symbol file not saved");
***************
*** 1580,1584 ****
           MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
           return;
!       } else if (FileNameHasExtension(ext, PIN_FILE_TYPE, &no_name)) {
           sprintf(gszMsgBox, "%s.\n\n%s.",
                 "No symbol defined in a pin file", "Pin file not saved");
--- 1686,1690 ----
           MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
           return;
!       } else if (FileNameHasExtension(ext, PIN_FILE_TYPE, NULL, &no_name)) {
           sprintf(gszMsgBox, "%s.\n\n%s.",
                 "No symbol defined in a pin file", "Pin file not saved");
***************
*** 1589,1593 ****
        break;
     case 1:
!       if (FileNameHasExtension(ext, OBJ_FILE_TYPE, &no_name)) {
           sprintf(gszMsgBox, "%s.\n\n%s.",
                 "One symbol defined in OBJECT file", "Object file not saved");
--- 1695,1699 ----
        break;
     case 1:
!       if (FileNameHasExtension(ext, OBJ_FILE_TYPE, NULL, &no_name)) {
           sprintf(gszMsgBox, "%s.\n\n%s.",
                 "One symbol defined in OBJECT file", "Object file not saved");
***************
*** 1597,1601 ****
        if ((attr_ptr=FindAttrWithName(obj_ptr1, "type=", NULL)) != NULL &&
              strcmp(attr_ptr->attr_value.s, "tgif_pin") == 0) {
!          if (FileNameHasExtension(ext, SYM_FILE_TYPE, &no_name)) {
              sprintf(gszMsgBox, "%s.\n\n%s.",
                    "The symbol is of type tgif_pin",
--- 1703,1707 ----
        if ((attr_ptr=FindAttrWithName(obj_ptr1, "type=", NULL)) != NULL &&
              strcmp(attr_ptr->attr_value.s, "tgif_pin") == 0) {
!          if (FileNameHasExtension(ext, SYM_FILE_TYPE, NULL, &no_name)) {
              sprintf(gszMsgBox, "%s.\n\n%s.",
                    "The symbol is of type tgif_pin",
***************
*** 1606,1610 ****
           file_type = PIN_FILE_TYPE;
        } else {
!          if (FileNameHasExtension(ext, PIN_FILE_TYPE, &no_name)) {
              sprintf(gszMsgBox, "%s.\n\n%s.",
                    "Only one symbol defined in a pin file",
--- 1712,1716 ----
           file_type = PIN_FILE_TYPE;
        } else {
!          if (FileNameHasExtension(ext, PIN_FILE_TYPE, NULL, &no_name)) {
              sprintf(gszMsgBox, "%s.\n\n%s.",
                    "Only one symbol defined in a pin file",
***************
*** 1617,1621 ****
        break;
     case 2:
!       if (FileNameHasExtension(ext, OBJ_FILE_TYPE, &no_name)) {
           sprintf(gszMsgBox, "%s.\n\n%s.",
                 "One symbol defined in OBJECT file", "Object file not saved");
--- 1723,1727 ----
        break;
     case 2:
!       if (FileNameHasExtension(ext, OBJ_FILE_TYPE, NULL, &no_name)) {
           sprintf(gszMsgBox, "%s.\n\n%s.",
                 "One symbol defined in OBJECT file", "Object file not saved");
***************
*** 1622,1626 ****
           MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
           return;
!       } else if (FileNameHasExtension(ext, SYM_FILE_TYPE, &no_name)) {
           sprintf(gszMsgBox, "%s.\n\n%s.",
                 "Too many symbols defined in a symbol file",
--- 1728,1732 ----
           MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
           return;
!       } else if (FileNameHasExtension(ext, SYM_FILE_TYPE, NULL, &no_name)) {
           sprintf(gszMsgBox, "%s.\n\n%s.",
                 "Too many symbols defined in a symbol file",
***************
*** 1642,1662 ****
        sprintf(full_name, "%s%c%s", curDir, DIR_SEP, curFileName);
     }
!    if ((short_name=IsPrefix(bootDir, full_name, &rest))) ++rest;
     if ((fp=fopen(full_name, "w")) == NULL) {
        if (short_name) {
!          sprintf(s, "Cannot open '%s', file not saved.", rest);
        } else {
!          sprintf(s, "Cannot open '%s', file not saved.", full_name);
        }
!       MsgBox(s, TOOL_NAME, INFO_MB);
        return;
     }
- 
     if (short_name) {
!       sprintf(s, "Saving '%s' ...", rest);
     } else {
!       sprintf(s, "Saving '%s' ...", full_name);
     }
!    Msg(s);
  
     watch_cursor = watchCursorOnMainWindow;
--- 1748,1785 ----
        sprintf(full_name, "%s%c%s", curDir, DIR_SEP, curFileName);
     }
!    if (file_type == OBJ_FILE_TYPE && gzipped) {
!       char tmp_fname[MAXPATHLENGTH];
! 
!       sprintf(tmp_fname, "%sTgifXXXXXX", TMP_DIR);
!       mktemp(tmp_fname);
!       unlink(tmp_fname);
!       strcpy(gzipped_fname, full_name);
!       strcpy(full_name, tmp_fname);
!    }
!    if (*gzipped_fname == '\0') {
!       if ((short_name=IsPrefix(bootDir, full_name, &rest))) ++rest;
!    } else {
!       if ((short_name=IsPrefix(bootDir, gzipped_fname, &rest))) ++rest;
!    }
     if ((fp=fopen(full_name, "w")) == NULL) {
        if (short_name) {
!          sprintf(gszMsgBox, "Cannot open '%s', file not saved.", rest);
        } else {
!          sprintf(gszMsgBox, "Cannot open '%s', file not saved.", full_name);
        }
!       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
!       if (*gzipped_fname != '\0') unlink(full_name);
        return;
     }
     if (short_name) {
!       sprintf(gszMsgBox, "Saving '%s' ...", rest);
     } else {
!       if (*gzipped_fname == '\0') {
!          sprintf(gszMsgBox, "Saving '%s' ...", full_name);
!       } else {
!          sprintf(gszMsgBox, "Saving '%s' ...", gzipped_fname);
!       }
     }
!    Msg(gszMsgBox);
  
     watch_cursor = watchCursorOnMainWindow;
***************
*** 1677,1681 ****
--- 1800,1806 ----
     topObj = curPage->top;
     botObj = curPage->bot;
+ 
     fclose(fp);
+ 
     if (!watch_cursor) {
        SetDefaultCursor(mainWindow);
***************
*** 1684,1697 ****
     if (writeFileFailed) {
        writeFileFailed = FALSE;
!       sprintf(s, "Fail to write to '%s'.\n\nFile system may be full.",
              full_name);
!       MsgBox(s, TOOL_NAME, INFO_MB);
     } else {
        if (short_name) {
!          sprintf(s, "File '%s' saved.", rest);
        } else {
!          sprintf(s, "File '%s' saved.", full_name);
        }
!       Msg(s);
        SetFileModified(FALSE);
        if (!NameInCurDir(curFileName)) UpdateDirInfo();
--- 1809,1835 ----
     if (writeFileFailed) {
        writeFileFailed = FALSE;
!       sprintf(gszMsgBox, "Fail to write to '%s'.\n\nFile system may be full.",
              full_name);
!       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
     } else {
+       if (*gzipped_fname != '\0') {
+          if (!GzipFile(full_name, gzipped_fname)) {
+             sprintf(gszMsgBox, "%s '%s' to '%s'.\n\n%s '%s'.  %s.",
+                   "Problems encountered while (g)zipping", full_name,
+                   gzipped_fname, "The unzipped file is", full_name,
+                   "Please save a copy of it before proceeding");
+             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+             unlink(full_name);
+             return;
+          }
+          unlink(full_name);
+          strcpy(full_name, gzipped_fname);
+       }
        if (short_name) {
!          sprintf(gszMsgBox, "File '%s' saved.", rest);
        } else {
!          sprintf(gszMsgBox, "File '%s' saved.", full_name);
        }
!       Msg(gszMsgBox);
        SetFileModified(FALSE);
        if (!NameInCurDir(curFileName)) UpdateDirInfo();
***************
*** 2560,2565 ****
     char *Inbuf, **ppsz_page_name;
  {
!    int page_num;
!    char *s, *c_ptr;
  
     if (ppsz_page_name != NULL) *ppsz_page_name = NULL;
--- 2698,2703 ----
     char *Inbuf, **ppsz_page_name;
  {
!    int page_num=0;
!    char *s=NULL, *c_ptr=NULL;
  
     if (ppsz_page_name != NULL) *ppsz_page_name = NULL;
***************
*** 3145,3148 ****
--- 3283,3287 ----
     char *rest, remote_fname[MAXPATHLENGTH+1], *remote_buf=NULL;
     char tmp_filename[MAXPATHLENGTH+1], *tmp_remote_fname=NULL, *page_spec=NULL;
+    char gzipped_fname[MAXPATHLENGTH+1];
     int short_name=FALSE, read_status=0, remote_buf_sz=0;
     int tmp_linenum, file_is_remote=FALSE, interrupted;
***************
*** 3150,3153 ****
--- 3289,3293 ----
     XEvent ev;
  
+    *gzipped_fname = '\0';
     if (FileIsRemote(file_name)) {
        int rc=TRUE;
***************
*** 3177,3182 ****
           return rc;
        }
!    }
  
     XSync(mainDisplay, False);
     if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
--- 3317,3336 ----
           return rc;
        }
!    } else {
!       int gzipped=FALSE;
  
+       if (FileNameHasExtension(file_name, OBJ_FILE_TYPE, &gzipped, NULL) &&
+             gzipped) {
+          char *tmp_fname=NULL;
+ 
+          if ((tmp_fname=GunzipFileIntoTemp(file_name)) == NULL) {
+             return BAD;
+          } else {
+             strcpy(gzipped_fname, file_name);
+             strcpy(file_name, tmp_fname);
+             free(tmp_fname);
+          }
+       }
+    }
     XSync(mainDisplay, False);
     if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
***************
*** 3194,3198 ****
        }
     } else {
!       if ((short_name=IsPrefix(bootDir, file_name, &rest))) ++rest;
        if ((fp=fopen(file_name, "r")) == NULL) {
           if (short_name) {
--- 3348,3356 ----
        }
     } else {
!       if (*gzipped_fname == '\0') {
!          if ((short_name=IsPrefix(bootDir, file_name, &rest))) ++rest;
!       } else {
!          if ((short_name=IsPrefix(bootDir, gzipped_fname, &rest))) ++rest;
!       }
        if ((fp=fopen(file_name, "r")) == NULL) {
           if (short_name) {
***************
*** 3199,3205 ****
              sprintf(gszMsgBox, "Cannot import '%s'.", rest);
           } else {
!             sprintf(gszMsgBox, "Cannot import '%s'.", file_name);
           }
           MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
           /* temporary problem -- may be the file does not exist yet */
           return FALSE;
--- 3357,3368 ----
              sprintf(gszMsgBox, "Cannot import '%s'.", rest);
           } else {
!             if (*gzipped_fname == '\0') {
!                sprintf(gszMsgBox, "Cannot import '%s'.", file_name);
!             } else {
!                sprintf(gszMsgBox, "Cannot import '%s'.", gzipped_fname);
!             }
           }
           MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+          if (*gzipped_fname != '\0') unlink(file_name);
           /* temporary problem -- may be the file does not exist yet */
           return FALSE;
***************
*** 3206,3210 ****
        }
     }
- 
     strcpy(tmp_filename, scanFileName);
     tmp_linenum = scanLineNum;
--- 3369,3372 ----
***************
*** 3226,3230 ****
           sprintf(gszMsgBox, "Importing '%s' ...", rest);
        } else {
!          sprintf(gszMsgBox, "Importing '%s' ...", file_name);
        }
     }
--- 3388,3396 ----
           sprintf(gszMsgBox, "Importing '%s' ...", rest);
        } else {
!          if (*gzipped_fname == '\0') {
!             sprintf(gszMsgBox, "Importing '%s' ...", file_name);
!          } else {
!             sprintf(gszMsgBox, "Importing '%s' ...", gzipped_fname);
!          }
        }
     }
***************
*** 3319,3323 ****
  
     if (fp != NULL) fclose(fp);
! 
     strcpy(scanFileName, tmp_filename);
     scanLineNum = tmp_linenum;
--- 3485,3492 ----
  
     if (fp != NULL) fclose(fp);
!    if (*gzipped_fname != '\0') {
!       unlink(file_name);
!       strcpy(file_name, gzipped_fname);
!    }
     strcpy(scanFileName, tmp_filename);
     scanLineNum = tmp_linenum;
***************
*** 3374,3379 ****
     HighLightForward();
  
!    if (!importFromLibrary && !file_is_remote) SetCurImportDir(file_name);
! 
     if (file_is_remote) {
        sprintf(gszMsgBox, "'%s' imported.", remote_fname);
--- 3543,3549 ----
     HighLightForward();
  
!    if (!importFromLibrary && !file_is_remote) {
!       SetCurImportDir(file_name);
!    }
     if (file_is_remote) {
        sprintf(gszMsgBox, "'%s' imported.", remote_fname);
***************
*** 3659,3663 ****
  }
  
! int LoadFile(FullName, ObjFile)
     char *FullName;
     int ObjFile; /* equals TRUE if the file is an OBJ file */
--- 3829,3833 ----
  }
  
! int LoadFile(FullName, ObjFile, GzippedObjFile)
     char *FullName;
     int ObjFile; /* equals TRUE if the file is an OBJ file */
***************
*** 3665,3675 ****
                  /* equals -1 if the file is an temporary OBJ file */
  {
!    struct ObjRec *obj_ptr;
     char file_name[MAXPATHLENGTH+1], tmp_filename[MAXPATHLENGTH+1];
!    char saved_cur_dir[MAXPATHLENGTH+1], *rest;
     int read_status, short_name, tmp_linenum, interrupted;
!    FILE *fp;
     XEvent ev;
  
     if (ObjFile != FALSE) {
        strcpy(saved_cur_dir, curDir);
--- 3835,3847 ----
                  /* equals -1 if the file is an temporary OBJ file */
  {
!    struct ObjRec *obj_ptr=NULL;
     char file_name[MAXPATHLENGTH+1], tmp_filename[MAXPATHLENGTH+1];
!    char saved_cur_dir[MAXPATHLENGTH+1], *rest=NULL;
!    char gzipped_fname[MAXPATHLENGTH+1];
     int read_status, short_name, tmp_linenum, interrupted;
!    FILE *fp=NULL;
     XEvent ev;
  
+    *gzipped_fname = '\0';
     if (ObjFile != FALSE) {
        strcpy(saved_cur_dir, curDir);
***************
*** 3677,3683 ****
        strcpy(saved_cur_dir, curSymDir);
     }
!    strcpy(file_name, FullName);
  
!    if ((short_name=IsPrefix(bootDir, file_name, &rest))) ++rest;
     if ((fp=fopen(file_name, "r")) == NULL) {
        if (short_name) {
--- 3849,3870 ----
        strcpy(saved_cur_dir, curSymDir);
     }
!    if (GzippedObjFile) {
!       char *tmp_fname=NULL;
  
!       if ((tmp_fname=GunzipFileIntoTemp(FullName)) == NULL) {
!          return FALSE;
!       } else {
!          strcpy(gzipped_fname, FullName);
!          strcpy(file_name, tmp_fname);
!          free(tmp_fname);
!       }
!    } else {
!       strcpy(file_name, FullName);
!    }
!    if (*gzipped_fname == '\0') {
!       if ((short_name=IsPrefix(bootDir, file_name, &rest))) ++rest;
!    } else {
!       if ((short_name=IsPrefix(bootDir, gzipped_fname, &rest))) ++rest;
!    }
     if ((fp=fopen(file_name, "r")) == NULL) {
        if (short_name) {
***************
*** 3684,3690 ****
           sprintf(gszMsgBox, "Cannot open '%s'.", rest);
        } else {
!          sprintf(gszMsgBox, "Cannot open '%s'.", file_name);
        }
        MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
        return FALSE;
     }
--- 3871,3882 ----
           sprintf(gszMsgBox, "Cannot open '%s'.", rest);
        } else {
!          if (*gzipped_fname == '\0') {
!             sprintf(gszMsgBox, "Cannot open '%s'.", file_name);
!          } else {
!             sprintf(gszMsgBox, "Cannot open '%s'.", gzipped_fname);
!          }
        }
        MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       if (*gzipped_fname != '\0') unlink(file_name);
        return FALSE;
     }
***************
*** 3709,3713 ****
        sprintf(gszMsgBox, "Loading '%s' ...", rest);
     } else {
!       sprintf(gszMsgBox, "Loading '%s' ...", file_name);
     }
     Msg(gszMsgBox);
--- 3901,3909 ----
        sprintf(gszMsgBox, "Loading '%s' ...", rest);
     } else {
!       if (*gzipped_fname == '\0') {
!          sprintf(gszMsgBox, "Loading '%s' ...", file_name);
!       } else {
!          sprintf(gszMsgBox, "Loading '%s' ...", gzipped_fname);
!       }
     }
     Msg(gszMsgBox);
***************
*** 3743,3746 ****
--- 3939,3943 ----
     }
     fclose(fp);
+    if (*gzipped_fname != '\0') unlink(file_name);
  
     if (!PRTGIF && colorLayers && needToRedrawColorWindow) {
***************
*** 3773,3777 ****
  
     if (ObjFile == TRUE) {
!       SetCurDir(file_name);
        *curSymDir = '\0';
     } else if (ObjFile == FALSE) {
--- 3970,3978 ----
  
     if (ObjFile == TRUE) {
!       if (*gzipped_fname == '\0') {
!          SetCurDir(file_name);
!       } else {
!          SetCurDir(gzipped_fname);
!       }
        *curSymDir = '\0';
     } else if (ObjFile == FALSE) {
***************
*** 3806,3810 ****
        sprintf(gszMsgBox, "Current file is '%s'.", rest);
     } else {
!       sprintf(gszMsgBox, "Current file is '%s'.", file_name);
     }
     Msg(gszMsgBox);
--- 4007,4015 ----
        sprintf(gszMsgBox, "Current file is '%s'.", rest);
     } else {
!       if (*gzipped_fname == '\0') {
!          sprintf(gszMsgBox, "Current file is '%s'.", file_name);
!       } else {
!          sprintf(gszMsgBox, "Current file is '%s'.", gzipped_fname);
!       }
     }
     Msg(gszMsgBox);
***************
*** 6339,6345 ****
           if (page_spec != NULL) free(page_spec);
        } else {
!          int obj_file=FileNameHasExtension(file_name, OBJ_FILE_TYPE, NULL);
  
!          if (!LoadFile(file_name, obj_file)) {
              if (do_not_save) {
                 SetFileModified(TRUE);
--- 6544,6552 ----
           if (page_spec != NULL) free(page_spec);
        } else {
!          int gzipped=FALSE, obj_file=FALSE;
  
!          obj_file = FileNameHasExtension(file_name, OBJ_FILE_TYPE, &gzipped,
!                NULL);
!          if (!LoadFile(file_name, obj_file, obj_file && gzipped)) {
              if (do_not_save) {
                 SetFileModified(TRUE);
*** font.c.orig	Sun Apr 11 10:46:58 1999
--- font.c	Sun Apr 11 10:46:58 1999
***************
*** 126,129 ****
--- 126,132 ----
  static char *menuFontName=NULL;
  
+ XFontSet	menuFontSet=NULL;
+ static char *menuFontSetName=NULL;
+ 
  XFontStruct	*boldMsgFontPtr=NULL;
  int	boldMsgFontWidth=0;
***************
*** 446,449 ****
--- 449,471 ----
  #define PS_FONT_NAME  2
  
+ char *GetCurFontInfoStr(retstr)
+    char* retstr;
+ {
+    int font_index=curFont;
+    int style_index=curStyle;
+    int size=SzUnitToFontSize(curSzUnit);
+    int info_index=InfoIndex(font_index, style_index);
+ 
+    if (strstr(fontInfoStr[info_index], "%d") != NULL) {
+       sprintf(gszAttemptedFontName, fontInfoStr[info_index], size);
+    } else {
+       sprintf(gszAttemptedFontName, "%s-%s-*-%1d-*-*-*-*-*-%s", fontNamePrefix,
+             fontInfoStr[info_index+X_FONT_PREFIX], size,
+             fontInfoStr[info_index+X_FONT_SUFFIX]);
+    }
+    strcpy(retstr, gszAttemptedFontName);
+    return retstr;
+ }
+ 
  static
  void LoadAFont(info_index, size, can_debug, pxfs, pn_vert)
***************
*** 626,630 ****
     char *FontStr;
  {
!    if (PRTGIF) {
        if (FontIndex < MAXFONTS) {
           sprintf(FontStr, "/%s",
--- 648,652 ----
     char *FontStr;
  {
!    if (PRTGIF && !cmdLineOpenDisplay) {
        if (FontIndex < MAXFONTS) {
           sprintf(FontStr, "/%s",
***************
*** 1151,1155 ****
  
        *szDontReencode = '\0';
!       if (PRTGIF) {
           if (cmdLineDontReencode != NULL) {
              UtilTrimBlanks(cmdLineDontReencode);
--- 1173,1177 ----
  
        *szDontReencode = '\0';
!       if (PRTGIF && !cmdLineOpenDisplay) {
           if (cmdLineDontReencode != NULL) {
              UtilTrimBlanks(cmdLineDontReencode);
***************
*** 1345,1349 ****
        int font_count=0;
  
!       font_count = (PRTGIF ? MAXFONTS+numFakedFonts : numFonts+numFakedFonts);
  
        encodeCharFlags =
--- 1367,1372 ----
        int font_count=0;
  
!       font_count = ((PRTGIF && !cmdLineOpenDisplay) ?
!             MAXFONTS+numFakedFonts : numFonts+numFakedFonts);
  
        encodeCharFlags =
***************
*** 1390,1394 ****
     int FontIndex, StyleIndex;
  {
!    if (PRTGIF) {
        /* No need to do anything here because encodeFont[] takes care of it */
     }
--- 1413,1417 ----
     int FontIndex, StyleIndex;
  {
!    if (PRTGIF && !cmdLineOpenDisplay) {
        /* No need to do anything here because encodeFont[] takes care of it */
     }
***************
*** 1404,1409 ****
  {
     int i;
!    int num_base_fonts=(PRTGIF ? MAXFONTS : numFonts);
!    char **base_font_info_str=(PRTGIF ? initFontInfoStr : fontInfoStr);
  
     for (i=0; i < num_base_fonts; i++) {
--- 1427,1433 ----
  {
     int i;
!    int num_base_fonts=((PRTGIF && !cmdLineOpenDisplay) ? MAXFONTS : numFonts);
!    char **base_font_info_str=((PRTGIF && !cmdLineOpenDisplay) ?
!          initFontInfoStr : fontInfoStr);
  
     for (i=0; i < num_base_fonts; i++) {
***************
*** 1448,1451 ****
--- 1472,1502 ----
  }
  
+ int GetFontAndStyle(FontStr, pnFont, pnStyle, MustFind)
+    char *FontStr;
+    int *pnFont, *pnStyle, MustFind;
+ {
+    int font=0;
+    int num_fonts=((PRTGIF && !cmdLineOpenDisplay) ? MAXFONTS : numFonts);
+ 
+    for (font=0; font < num_fonts; font++) {
+       int style=0;
+ 
+       for (style=0; style < MAXFONTSTYLES; style++) {
+          char font_str[MAXSTRING];
+ 
+          GetPSFontStr(font, style, font_str);
+          /* font_str[0] is '/' */
+          if (UtilStrICmp(FontStr, &font_str[1]) == 0) {
+             if (pnFont != NULL) *pnFont = font;
+             if (pnStyle != NULL) *pnStyle = style;
+             return TRUE;
+          }
+       }
+    }
+    if (MustFind) return FALSE;
+ 
+    return TRUE;
+ }
+ 
  void PrTgifInitBaseFonts()
  {
***************
*** 1495,1516 ****
     StrSegInfo *pStrSeg;
  {
!    char style[20];
  
!    switch (curStyle) {
!    case STYLE_BI: strcpy(style, "BoldItalic"); break;
!    case STYLE_BR: strcpy(style, "Bold"); break;
!    case STYLE_NI: strcpy(style, "Italic"); break;
!    case STYLE_NR: strcpy(style, "Roman"); break;
!    }
     if (pStrSeg != NULL && editTextSize != 0) {
        if (showFontSizeInPoints) {
!          sprintf(buf, "%s-%s-%1dpt (edit text size %1dpt)",
!                fontMenuStr[curFont], style,
!                SzUnitToPointSize(pStrSeg->real_sz_unit),
                 SzUnitToPointSize(curSzUnit));
        } else {
!          sprintf(buf, "%s-%s-%1d (edit text size %1d)",
!                fontMenuStr[curFont], style,
!                SzUnitToFontSize(pStrSeg->real_sz_unit),
                 SzUnitToFontSize(curSzUnit));
        }
--- 1546,1561 ----
     StrSegInfo *pStrSeg;
  {
!    char font_str[MAXSTRING];
  
!    GetPSFontStr(curFont, curStyle, font_str);
! 
     if (pStrSeg != NULL && editTextSize != 0) {
        if (showFontSizeInPoints) {
!          sprintf(buf, "%s-%1dpt (edit text size %1dpt)",
!                &font_str[1], SzUnitToPointSize(pStrSeg->real_sz_unit),
                 SzUnitToPointSize(curSzUnit));
        } else {
!          sprintf(buf, "%s-%1d (edit text size %1d)",
!                &font_str[1], SzUnitToFontSize(pStrSeg->real_sz_unit),
                 SzUnitToFontSize(curSzUnit));
        }
***************
*** 1517,1525 ****
     } else {
        if (showFontSizeInPoints) {
!          sprintf(buf, "%s-%s-%1dpt", fontMenuStr[curFont], style,
!                SzUnitToPointSize(curSzUnit));
        } else {
!          sprintf(buf, "%s-%s-%1d", fontMenuStr[curFont], style,
!                SzUnitToFontSize(curSzUnit));
        }
     }
--- 1562,1568 ----
     } else {
        if (showFontSizeInPoints) {
!          sprintf(buf, "%s-%1dpt", &font_str[1], SzUnitToPointSize(curSzUnit));
        } else {
!          sprintf(buf, "%s-%1d", &font_str[1], SzUnitToFontSize(curSzUnit));
        }
     }
***************
*** 1546,1550 ****
     char font_str[MAXSTRING];
  
!    font_count = (PRTGIF ? MAXFONTS+numFakedFonts : numFonts+numFakedFonts);
  
     for (font_index=0; font_index < font_count; font_index++) {
--- 1589,1594 ----
     char font_str[MAXSTRING];
  
!    font_count = ((PRTGIF && !cmdLineOpenDisplay) ? MAXFONTS+numFakedFonts :
!          numFonts+numFakedFonts);
  
     for (font_index=0; font_index < font_count; font_index++) {
***************
*** 2166,2170 ****
--- 2210,2216 ----
     struct FontSizeRec *fs_ptr=NULL;
     XFontStruct *xfs=NULL;
+    XFontSet xfset=NULL;
  
+    memset(&xfset, 0, sizeof(XFontSet));
     memset(&gstSavedFontInfo, 0, sizeof(struct PushedFontRec));
  
***************
*** 2278,2282 ****
     curFont = FONT_COU;
     curStyle = STYLE_NR;
!    curSzUnit = FontSizeToSzUnit(17);
  
     ruler_font_size = 10;
--- 2324,2328 ----
     curFont = FONT_COU;
     curStyle = STYLE_NR;
!    curSzUnit = FontSizeToSzUnit(14);
  
     ruler_font_size = 10;
***************
*** 2393,2430 ****
        rulerFontHeight = 12;
     }
!    if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "MenuFont")) != NULL) {
!       menuFontName = UtilStrDup(c_ptr);
!       if (menuFontName == NULL) FailAllocMessage();
!       xfs = XLoadQueryFont(mainDisplay, menuFontName);
!       if (xfs == NULL) {
!          fprintf(stderr, "Cannot load font specified by %s*MenuFont: '%s'.\n",
!                TOOL_NAME, menuFontName);
!          if (menuFontName != NULL) free(menuFontName);
!          menuFontName = NULL;
!          menuFontPtr = NULL;
        } else {
!          menuFontPtr = xfs;
!          menuFontWidth = XTextWidth(menuFontPtr, "x", 1);
!          menuFontAsc = menuFontPtr->max_bounds.ascent;
!          menuFontDes = menuFontPtr->max_bounds.descent;
!          menuFontHeight = menuFontAsc + menuFontDes;
        }
     } else {
!       menuFontName =
!             UtilStrDup("-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*");
!       if (menuFontName == NULL) FailAllocMessage();
!       xfs = XLoadQueryFont(mainDisplay, menuFontName);
!       if (xfs == NULL) {
!          if (menuFontName != NULL) free(menuFontName);
!          menuFontName = NULL;
!          menuFontPtr = NULL;
        } else {
!          menuFontPtr = xfs;
!          menuFontWidth = XTextWidth(menuFontPtr, "x", 1);
!          menuFontAsc = menuFontPtr->max_bounds.ascent;
!          menuFontDes = menuFontPtr->max_bounds.descent;
!          menuFontHeight = menuFontAsc + menuFontDes;
        }
     }
     if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "MsgFont")) != NULL) {
        msgFontName = UtilStrDup(c_ptr);
--- 2439,2544 ----
        rulerFontHeight = 12;
     }
!    menuFontSet = NULL;
! #ifndef _NO_LOCALE_SUPPORT
! #ifdef _ENABLE_NLS
!    if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "MenuFontSet")) != NULL) {
!       char **missing_charsets=NULL, *default_string=NULL;
!       int num_missing_charsets=0;
! 
!       menuFontSetName = UtilStrDup(c_ptr);
!       if (menuFontSetName == NULL) FailAllocMessage();
!       xfset = XCreateFontSet(mainDisplay, menuFontSetName,
!             &missing_charsets, &num_missing_charsets, &default_string);
!       if (xfset == NULL) {
!          fprintf(stderr,
!                "Cannot load fontset specified by %s*MenuFontSet: '%s'.\n",
!                TOOL_NAME, menuFontSetName);
!          if (menuFontSetName != NULL) free(menuFontSetName);
!          menuFontSetName = NULL;
!          menuFontSet = NULL;
        } else {
!         XFontStruct **xfset_list=NULL;
!         char **font_name_list=NULL;
!         int n=0;
! 
!         menuFontSet = xfset;
!         n = XFontsOfFontSet(xfset, &xfset_list, &font_name_list);
!         menuFontWidth = XmbTextEscapement(menuFontSet, "x", 1);
!         menuFontAsc = (*xfset_list)->max_bounds.ascent;
!         menuFontDes = (*xfset_list)->max_bounds.descent;
!         menuFontHeight = menuFontAsc + menuFontDes;
        }
     } else {
!       char **missing_charsets=NULL, *default_string=NULL;
!       int num_missing_charsets=0;
!       char *fn1="-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*";
!       char *fn2="-*-*-medium-r-*--12-*-*-*-*-*-*-*";
!       int sz=strlen(fn1)+strlen(fn2)+1;
! 
!       menuFontSetName = (char*)malloc((sz+1)*sizeof(char));
!       if (menuFontSetName == NULL) FailAllocMessage();
!       sprintf(menuFontSetName, "%s,%s", fn1, fn2);
!       xfset = XCreateFontSet(mainDisplay, menuFontSetName,
!             &missing_charsets, &num_missing_charsets, &default_string);
!       if (xfset == NULL) {
!          fprintf(stderr,
!                "Cannot load fontset specified by %s*MenuFontSet: '%s'.\n",
!                TOOL_NAME, menuFontSetName);
!          if (menuFontSetName != NULL) free(menuFontSetName);
!          menuFontSetName = NULL;
!          menuFontSet = NULL;
        } else {
!         XFontStruct **xfset_list=NULL;
!         char **font_name_list=NULL;
!         int n=0;
! 
!         menuFontSet = xfset;
!         n = XFontsOfFontSet(xfset, &xfset_list, &font_name_list);
!         menuFontWidth = XmbTextEscapement(menuFontSet, "x", 1);
!         menuFontAsc = (*xfset_list)->max_bounds.ascent;
!         menuFontDes = (*xfset_list)->max_bounds.descent;
!         menuFontHeight = menuFontAsc + menuFontDes;
        }
     }
+ #endif /* _ENABLE_NLS */
+ #endif /* ~_NO_LOCALE_SUPPORT */
+ 
+    if (menuFontSet == NULL) {
+       if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "MenuFont")) != NULL) {
+          menuFontName = UtilStrDup(c_ptr);
+          if (menuFontName == NULL) FailAllocMessage();
+          xfs = XLoadQueryFont(mainDisplay, menuFontName);
+          if (xfs == NULL) {
+             fprintf(stderr,
+                   "Cannot load font specified by %s*MenuFont: '%s'.\n",
+                   TOOL_NAME, menuFontName);
+             if (menuFontName != NULL) free(menuFontName);
+             menuFontName = NULL;
+             menuFontPtr = NULL;
+          } else {
+             menuFontPtr = xfs;
+             menuFontWidth = XTextWidth(menuFontPtr, "x", 1);
+             menuFontAsc = menuFontPtr->max_bounds.ascent;
+             menuFontDes = menuFontPtr->max_bounds.descent;
+             menuFontHeight = menuFontAsc + menuFontDes;
+          }
+       } else {
+          menuFontName =
+                UtilStrDup("-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*");
+          if (menuFontName == NULL) FailAllocMessage();
+          xfs = XLoadQueryFont(mainDisplay, menuFontName);
+          if (xfs == NULL) {
+             if (menuFontName != NULL) free(menuFontName);
+             menuFontName = NULL;
+             menuFontPtr = NULL;
+          } else {
+             menuFontPtr = xfs;
+             menuFontWidth = XTextWidth(menuFontPtr, "x", 1);
+             menuFontAsc = menuFontPtr->max_bounds.ascent;
+             menuFontDes = menuFontPtr->max_bounds.descent;
+             menuFontHeight = menuFontAsc + menuFontDes;
+          }
+       }
+    }
     if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "MsgFont")) != NULL) {
        msgFontName = UtilStrDup(c_ptr);
***************
*** 3893,3903 ****
  }
  
  void SetSelFontSize(pszBuf)
     char *pszBuf;
  {
-    struct SelRec *sel_ptr;
     char *psz=NULL, spec[MAXSTRING+1], spec_copy[MAXSTRING+1];
!    int ltx, lty, rbx, rby;
!    int sz_unit=(-1), font_size=(-1), point_size=(-1), changed=FALSE;
  
     if (topSel == NULL) {
--- 4007,4051 ----
  }
  
+ void ChangeAllSelRealSzUnit(sz_unit, HighLight)
+    int sz_unit, HighLight;
+ {
+    struct SelRec *sel_ptr=NULL;
+    int changed=FALSE;
+ 
+    if (topSel == NULL) {
+       MsgBox("No object selected!", TOOL_NAME, INFO_MB);
+       return;
+    }
+    if (HighLight) HighLightReverse();
+    StartCompositeCmd();
+    for (sel_ptr=botSel; sel_ptr != NULL; sel_ptr=sel_ptr->prev) {
+       PrepareToReplaceAnObj(sel_ptr->obj);
+       if (ChangeObjTextSzUnit(sel_ptr->obj, sz_unit)) {
+          changed = TRUE;
+          RecordReplaceAnObj(sel_ptr->obj);
+       } else {
+          AbortPrepareCmd(CMD_REPLACE);
+       }
+    }
+    EndCompositeCmd();
+ 
+    if (changed) {
+       int ltx=selLtX, lty=selLtY, rbx=selRbX, rby=selRbY;
+ 
+       SetFileModified(TRUE);
+       UpdSelBBox();
+       RedrawAreas(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
+             rbx+GRID_ABS_SIZE(1), rby+GRID_ABS_SIZE(1), selLtX-GRID_ABS_SIZE(1),
+             selLtY-GRID_ABS_SIZE(1), selRbX+GRID_ABS_SIZE(1),
+             selRbY+GRID_ABS_SIZE(1));
+    }
+    if (HighLight) HighLightForward();
+ }
+ 
  void SetSelFontSize(pszBuf)
     char *pszBuf;
  {
     char *psz=NULL, spec[MAXSTRING+1], spec_copy[MAXSTRING+1];
!    int sz_unit=(-1), font_size=(-1), point_size=(-1);
  
     if (topSel == NULL) {
***************
*** 3951,3978 ****
        return;
     }
!    ltx = selLtX; lty = selLtY; rbx = selRbX; rby = selRbY;
! 
!    HighLightReverse();
!    StartCompositeCmd();
!    for (sel_ptr=botSel; sel_ptr != NULL; sel_ptr=sel_ptr->prev) {
!       PrepareToReplaceAnObj(sel_ptr->obj);
!       if (ChangeObjTextSzUnit(sel_ptr->obj, sz_unit)) {
!          changed = TRUE;
!          RecordReplaceAnObj(sel_ptr->obj);
!       } else {
!          AbortPrepareCmd(CMD_REPLACE);
!       }
!    }
!    EndCompositeCmd();
! 
!    if (changed) {
!       UpdSelBBox();
!       RedrawAreas(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
!             rbx+GRID_ABS_SIZE(1), rby+GRID_ABS_SIZE(1), selLtX-GRID_ABS_SIZE(1),
!             selLtY-GRID_ABS_SIZE(1), selRbX+GRID_ABS_SIZE(1),
!             selRbY+GRID_ABS_SIZE(1));
!       SetFileModified(TRUE);
!    }
!    HighLightForward();
  }
  
--- 4099,4103 ----
        return;
     }
!    ChangeAllSelRealSzUnit(sz_unit, TRUE);
  }
  
***************
*** 4048,4051 ****
--- 4173,4178 ----
     numFonts = MAXFONTS;
     numFakedFonts = 0;
+    if (menuFontSet != NULL) XFreeFontSet(mainDisplay, menuFontSet);
+    menuFontSet = NULL;
     if (menuFontPtr != NULL) XFreeFont(mainDisplay, menuFontPtr);
     if (boldMsgFontPtr != NULL) XFreeFont(mainDisplay, boldMsgFontPtr);
***************
*** 4055,4062 ****
     if (defaultFontName != NULL) free(defaultFontName);
     if (menuFontName != NULL) free(menuFontName);
     if (boldMsgFontName != NULL) free(boldMsgFontName);
     if (msgFontName != NULL) free(msgFontName);
     rulerFontName = defaultFontName = NULL;
!    menuFontName = boldMsgFontName = msgFontName = NULL;
  }
  
--- 4182,4190 ----
     if (defaultFontName != NULL) free(defaultFontName);
     if (menuFontName != NULL) free(menuFontName);
+    if (menuFontSetName != NULL) free(menuFontSetName);
     if (boldMsgFontName != NULL) free(boldMsgFontName);
     if (msgFontName != NULL) free(msgFontName);
     rulerFontName = defaultFontName = NULL;
!    menuFontSetName = menuFontName = boldMsgFontName = msgFontName = NULL;
  }
  
***************
*** 4085,4089 ****
     char *font_str;
  {
!    int num_fonts=(PRTGIF? MAXFONTS+numFakedFonts: numFonts+numFakedFonts);
     int cSingle=0;
     int cDouble=0;
--- 4213,4217 ----
     char *font_str;
  {
!    int i;
     int cSingle=0;
     int cDouble=0;
***************
*** 4092,4096 ****
     int old_font_single=(old_font_index % 1000);
     int old_font_double=((old_font_index / 1000) - 1);
!    int i;
  
     for (i=0; i < num_fonts; i++) {
--- 4220,4225 ----
     int old_font_single=(old_font_index % 1000);
     int old_font_double=((old_font_index / 1000) - 1);
!    int num_fonts=((PRTGIF && !cmdLineOpenDisplay) ? MAXFONTS+numFakedFonts:
!          numFonts+numFakedFonts);
  
     for (i=0; i < num_fonts; i++) {
***************
*** 4107,4114 ****
     } else {
        GetFontStr(defaultCurFont, style, font_str);
!       if (!PRTGIF) {
!          sprintf(gszMsgBox, "%s substituted for font number (`%d').\n\n%s",
!                font_str, old_font_single,
!                "There is no such font. Use default.");
           MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
        }
--- 4236,4245 ----
     } else {
        GetFontStr(defaultCurFont, style, font_str);
!       sprintf(gszMsgBox, "%s substituted for font number (`%d').\n\n%s",
!             font_str, old_font_single,
!             "There is no such font. Use default.");
!       if (PRTGIF) {
!          fprintf(stderr, "%s\n", gszMsgBox);
!       } else {
           MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
        }
***************
*** 4118,4124 ****
        GetFontStr(cpDouble, style, font_str+strlen(font_str));
     } else if (old_font_double >=0) {
!       if (!PRTGIF) {
!          sprintf(gszMsgBox, "There is not kanji-font number (`%d').",
!                old_font_double);
           MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
        }
--- 4249,4257 ----
        GetFontStr(cpDouble, style, font_str+strlen(font_str));
     } else if (old_font_double >=0) {
!       sprintf(gszMsgBox, "There is not kanji-font number (`%d').",
!             old_font_double);
!       if (PRTGIF) {
!          fprintf(stderr, "%s\n", gszMsgBox);
!       } else {
           MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
        }
*** inmethod.c.orig	Sun Apr 11 10:47:00 1999
--- inmethod.c	Sun Apr 11 10:47:00 1999
***************
*** 398,401 ****
--- 398,408 ----
     Window win;
  {
+    char *c_ptr=NULL;
+    gnOverTheSpot = FALSE;
+    if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "PreeditType")) != NULL &&
+          UtilStrICmp(c_ptr, "overthespot") == 0) {
+       gnOverTheSpot = TRUE;
+    }
+    XIMSetConvOverSpot(gnOverTheSpot);
     return TRUE;
  }
***************
*** 469,472 ****
--- 476,489 ----
     return TRUE;
  }
+ 
+ static
+ int XimTellCursorPos(dpy, win, cur_x, cur_y)
+    Display *dpy;
+    Window win;
+    int cur_x, cur_y;
+ {
+    XIMTellCursorPosition(dpy, win, cur_x, cur_y);
+    return TRUE;
+ }
  #endif /* ~_NO_XIM */
  
***************
*** 502,507 ****
       NULL, NULL, NULL, NULL, NULL, NULL,
       XimDeactiveOnCreateText, XimHandleCreateText,
!      NULL, XimExpectNextEvent, XimHandleNextEvent, XimHandleNewCurText,
!      XimExpectLookupString, XimHandleLookupString
     },
  #endif /* ~_NO_XIM */
--- 519,524 ----
       NULL, NULL, NULL, NULL, NULL, NULL,
       XimDeactiveOnCreateText, XimHandleCreateText,
!      XimTellCursorPos, XimExpectNextEvent, XimHandleNextEvent,
!      XimHandleNewCurText, XimExpectLookupString, XimHandleLookupString
     },
  #endif /* ~_NO_XIM */
*** mainloop.c.orig	Sun Apr 11 10:47:01 1999
--- mainloop.c	Sun Apr 11 10:47:01 1999
***************
*** 43,50 ****
  #endif /* USE_XT_INITIALIZE */
  
- #ifndef _NO_LOCALE_SUPPORT
- #include <X11/Xlocale.h>
- #endif /* ~_NO_LOCALE_SUPPORT */
- 
  #include "animate.e"
  #include "auxtext.e"
--- 43,46 ----
***************
*** 192,195 ****
--- 188,214 ----
  }
  
+ static char gszCurLocale[MAXSTRING];
+ 
+ void SaveAndSetLocale(new_locale, prev_locale)
+    char *new_locale, *prev_locale;
+ {
+ #ifndef _NO_LOCALE_SUPPORT
+    if (prev_locale != NULL) strcpy(prev_locale, gszCurLocale);
+    *gszCurLocale = '\0';
+    UtilStrCpyN(gszCurLocale, sizeof(gszCurLocale), new_locale);
+    setlocale(LC_ALL, gszCurLocale);
+ #endif /* ~_NO_LOCALE_SUPPORT */
+ }
+ 
+ void RestoreLocale(prev_locale)
+    char *prev_locale;
+ {
+ #ifndef _NO_LOCALE_SUPPORT
+    *gszCurLocale = '\0';
+    UtilStrCpyN(gszCurLocale, sizeof(gszCurLocale), prev_locale);
+    setlocale(LC_ALL, gszCurLocale);
+ #endif /* ~_NO_LOCALE_SUPPORT */
+ }
+ 
  static
  void ExecWithFile(CmdName, FileName)
***************
*** 428,431 ****
--- 447,564 ----
  }
  
+ int GzipFile(fname, gzipped_fname)
+    char *fname, *gzipped_fname;
+ {
+    int rc=TRUE;
+    FILE *pfp=NULL, *out_fp=NULL;
+    char *compress_cmd=gunzipCmd, *cmd=NULL;
+ 
+    if ((out_fp=fopen(gzipped_fname, "w")) == NULL) {
+       return FailToOpenMessage(gzipped_fname, "w", NULL);
+    }
+    SaveStatusStrings();
+    compress_cmd = gzipCmd;
+ 
+    cmd = (char*)malloc((strlen(fname)+strlen(compress_cmd)+20) * sizeof(char));
+    if (cmd == NULL) FailAllocMessage();
+ 
+    if (strstr(compress_cmd, "%s") == NULL) {
+       sprintf(cmd, "%s %s", compress_cmd, fname);
+    } else {
+       sprintf(cmd, compress_cmd, fname);
+    }
+    sprintf(gszMsgBox, "Executing '%s'...", gzipCmd);
+    SetStringStatus(gszMsgBox);
+ 
+    if ((pfp=(FILE*)popen(cmd, "r")) == NULL) {
+       sprintf(gszMsgBox, "Cannot execute '%s'.", cmd);
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       fclose(out_fp);
+       rc = FALSE;
+    } else {
+       int bytes_read=0;
+ 
+       writeFileFailed = FALSE;
+       while ((bytes_read=fread(gszMsgBox, sizeof(char), sizeof(gszMsgBox),
+             pfp)) > 0) {
+          if ((int)fwrite(gszMsgBox, sizeof(char), bytes_read, out_fp) <= 0) {
+             writeFileFailed = TRUE;
+             break;
+          }
+       }
+       pclose(pfp);
+       fclose(out_fp);
+       if (writeFileFailed) {
+          FailToWriteFileMessage(gzipped_fname);
+          rc = FALSE;
+       }
+    }
+    RestoreStatusStrings();
+    return rc;
+ }
+ 
+ char *GunzipFileIntoTemp(gzipped_fname)
+    char *gzipped_fname;
+ {
+    FILE *pfp=NULL, *out_fp=NULL;
+    char *uncompress_cmd=gunzipCmd, *tmp_fname=NULL, *cmd=NULL;
+ 
+    tmp_fname = (char*)malloc((strlen(TMP_DIR)+20)*sizeof(char));
+    if (tmp_fname == NULL) {
+       FailAllocMessage();
+       return NULL;
+    }
+    sprintf(tmp_fname, "%sTgifXXXXXX", TMP_DIR);
+    mktemp(tmp_fname);
+    unlink(tmp_fname);
+    if ((out_fp=fopen(tmp_fname, "w")) == NULL) {
+       sprintf(gszMsgBox, "Fail to create temporary file '%s'.", tmp_fname);
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       return NULL;
+    }
+    SaveStatusStrings();
+    uncompress_cmd = gunzipCmd;
+ 
+    cmd = (char*)malloc((strlen(gzipped_fname)+strlen(uncompress_cmd)+20) *
+          sizeof(char));
+    if (cmd == NULL) FailAllocMessage();
+ 
+    if (strstr(uncompress_cmd, "%s") == NULL) {
+       sprintf(cmd, "%s %s", uncompress_cmd, gzipped_fname);
+    } else {
+       sprintf(cmd, uncompress_cmd, gzipped_fname);
+    }
+    sprintf(gszMsgBox, "Executing '%s'...", gunzipCmd);
+    SetStringStatus(gszMsgBox);
+ 
+    if ((pfp=(FILE*)popen(cmd, "r")) == NULL) {
+       sprintf(gszMsgBox, "Cannot execute '%s'.", cmd);
+       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
+       fclose(out_fp);
+       unlink(tmp_fname);
+       tmp_fname = NULL;
+    } else {
+       int bytes_read=0;
+ 
+       writeFileFailed = FALSE;
+       while ((bytes_read=fread(gszMsgBox, sizeof(char), sizeof(gszMsgBox),
+             pfp)) > 0) {
+          if ((int)fwrite(gszMsgBox, sizeof(char), bytes_read, out_fp) <= 0) {
+             writeFileFailed = TRUE;
+             break;
+          }
+       }
+       pclose(pfp);
+       fclose(out_fp);
+       if (writeFileFailed) {
+          FailToWriteFileMessage(tmp_fname);
+          unlink(tmp_fname);
+          tmp_fname = NULL;
+       }
+    }
+    RestoreStatusStrings();
+    return tmp_fname;
+ }
+ 
  #ifdef USE_XAPPLRESDIR
  static
***************
*** 456,459 ****
--- 589,625 ----
  #endif /* USE_XAPPLRESDIR */
  
+ #ifndef _NO_LOCALE_SUPPORT
+ #ifdef _ENABLE_NLS
+ static
+ void InitLocale()
+ {
+    DIR *dirp=NULL;
+    char package[80], *c_ptr=NULL, locale_dir[MAXPATHLENGTH];
+ 
+    *locale_dir = '\0';
+    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"LocaleDir")) != NULL) {
+       strcpy(locale_dir, c_ptr);
+    } else {
+       strcpy(locale_dir, LOCALEDIR);
+    }
+    UtilTrimBlanks(locale_dir);
+ 
+    strcpy(package, TOOL_NAME);
+    UtilStrLower(package);
+    SaveAndSetLocale("", NULL);
+    bindtextdomain(package, locale_dir);
+    textdomain(package);
+ 
+    if ((dirp=opendir(locale_dir)) == NULL) {
+       fprintf(stderr, "Locale directory '%s' does not exist.  %s %s.%s.\n",
+             locale_dir, "Please specify locale direory with", TOOL_NAME,
+             "LocaleDir");
+    } else {
+       closedir(dirp);
+    }
+ }
+ #endif /* _ENABLE_NLS */
+ #endif /* ~_NO_LOCALE_SUPPORT */
+ 
  int JustInit(pszFile, pnNeedToCheckAutoExec)
     char *pszFile;
***************
*** 463,468 ****
     char tmp_filename[MAXPATHLENGTH+1];
     char full_name[MAXPATHLENGTH+1], *rest;
!    char *c_ptr=NULL, file_name[MAXPATHLENGTH+1];
!    int rc;
     int file_is_remote=FALSE, remote_buf_sz=0, is_html=FALSE;
     char remote_fname[MAXPATHLENGTH+1], *tmp_remote_fname=NULL;
--- 629,634 ----
     char tmp_filename[MAXPATHLENGTH+1];
     char full_name[MAXPATHLENGTH+1], *rest;
!    char *c_ptr=NULL, file_name[MAXPATHLENGTH+1], gzipped_fname[MAXPATHLENGTH+1];
!    int rc, gzipped_obj_file=FALSE;
     int file_is_remote=FALSE, remote_buf_sz=0, is_html=FALSE;
     char remote_fname[MAXPATHLENGTH+1], *tmp_remote_fname=NULL;
***************
*** 476,523 ****
     FILE *fp=NULL;
  
- #ifndef _NO_LOCALE_SUPPORT
-    setlocale(LC_ALL, "C");
- 
-    if (x11R6OrAbove) {
- #ifdef USE_XT_INITIALIZE
-       XtSetLanguageProc(NULL, NULL, NULL);
- #else /* _NO_LOCALE_SUPPORT */
-       char *c_ptr1=NULL;
- #ifndef _DONT_USE_PORTABLE_LOCALE
-       int use_portable_locale=TRUE;
- #else /* _DONT_USE_PORTABLE_LOCALE */
-       int use_portable_locale=FALSE;
- #endif /* ~_DONT_USE_PORTABLE_LOCALE */
- 
-       if (use_portable_locale) {
-          setlocale(LC_ALL, "C");
-       } else {
-          setlocale(LC_ALL, NULL);
-          if ((c_ptr1=((char*)getenv("LANG"))) != NULL) {
-             setlocale(LC_ALL, c_ptr1);
-          }
-          if ((c_ptr1=((char*)getenv("LC_COLLATE"))) != NULL) {
-             setlocale(LC_COLLATE, c_ptr1);
-          }
-          if ((c_ptr1=((char*)getenv("LC_CTYPE"))) != NULL) {
-             setlocale(LC_CTYPE, c_ptr1);
-          }
-          if ((c_ptr1=((char*)getenv("LC_NUMERIC"))) != NULL) {
-             setlocale(LC_NUMERIC, c_ptr1);
-          }
-          if ((c_ptr1=((char*)getenv("LC_TIME"))) != NULL) {
-             setlocale(LC_TIME, c_ptr1);
-          }
-          if ((c_ptr1=((char*)getenv("LC_MONETARY"))) != NULL) {
-             setlocale(LC_MONETARY, c_ptr1);
-          }
-          if (XSupportsLocale()) {
-             XSetLocaleModifiers(NULL);
-          }
-       }
- #endif /* USE_XT_INITIALIZE */
-    }
- #endif /* ~_NO_LOCALE_SUPPORT */
- 
  #ifdef USE_XAPPLRESDIR
  #ifdef XAPPLOADDIR_DEF
--- 642,645 ----
***************
*** 602,605 ****
--- 724,775 ----
     signal(SIGSEGV, EmergencySave);
  
+ #ifndef _NO_LOCALE_SUPPORT
+ #ifdef _ENABLE_NLS
+    InitLocale();
+ #endif /* _ENABLE_NLS */
+ #endif /* ~_NO_LOCALE_SUPPORT */
+    SaveAndSetLocale("C", NULL);
+ 
+    if (x11R6OrAbove) {
+ #ifndef _NO_LOCALE_SUPPORT
+ #ifdef USE_XT_INITIALIZE
+       XtSetLanguageProc(NULL, NULL, NULL);
+ #else /* ~USE_XT_INITIALIZE */
+       char *c_ptr1=NULL;
+ #ifndef _DONT_USE_PORTABLE_LOCALE
+       int use_portable_locale=TRUE;
+ #else /* _DONT_USE_PORTABLE_LOCALE */
+       int use_portable_locale=FALSE;
+ #endif /* ~_DONT_USE_PORTABLE_LOCALE */
+ 
+       if (use_portable_locale) {
+          setlocale(LC_ALL, "C");
+       } else {
+          setlocale(LC_ALL, NULL);
+          if ((c_ptr1=((char*)getenv("LANG"))) != NULL) {
+             setlocale(LC_ALL, c_ptr1);
+          }
+          if ((c_ptr1=((char*)getenv("LC_COLLATE"))) != NULL) {
+             setlocale(LC_COLLATE, c_ptr1);
+          }
+          if ((c_ptr1=((char*)getenv("LC_CTYPE"))) != NULL) {
+             setlocale(LC_CTYPE, c_ptr1);
+          }
+          if ((c_ptr1=((char*)getenv("LC_NUMERIC"))) != NULL) {
+             setlocale(LC_NUMERIC, c_ptr1);
+          }
+          if ((c_ptr1=((char*)getenv("LC_TIME"))) != NULL) {
+             setlocale(LC_TIME, c_ptr1);
+          }
+          if ((c_ptr1=((char*)getenv("LC_MONETARY"))) != NULL) {
+             setlocale(LC_MONETARY, c_ptr1);
+          }
+          if (XSupportsLocale()) {
+             XSetLocaleModifiers(NULL);
+          }
+       }
+ #endif /* USE_XT_INITIALIZE */
+ #endif /* ~_NO_LOCALE_SUPPORT */
+    }
     Setup();
     InitExtraWinInfo();
***************
*** 607,611 ****
     prTgifFoundColorInfo = FALSE;
  
!    *remote_fname = '\0';
  
     if (pszFile == NULL) {
--- 777,781 ----
     prTgifFoundColorInfo = FALSE;
  
!    *remote_fname = *gzipped_fname = '\0';
  
     if (pszFile == NULL) {
***************
*** 639,643 ****
                 UtilStrCpyN(remote_fname, MAXPATHLENGTH+1, final_url);
              }
!             if (UseExternalViewer(is_html, remote_fname, content_type,
                    tmp_remote_fname) != FALSE) {
                 unlink(tmp_remote_fname);
--- 809,816 ----
                 UtilStrCpyN(remote_fname, MAXPATHLENGTH+1, final_url);
              }
!             if (FileNameHasExtension(remote_fname, OBJ_FILE_TYPE,
!                   &gzipped_obj_file, NULL)) {
!                file_is_remote = TRUE;
!             } else if (UseExternalViewer(is_html, remote_fname, content_type,
                    tmp_remote_fname) != FALSE) {
                 unlink(tmp_remote_fname);
***************
*** 659,664 ****
     }
     if (*pszFile != '\0') {
!       int short_name=FALSE;
!       int obj_file=TRUE;
  
        *file_name = '\0';
--- 832,836 ----
     }
     if (*pszFile != '\0') {
!       int short_name=FALSE, obj_file=TRUE;
  
        *file_name = '\0';
***************
*** 674,681 ****
              file_is_remote = FALSE;
           } else {
!             if (FileNameHasExtension(remote_fname, SYM_FILE_TYPE, NULL)) {
                 obj_file = FALSE;
!             } else if (FileNameHasExtension(remote_fname, SYM_FILE_TYPE,
!                   NULL)) {
                 obj_file = FALSE;
              } else {
--- 846,853 ----
              file_is_remote = FALSE;
           } else {
!             if (FileNameHasExtension(remote_fname, SYM_FILE_TYPE, NULL, NULL)) {
                 obj_file = FALSE;
!             } else if (FileNameHasExtension(remote_fname, PIN_FILE_TYPE,
!                   NULL, NULL)) {
                 obj_file = FALSE;
              } else {
***************
*** 684,693 ****
           }
        } else {
!          if (FileNameHasExtension(pszFile, OBJ_FILE_TYPE, NULL)) {
              strcpy(file_name, pszFile);
-          } else if (FileNameHasExtension(pszFile, SYM_FILE_TYPE, NULL)) {
-             strcpy(file_name, pszFile);
              obj_file = FALSE;
!          } else if (FileNameHasExtension(pszFile, PIN_FILE_TYPE, NULL)) {
              strcpy(file_name, pszFile);
              obj_file = FALSE;
--- 856,878 ----
           }
        } else {
!          if (FileNameHasExtension(pszFile, OBJ_FILE_TYPE, &gzipped_obj_file,
!                NULL)) {
!             if (gzipped_obj_file) {
!                char *tmp_fname=NULL;
! 
!                if ((tmp_fname=GunzipFileIntoTemp(pszFile)) == NULL) {
!                   *file_name = '\0';
!                } else {
!                   strcpy(gzipped_fname, pszFile);
!                   strcpy(file_name, tmp_fname);
!                   free(tmp_fname);
!                }
!             } else {
!                strcpy(file_name, pszFile);
!             }
!          } else if (FileNameHasExtension(pszFile, SYM_FILE_TYPE, NULL, NULL)) {
              strcpy(file_name, pszFile);
              obj_file = FALSE;
!          } else if (FileNameHasExtension(pszFile, PIN_FILE_TYPE, NULL, NULL)) {
              strcpy(file_name, pszFile);
              obj_file = FALSE;
***************
*** 695,701 ****
              sprintf(file_name, "%s.%s", pszFile, OBJ_FILE_EXT);
           }
!          if ((short_name=IsPrefix(bootDir, file_name, &rest))) ++rest;
        }
- 
        if (*file_name != '\0' && (fp=fopen(file_name, "r")) == NULL) {
           DelAllPages();
--- 880,889 ----
              sprintf(file_name, "%s.%s", pszFile, OBJ_FILE_EXT);
           }
!          if (*gzipped_fname == '\0') {
!             if ((short_name=IsPrefix(bootDir, file_name, &rest))) ++rest;
!          } else {
!             if ((short_name=IsPrefix(bootDir, gzipped_fname, &rest))) ++rest;
!          }
        }
        if (*file_name != '\0' && (fp=fopen(file_name, "r")) == NULL) {
           DelAllPages();
***************
*** 740,744 ****
                 sprintf(gszMsgBox, "Loading '%s' ...", rest);
              } else {
!                sprintf(gszMsgBox, "Loading '%s' ...", file_name);
              }
           }
--- 928,936 ----
                 sprintf(gszMsgBox, "Loading '%s' ...", rest);
              } else {
!                if (*gzipped_fname == '\0') {
!                   sprintf(gszMsgBox, "Loading '%s' ...", file_name);
!                } else {
!                   sprintf(gszMsgBox, "Loading '%s' ...", gzipped_fname);
!                }
              }
           }
***************
*** 790,797 ****
                 if (!foundGoodStateObject) PasteString(remote_buf);
              } else {
!                if (*file_name == DIR_SEP) {
!                   strcpy(full_name, file_name);
                 } else {
!                   sprintf(full_name, "%s%c%s", curDir, DIR_SEP, file_name);
                 }
                 if (obj_file) {
--- 982,998 ----
                 if (!foundGoodStateObject) PasteString(remote_buf);
              } else {
!                if (*gzipped_fname == '\0') {
!                   if (*file_name == DIR_SEP) {
!                      strcpy(full_name, file_name);
!                   } else {
!                      sprintf(full_name, "%s%c%s", curDir, DIR_SEP, file_name);
!                   }
                 } else {
!                   if (*gzipped_fname == DIR_SEP) {
!                      strcpy(full_name, gzipped_fname);
!                   } else {
!                      sprintf(full_name, "%s%c%s", curDir, DIR_SEP,
!                            gzipped_fname);
!                   }
                 }
                 if (obj_file) {
***************
*** 807,811 ****
                 sprintf(gszMsgBox, "Current file is '%s'.", rest);
              } else {
!                sprintf(gszMsgBox, "Current file is '%s'.", file_name);
              }
              Msg(gszMsgBox);
--- 1008,1016 ----
                 sprintf(gszMsgBox, "Current file is '%s'.", rest);
              } else {
!                if (*gzipped_fname == '\0') {
!                   sprintf(gszMsgBox, "Current file is '%s'.", file_name);
!                } else {
!                   sprintf(gszMsgBox, "Current file is '%s'.", gzipped_fname);
!                }
              }
              Msg(gszMsgBox);
***************
*** 821,824 ****
--- 1026,1033 ----
              remote_buf = tmp_remote_fname = NULL;
              CommitNavigate();
+          } else {
+             if (*gzipped_fname != '\0') {
+                unlink(file_name);
+             }
           }
           if (foundGoodStateObject) {
***************
*** 877,911 ****
  
  #ifdef _TGIF_WB2
- #ifdef _TGIF_DBG_WB2
     if (!XPending(mainDisplay)) {
!       if (gstWBInfo.listening && gstWBInfo.listen_socket != (-1)) {
!          /*
!           * Receives one command at a time -- just like HTTP.
!           */
!          int csd=(-1);
  
           deserializingFile = TRUE;
-          if ((csd=AcceptWBSocket()) != (-1)) {
-             char *buf=NULL;
-             int buf_sz=0;
-             int status=HttpDoRead(csd, &buf, &buf_sz);
  
!             if (status == TG_REMOTE_STATUS_OK &&
!                   buf != NULL && *buf != '\0') {
!                char *psz_content=NULL, *psz_content_type=NULL;
!                int content_sz=0;
  
! fprintf(stderr, "Got %1d bytes!\n", buf_sz);
!                psz_content = HttpExtractText(buf, &content_sz, NULL,
!                      &psz_content_type);
!                if (psz_content != NULL) {
!                   ProcessRemoteCmd(psz_content, content_sz);
!                }
!                if (psz_content_type != NULL) UtilFree(psz_content_type);
!                if (psz_content != NULL) FreeRemoteBuf(psz_content);
!                FreeRemoteBuf(buf);
              }
!             shutdown(csd, 2);
!             close(csd);
           }
           deserializingFile = FALSE;
--- 1086,1110 ----
  
  #ifdef _TGIF_WB2
     if (!XPending(mainDisplay)) {
!       int flag=0, retry=TRUE;
  
+       while (retry && WBHasReadData(&flag, &retry)) {
+          char *buf=NULL;
+          int buf_sz=0;
+ 
           deserializingFile = TRUE;
  
!          if (RecvWBData(flag, &buf, &buf_sz)) {
!             char *psz_content=NULL, *psz_content_type=NULL;
!             int content_sz=0;
  
!             psz_content = HttpExtractText(buf, &content_sz, NULL,
!                   &psz_content_type);
!             if (psz_content != NULL) {
!                ProcessRemoteCmd(psz_content, content_sz);
              }
!             if (psz_content_type != NULL) UtilFree(psz_content_type);
!             if (psz_content != NULL) FreeRemoteBuf(psz_content);
!             FreeRemoteBuf(buf);
           }
           deserializingFile = FALSE;
***************
*** 913,917 ****
        return FALSE;
     }
! #endif /* _TGIF_DBG_WB2 */
     if (gnInputMethod != TGIM_NONE && tgIMExpectNextEvent(mainDisplay,
           drawWindow)) {
--- 1112,1116 ----
        return FALSE;
     }
!    gstWBInfo.CanProcessRemoteCmd = TRUE; /* is this right? */
     if (gnInputMethod != TGIM_NONE && tgIMExpectNextEvent(mainDisplay,
           drawWindow)) {
***************
*** 921,924 ****
--- 1120,1124 ----
        XNextEvent(mainDisplay, pXEvent);
     }
+    gstWBInfo.CanProcessRemoteCmd = FALSE;
  #endif /* _TGIF_WB2 */
  
*** menu.c.orig	Sun Apr 11 10:47:02 1999
--- menu.c	Sun Apr 11 10:47:03 1999
***************
*** 144,148 ****
        if (MenuX != NULL) {
           *MenuX = main_win_x + win_x + x - 3 -
!                (menuFontPtr==NULL ? 0 : (menuFontWidth>>1));
           if (!threeDLook) {
              *MenuX += 4;
--- 144,149 ----
        if (MenuX != NULL) {
           *MenuX = main_win_x + win_x + x - 3 -
!                ((menuFontSet==NULL && menuFontPtr==NULL) ? 0 :
!                (menuFontWidth>>1));
           if (!threeDLook) {
              *MenuX += 4;
***************
*** 154,161 ****
     }
     if (TextBBox != NULL) {
!       TextBBox->ltx = x-(menuFontPtr==NULL ? 0 : (menuFontWidth>>1));
!       TextBBox->rbx = x+w+(menuFontPtr==NULL ? 0 : menuFontWidth);
!       TextBBox->lty = h-(menuFontPtr == NULL ? initialMenubarWindowH :
!             menuFontHeight);
        TextBBox->rby = h;
     }
--- 155,164 ----
     }
     if (TextBBox != NULL) {
!       TextBBox->ltx = x-((menuFontSet==NULL && menuFontPtr==NULL) ? 0 :
!             (menuFontWidth>>1));
!       TextBBox->rbx = x+w+((menuFontSet==NULL && menuFontPtr==NULL) ? 0 :
!             menuFontWidth);
!       TextBBox->lty = h-((menuFontSet==NULL && menuFontPtr == NULL) ?
!             initialMenubarWindowH : menuFontHeight);
        TextBBox->rby = h;
     }
***************
*** 163,166 ****
--- 166,180 ----
  
  static
+ int MyMenuTextWidth(psz_str, len)
+    char *psz_str;
+    int len;
+ {
+    if (menuFontSet != NULL) {
+       return XmbTextEscapement(menuFontSet, psz_str, len);
+    }
+    return XTextWidth(menuFontPtr, psz_str, len);
+ }
+ 
+ static
  int WhichMenubarItem(X, Y, MenuX, MenuY, TextBBox)
     int X, Y, *MenuX, *MenuY;
***************
*** 168,172 ****
  {
     int i, x=0, w=0, h=0, len=0, gap=0, padding=(windowPadding>>1);
!    int min_x=(menuFontPtr==NULL ? 2 : menuFontWidth);
  
     if (noMenubar ||
--- 182,186 ----
  {
     int i, x=0, w=0, h=0, len=0, gap=0, padding=(windowPadding>>1);
!    int min_x=((menuFontSet==NULL && menuFontPtr==NULL) ? 2 : menuFontWidth);
  
     if (noMenubar ||
***************
*** 174,178 ****
        return INVALID;
     }
!    if (menuFontPtr != NULL) {
        x = menuFontWidth;
        h = menuFontHeight;
--- 188,192 ----
        return INVALID;
     }
!    if (menuFontSet != NULL || menuFontPtr != NULL) {
        x = menuFontWidth;
        h = menuFontHeight;
***************
*** 181,186 ****
        h += padding;
        for (i=0; i < gnNumMenubarItems; i++) {
!          len = strlen(gpMenubarItemInfos[i].menu_str);
!          w = XTextWidth(menuFontPtr, gpMenubarItemInfos[i].menu_str, len);
           if (x+w+padding >= menubarWindowW) {
              if (Y < h) return INVALID;
--- 195,200 ----
        h += padding;
        for (i=0; i < gnNumMenubarItems; i++) {
!          len = strlen(_(gpMenubarItemInfos[i].menu_str));
!          w = MyMenuTextWidth(_(gpMenubarItemInfos[i].menu_str), len);
           if (x+w+padding >= menubarWindowW) {
              if (Y < h) return INVALID;
***************
*** 201,205 ****
        h += padding;
        for (i=0; i < gnNumMenubarItems; i++) {
!          len = strlen(gpMenubarItemInfos[i].menu_str);
           w = defaultFontWidth*len;
           if (x+w+padding >= menubarWindowW) {
--- 215,219 ----
        h += padding;
        for (i=0; i < gnNumMenubarItems; i++) {
!          len = strlen(_(gpMenubarItemInfos[i].menu_str));
           w = defaultFontWidth*len;
           if (x+w+padding >= menubarWindowW) {
***************
*** 225,229 ****
     int i, x=0, w=0, h=0, len=0, gap=0, padding=(windowPadding>>1);
  
!    if (menuFontPtr != NULL) {
        x = menuFontWidth;
        h = menuFontHeight;
--- 239,243 ----
     int i, x=0, w=0, h=0, len=0, gap=0, padding=(windowPadding>>1);
  
!    if (menuFontSet != NULL || menuFontPtr != NULL) {
        x = menuFontWidth;
        h = menuFontHeight;
***************
*** 232,237 ****
        h += padding;
        for (i=0; i < gnNumMenubarItems; i++) {
!          len = strlen(gpMenubarItemInfos[i].menu_str);
!          w = XTextWidth(menuFontPtr, gpMenubarItemInfos[i].menu_str, len);
           if (x+w+padding >= menubarWindowW) {
              x = menuFontWidth+padding;
--- 246,251 ----
        h += padding;
        for (i=0; i < gnNumMenubarItems; i++) {
!          len = strlen(_(gpMenubarItemInfos[i].menu_str));
!          w = MyMenuTextWidth(_(gpMenubarItemInfos[i].menu_str), len);
           if (x+w+padding >= menubarWindowW) {
              x = menuFontWidth+padding;
***************
*** 251,255 ****
        h += padding;
        for (i=0; i < gnNumMenubarItems; i++) {
!          len = strlen(gpMenubarItemInfos[i].menu_str);
           w = defaultFontWidth*len;
           if (x+w+padding >= menubarWindowW) {
--- 265,269 ----
        h += padding;
        for (i=0; i < gnNumMenubarItems; i++) {
!          len = strlen(_(gpMenubarItemInfos[i].menu_str));
           w = defaultFontWidth*len;
           if (x+w+padding >= menubarWindowW) {
***************
*** 566,569 ****
--- 580,598 ----
  
  static
+ void MyDrawMenuString(dpy, win, gc, x, baseline_y, menu_str, len)
+    Display *dpy;
+    Window win;
+    GC gc;
+    int x, baseline_y, len;
+    char *menu_str;
+ {
+    if (menuFontSet != NULL) {
+       XmbDrawString(dpy, win, menuFontSet, gc, x, baseline_y, menu_str, len);
+    } else {
+       XDrawString(dpy, win, gc, x, baseline_y, menu_str, len);
+    }
+ }
+ 
+ static
  void TgDrawTextMenuItem(menu, menu_item)
     TgMenu *menu;
***************
*** 629,634 ****
        return;
     }
!    baseline = menu_item->bbox.lty +
!          (menuFontPtr==NULL ? defaultFontAsc : menuFontAsc);
     x = menu->check_start;
     if ((flags & (TGMU_HAS_CHECK|TGMU_HAS_RADIO)) != 0 && checked) {
--- 658,663 ----
        return;
     }
!    baseline = menu_item->bbox.lty + ((menuFontSet==NULL && menuFontPtr==NULL) ?
!          defaultFontAsc : menuFontAsc);
     x = menu->check_start;
     if ((flags & (TGMU_HAS_CHECK|TGMU_HAS_RADIO)) != 0 && checked) {
***************
*** 664,681 ****
        if (state == TGBS_GRAYED) {
           XSetForeground(mainDisplay, textMenuGC, myWhitePixel);
!          XDrawString(mainDisplay, menu->window, textMenuGC, x+1,
!                baseline+1, menu_item->menu_str, strlen(menu_item->menu_str));
        }
        XSetForeground(mainDisplay, textMenuGC, fg_pixels[state]);
!       XDrawString(mainDisplay, menu->window, textMenuGC, x,
!             baseline, menu_item->menu_str, strlen(menu_item->menu_str));
     } else {
        if (state == TGBS_GRAYED) {
!          XDrawString(mainDisplay, menu->window, revGrayGC, x,
!                baseline, menu_item->menu_str, strlen(menu_item->menu_str));
        } else {
           XSetForeground(mainDisplay, textMenuGC, fg_pixels[state]);
!          XDrawString(mainDisplay, menu->window, textMenuGC, x,
!                baseline, menu_item->menu_str, strlen(menu_item->menu_str));
        }
     }
--- 693,711 ----
        if (state == TGBS_GRAYED) {
           XSetForeground(mainDisplay, textMenuGC, myWhitePixel);
!          MyDrawMenuString(mainDisplay, menu->window, textMenuGC, x+1,
!                baseline+1, _(menu_item->menu_str),
!                strlen(_(menu_item->menu_str)));
        }
        XSetForeground(mainDisplay, textMenuGC, fg_pixels[state]);
!       MyDrawMenuString(mainDisplay, menu->window, textMenuGC, x,
!             baseline, _(menu_item->menu_str), strlen(_(menu_item->menu_str)));
     } else {
        if (state == TGBS_GRAYED) {
!          MyDrawMenuString(mainDisplay, menu->window, revGrayGC, x, baseline,
!                _(menu_item->menu_str), strlen(_(menu_item->menu_str)));
        } else {
           XSetForeground(mainDisplay, textMenuGC, fg_pixels[state]);
!          MyDrawMenuString(mainDisplay, menu->window, textMenuGC, x, baseline,
!                _(menu_item->menu_str), strlen(_(menu_item->menu_str)));
        }
     }
***************
*** 684,693 ****
        if (state == TGBS_GRAYED) {
           XSetForeground(mainDisplay, textMenuGC, myWhitePixel);
!          XDrawString(mainDisplay, menu->window, textMenuGC, x+1, baseline+1,
!                menu_item->detail.shortcut_str,
                 strlen(menu_item->detail.shortcut_str));
        }
        XSetForeground(mainDisplay, textMenuGC, fg_pixels[state]);
!       XDrawString(mainDisplay, menu->window, textMenuGC, x, baseline,
              menu_item->detail.shortcut_str,
              strlen(menu_item->detail.shortcut_str));
--- 714,723 ----
        if (state == TGBS_GRAYED) {
           XSetForeground(mainDisplay, textMenuGC, myWhitePixel);
!          MyDrawMenuString(mainDisplay, menu->window, textMenuGC, x+1,
!                baseline+1, menu_item->detail.shortcut_str,
                 strlen(menu_item->detail.shortcut_str));
        }
        XSetForeground(mainDisplay, textMenuGC, fg_pixels[state]);
!       MyDrawMenuString(mainDisplay, menu->window, textMenuGC, x, baseline,
              menu_item->detail.shortcut_str,
              strlen(menu_item->detail.shortcut_str));
***************
*** 1296,1303 ****
        char *menu_str=menu_item->menu_str;
  
!       if (menuFontPtr != NULL) {
!          *pn_str_w = XTextWidth(menuFontPtr, menu_str, strlen(menu_str));
        } else {
!          *pn_str_w = defaultFontWidth * strlen(menu_str);
        }
     }
--- 1326,1333 ----
        char *menu_str=menu_item->menu_str;
  
!       if (menuFontSet != NULL || menuFontPtr != NULL) {
!          *pn_str_w = MyMenuTextWidth(_(menu_str), strlen(_(menu_str)));
        } else {
!          *pn_str_w = defaultFontWidth * strlen(_(menu_str));
        }
     }
***************
*** 1306,1311 ****
           char *shortcut_str=menu_item->detail.shortcut_str;
  
!          if (menuFontPtr != NULL) {
!             *pn_shortcut_w = XTextWidth(menuFontPtr, shortcut_str,
                    strlen(shortcut_str));
           } else {
--- 1336,1342 ----
           char *shortcut_str=menu_item->detail.shortcut_str;
  
!          /* don't translate shortuct_str */
!          if (menuFontSet != NULL || menuFontPtr != NULL) {
!             *pn_shortcut_w = MyMenuTextWidth(shortcut_str,
                    strlen(shortcut_str));
           } else {
***************
*** 1403,1407 ****
     switch (menu->type) {
     case TGMUTYPE_TEXT:
!       if (menuFontPtr != NULL) {
           menu_item->bbox.rby = menu_item->bbox.lty+menuFontHeight;
        } else {
--- 1434,1438 ----
     switch (menu->type) {
     case TGMUTYPE_TEXT:
!       if (menuFontSet != NULL || menuFontPtr != NULL) {
           menu_item->bbox.rby = menu_item->bbox.lty+menuFontHeight;
        } else {
***************
*** 2029,2032 ****
--- 2060,2067 ----
     values.background = (threeDLook ? myLtGryPixel : myBgPixel);
     values.fill_style = FillSolid;
+    /*
+     * If (menuFontSet) is not NULL, it's okay to set values.font to
+     *       whatever because it won't get used.
+     */
     values.font = (menuFontPtr==NULL ? defaultFontPtr->fid : menuFontPtr->fid);
     textMenuGC = XCreateGC(mainDisplay, rootWindow,
***************
*** 2239,2243 ****
     BuildMenubarInfo();
  
!    if (menuFontPtr != NULL) {
        x = menuFontWidth;
        h = menuFontHeight;
--- 2274,2278 ----
     BuildMenubarInfo();
  
!    if (menuFontSet != NULL || menuFontPtr != NULL) {
        x = menuFontWidth;
        h = menuFontHeight;
***************
*** 2246,2251 ****
        h += padding;
        for (i=0; i < gnNumMenubarItems; i++) {
!          w = XTextWidth(menuFontPtr, gpMenubarItemInfos[i].menu_str,
!                strlen(gpMenubarItemInfos[i].menu_str));
           if (x+w+padding >= menubarWindowW) {
              x = menuFontWidth+padding;
--- 2281,2286 ----
        h += padding;
        for (i=0; i < gnNumMenubarItems; i++) {
!          w = MyMenuTextWidth(_(gpMenubarItemInfos[i].menu_str),
!                strlen(_(gpMenubarItemInfos[i].menu_str)));
           if (x+w+padding >= menubarWindowW) {
              x = menuFontWidth+padding;
***************
*** 2263,2267 ****
        h += padding;
        for (i=0; i < gnNumMenubarItems; i++) {
!          w = defaultFontWidth*strlen(gpMenubarItemInfos[i].menu_str);
           if (x+w+padding >= menubarWindowW) {
              x = 2+padding;
--- 2298,2302 ----
        h += padding;
        for (i=0; i < gnNumMenubarItems; i++) {
!          w = defaultFontWidth*strlen(_(gpMenubarItemInfos[i].menu_str));
           if (x+w+padding >= menubarWindowW) {
              x = 2+padding;
***************
*** 2281,2284 ****
--- 2316,2320 ----
     struct BBRec *bbox;
     int highlight;
+    /* HighLightMenubarString() will use _(item_str) internally */
  {
     if (threeDLook) {
***************
*** 2305,2312 ****
              bbox->ltx-2, bbox->lty, bbox->rbx-bbox->ltx+4, bbox->rby-bbox->lty);
        XSetForeground(mainDisplay, textMenuGC, fg_pixel);
!       XDrawString(mainDisplay, menubarWindow, textMenuGC,
!             bbox->ltx+(menuFontPtr==NULL ? 0 : (menuFontWidth>>1)),
!             (menuFontPtr==NULL ? defaultFontAsc : menuFontAsc)+bbox->lty,
!             item_str, strlen(item_str));
     }
  }
--- 2341,2352 ----
              bbox->ltx-2, bbox->lty, bbox->rbx-bbox->ltx+4, bbox->rby-bbox->lty);
        XSetForeground(mainDisplay, textMenuGC, fg_pixel);
!       if (menuFontSet != NULL || menuFontPtr != NULL) {
!          MyDrawMenuString(mainDisplay, menubarWindow, textMenuGC,
!                bbox->ltx+(menuFontWidth>>1), menuFontAsc+bbox->lty,
!                _(item_str), strlen(_(item_str)));
!       } else {
!          MyDrawMenuString(mainDisplay, menubarWindow, textMenuGC, bbox->ltx,
!                defaultFontAsc+bbox->lty, _(item_str), strlen(_(item_str)));
!       }
     }
  }
***************
*** 2319,2323 ****
     XClearWindow(mainDisplay, menubarWindow);
  
!    if (menuFontPtr != NULL) {
        x = menuFontWidth;
        y = menuFontAsc;
--- 2359,2363 ----
     XClearWindow(mainDisplay, menubarWindow);
  
!    if (menuFontSet != NULL || menuFontPtr != NULL) {
        x = menuFontWidth;
        y = menuFontAsc;
***************
*** 2326,2333 ****
        y += padding;
  
!       XSetFont(mainDisplay, defaultGC, menuFontPtr->fid);
        for (i=0; i < gnNumMenubarItems; i++) {
!          len = strlen(gpMenubarItemInfos[i].menu_str);
!          w = XTextWidth(menuFontPtr, gpMenubarItemInfos[i].menu_str, len);
           if (x+w+padding >= menubarWindowW) {
              x = menuFontWidth+padding;
--- 2366,2375 ----
        y += padding;
  
!       if (menuFontPtr != NULL) {
!          XSetFont(mainDisplay, defaultGC, menuFontPtr->fid);
!       }
        for (i=0; i < gnNumMenubarItems; i++) {
!          len = strlen(_(gpMenubarItemInfos[i].menu_str));
!          w = MyMenuTextWidth(_(gpMenubarItemInfos[i].menu_str), len);
           if (x+w+padding >= menubarWindowW) {
              x = menuFontWidth+padding;
***************
*** 2334,2342 ****
              y += menuFontHeight+padding;
           }
!          XDrawString(mainDisplay, menubarWindow, defaultGC, x+padding,
!                y+padding, gpMenubarItemInfos[i].menu_str, len);
           x += w+gap+padding;
        }
!       XSetFont(mainDisplay, defaultGC, defaultFontPtr->fid);
     } else {
        x = 2;
--- 2376,2386 ----
              y += menuFontHeight+padding;
           }
!          MyDrawMenuString(mainDisplay, menubarWindow, defaultGC, x+padding,
!                y+padding, _(gpMenubarItemInfos[i].menu_str), len);
           x += w+gap+padding;
        }
!       if (menuFontPtr != NULL) {
!          XSetFont(mainDisplay, defaultGC, defaultFontPtr->fid);
!       }
     } else {
        x = 2;
***************
*** 2347,2351 ****
  
        for (i=0; i < gnNumMenubarItems; i++) {
!          len = strlen(gpMenubarItemInfos[i].menu_str);
           w = defaultFontWidth*len;
           if (x+w+padding >= menubarWindowW) {
--- 2391,2395 ----
  
        for (i=0; i < gnNumMenubarItems; i++) {
!          len = strlen(_(gpMenubarItemInfos[i].menu_str));
           w = defaultFontWidth*len;
           if (x+w+padding >= menubarWindowW) {
***************
*** 2353,2358 ****
              y += initialMenubarWindowH+padding;
           }
!          XDrawString(mainDisplay, menubarWindow, defaultGC, x+padding,
!                y+padding, gpMenubarItemInfos[i].menu_str, len);
           x += w+gap+padding;
        }
--- 2397,2402 ----
              y += initialMenubarWindowH+padding;
           }
!          MyDrawMenuString(mainDisplay, menubarWindow, defaultGC, x+padding,
!                y+padding, _(gpMenubarItemInfos[i].menu_str), len);
           x += w+gap+padding;
        }
***************
*** 2368,2373 ****
     if (excludeMenubarIndex != INVALID) {
        struct BBRec text_bbox;
!       int exclude_gap=(menuFontPtr==NULL ? (defaultFontWidth<<1) :
!             (menuFontWidth<<1));
  
        SetBBRec(&text_bbox,
--- 2412,2417 ----
     if (excludeMenubarIndex != INVALID) {
        struct BBRec text_bbox;
!       int exclude_gap=((menuFontSet==NULL && menuFontPtr==NULL) ?
!             (defaultFontWidth<<1) : (menuFontWidth<<1));
  
        SetBBRec(&text_bbox,
***************
*** 2376,2379 ****
--- 2420,2424 ----
              excludeMenubarWinBBox.rbx-2-windowPadding-exclude_gap,
              excludeMenubarWinBBox.rby-2-windowPadding);
+       /* HighLightMenubarString() doesn't need _() */
        HighLightMenubarString(gpMenubarItemInfos[excludeMenubarIndex].menu_str,
              &text_bbox, TRUE);
***************
*** 2387,2395 ****
  {
     int rc=BAD;
!    int exclude_gap=(menuFontPtr==NULL ? (defaultFontWidth<<1) :
!          (menuFontWidth<<1));
  
     while (rc == BAD) {
        if (index != INVALID) {
           HighLightMenubarString(gpMenubarItemInfos[index].menu_str, text_bbox,
                 TRUE);
--- 2432,2441 ----
  {
     int rc=BAD;
!    int exclude_gap=((menuFontSet==NULL && menuFontPtr==NULL) ?
!          (defaultFontWidth<<1) : (menuFontWidth<<1));
  
     while (rc == BAD) {
        if (index != INVALID) {
+          /* HighLightMenubarString() doesn't need _() */
           HighLightMenubarString(gpMenubarItemInfos[index].menu_str, text_bbox,
                 TRUE);
***************
*** 2433,2436 ****
--- 2479,2483 ----
        }
        if (index != INVALID) {
+          /* HighLightMenubarString() doesn't need _() */
           HighLightMenubarString(gpMenubarItemInfos[index].menu_str, text_bbox,
                 FALSE);
***************
*** 2472,2476 ****
--- 2519,2525 ----
        if (curRaisedMenuItem != INVALID) {
           struct BBRec text_bbox;
+ 
           GetMenubarItemInfo(curRaisedMenuItem, NULL, NULL, &text_bbox);
+          /* HighLightMenubarString() doesn't need _() */
           HighLightMenubarString(gpMenubarItemInfos[curRaisedMenuItem].menu_str,
                 &text_bbox, FALSE);
***************
*** 2493,2496 ****
--- 2542,2546 ----
              if (curRaisedMenuItem != INVALID) {
                 GetMenubarItemInfo(curRaisedMenuItem, NULL, NULL, &text_bbox);
+                /* HighLightMenubarString() doesn't need _() */
                 HighLightMenubarString(
                       gpMenubarItemInfos[curRaisedMenuItem].menu_str,
***************
*** 2500,2503 ****
--- 2550,2554 ----
              if (index != INVALID) {
                 GetMenubarItemInfo(index, NULL, NULL, &text_bbox);
+                /* HighLightMenubarString() doesn't need _() */
                 HighLightMenubarString(gpMenubarItemInfos[index].menu_str,
                       &text_bbox, TRUE);
***************
*** 2531,2534 ****
--- 2582,2586 ----
              if (curRaisedMenuItem != INVALID) {
                 GetMenubarItemInfo(curRaisedMenuItem, NULL, NULL, &text_bbox);
+                /* HighLightMenubarString() doesn't need _() */
                 HighLightMenubarString(
                       gpMenubarItemInfos[curRaisedMenuItem].menu_str,
***************
*** 2537,2540 ****
--- 2589,2593 ----
              }
              GetMenubarItemInfo(index, NULL, NULL, &text_bbox);
+             /* HighLightMenubarString() doesn't need _() */
              HighLightMenubarString(gpMenubarItemInfos[index].menu_str,
                    &text_bbox, TRUE);
*** menuinfo.c.orig	Sun Apr 11 10:47:04 1999
--- menuinfo.c	Sun Apr 11 10:47:04 1999
***************
*** 217,222 ****
  
  static TgMenuItemInfo pageStyleMenuItemInfo[] = {
!    { "Portrait", NULL, "Portrait page style", NULL, CMDID_PORTRAITMODE },
!    { "Landscape", NULL, "Lanscape page style", NULL,
       CMDID_LANDSCAPEMODE },
     { NULL, NULL, NULL, NULL, INVALID }
--- 217,222 ----
  
  static TgMenuItemInfo pageStyleMenuItemInfo[] = {
!    { N_("Portrait"), NULL, "Portrait page style", NULL, CMDID_PORTRAITMODE },
!    { N_("Landscape"), NULL, "Lanscape page style", NULL,
       CMDID_LANDSCAPEMODE },
     { NULL, NULL, NULL, NULL, INVALID }
***************
*** 230,252 ****
  
  static TgMenuItemInfo fontStyleMenuItemInfo[] = {
!    { "Roman", "Alt+Cntrl+o", "Roman text style", NULL,
       CMDID_CHANGEALLSELFONTSTYLE },
!    { "Bold", "Alt+Cntrl+b", "Bold text style", NULL,
       CMDID_CHANGEALLSELFONTSTYLE },
!    { "Italic", "Alt+Cntrl+t", "Italic text style", NULL,
       CMDID_CHANGEALLSELFONTSTYLE },
!    { "BoldItalic", "Alt+Cntrl+p", "Bold-italic text style", NULL,
       CMDID_CHANGEALLSELFONTSTYLE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Left", "Alt+Cntrl+l", "Left justified text", NULL,
       CMDID_CHANGEALLSELFONTJUST },
!    { "Center", "Alt+Cntrl+c", "Center justified text", NULL,
       CMDID_CHANGEALLSELFONTJUST },
!    { "Right", "Alt+Cntrl+r", "Right justified text", NULL,
       CMDID_CHANGEALLSELFONTJUST },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "NoUnderlined", NULL, "No underlined text", NULL,
       CMDID_CHANGEALLSELFONTUNDERLINE },
!    { "Underlined", NULL, "Underlined text", NULL,
       CMDID_CHANGEALLSELFONTUNDERLINE },
     { NULL, NULL, NULL, NULL, INVALID }
--- 230,252 ----
  
  static TgMenuItemInfo fontStyleMenuItemInfo[] = {
!    { N_("Roman"), "Alt+Cntrl+o", "Roman text style", NULL,
       CMDID_CHANGEALLSELFONTSTYLE },
!    { N_("Bold"), "Alt+Cntrl+b", "Bold text style", NULL,
       CMDID_CHANGEALLSELFONTSTYLE },
!    { N_("Italic"), "Alt+Cntrl+t", "Italic text style", NULL,
       CMDID_CHANGEALLSELFONTSTYLE },
!    { N_("BoldItalic"), "Alt+Cntrl+p", "Bold-italic text style", NULL,
       CMDID_CHANGEALLSELFONTSTYLE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Left"), "Alt+Cntrl+l", "Left justified text", NULL,
       CMDID_CHANGEALLSELFONTJUST },
!    { N_("Center"), "Alt+Cntrl+c", "Center justified text", NULL,
       CMDID_CHANGEALLSELFONTJUST },
!    { N_("Right"), "Alt+Cntrl+r", "Right justified text", NULL,
       CMDID_CHANGEALLSELFONTJUST },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("NoUnderlined"), NULL, "No underlined text", NULL,
       CMDID_CHANGEALLSELFONTUNDERLINE },
!    { N_("Underlined"), NULL, "Underlined text", NULL,
       CMDID_CHANGEALLSELFONTUNDERLINE },
     { NULL, NULL, NULL, NULL, INVALID }
***************
*** 258,284 ****
  
  static TgMenuItemInfo stackedPageMenuItemInfo[] = {
!    { "NextPage", NULL, "Go to next page", NULL, CMDID_NEXTPAGE },
!    { "PrevPage", NULL, "Go to previous page", NULL, CMDID_PREVPAGE },
!    { "GotoPage...", NULL, "Go to a specified page", NULL, CMDID_GOTOPAGE },
!    { "NamePages...", NULL, "Assign names to pages", NULL, CMDID_NAMEPAGES },
!    { "EditPageFileNames...", NULL,
       "Assign file names to pages to be used for PrintOneFilePerPage()", NULL,
       CMDID_EDITPAGEFILENAMES },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "AddPageBefore...", NULL, "Add a page before the current page", NULL,
       CMDID_ADDPAGEBEFORE },
!    { "AddPageAfter...", NULL, "Add a page after the current page", NULL,
       CMDID_ADDPAGEAFTER },
!    { "DeleteCurPage", NULL, "Delete the current page", NULL,
       CMDID_DELETECURPAGE },
!    { "DeletePages...", NULL, "Delete user-specified pages", NULL,
       CMDID_DELETEPAGES },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "PrintOnePage", NULL, "Print the curret page", NULL, CMDID_PRINTONEPAGE },
!    { "PrintOneFilePerPage", NULL, "Print into a separate file for each page",
       NULL, CMDID_PRINTONEFILEPERPAGE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SpecifyPaperSize...", NULL, "Set the physical size of the paper", NULL,
!      CMDID_SPECIFYPAPERSIZE },
     { NULL, NULL, NULL, NULL, INVALID }
  };
--- 258,286 ----
  
  static TgMenuItemInfo stackedPageMenuItemInfo[] = {
!    { N_("NextPage"), NULL, "Go to next page", NULL, CMDID_NEXTPAGE },
!    { N_("PrevPage"), NULL, "Go to previous page", NULL, CMDID_PREVPAGE },
!    { N_("GotoPage..."), NULL, "Go to a specified page", NULL, CMDID_GOTOPAGE },
!    { N_("NamePages..."), NULL, "Assign names to pages", NULL, CMDID_NAMEPAGES },
!    { N_("EditPageFileNames..."), NULL,
       "Assign file names to pages to be used for PrintOneFilePerPage()", NULL,
       CMDID_EDITPAGEFILENAMES },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("AddPageBefore..."), NULL, "Add a page before the current page", NULL,
       CMDID_ADDPAGEBEFORE },
!    { N_("AddPageAfter..."), NULL, "Add a page after the current page", NULL,
       CMDID_ADDPAGEAFTER },
!    { N_("DeleteCurPage"), NULL, "Delete the current page", NULL,
       CMDID_DELETECURPAGE },
!    { N_("DeletePages..."), NULL, "Delete user-specified pages", NULL,
       CMDID_DELETEPAGES },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("PrintOnePage"), NULL, "Print the curret page", NULL,
!      CMDID_PRINTONEPAGE },
!    { N_("PrintOneFilePerPage"), NULL,
!      "Print into a separate file for each page",
       NULL, CMDID_PRINTONEFILEPERPAGE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SpecifyPaperSize..."), NULL, "Set the physical size of the paper",
!      NULL, CMDID_SPECIFYPAPERSIZE },
     { NULL, NULL, NULL, NULL, INVALID }
  };
***************
*** 287,298 ****
  
  static TgMenuItemInfo tiledPageMenuItemInfo[] = {
!    { "TogglePageLineShown", NULL, "Toggle the showing of page boundaries", NULL,
!      CMDID_TOGGLEPAGELINESHOWN },
!    { "SpecifyDrawingSize...", NULL, "Change the drawing size", NULL,
       CMDID_SPECIFYDRAWINGSIZE },
!    { "PrintOnePage", NULL, "Select and print one of the pages", NULL,
       CMDID_PRINTONEPAGE },
!    { "SpecifyPaperSize...", NULL, "Set the physical size of the paper", NULL,
!      CMDID_SPECIFYPAPERSIZE },
     { NULL, NULL, NULL, NULL, INVALID }
  };
--- 289,300 ----
  
  static TgMenuItemInfo tiledPageMenuItemInfo[] = {
!    { N_("TogglePageLineShown"), NULL, "Toggle the showing of page boundaries",
!      NULL, CMDID_TOGGLEPAGELINESHOWN },
!    { N_("SpecifyDrawingSize..."), NULL, "Change the drawing size", NULL,
       CMDID_SPECIFYDRAWINGSIZE },
!    { N_("PrintOnePage"), NULL, "Select and print one of the pages", NULL,
       CMDID_PRINTONEPAGE },
!    { N_("SpecifyPaperSize..."), NULL, "Set the physical size of the paper",
!      NULL, CMDID_SPECIFYPAPERSIZE },
     { NULL, NULL, NULL, NULL, INVALID }
  };
***************
*** 301,307 ****
  
  static TgMenuItemInfo pageMenuItemInfo[] = {
!    { "StackedPage", TGMUITEM_PINNABLESUBMENU,
       "StackedPage Menu", &stackedPageMenuInfo, MENU_STACKEDPAGE },
!    { "TiledPage", TGMUITEM_PINNABLESUBMENU,
       "TiledPage Menu", &tiledPageMenuInfo, MENU_TILEDPAGE },
     { NULL, NULL, NULL, NULL, INVALID }
--- 303,309 ----
  
  static TgMenuItemInfo pageMenuItemInfo[] = {
!    { N_("StackedPage"), TGMUITEM_PINNABLESUBMENU,
       "StackedPage Menu", &stackedPageMenuInfo, MENU_STACKEDPAGE },
!    { N_("TiledPage"), TGMUITEM_PINNABLESUBMENU,
       "TiledPage Menu", &tiledPageMenuInfo, MENU_TILEDPAGE },
     { NULL, NULL, NULL, NULL, INVALID }
***************
*** 310,326 ****
  
  static TgMenuItemInfo reduceColorMenuItemInfo[] = {
!    { "ReduceColors...", NULL, "Reduce the number of colors of a selected image",
       NULL, CMDID_REDUCECOLORS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SetDefaultColorLevels...", NULL,
       "Set the number of R G B color levels for the ``standard colors''", NULL,
       CMDID_SETDEFAULTCOLORLEVELS },
!    { "ReduceToPixmapColors...", NULL,
       "Reduce the colors of a selected image to a the colors in an XPM file",
       NULL, CMDID_REDUCETOPIXMAPCOLORS },
!    { "ReduceToDefaultColors", NULL,
       "Reduce the colors of a selected image to standard colors", NULL,
       CMDID_REDUCETODEFAULTCOLORs },
!    { "DefaultErrorDiffuse", NULL,
       "Error diffuse to reduce colors of a selected image to standard colors",
       NULL, CMDID_DEFAULTERRORDIFFUSE },
--- 312,329 ----
  
  static TgMenuItemInfo reduceColorMenuItemInfo[] = {
!    { N_("ReduceColors..."), NULL,
!      "Reduce the number of colors of a selected image",
       NULL, CMDID_REDUCECOLORS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SetDefaultColorLevels..."), NULL,
       "Set the number of R G B color levels for the ``standard colors''", NULL,
       CMDID_SETDEFAULTCOLORLEVELS },
!    { N_("ReduceToPixmapColors..."), NULL,
       "Reduce the colors of a selected image to a the colors in an XPM file",
       NULL, CMDID_REDUCETOPIXMAPCOLORS },
!    { N_("ReduceToDefaultColors"), NULL,
       "Reduce the colors of a selected image to standard colors", NULL,
       CMDID_REDUCETODEFAULTCOLORs },
!    { N_("DefaultErrorDiffuse"), NULL,
       "Error diffuse to reduce colors of a selected image to standard colors",
       NULL, CMDID_DEFAULTERRORDIFFUSE },
***************
*** 331,348 ****
  
  static TgMenuItemInfo effectsMenuItemInfo[] = {
!    { "EdgeDetect", NULL, "Perform edge-detection on a selected image", NULL,
       CMDID_EDGEDETECT },
!    { "Emboss", NULL, "Convert a selected image to gray and then emboss", NULL,
!      CMDID_EMBOSS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Spread...", NULL, "Spread the pixels of a selected image around", NULL,
!      CMDID_SPREAD },
!    { "Sharpen", NULL, "Sharpen a selected image", NULL, CMDID_SHARPEN },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Blur(3x3)", NULL, "Blur a selected image using a 3 by 3 filter", NULL,
       CMDID_BLUR3 },
!    { "Blur(5x5)", NULL, "Blur a selected image using a 5 by 5 filter", NULL,
       CMDID_BLUR5 },
!    { "Blur(7x7)", NULL, "Blur a selected image using a 7 by 7 filter", NULL,
       CMDID_BLUR7 },
     { NULL, NULL, NULL, NULL, INVALID }
--- 334,351 ----
  
  static TgMenuItemInfo effectsMenuItemInfo[] = {
!    { N_("EdgeDetect"), NULL, "Perform edge-detection on a selected image", NULL,
       CMDID_EDGEDETECT },
!    { N_("Emboss"), NULL, "Convert a selected image to gray and then emboss",
!      NULL, CMDID_EMBOSS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Spread..."), NULL, "Spread the pixels of a selected image around",
!      NULL, CMDID_SPREAD },
!    { N_("Sharpen"), NULL, "Sharpen a selected image", NULL, CMDID_SHARPEN },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Blur(3x3)"), NULL, "Blur a selected image using a 3 by 3 filter", NULL,
       CMDID_BLUR3 },
!    { N_("Blur(5x5)"), NULL, "Blur a selected image using a 5 by 5 filter", NULL,
       CMDID_BLUR5 },
!    { N_("Blur(7x7)"), NULL, "Blur a selected image using a 7 by 7 filter", NULL,
       CMDID_BLUR7 },
     { NULL, NULL, NULL, NULL, INVALID }
***************
*** 352,362 ****
  
  static TgMenuItemInfo generateMenuItemInfo[] = {
!    { "RunBggen...", NULL,
       "Run 'bggen' to create an image using the size of a selected image", NULL,
       CMDID_RUNBGGEN },
!    { "CircularBggen...", NULL,
       "Create a gray circular image using the size of a selected image", NULL,
       CMDID_CIRCULARBGGEN },
!    { "SimpleRectBggen...", NULL,
       "Create a single-color rectanglar image using the size of selected image",
       NULL, CMDID_SIMPLERECTBGGEN },
--- 355,365 ----
  
  static TgMenuItemInfo generateMenuItemInfo[] = {
!    { N_("RunBggen..."), NULL,
       "Run 'bggen' to create an image using the size of a selected image", NULL,
       CMDID_RUNBGGEN },
!    { N_("CircularBggen..."), NULL,
       "Create a gray circular image using the size of a selected image", NULL,
       CMDID_CIRCULARBGGEN },
!    { N_("SimpleRectBggen..."), NULL,
       "Create a single-color rectanglar image using the size of selected image",
       NULL, CMDID_SIMPLERECTBGGEN },
***************
*** 367,424 ****
  
  static TgMenuItemInfo imageProcMenuItemInfo[] = {
!    { "MakeGray", NULL, "Convert a selected image into gray-scale", NULL,
       CMDID_MAKEGRAY },
!    { "Brighten/Darken...", NULL, "Brighten or darken a selected image", NULL,
!      CMDID_BRIGHTENDARKEN },
!    { "ContrastEnhance...", NULL, "Adjust contrast of a selected image", NULL,
!      CMDID_CONTRASTENHANCE },
!    { "GammaCorrect...", NULL, "Apply gamma correction a selected image", NULL,
!      CMDID_GAMMA },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ChangeSaturation...", NULL, "Change saturation of a selected image", NULL,
!      CMDID_CHANGESATURATION },
!    { "ChangeHue...", NULL, "Change hue of a selected image", NULL,
       CMDID_CHANGEHUE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "InvertColor", NULL,
       "Subtract every pixel of a selected image from White (in RGB-model)",
       NULL, CMDID_INVERTCOLOR },
!    { "InterpolateColor...", NULL,
       "Map pixel intensities of a selected image between two specified colors",
       NULL, CMDID_INTERPOLATECOLOR },
!    { "ColorBalance...", NULL, "Balance the RGB components of a selected image",
       NULL, CMDID_COLORBALANCE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ReduceNumberOfColors", TGMUITEM_SUBMENU,
       "Reduce number of colors submenu >>>", &reduceColorMenuInfo, INVALID },
!    { "Effects", TGMUITEM_SUBMENU,
       "Effects submenu >>>", &effectsMenuInfo, INVALID },
!    { "Generate", TGMUITEM_SUBMENU,
       "Generate submenu >>>", &generateMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "RegenerateImage", NULL,
       "Regenerated a selected image", NULL, CMDID_REGENERATEIMAGE },
!    { "CropImage", NULL, "Crop a selected image", NULL, CMDID_CROPIMAGE },
     { "GetColor", NULL,
       "Pick a color from a selected image to be the current color", NULL,
       CMDID_GETCOLOR },
!    { "ReplaceColor", NULL,
       "Replace a color in a selected image with the current color", NULL,
       CMDID_REPLACECOLOR },
!    { "FloodFill", NULL, "Flood-filling a selected image with the current color",
       NULL, CMDID_FLOODFILL },
!    { "CreateContour", NULL,
       "Generate a contour from a point in a selected image", NULL,
       CMDID_CREATECONTOUR },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Subtract", NULL,
       "Subtract one image from another", NULL, CMDID_SUBTRACT },
!    { "AlphaCombine", NULL,
       "Combine 2 images using another image as the alpha channel", NULL,
       CMDID_ALPHACOMBINE },
!    { "XorColor", NULL, "XOR the colors of one image into another", NULL,
       CMDID_XORCOLORS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "VectorWarp", NULL,
       "Warp selected image in a specified direction for a specified amount",
       NULL, CMDID_VECTORWARP },
--- 370,429 ----
  
  static TgMenuItemInfo imageProcMenuItemInfo[] = {
!    { "N_(MakeGray)", NULL, "Convert a selected image into gray-scale", NULL,
       CMDID_MAKEGRAY },
!    { "N_(Brighten/Darken...)", NULL, "Brighten or darken a selected image",
!      NULL, CMDID_BRIGHTENDARKEN },
!    { "N_(ContrastEnhance...)", NULL, "Adjust contrast of a selected image",
!      NULL, CMDID_CONTRASTENHANCE },
!    { "N_(GammaCorrect...)", NULL, "Apply gamma correction a selected image",
!      NULL, CMDID_GAMMA },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "N_(ChangeSaturation...)", NULL, "Change saturation of a selected image",
!      NULL, CMDID_CHANGESATURATION },
!    { "N_(ChangeHue...)", NULL, "Change hue of a selected image", NULL,
       CMDID_CHANGEHUE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "N_(InvertColor)", NULL,
       "Subtract every pixel of a selected image from White (in RGB-model)",
       NULL, CMDID_INVERTCOLOR },
!    { "N_(InterpolateColor...)", NULL,
       "Map pixel intensities of a selected image between two specified colors",
       NULL, CMDID_INTERPOLATECOLOR },
!    { "N_(ColorBalance...)", NULL,
!      "Balance the RGB components of a selected image",
       NULL, CMDID_COLORBALANCE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "N_(ReduceNumberOfColors)", TGMUITEM_SUBMENU,
       "Reduce number of colors submenu >>>", &reduceColorMenuInfo, INVALID },
!    { "N_(Effects)", TGMUITEM_SUBMENU,
       "Effects submenu >>>", &effectsMenuInfo, INVALID },
!    { "N_(Generate)", TGMUITEM_SUBMENU,
       "Generate submenu >>>", &generateMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "N_(RegenerateImage)", NULL,
       "Regenerated a selected image", NULL, CMDID_REGENERATEIMAGE },
!    { "N_(CropImage)", NULL, "Crop a selected image", NULL, CMDID_CROPIMAGE },
     { "GetColor", NULL,
       "Pick a color from a selected image to be the current color", NULL,
       CMDID_GETCOLOR },
!    { "N_(ReplaceColor)", NULL,
       "Replace a color in a selected image with the current color", NULL,
       CMDID_REPLACECOLOR },
!    { "N_(FloodFill)", NULL,
!      "Flood-filling a selected image with the current color",
       NULL, CMDID_FLOODFILL },
!    { "N_(CreateContour)", NULL,
       "Generate a contour from a point in a selected image", NULL,
       CMDID_CREATECONTOUR },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "N_(Subtract)", NULL,
       "Subtract one image from another", NULL, CMDID_SUBTRACT },
!    { "N_(AlphaCombine)", NULL,
       "Combine 2 images using another image as the alpha channel", NULL,
       CMDID_ALPHACOMBINE },
!    { "N_(XorColor)", NULL, "XOR the colors of one image into another", NULL,
       CMDID_XORCOLORS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "N_(VectorWarp)", NULL,
       "Warp selected image in a specified direction for a specified amount",
       NULL, CMDID_VECTORWARP },
***************
*** 429,437 ****
  
  static TgMenuItemInfo driverMenuItemInfo[] = {
!    { "Solve", "Alt+s", "Escape to driver", NULL, CMDID_SOLVE },
!    { "Simulate", "Alt+y", "Escape to driver", NULL, CMDID_SIMULATE },
!    { "Probe", "Alt+b", "Escape to driver", NULL, CMDID_PROBE },
!    { "Animate", "Cntrl+z", "Escape to driver", NULL, CMDID_ANIMATE },
!    { "Escape", "Alt+x", "Escape to driver", NULL, CMDID_ESCAPE },
     { NULL, NULL, NULL, NULL, INVALID }
  };
--- 434,442 ----
  
  static TgMenuItemInfo driverMenuItemInfo[] = {
!    { N_("Solve"), "Alt+s", "Escape to driver", NULL, CMDID_SOLVE },
!    { N_("Simulate"), "Alt+y", "Escape to driver", NULL, CMDID_SIMULATE },
!    { N_("Probe"), "Alt+b", "Escape to driver", NULL, CMDID_PROBE },
!    { N_("Animate"), "Cntrl+z", "Escape to driver", NULL, CMDID_ANIMATE },
!    { N_("Escape"), "Alt+x", "Escape to driver", NULL, CMDID_ESCAPE },
     { NULL, NULL, NULL, NULL, INVALID }
  };
***************
*** 440,456 ****
  
  static TgMenuItemInfo importMenuItemInfo[] = {
!    { "Import...", "Alt+p", "Embed/Import another drawing", NULL, CMDID_IMPORT },
!    { "ImportXBitmap...", "Alt+Cntrl+.", "Embed/Import an X11 bitmap file", NULL,
!      CMDID_IMPORTXBITMAP },
!    { "ImportXPixmap...", "Alt+Cntrl+,", "Embed/Import an X11 pixmap file", NULL,
!      CMDID_IMPORTXPIXMAP },
!    { "ImportEPSFile...", "Alt+(", "Link to an PS/EPS file", NULL,
       CMDID_IMPORTEPSFILE },
!    { "ImportGIFFile...", NULL, "Embed/Import a GIF file", NULL,
       CMDID_IMPORTGIFFILE },
!    { "ImportOtherFile...", NULL, "Embed/Import another type of file", NULL,
       CMDID_IMPORTOTHERFILE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "EmbedEPSFile...", NULL, "Embed/Import an PS/EPS file", NULL,
       CMDID_EMBEDEPSFILE },
     { NULL, NULL, NULL, NULL, INVALID }
--- 445,462 ----
  
  static TgMenuItemInfo importMenuItemInfo[] = {
!    { N_("Import..."), "Alt+p", "Embed/Import another drawing", NULL,
!      CMDID_IMPORT },
!    { N_("ImportXBitmap..."), "Alt+Cntrl+.", "Embed/Import an X11 bitmap file",
!      NULL, CMDID_IMPORTXBITMAP },
!    { N_("ImportXPixmap..."), "Alt+Cntrl+,", "Embed/Import an X11 pixmap file",
!      NULL, CMDID_IMPORTXPIXMAP },
!    { N_("ImportEPSFile..."), "Alt+(", "Link to an PS/EPS file", NULL,
       CMDID_IMPORTEPSFILE },
!    { N_("ImportGIFFile..."), NULL, "Embed/Import a GIF file", NULL,
       CMDID_IMPORTGIFFILE },
!    { N_("ImportOtherFile..."), NULL, "Embed/Import another type of file", NULL,
       CMDID_IMPORTOTHERFILE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("EmbedEPSFile..."), NULL, "Embed/Import an PS/EPS file", NULL,
       CMDID_EMBEDEPSFILE },
     { NULL, NULL, NULL, NULL, INVALID }
***************
*** 460,469 ****
  
  static TgMenuItemInfo browseMenuItemInfo[] = {
!    { "BrowseXBitmap", NULL, "Recursively read in all X11 bitmap files", NULL,
!      CMDID_BROWSEXBITMAP },
!    { "BrowseXPixmap", NULL, "Recursively read in all X11 pixmap files", NULL,
!      CMDID_BROWSEXPIXMAP },
!    { "BrowseOther...", NULL, "Recursively read in all another type of files",
!      NULL, CMDID_BROWSEOTHER },
     { NULL, NULL, NULL, NULL, INVALID }
  };
--- 466,475 ----
  
  static TgMenuItemInfo browseMenuItemInfo[] = {
!    { N_("BrowseXBitmap"), NULL, "Recursively read in all X11 bitmap files",
!      NULL, CMDID_BROWSEXBITMAP },
!    { N_("BrowseXPixmap"), NULL, "Recursively read in all X11 pixmap files",
!      NULL, CMDID_BROWSEXPIXMAP },
!    { N_("BrowseOther..."), NULL,
!      "Recursively read in all another type of files", NULL, CMDID_BROWSEOTHER },
     { NULL, NULL, NULL, NULL, INVALID }
  };
***************
*** 475,482 ****
  
  static TgMenuItemInfo gifAnimateMenuItemInfo[] = {
!    { "ExportXPixmapDeckToGIF", NULL,
       "Export a deck of X11 pixmap images to an animated GIF file", NULL,
       CMDID_EXPORTXPMDECKTOGIF },
!    { "ImportGIFToXPixmapDeck...", NULL,
       "Import an animated GIF file into a deck of X11 pixmap images", NULL,
       CMDID_IMPORTGIFTOXPMDECK },
--- 481,488 ----
  
  static TgMenuItemInfo gifAnimateMenuItemInfo[] = {
!    { N_("ExportXPixmapDeckToGIF"), NULL,
       "Export a deck of X11 pixmap images to an animated GIF file", NULL,
       CMDID_EXPORTXPMDECKTOGIF },
!    { N_("ImportGIFToXPixmapDeck..."), NULL,
       "Import an animated GIF file into a deck of X11 pixmap images", NULL,
       CMDID_IMPORTGIFTOXPMDECK },
***************
*** 488,498 ****
  #ifdef _TGIF_DBG
  static TgMenuItemInfo mimeMenuItemInfo[] = {
!    { "FakeUserAgent...", NULL,
       "Set 'UserAgent' to be used when making an HTTP request", NULL,
       CMDID_FAKEUSERAGENT },
!    { "FakeReferer...", NULL,
       "Set 'Referer' to be used when making an HTTP request", NULL,
       CMDID_FAKEREFERER },
!    { "ToggleKeepAlive", NULL,
       "Toggle between using Keep-Alive and non-Keep-Alive HTTP connections",
       NULL, CMDID_TOGGLEKEEPALIVE },
--- 494,504 ----
  #ifdef _TGIF_DBG
  static TgMenuItemInfo mimeMenuItemInfo[] = {
!    { N_("FakeUserAgent..."), NULL,
       "Set 'UserAgent' to be used when making an HTTP request", NULL,
       CMDID_FAKEUSERAGENT },
!    { N_("FakeReferer..."), NULL,
       "Set 'Referer' to be used when making an HTTP request", NULL,
       CMDID_FAKEREFERER },
!    { N_("ToggleKeepAlive"), NULL,
       "Toggle between using Keep-Alive and non-Keep-Alive HTTP connections",
       NULL, CMDID_TOGGLEKEEPALIVE },
***************
*** 504,563 ****
  
  static TgMenuItemInfo fileMenuItemInfo[] = {
!    { "New", "Cntrl+n", "Start with a blank/new drawing", NULL, CMDID_NEW },
!    { "Open...", "Cntrl+o", "Open an existing drawing", NULL, CMDID_OPEN },
!    { "Import", TGMUITEM_SUBMENU,
       "Import submenu >>>", &importMenuInfo, INVALID },
!    { "Browse", TGMUITEM_SUBMENU,
       "Browse submenu >>>", &browseMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Save", "Cntrl+s", "Save current drawing", NULL, CMDID_SAVE },
!    { "SaveNew...", "Alt+Cntrl+s", "Save current drawing in a different file",
!      NULL, CMDID_SAVENEW },
!    { "SaveSelectedAs...", "Alt+~", "Save selected objects in a different file",
!      NULL, CMDID_SAVESELECTEDAS },
!    { "SaveSymInLibrary...", NULL,
       "Save symbol file in a library path within the current domain", NULL,
       CMDID_SAVESYMINLIBRARY },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ChangeDomain...", "Cntrl+c", "Change to a different domain", NULL,
       CMDID_CHANGEDOMAIN },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Print", "Cntrl+p", "Print/export current drawing", NULL, CMDID_PRINT },
!    { "Print/ExportFormat", TGMUITEM_SUBMENU,
       "Select print/export format submenu >>>", &exportFormatMenuInfo, INVALID },
!    { "Print/ExportInColor", "Alt+Cntrl+k",
       "Toggle between color and black & white printing modes", NULL,
       CMDID_TOGGLEBWCOLORPS },
!    { "PrintWithCmd...", "Cntrl+-",
       "Print/export current drawing with a specific command", NULL,
       CMDID_PRINTWITHCMD },
!    { "PrintSelectedObjs", NULL, "Print/export only selected objects", NULL,
       CMDID_PRINTSELECTEDOBJS },
!    { "PrintOnePage", NULL, "Print a page in a multipage drawing", NULL,
       CMDID_PRINTONEPAGE },
!    { "PrintOneFilePerPage", NULL, "Print into a separate file for each page",
       NULL, CMDID_PRINTONEFILEPERPAGE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "GIFAnimation", TGMUITEM_SUBMENU,
       "GIFAnimation submenu >>>", &gifAnimateMenuInfo, INVALID },
  #ifdef _TGIF_DBG
!    { "Mime", TGMUITEM_SUBMENU, "Mime submenu >>>",
       &mimeMenuInfo, INVALID },
  #endif /* _TGIF_DBG */
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "PrintMsgBuffer...", NULL,
       "Display/save the contents of the message window", NULL,
       CMDID_PRINTMSGBUFFER },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SetExportPixelTrim...", NULL,
       "Specify the number of pixels to trim when exporting", NULL,
       CMDID_SETEXPORTPIXELTRIM },
!    { "SetTemplate...", NULL,
       "Select a template file be used in STACKED page mode", NULL,
       CMDID_SETTEMPLATE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Return", TGMUITEM_SUBMENU,
!      "Return submenu >>>", &driverMenuInfo, INVALID },
!    { "Quit", "Cntrl+q", "Exit <<PROGRAM_NAME>>", NULL, CMDID_QUIT },
     { NULL, NULL, NULL, NULL, INVALID }
  };
--- 510,571 ----
  
  static TgMenuItemInfo fileMenuItemInfo[] = {
!    { N_("New"), "Cntrl+n", "Start with a blank/new drawing", NULL, CMDID_NEW },
!    { N_("Open..."), "Cntrl+o", "Open an existing drawing", NULL, CMDID_OPEN },
!    { N_("Import"), TGMUITEM_SUBMENU,
       "Import submenu >>>", &importMenuInfo, INVALID },
!    { N_("Browse"), TGMUITEM_SUBMENU,
       "Browse submenu >>>", &browseMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Save"), "Cntrl+s", "Save current drawing", NULL, CMDID_SAVE },
!    { N_("SaveNew..."), "Alt+Cntrl+s",
!      "Save current drawing in a different file", NULL, CMDID_SAVENEW },
!    { N_("SaveSelectedAs..."), "Alt+~",
!      "Save selected objects in a different file", NULL, CMDID_SAVESELECTEDAS },
!    { N_("SaveSymInLibrary..."), NULL,
       "Save symbol file in a library path within the current domain", NULL,
       CMDID_SAVESYMINLIBRARY },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("ChangeDomain..."), "Cntrl+c", "Change to a different domain", NULL,
       CMDID_CHANGEDOMAIN },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Print"), "Cntrl+p", "Print/export current drawing", NULL,
!      CMDID_PRINT },
!    { N_("Print/ExportFormat"), TGMUITEM_SUBMENU,
       "Select print/export format submenu >>>", &exportFormatMenuInfo, INVALID },
!    { N_("Print/ExportInColor"), "Alt+Cntrl+k",
       "Toggle between color and black & white printing modes", NULL,
       CMDID_TOGGLEBWCOLORPS },
!    { N_("PrintWithCmd..."), "Cntrl+-",
       "Print/export current drawing with a specific command", NULL,
       CMDID_PRINTWITHCMD },
!    { N_("PrintSelectedObjs"), NULL, "Print/export only selected objects", NULL,
       CMDID_PRINTSELECTEDOBJS },
!    { N_("PrintOnePage"), NULL, "Print a page in a multipage drawing", NULL,
       CMDID_PRINTONEPAGE },
!    { N_("PrintOneFilePerPage"), NULL,
!      "Print into a separate file for each page",
       NULL, CMDID_PRINTONEFILEPERPAGE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("GIFAnimation"), TGMUITEM_SUBMENU,
       "GIFAnimation submenu >>>", &gifAnimateMenuInfo, INVALID },
  #ifdef _TGIF_DBG
!    { N_("Mime"), TGMUITEM_SUBMENU, "Mime submenu >>>",
       &mimeMenuInfo, INVALID },
  #endif /* _TGIF_DBG */
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("PrintMsgBuffer..."), NULL,
       "Display/save the contents of the message window", NULL,
       CMDID_PRINTMSGBUFFER },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SetExportPixelTrim..."), NULL,
       "Specify the number of pixels to trim when exporting", NULL,
       CMDID_SETEXPORTPIXELTRIM },
!    { N_("SetTemplate..."), NULL,
       "Select a template file be used in STACKED page mode", NULL,
       CMDID_SETTEMPLATE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Return"), TGMUITEM_SUBMENU,
!      N_("Return submenu >>>"), &driverMenuInfo, INVALID },
!    { N_("Quit"), "Cntrl+q", "Exit <<PROGRAM_NAME>>", NULL, CMDID_QUIT },
     { NULL, NULL, NULL, NULL, INVALID }
  };
***************
*** 565,577 ****
  
  static TgMenuItemInfo transformMenuItemInfo[] = {
!    { "PreciseScale...", "Alt+)", "Scale selected objects", NULL,
       CMDID_PRECISESCALE },
!    { "PreciseRotate...", NULL,
       "Rotate selected objects by a specified number of degrees", NULL,
       CMDID_PRECISEROTATE },
!    { "RestoreImageWH", NULL,
       "Restore a seleted bitmap/pixmap/EPS object to its original dimension",
       NULL, CMDID_RESTOREIMAGEWH },
!    { "NoTransform", NULL,
       "Get rid of transformations on selected simple objects", NULL,
       CMDID_NOTRANSFORM },
--- 573,585 ----
  
  static TgMenuItemInfo transformMenuItemInfo[] = {
!    { N_("PreciseScale..."), "Alt+)", "Scale selected objects", NULL,
       CMDID_PRECISESCALE },
!    { N_("PreciseRotate..."), NULL,
       "Rotate selected objects by a specified number of degrees", NULL,
       CMDID_PRECISEROTATE },
!    { N_("RestoreImageWH"), NULL,
       "Restore a seleted bitmap/pixmap/EPS object to its original dimension",
       NULL, CMDID_RESTOREIMAGEWH },
!    { N_("NoTransform"), NULL,
       "Get rid of transformations on selected simple objects", NULL,
       CMDID_NOTRANSFORM },
***************
*** 582,605 ****
  
  static TgMenuItemInfo bitPixmapMenuItemInfo[] = {
!    { "InvertXBitmap", "Alt+Cntrl+f",
       "Invert pixels for selected bitmap objects", NULL, CMDID_INVERTXBITMAP },
!    { "CutBit/Pixmap...", "Alt+;", "Trim/scale a selected bitmap/pixmap object",
!      NULL, CMDID_CUTBITPIXMAP },
!    { "BreakUpBit/Pixmap...", NULL,
       "Break selected bitmap/pixmap object into smaller objects", NULL,
       CMDID_BREAKUPBITPIXMAP },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ExportHalfToneBitmap", NULL,
       "Use Floyd-Steinberg half-tone method when exporting an X11 bitmap file",
       NULL, CMDID_EXPORTHALFTONEBITMAP },
!    { "ExportThresholdBitmap", NULL,
       "Use simple thresholding method when exporting an X11 bitmap file",
       NULL, CMDID_EXPORTTHRESHOLDBITMAP },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SetExportBitmapThreshold...", NULL,
       "Set bitmap threshold value for the simple thresholding method",
       NULL, CMDID_SETEXPORTBITMAPTHRESHOLD },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "UpdateEPS", NULL, "Refresh a selected EPS object", NULL,
       CMDID_UPDATEEPS },
     { NULL, NULL, NULL, NULL, INVALID }
--- 590,613 ----
  
  static TgMenuItemInfo bitPixmapMenuItemInfo[] = {
!    { N_("InvertXBitmap"), "Alt+Cntrl+f",
       "Invert pixels for selected bitmap objects", NULL, CMDID_INVERTXBITMAP },
!    { N_("CutBit/Pixmap..."), "Alt+;",
!      "Trim/scale a selected bitmap/pixmap object", NULL, CMDID_CUTBITPIXMAP },
!    { N_("BreakUpBit/Pixmap..."), NULL,
       "Break selected bitmap/pixmap object into smaller objects", NULL,
       CMDID_BREAKUPBITPIXMAP },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("ExportHalfToneBitmap"), NULL,
       "Use Floyd-Steinberg half-tone method when exporting an X11 bitmap file",
       NULL, CMDID_EXPORTHALFTONEBITMAP },
!    { N_("ExportThresholdBitmap"), NULL,
       "Use simple thresholding method when exporting an X11 bitmap file",
       NULL, CMDID_EXPORTTHRESHOLDBITMAP },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SetExportBitmapThreshold..."), NULL,
       "Set bitmap threshold value for the simple thresholding method",
       NULL, CMDID_SETEXPORTBITMAPTHRESHOLD },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("UpdateEPS"), NULL, "Refresh a selected EPS object", NULL,
       CMDID_UPDATEEPS },
     { NULL, NULL, NULL, NULL, INVALID }
***************
*** 609,628 ****
  
  static TgMenuItemInfo polyMenuItemInfo[] = {
!    { "DeletePoint", "Alt+Cntrl+d", "Delete vertices from a poly/polygon/spline",
!      NULL, CMDID_DELETEPOINT },
!    { "AddPoint", "Alt+Cntrl+a", "Add vertices to a polygon/polygon/spline",
       NULL, CMDID_ADDPOINT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ConvertIntSpline", NULL,
       "Convert selected interpolated splines to regular splines", NULL,
       CMDID_CONVERTINTSPLINE },
!    { "Smooth<->Hinge", NULL,
       "Toggle smooth/hinge vertices for a selected poly/polygon/spline", NULL,
       CMDID_TOGGLESMOOTHHINGE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "JoinPoly", NULL, "Join polylines or open-splines at endpoints", NULL,
       CMDID_JOINPOLY },
!    { "CutPoly", NULL, "Cut a poly/polygon at a vertex into two pieces", NULL,
!      CMDID_CUTPOLY },
     { NULL, NULL, NULL, NULL, INVALID }
  };
--- 617,636 ----
  
  static TgMenuItemInfo polyMenuItemInfo[] = {
!    { N_("DeletePoint"), "Alt+Cntrl+d",
!      "Delete vertices from a poly/polygon/spline", NULL, CMDID_DELETEPOINT },
!    { N_("AddPoint"), "Alt+Cntrl+a", "Add vertices to a polygon/polygon/spline",
       NULL, CMDID_ADDPOINT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("ConvertIntSpline"), NULL,
       "Convert selected interpolated splines to regular splines", NULL,
       CMDID_CONVERTINTSPLINE },
!    { N_("Smooth<->Hinge"), NULL,
       "Toggle smooth/hinge vertices for a selected poly/polygon/spline", NULL,
       CMDID_TOGGLESMOOTHHINGE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("JoinPoly"), NULL, "Join polylines or open-splines at endpoints", NULL,
       CMDID_JOINPOLY },
!    { N_("CutPoly"), NULL,
!      "Cut a poly/polygon at a vertex into two pieces", NULL, CMDID_CUTPOLY },
     { NULL, NULL, NULL, NULL, INVALID }
  };
***************
*** 631,672 ****
  
  static TgMenuItemInfo textMenuItemInfo[] = {
!    { "BreakUpText", "Alt+#",
       "Break up selected text objects into one-character text objects", NULL,
       CMDID_BREAKUPTEXT },
!    { "SetTextFillPatternColor", NULL,
       "Set the fill pattern color of a text object to be the current color",
       NULL, CMDID_SETTEXTFILLPATTERNCOLOR },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "InsertRightSuperscript", NULL,
       "Insert superscript to the right of the text cursor", NULL,
       CMDID_INSERTRIGHTSUPERSCRIPT },
!    { "InsertRightSubscript", NULL,
       "Insert subscript to the right of the text cursor", NULL,
       CMDID_INSERTRIGHTSUBSCRIPT },
!    { "InsertLeftSuperscript", NULL,
       "Insert superscript to the left of the text cursor", NULL,
       CMDID_INSERTLEFTSUPERSCRIPT },
!    { "InsertLeftSubscript", NULL,
       "Insert subscript to the left of the text cursor", NULL,
       CMDID_INSERTLEFTSUBSCRIPT },
!    { "InsertCenterSuperscript", NULL,
       "Insert superscript above the text cursor", NULL,
       CMDID_INSERTCENTERSUPERSCRIPT },
!    { "InsertCenterSubscript", NULL,
       "Insert subscript below the text cursor", NULL,
       CMDID_INSERTCENTERSUBSCRIPT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "InsertThinSpace...", NULL,
       "Insert a think space at the text cursor", NULL,
       CMDID_INSERTTHINSPACE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "InsertVerticalOffset...", NULL,
       "Insert a vertical offset at the text cursor", NULL,
       CMDID_INSERTVERTICALOFFSET },
!    { "RemoveVerticalOffset...", NULL,
       "Remove any vertical offset at the text cursor", NULL,
       CMDID_REMOVEVERTICALOFFSET },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SetScriptFraction", NULL,
       "Set the relative size of super/subscript text", NULL,
       CMDID_SETSCRIPTFRACTION },
--- 639,680 ----
  
  static TgMenuItemInfo textMenuItemInfo[] = {
!    { N_("BreakUpText"), "Alt+#",
       "Break up selected text objects into one-character text objects", NULL,
       CMDID_BREAKUPTEXT },
!    { N_("SetTextFillPatternColor"), NULL,
       "Set the fill pattern color of a text object to be the current color",
       NULL, CMDID_SETTEXTFILLPATTERNCOLOR },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("InsertRightSuperscript"), NULL,
       "Insert superscript to the right of the text cursor", NULL,
       CMDID_INSERTRIGHTSUPERSCRIPT },
!    { N_("InsertRightSubscript"), NULL,
       "Insert subscript to the right of the text cursor", NULL,
       CMDID_INSERTRIGHTSUBSCRIPT },
!    { N_("InsertLeftSuperscript"), NULL,
       "Insert superscript to the left of the text cursor", NULL,
       CMDID_INSERTLEFTSUPERSCRIPT },
!    { N_("InsertLeftSubscript"), NULL,
       "Insert subscript to the left of the text cursor", NULL,
       CMDID_INSERTLEFTSUBSCRIPT },
!    { N_("InsertCenterSuperscript"), NULL,
       "Insert superscript above the text cursor", NULL,
       CMDID_INSERTCENTERSUPERSCRIPT },
!    { N_("InsertCenterSubscript"), NULL,
       "Insert subscript below the text cursor", NULL,
       CMDID_INSERTCENTERSUBSCRIPT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("InsertThinSpace..."), NULL,
       "Insert a think space at the text cursor", NULL,
       CMDID_INSERTTHINSPACE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("InsertVerticalOffset..."), NULL,
       "Insert a vertical offset at the text cursor", NULL,
       CMDID_INSERTVERTICALOFFSET },
!    { N_("RemoveVerticalOffset..."), NULL,
       "Remove any vertical offset at the text cursor", NULL,
       CMDID_REMOVEVERTICALOFFSET },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SetScriptFraction"), NULL,
       "Set the relative size of super/subscript text", NULL,
       CMDID_SETSCRIPTFRACTION },
***************
*** 677,691 ****
  
  static TgMenuItemInfo createObjectMenuItemInfo[] = {
!    { "InputPolyPts", NULL, "Read points from terminal and create a poly", NULL,
!      CMDID_INPUTPOLYPTS },
!    { "InputPolygonPts", NULL, "Read points from terminal and create a polygon",
       NULL, CMDID_INPUTPOLYGONPTS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SpecifyAnArc...", "Alt+9", "Create and specify an arc", NULL,
       CMDID_SPECIFYANARC },
!    { "MakeRegPolygon...", "Alt+\"",
       "Make a selected polygon/closed spline into a regular one", NULL,
       CMDID_MAKEREGPOLYGON },
!    { "GetBoundingBox", NULL,
       "Get rectangular bounding boxes of selected objects", NULL,
       CMDID_GETBOUNDINGBOX },
--- 685,700 ----
  
  static TgMenuItemInfo createObjectMenuItemInfo[] = {
!    { N_("InputPolyPts"), NULL, "Read points from terminal and create a poly",
!      NULL, CMDID_INPUTPOLYPTS },
!    { N_("InputPolygonPts"), NULL,
!      "Read points from terminal and create a polygon",
       NULL, CMDID_INPUTPOLYGONPTS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SpecifyAnArc..."), "Alt+9", "Create and specify an arc", NULL,
       CMDID_SPECIFYANARC },
!    { N_("MakeRegPolygon..."), "Alt+\"",
       "Make a selected polygon/closed spline into a regular one", NULL,
       CMDID_MAKEREGPOLYGON },
!    { N_("GetBoundingBox"), NULL,
       "Get rectangular bounding boxes of selected objects", NULL,
       CMDID_GETBOUNDINGBOX },
***************
*** 697,753 ****
  
  static TgMenuItemInfo editMenuItemInfo[] = {
!    { "Redraw", "Cntrl+r", "Redraw canvas window", NULL, CMDID_REDRAW },
!    { "Duplicate", "Cntrl+d", "Duplicate selected objects", NULL,
       CMDID_DUPLICATE },
!    { "Delete", "Cntrl+x", "Delete selected objects", NULL, CMDID_DELETE },
!    { "SelectAll", "Cntrl+a", "Select all objects on the current page", NULL,
       CMDID_SELECTALL },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Undo", "Alt+u", "Undo the most recent command", NULL, CMDID_UNDO },
!    { "Redo", "Alt+*", "Redo the most undone command", NULL, CMDID_REDO },
!    { "FlushUndoBuffer", NULL, "Flush undo buffer and unused colors", NULL,
       CMDID_FLUSHUNDOBUFFER },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Copy", "Cntrl+y", "Copy selected objects into the cut buffer", NULL,
       CMDID_COPY },
!    { "CopyPlainTextAsObject", NULL,
       "Copy highlighted plain text as an object into the cut buffer", NULL,
       CMDID_COPYPLAINTEXTASOBJECT },
!    { "Cut", NULL, "Cut selected objects into the cut buffer", NULL, CMDID_CUT },
!    { "Paste", "Alt+Cntrl+y", "Paste from the cut buffer", NULL, CMDID_PASTE },
!    { "PasteFromFile...", NULL, "Select a file and paste the content as text",
!      NULL, CMDID_PASTEFROMFILE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Shape", TGMUITEM_PINNABLESUBMENU,
       "Shape submenu >>>", &shapeMenuInfo, MENU_SHAPE },
!    { "SetShapeShadow...", NULL, "Specify the shadow for shapes", NULL,
       CMDID_SETSHAPESHADOW },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ImageProc", TGMUITEM_PINNABLESUBMENU,
       "ImageProc submenu >>>", &imageProcMenuInfo, MENU_IMAGEPROC },
!    { "Properties", TGMUITEM_PINNABLESUBMENU,
       "Properties submenu >>>", &propertiesMenuInfo, MENU_PROPERTIES },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Transformation", TGMUITEM_SUBMENU,
       "Transformation submenu >>>", &transformMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Bitmap/Pixmap/EPS", TGMUITEM_SUBMENU,
       "Bitmap/Pixmap/EPS submenu >>>", &bitPixmapMenuInfo, INVALID },
!    { "Poly/Polygon", TGMUITEM_SUBMENU,
       "Poly/Polygon submenu >>>", &polyMenuInfo, INVALID },
!    { "Text", TGMUITEM_SUBMENU, "Text submenu >>>", &textMenuInfo, INVALID },
!    { "CreateObject", TGMUITEM_SUBMENU,
       "Create object submenu >>>", &createObjectMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "PushCurChoice", "Cntrl+e", "Save/restore current drawing mode", NULL,
       CMDID_PUSHCURCHOICE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "FindCaseSensitive...", "Alt+Cntrl+0",
       "Find string in visible text objects (case sensitive)", NULL,
       CMDID_FINDCASESENSITIVE },
!    { "FindNoCase...", "Alt+Cntrl+9",
       "Find string in visible text objects (case insensitive)", NULL,
       CMDID_FINDNOCASE },
!    { "FindAgain", "Alt+Cntrl+=", "Repeat the last Find command", NULL,
       CMDID_FINDAGAIN },
  /*
--- 706,764 ----
  
  static TgMenuItemInfo editMenuItemInfo[] = {
!    { N_("Redraw"), "Cntrl+r", "Redraw canvas window", NULL, CMDID_REDRAW },
!    { N_("Duplicate"), "Cntrl+d", "Duplicate selected objects", NULL,
       CMDID_DUPLICATE },
!    { N_("Delete"), "Cntrl+x", "Delete selected objects", NULL, CMDID_DELETE },
!    { N_("SelectAll"), "Cntrl+a", "Select all objects on the current page", NULL,
       CMDID_SELECTALL },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Undo"), "Alt+u", "Undo the most recent command", NULL, CMDID_UNDO },
!    { N_("Redo"), "Alt+*", "Redo the most undone command", NULL, CMDID_REDO },
!    { N_("FlushUndoBuffer"), NULL, "Flush undo buffer and unused colors", NULL,
       CMDID_FLUSHUNDOBUFFER },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Copy"), "Cntrl+y", "Copy selected objects into the cut buffer", NULL,
       CMDID_COPY },
!    { N_("CopyPlainTextAsObject"), NULL,
       "Copy highlighted plain text as an object into the cut buffer", NULL,
       CMDID_COPYPLAINTEXTASOBJECT },
!    { N_("Cut"), NULL, "Cut selected objects into the cut buffer", NULL,
!      CMDID_CUT },
!    { N_("Paste"), "Alt+Cntrl+y", "Paste from the cut buffer", NULL,
!      CMDID_PASTE },
!    { N_("PasteFromFile..."), NULL,
!      "Select a file and paste the content as text", NULL, CMDID_PASTEFROMFILE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Shape"), TGMUITEM_PINNABLESUBMENU,
       "Shape submenu >>>", &shapeMenuInfo, MENU_SHAPE },
!    { N_("SetShapeShadow..."), NULL, "Specify the shadow for shapes", NULL,
       CMDID_SETSHAPESHADOW },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("ImageProc"), TGMUITEM_PINNABLESUBMENU,
       "ImageProc submenu >>>", &imageProcMenuInfo, MENU_IMAGEPROC },
!    { N_("Properties"), TGMUITEM_PINNABLESUBMENU,
       "Properties submenu >>>", &propertiesMenuInfo, MENU_PROPERTIES },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Transformation"), TGMUITEM_SUBMENU,
       "Transformation submenu >>>", &transformMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Bitmap/Pixmap/EPS"), TGMUITEM_SUBMENU,
       "Bitmap/Pixmap/EPS submenu >>>", &bitPixmapMenuInfo, INVALID },
!    { N_("Poly/Polygon"), TGMUITEM_SUBMENU,
       "Poly/Polygon submenu >>>", &polyMenuInfo, INVALID },
!    { N_("Text"), TGMUITEM_SUBMENU, "Text submenu >>>", &textMenuInfo, INVALID },
!    { N_("CreateObject"), TGMUITEM_SUBMENU,
       "Create object submenu >>>", &createObjectMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("PushCurChoice"), "Cntrl+e", "Save/restore current drawing mode", NULL,
       CMDID_PUSHCURCHOICE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("FindCaseSensitive..."), "Alt+Cntrl+0",
       "Find string in visible text objects (case sensitive)", NULL,
       CMDID_FINDCASESENSITIVE },
!    { N_("FindNoCase..."), "Alt+Cntrl+9",
       "Find string in visible text objects (case insensitive)", NULL,
       CMDID_FINDNOCASE },
!    { N_("FindAgain"), "Alt+Cntrl+=", "Repeat the last Find command", NULL,
       CMDID_FINDAGAIN },
  /*
***************
*** 760,775 ****
  
  static TgMenuItemInfo alignMenuItemInfo[] = {
!    { "AlignObjsTop", "Alt+{", "Align top sides of selected objects", NULL,
       CMDID_ALIGNOBJSTOP },
!    { "AlignObjsMiddle", "Alt++", "Align vertical centers of selected objects",
       NULL, CMDID_ALIGNOBJSMIDDLE },
!    { "AlignObjsBottom", "Alt+}", "Align bottom sides of selected objects", NULL,
!      CMDID_ALIGNOBJSBOTTOM },
!    { "AlignObjsLeft", "Alt+[", "Align left sides of selected objects", NULL,
       CMDID_ALIGNOBJSLEFT },
!    { "AlignObjsCenter", "Alt+=", "Align horizontal centers of selected objects",
       NULL, CMDID_ALIGNOBJSCENTER },
!    { "AlignObjsRight", "Alt+]", "Align right sides of selected objects", NULL,
!      CMDID_ALIGNOBJSRIGHT },
     { NULL, NULL, NULL, NULL, INVALID }
  };
--- 771,788 ----
  
  static TgMenuItemInfo alignMenuItemInfo[] = {
!    { N_("AlignObjsTop"), "Alt+{", "Align top sides of selected objects", NULL,
       CMDID_ALIGNOBJSTOP },
!    { N_("AlignObjsMiddle"), "Alt++",
!      "Align vertical centers of selected objects",
       NULL, CMDID_ALIGNOBJSMIDDLE },
!    { N_("AlignObjsBottom"), "Alt+}",
!      "Align bottom sides of selected objects", NULL, CMDID_ALIGNOBJSBOTTOM },
!    { N_("AlignObjsLeft"), "Alt+[", "Align left sides of selected objects", NULL,
       CMDID_ALIGNOBJSLEFT },
!    { N_("AlignObjsCenter"), "Alt+=",
!      "Align horizontal centers of selected objects",
       NULL, CMDID_ALIGNOBJSCENTER },
!    { N_("AlignObjsRight"), "Alt+]", "Align right sides of selected objects",
!      NULL, CMDID_ALIGNOBJSRIGHT },
     { NULL, NULL, NULL, NULL, INVALID }
  };
***************
*** 778,801 ****
  
  static TgMenuItemInfo sizeMenuItemInfo[] = {
!    { "SizeToWidest", NULL,
       "Resize all selected objects to be as wide as the widest one", NULL,
       CMDID_SIZETOWIDEST },
!    { "SizeToNarrowest", NULL,
       "Resize all selected objects to be as narrow as the narrowest one", NULL,
       CMDID_SIZETONARROWEST },
!    { "SizeToTallest", NULL,
       "Resize all selected objects to be as tall as the tallest one", NULL,
       CMDID_SIZETOTALLEST },
!    { "SizeToShortest", NULL,
       "Resize all selected objects to be as short as the shortest one", NULL,
       CMDID_SIZETOSHORTEST },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SizeToGivenWidthHeight...", NULL,
       "Resize all selected objects to a specified width and height", NULL,
       CMDID_SIZETOGIVENWIDTHHEIGHT },
!    { "SizeToGivenWidth...", NULL,
       "Resize all selected objects to a specified width", NULL,
       CMDID_SIZETOGIVENWIDTH },
!    { "SizeToGivenHeight...", NULL,
       "Resize all selected objects to a specified height", NULL,
       CMDID_SIZETOGIVENHEIGHT },
--- 791,814 ----
  
  static TgMenuItemInfo sizeMenuItemInfo[] = {
!    { N_("SizeToWidest"), NULL,
       "Resize all selected objects to be as wide as the widest one", NULL,
       CMDID_SIZETOWIDEST },
!    { N_("SizeToNarrowest"), NULL,
       "Resize all selected objects to be as narrow as the narrowest one", NULL,
       CMDID_SIZETONARROWEST },
!    { N_("SizeToTallest"), NULL,
       "Resize all selected objects to be as tall as the tallest one", NULL,
       CMDID_SIZETOTALLEST },
!    { N_("SizeToShortest"), NULL,
       "Resize all selected objects to be as short as the shortest one", NULL,
       CMDID_SIZETOSHORTEST },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SizeToGivenWidthHeight..."), NULL,
       "Resize all selected objects to a specified width and height", NULL,
       CMDID_SIZETOGIVENWIDTHHEIGHT },
!    { N_("SizeToGivenWidth..."), NULL,
       "Resize all selected objects to a specified width", NULL,
       CMDID_SIZETOGIVENWIDTH },
!    { N_("SizeToGivenHeight..."), NULL,
       "Resize all selected objects to a specified height", NULL,
       CMDID_SIZETOGIVENHEIGHT },
***************
*** 816,889 ****
  
  static TgMenuItemInfo arrangeMenuItemInfo[] = {
!    { "Front", "Cntrl+f", "Bring selected objects to the front", NULL,
       CMDID_FRONT },
!    { "Back", "Cntrl+b", "Send selected objects to the back", NULL, CMDID_BACK },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Group", "Cntrl+g", "Group selected objects into a compound object", NULL,
!      CMDID_GROUP },
!    { "UnGroup", "Cntrl+u",
       "Break up selected grouped objects into its components", NULL,
       CMDID_UNGROUP },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Lock", "Alt+<", "Lock the positions of selected objects", NULL,
       CMDID_LOCK },
!    { "UnLock", "Alt+>", "UnLock the positions of selected objects", NULL,
       CMDID_UNLOCK },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "HoriAlign", TGMUITEM_PINNABLESUBMENU,
       "HoriAlign submenu >>>", &horiAlignMenuInfo, MENU_HORIALIGN },
!    { "VertAlign", TGMUITEM_PINNABLESUBMENU,
       "VertAlign submenu >>>", &vertAlignMenuInfo,
       MENU_VERTALIGN },
!    { "AlignObjs", "Cntrl+l",
       "Align selected objects with each other using the current alignments",
       NULL, CMDID_ALIGNOBJS },
!    { "AlignToGrid", "Cntrl+t",
       "Align selected objects to grid points using the current alignments", NULL,
       CMDID_ALIGNTOGRID },
!    { "AlignToPage", "Alt+&",
       "Align selected objects to the page using the current alignments", NULL,
       CMDID_ALIGNTOPAGE },
!    { "AlignObjsDirect", TGMUITEM_SUBMENU,
       "Align objects direct submenu >>>", &alignObjsDirectMenuInfo, INVALID },
!    { "AlignToGridDirect", TGMUITEM_SUBMENU,
       "Align to grid direct submenu >>>", &alignToGridDirectMenuInfo, INVALID },
!    { "AlignToPageDirect", TGMUITEM_SUBMENU,
       "Align to page direct submenu >>>", &alignToPageDirectMenuInfo, INVALID },
!    { "More Object Alignments", TGMUITEM_SUBMENU,
       "Align objects submenu >>>", &alignMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SizeObjects", TGMUITEM_SUBMENU,
       "Size objects submenu >>>", &sizeMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "DistributeObjs", "Alt+l",
       "Distribute selected objects using the current alignments", NULL,
       CMDID_DISTRIBUTEOBJS },
!    { "DistributeObjsDirect", TGMUITEM_SUBMENU,
       "Distribute objects direct submenu >>>", &distrObjsDirectMenuInfo,
       INVALID },
!    { "LayoutOnArc", NULL, "Layout objects on an arc", NULL, CMDID_LAYOUTONARC },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "FlipHorizontal", "Alt+h", "Flip selected objects horizontally", NULL,
       CMDID_FLIPHORIZONTAL },
!    { "FlipVertical", "Alt+v", "Flip selected objects vertically", NULL,
       CMDID_FLIPVERTICAL },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "RotateClockWise", "Alt+w", "Rotate selected objects clockwise", NULL,
       CMDID_ROTATECLOCKWISE },
!    { "RotateCounter", "Alt+c", "Rotate selected objects counter-clockwise",
       NULL, CMDID_ROTATECOUNTER },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SetTextRotation...", NULL, "Set text rotation in degrees", NULL,
       CMDID_SETTEXTROTATION },
!    { "SetRotationIncrement...", NULL, "Set rotation increment in degrees", NULL,
!      CMDID_SETROTATIONINCREMENT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "AbutHorizontal", "Alt+_", "Squish selected objects together horizontally",
       NULL, CMDID_ABUTHORIZONTAL },
!    { "AbutVertical", "Alt+|", "Squish selected objects together vertically",
       NULL, CMDID_ABUTVERTICAL },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "CenterAnEndPoint", NULL,
       "Move an endpoint of a selected poly to the center of another object",
       NULL, CMDID_CENTERANENDPOINT },
--- 829,905 ----
  
  static TgMenuItemInfo arrangeMenuItemInfo[] = {
!    { N_("Front"), "Cntrl+f", "Bring selected objects to the front", NULL,
       CMDID_FRONT },
!    { N_("Back"), "Cntrl+b", "Send selected objects to the back", NULL,
!      CMDID_BACK },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Group"), "Cntrl+g", "Group selected objects into a compound object",
!      NULL, CMDID_GROUP },
!    { N_("UnGroup"), "Cntrl+u",
       "Break up selected grouped objects into its components", NULL,
       CMDID_UNGROUP },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Lock"), "Alt+<", "Lock the positions of selected objects", NULL,
       CMDID_LOCK },
!    { N_("UnLock"), "Alt+>", "UnLock the positions of selected objects", NULL,
       CMDID_UNLOCK },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("HoriAlign"), TGMUITEM_PINNABLESUBMENU,
       "HoriAlign submenu >>>", &horiAlignMenuInfo, MENU_HORIALIGN },
!    { N_("VertAlign"), TGMUITEM_PINNABLESUBMENU,
       "VertAlign submenu >>>", &vertAlignMenuInfo,
       MENU_VERTALIGN },
!    { N_("AlignObjs"), "Cntrl+l",
       "Align selected objects with each other using the current alignments",
       NULL, CMDID_ALIGNOBJS },
!    { N_("AlignToGrid"), "Cntrl+t",
       "Align selected objects to grid points using the current alignments", NULL,
       CMDID_ALIGNTOGRID },
!    { N_("AlignToPage"), "Alt+&",
       "Align selected objects to the page using the current alignments", NULL,
       CMDID_ALIGNTOPAGE },
!    { N_("AlignObjsDirect"), TGMUITEM_SUBMENU,
       "Align objects direct submenu >>>", &alignObjsDirectMenuInfo, INVALID },
!    { N_("AlignToGridDirect"), TGMUITEM_SUBMENU,
       "Align to grid direct submenu >>>", &alignToGridDirectMenuInfo, INVALID },
!    { N_("AlignToPageDirect"), TGMUITEM_SUBMENU,
       "Align to page direct submenu >>>", &alignToPageDirectMenuInfo, INVALID },
!    { N_("More Object Alignments"), TGMUITEM_SUBMENU,
       "Align objects submenu >>>", &alignMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SizeObjects"), TGMUITEM_SUBMENU,
       "Size objects submenu >>>", &sizeMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("DistributeObjs"), "Alt+l",
       "Distribute selected objects using the current alignments", NULL,
       CMDID_DISTRIBUTEOBJS },
!    { N_("DistributeObjsDirect"), TGMUITEM_SUBMENU,
       "Distribute objects direct submenu >>>", &distrObjsDirectMenuInfo,
       INVALID },
!    { N_("LayoutOnArc"), NULL, "Layout objects on an arc", NULL,
!      CMDID_LAYOUTONARC },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("FlipHorizontal"), "Alt+h", "Flip selected objects horizontally", NULL,
       CMDID_FLIPHORIZONTAL },
!    { N_("FlipVertical"), "Alt+v", "Flip selected objects vertically", NULL,
       CMDID_FLIPVERTICAL },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("RotateClockWise"), "Alt+w", "Rotate selected objects clockwise", NULL,
       CMDID_ROTATECLOCKWISE },
!    { N_("RotateCounter"), "Alt+c", "Rotate selected objects counter-clockwise",
       NULL, CMDID_ROTATECOUNTER },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SetTextRotation..."), NULL, "Set text rotation in degrees", NULL,
       CMDID_SETTEXTROTATION },
!    { N_("SetRotationIncrement..."), NULL, "Set rotation increment in degrees",
!      NULL, CMDID_SETROTATIONINCREMENT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("AbutHorizontal"), "Alt+_",
!      "Squish selected objects together horizontally",
       NULL, CMDID_ABUTHORIZONTAL },
!    { N_("AbutVertical"), "Alt+|", "Squish selected objects together vertically",
       NULL, CMDID_ABUTVERTICAL },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("CenterAnEndPoint"), NULL,
       "Move an endpoint of a selected poly to the center of another object",
       NULL, CMDID_CENTERANENDPOINT },
***************
*** 894,902 ****
  
  static TgMenuItemInfo scrollModeMenuItemInfo[] = {
!    { "Off", NULL, "Do not update canvas window while scrolling", NULL,
       CMDID_CHANGESCROLLMODE },
!    { "Jump", NULL, "Jump update canvas window while scrolling", NULL,
       CMDID_CHANGESCROLLMODE },
!    { "Smooth", NULL, "Update canvas window smoothly while scrolling", NULL,
       CMDID_CHANGESCROLLMODE },
  };
--- 910,918 ----
  
  static TgMenuItemInfo scrollModeMenuItemInfo[] = {
!    { N_("Off"), NULL, "Do not update canvas window while scrolling", NULL,
       CMDID_CHANGESCROLLMODE },
!    { N_("Jump"), NULL, "Jump update canvas window while scrolling", NULL,
       CMDID_CHANGESCROLLMODE },
!    { N_("Smooth"), NULL, "Update canvas window smoothly while scrolling", NULL,
       CMDID_CHANGESCROLLMODE },
  };
***************
*** 905,920 ****
  
  static TgMenuItemInfo showHideMenuItemInfo[] = {
!    { "ShowBit/Pixmap", NULL,
       "Toggle between hiding/showing detailed bitmap/pixmap objects", NULL,
       CMDID_TOGGLEMAPSHOWN },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ShowMeasurement", NULL,
       "Show cursor measurements", NULL, CMDID_TOGGLESHOWMEASUREMENT },
!    { "SetMeasureUnit...", NULL, "Set the unit of measurements", NULL,
       CMDID_SETMEASUREUNIT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ShowMenubar", NULL, "Show menubar window", NULL,
       CMDID_TOGGLESHOWMENUBAR },
!    { "ShowStatus", NULL, "Show status window", NULL, CMDID_TOGGLESHOWSTATUS },
     { NULL, NULL, NULL, NULL, INVALID }
  };
--- 921,937 ----
  
  static TgMenuItemInfo showHideMenuItemInfo[] = {
!    { N_("ShowBit/Pixmap"), NULL,
       "Toggle between hiding/showing detailed bitmap/pixmap objects", NULL,
       CMDID_TOGGLEMAPSHOWN },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("ShowMeasurement"), NULL,
       "Show cursor measurements", NULL, CMDID_TOGGLESHOWMEASUREMENT },
!    { N_("SetMeasureUnit..."), NULL, "Set the unit of measurements", NULL,
       CMDID_SETMEASUREUNIT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("ShowMenubar"), NULL, "Show menubar window", NULL,
       CMDID_TOGGLESHOWMENUBAR },
!    { N_("ShowStatus"), NULL, "Show status window", NULL,
!      CMDID_TOGGLESHOWSTATUS },
     { NULL, NULL, NULL, NULL, INVALID }
  };
***************
*** 923,935 ****
  
  static TgMenuItemInfo slideShowMenuItemInfo[] = {
!    { "SlideShow", "Alt+Cntrl+8", "Toggle SlideShow mode", NULL,
       CMDID_TOGGLESLIDESHOW },
!    { "SetSlideShowBorderColor...", NULL,
       "Set the color of the slideshow border", NULL,
       CMDID_SETSLIDESHOWBRDRCOLOR },
!    { "SetSlideShowWindowOffsets...", NULL,
       "Set the offsets of the slideshow window", NULL,
       CMDID_SETSLIDESHOWWINOFFSETS },
!    { "VisibleGridInSlideShow", NULL,
       "Toggle visible grid in slideshow mode", NULL,
       CMDID_VISIBLEGRIDINSLIDESHOW },
--- 940,952 ----
  
  static TgMenuItemInfo slideShowMenuItemInfo[] = {
!    { N_("SlideShow"), "Alt+Cntrl+8", "Toggle SlideShow mode", NULL,
       CMDID_TOGGLESLIDESHOW },
!    { N_("SetSlideShowBorderColor..."), NULL,
       "Set the color of the slideshow border", NULL,
       CMDID_SETSLIDESHOWBRDRCOLOR },
!    { N_("SetSlideShowWindowOffsets..."), NULL,
       "Set the offsets of the slideshow window", NULL,
       CMDID_SETSLIDESHOWWINOFFSETS },
!    { N_("VisibleGridInSlideShow"), NULL,
       "Toggle visible grid in slideshow mode", NULL,
       CMDID_VISIBLEGRIDINSLIDESHOW },
***************
*** 940,997 ****
  
  static TgMenuItemInfo layoutMenuItemInfo[] = {
!    { "+Grid", "Alt+i", "Increment grid size", NULL, CMDID_INCGRID },
!    { "-Grid", "Alt+d", "Decrement grid size", NULL, CMDID_DECGRID },
!    { "VisibleGrid", "Alt+g", "Hide/show grid lines", NULL, CMDID_TOGGLEGRID },
!    { "SnapToGrid", "Alt+Cntrl+g", "Toggle the snapping to grid points effect",
!      NULL, CMDID_TOGGLESNAP },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SaveOrigin", NULL, "Save current location as the 'origin' of the drawing",
       NULL, CMDID_SAVEORIGIN },
!    { "ScrollToOrig", "Alt+^", "Scroll to the 'origin' of the drawing", NULL,
       CMDID_SCROLLTOORIG },
!    { "ScrollMode", TGMUITEM_SUBMENU,
       "ScrollMode submenu >>>", &scrollModeMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ZoomIn", "Alt+z", "Zoom in", NULL, CMDID_ZOOMIN },
!    { "ZoomOut", "Alt+o", "Zoom out", NULL, CMDID_ZOOMOUT },
!    { "DefaultZoom", "Alt+:", "No zoom", NULL, CMDID_DEFAULTZOOM },
!    { "ZoomWayOut", "Alt+`", "Zoom way out to see the whole drawing", NULL,
       CMDID_ZOOMWAYOUT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Portrait", NULL, "Portrait page style", NULL, CMDID_PORTRAITMODE },
!    { "Landscape", NULL, "Lanscape page style", NULL,
       CMDID_LANDSCAPEMODE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "StackedPage", TGMUITEM_PINNABLESUBMENU,
       "StackedPage submenu >>>", &stackedPageMenuInfo, MENU_STACKEDPAGE },
!    { "TiledPage", TGMUITEM_PINNABLESUBMENU,
       "TiledPage submenu >>>", &tiledPageMenuInfo, MENU_TILEDPAGE },
!    { "PageLayout", TGMUITEM_PINNABLESUBMENU,
       "PageLayout submenu >>>", &pageLayoutMenuInfo, MENU_PAGELAYOUT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Print/ExportFormat", TGMUITEM_SUBMENU,
       "Select print/export format submenu >>>", &exportFormatMenuInfo, INVALID },
!    { "Print/ExportInColor", "Alt+Cntrl+k",
       "Toggle between color and black & white printing modes", NULL,
       CMDID_TOGGLEBWCOLORPS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SetReduction...", "Alt+%",
       "Specify reduction/magnification of the whole drawing", NULL,
       CMDID_SETREDUCTION },
!    { "MetricGrid", "Alt+Cntrl+-",
       "Toggle between English and Metric grid systems", NULL,
       CMDID_TOGGLEGRIDSYSTEM },
!    { "OneMotionSelMove", NULL,
       "Toggle between click-select-move and click-select-click-move modes", NULL,
       CMDID_TOGGLEONEMOTIONSELMOVE },
!    { "UseGrayScale", NULL,
       "Toggle between using gray scales to tile patterns to speed up printing",
       NULL, CMDID_TOGGLEUSEGRAYSCALE },
!    { "UseColorLayers", NULL, "Toggle color layers", NULL,
       CMDID_TOGGLECOLORLAYERS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Show/Hide", TGMUITEM_SUBMENU,
       "Show/Hide submenu >>>", &showHideMenuInfo, INVALID },
!    { "SlideShow", TGMUITEM_SUBMENU,
       "SlideShow submenu >>>", &slideShowMenuInfo, INVALID },
     { NULL, NULL, NULL, NULL, INVALID }
--- 957,1016 ----
  
  static TgMenuItemInfo layoutMenuItemInfo[] = {
!    { N_("+Grid"), "Alt+i", "Increment grid size", NULL, CMDID_INCGRID },
!    { N_("-Grid"), "Alt+d", "Decrement grid size", NULL, CMDID_DECGRID },
!    { N_("VisibleGrid"), "Alt+g", "Hide/show grid lines", NULL,
!      CMDID_TOGGLEGRID },
!    { N_("SnapToGrid"), "Alt+Cntrl+g",
!      "Toggle the snapping to grid points effect", NULL, CMDID_TOGGLESNAP },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SaveOrigin"), NULL,
!      "Save current location as the 'origin' of the drawing",
       NULL, CMDID_SAVEORIGIN },
!    { N_("ScrollToOrig"), "Alt+^", "Scroll to the 'origin' of the drawing", NULL,
       CMDID_SCROLLTOORIG },
!    { N_("ScrollMode"), TGMUITEM_SUBMENU,
       "ScrollMode submenu >>>", &scrollModeMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("ZoomIn"), "Alt+z", "Zoom in", NULL, CMDID_ZOOMIN },
!    { N_("ZoomOut"), "Alt+o", "Zoom out", NULL, CMDID_ZOOMOUT },
!    { N_("DefaultZoom"), "Alt+:", "No zoom", NULL, CMDID_DEFAULTZOOM },
!    { N_("ZoomWayOut"), "Alt+`", "Zoom way out to see the whole drawing", NULL,
       CMDID_ZOOMWAYOUT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Portrait"), NULL, "Portrait page style", NULL, CMDID_PORTRAITMODE },
!    { N_("Landscape"), NULL, "Lanscape page style", NULL,
       CMDID_LANDSCAPEMODE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("StackedPage"), TGMUITEM_PINNABLESUBMENU,
       "StackedPage submenu >>>", &stackedPageMenuInfo, MENU_STACKEDPAGE },
!    { N_("TiledPage"), TGMUITEM_PINNABLESUBMENU,
       "TiledPage submenu >>>", &tiledPageMenuInfo, MENU_TILEDPAGE },
!    { N_("PageLayout"), TGMUITEM_PINNABLESUBMENU,
       "PageLayout submenu >>>", &pageLayoutMenuInfo, MENU_PAGELAYOUT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Print/ExportFormat"), TGMUITEM_SUBMENU,
       "Select print/export format submenu >>>", &exportFormatMenuInfo, INVALID },
!    { N_("Print/ExportInColor"), "Alt+Cntrl+k",
       "Toggle between color and black & white printing modes", NULL,
       CMDID_TOGGLEBWCOLORPS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SetReduction..."), "Alt+%",
       "Specify reduction/magnification of the whole drawing", NULL,
       CMDID_SETREDUCTION },
!    { N_("MetricGrid"), "Alt+Cntrl+-",
       "Toggle between English and Metric grid systems", NULL,
       CMDID_TOGGLEGRIDSYSTEM },
!    { N_("OneMotionSelMove"), NULL,
       "Toggle between click-select-move and click-select-click-move modes", NULL,
       CMDID_TOGGLEONEMOTIONSELMOVE },
!    { N_("UseGrayScale"), NULL,
       "Toggle between using gray scales to tile patterns to speed up printing",
       NULL, CMDID_TOGGLEUSEGRAYSCALE },
!    { N_("UseColorLayers"), NULL, "Toggle color layers", NULL,
       CMDID_TOGGLECOLORLAYERS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Show/Hide"), TGMUITEM_SUBMENU,
       "Show/Hide submenu >>>", &showHideMenuInfo, INVALID },
!    { N_("SlideShow"), TGMUITEM_SUBMENU,
       "SlideShow submenu >>>", &slideShowMenuInfo, INVALID },
     { NULL, NULL, NULL, NULL, INVALID }
***************
*** 1001,1070 ****
  
  static TgMenuItemInfo propertiesMenuItemInfo[] = {
!    { "CopyProperties...", NULL,
       "Copy properties (e.g., color, fill, etc.) into the cut buffer", NULL,
       CMDID_COPYPROPERTIES },
!    { "PasteProperties...", NULL,
       "Paste properties (e.g., color, fill, etc.) from the cut buffer", NULL,
       CMDID_PASTEPROPERTIES },
!    { "SaveProperties...", NULL,
       "Save and name a property (e.g., color, fill, etc.) set", NULL,
       CMDID_SAVEPROPERTIES },
!    { "RestoreProperties...", NULL,
       "Restore a named property (e.g., color, fill, etc.) set", NULL,
       CMDID_RESTOREPROPERTIES },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "UpdateObjects", "Alt+0",
       "Update selected objects to have current drawing properties", NULL,
       CMDID_UPDATE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SetSelLineWidth...", NULL,
       "Change the line width (and arrow width/height) of selected objects", NULL,
       CMDID_SETSELLINEWIDTH },
!    { "SetSelFontSize...", NULL,
       "Change the font size of selected objects", NULL, CMDID_SETSELFONTSIZE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "AddColor...", NULL, "Add colors to the current palette", NULL,
       CMDID_ADDCOLOR },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SetEditTextSize...", NULL,
       "Set the text size to be used in editing existing text objects", NULL,
       CMDID_SETEDITTEXTSIZE },
!    { "SetAltEditTextBgColor...", NULL,
       "Set the background color to be used in editing existing text objects",
       NULL, CMDID_SETALTEDITTEXTBGCOLOR },
!    { "SetAltEditTextHighlightColor...", NULL,
       "Set the highlight color to be used in editing existing text objects",
       NULL, CMDID_SETALTEDITTEXTHIGHLIGHTCOLOR },
!    { "UseAltEditTextBgColor", NULL,
       "Toggles the background color to be used in editing existing text objects",
       NULL, CMDID_TOGGLEALTEDITTEXTBGCOLOR },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Font", TGMUITEM_PINNABLESUBMENU,
       "Font submenu >>>", &fontMenuInfo, MENU_FONT },
!    { "TextStyle", TGMUITEM_PINNABLESUBMENU,
       "TextStyle submenu >>>", &fontStyleMenuInfo, MENU_STYLE },
!    { "TextSize", TGMUITEM_PINNABLESUBMENU,
       "TextSize submenu >>>", &fontSizeMenuInfo, MENU_SIZE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "LineDash", TGMUITEM_PINNABLESUBMENU,
       "LineDash submenu >>>", &lineDashMenuInfo, MENU_LINEDASH },
!    { "LineStyle", TGMUITEM_PINNABLESUBMENU,
       "LineStyle submenu >>>", &lineStyleMenuInfo, MENU_LINESTYLE },
!    { "LineType", TGMUITEM_PINNABLESUBMENU,
       "LineType submenu >>>", &lineTypeMenuInfo, MENU_LINETYPE },
!    { "LineWidth", TGMUITEM_PINNABLESUBMENU,
       "LineWidth submenu >>>", &lineWidthMenuInfo, MENU_LINEWIDTH },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Fill", TGMUITEM_PINNABLESUBMENU,
       "Fill submenu >>>", &fillMenuInfo, MENU_FILL },
!    { "Pen", TGMUITEM_PINNABLESUBMENU,
       "Pen submenu >>>", &penMenuInfo, MENU_PEN },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "MoveMode", TGMUITEM_PINNABLESUBMENU,
       "MoveMode submenu >>>", &moveModeMenuInfo, MENU_MOVEMODE },
!    { "StretchText", TGMUITEM_PINNABLESUBMENU,
       "StretchText submenu >>>", &stretchableTextModeMenuInfo,
       MENU_STRETCHTEXT },
!    { "TransPattern", TGMUITEM_PINNABLESUBMENU,
       "TransPattern submenu >>>", &transPatModeMenuInfo, MENU_TRANSPAT },
     { NULL, NULL, NULL, NULL, INVALID }
--- 1020,1089 ----
  
  static TgMenuItemInfo propertiesMenuItemInfo[] = {
!    { N_("CopyProperties..."), NULL,
       "Copy properties (e.g., color, fill, etc.) into the cut buffer", NULL,
       CMDID_COPYPROPERTIES },
!    { N_("PasteProperties..."), NULL,
       "Paste properties (e.g., color, fill, etc.) from the cut buffer", NULL,
       CMDID_PASTEPROPERTIES },
!    { N_("SaveProperties..."), NULL,
       "Save and name a property (e.g., color, fill, etc.) set", NULL,
       CMDID_SAVEPROPERTIES },
!    { N_("RestoreProperties..."), NULL,
       "Restore a named property (e.g., color, fill, etc.) set", NULL,
       CMDID_RESTOREPROPERTIES },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("UpdateObjects"), "Alt+0",
       "Update selected objects to have current drawing properties", NULL,
       CMDID_UPDATE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SetSelLineWidth..."), NULL,
       "Change the line width (and arrow width/height) of selected objects", NULL,
       CMDID_SETSELLINEWIDTH },
!    { N_("SetSelFontSize..."), NULL,
       "Change the font size of selected objects", NULL, CMDID_SETSELFONTSIZE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("AddColor..."), NULL, "Add colors to the current palette", NULL,
       CMDID_ADDCOLOR },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SetEditTextSize..."), NULL,
       "Set the text size to be used in editing existing text objects", NULL,
       CMDID_SETEDITTEXTSIZE },
!    { N_("SetAltEditTextBgColor..."), NULL,
       "Set the background color to be used in editing existing text objects",
       NULL, CMDID_SETALTEDITTEXTBGCOLOR },
!    { N_("SetAltEditTextHighlightColor..."), NULL,
       "Set the highlight color to be used in editing existing text objects",
       NULL, CMDID_SETALTEDITTEXTHIGHLIGHTCOLOR },
!    { N_("UseAltEditTextBgColor"), NULL,
       "Toggles the background color to be used in editing existing text objects",
       NULL, CMDID_TOGGLEALTEDITTEXTBGCOLOR },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Font"), TGMUITEM_PINNABLESUBMENU,
       "Font submenu >>>", &fontMenuInfo, MENU_FONT },
!    { N_("TextStyle"), TGMUITEM_PINNABLESUBMENU,
       "TextStyle submenu >>>", &fontStyleMenuInfo, MENU_STYLE },
!    { N_("TextSize"), TGMUITEM_PINNABLESUBMENU,
       "TextSize submenu >>>", &fontSizeMenuInfo, MENU_SIZE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("LineDash"), TGMUITEM_PINNABLESUBMENU,
       "LineDash submenu >>>", &lineDashMenuInfo, MENU_LINEDASH },
!    { N_("LineStyle"), TGMUITEM_PINNABLESUBMENU,
       "LineStyle submenu >>>", &lineStyleMenuInfo, MENU_LINESTYLE },
!    { N_("LineType"), TGMUITEM_PINNABLESUBMENU,
       "LineType submenu >>>", &lineTypeMenuInfo, MENU_LINETYPE },
!    { N_("LineWidth"), TGMUITEM_PINNABLESUBMENU,
       "LineWidth submenu >>>", &lineWidthMenuInfo, MENU_LINEWIDTH },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Fill"), TGMUITEM_PINNABLESUBMENU,
       "Fill submenu >>>", &fillMenuInfo, MENU_FILL },
!    { N_("Pen"), TGMUITEM_PINNABLESUBMENU,
       "Pen submenu >>>", &penMenuInfo, MENU_PEN },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("MoveMode"), TGMUITEM_PINNABLESUBMENU,
       "MoveMode submenu >>>", &moveModeMenuInfo, MENU_MOVEMODE },
!    { N_("StretchText"), TGMUITEM_PINNABLESUBMENU,
       "StretchText submenu >>>", &stretchableTextModeMenuInfo,
       MENU_STRETCHTEXT },
!    { N_("TransPattern"), TGMUITEM_PINNABLESUBMENU,
       "TransPattern submenu >>>", &transPatModeMenuInfo, MENU_TRANSPAT },
     { NULL, NULL, NULL, NULL, INVALID }
***************
*** 1074,1091 ****
  
  static TgMenuItemInfo navigateMenuItemInfo[] = {
!    { "GoBack", NULL, "Go back one file", NULL, CMDID_GOBACK },
!    { "GoForward", NULL, "Go forward one file", NULL, CMDID_GOFORWARD },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "RefreshCurrent", NULL, "Reload the current file", NULL,
       CMDID_REFRESHCURRENT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "HotList...", NULL, "Navigate using the hot-list", NULL, CMDID_HOTLIST },
!    { "AddCurrentToHotList", NULL, "Add the current file to the hot-list", NULL,
!      CMDID_ADDCURRENTTOHOTLIST },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "SessionHistory...", NULL, "Go to a file visited during this session",
       NULL, CMDID_SESSIONHISTORY },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "HyperSpace", NULL, "Toggle HyperSpace mode", NULL,
       CMDID_TOGGLEHYPERSPACE },
     { NULL, NULL, NULL, NULL, INVALID }
--- 1093,1111 ----
  
  static TgMenuItemInfo navigateMenuItemInfo[] = {
!    { N_("GoBack"), NULL, "Go back one file", NULL, CMDID_GOBACK },
!    { N_("GoForward"), NULL, "Go forward one file", NULL, CMDID_GOFORWARD },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("RefreshCurrent"), NULL, "Reload the current file", NULL,
       CMDID_REFRESHCURRENT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("HotList..."), NULL, "Navigate using the hot-list", NULL,
!      CMDID_HOTLIST },
!    { N_("AddCurrentToHotList"), NULL, "Add the current file to the hot-list",
!      NULL, CMDID_ADDCURRENTTOHOTLIST },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("SessionHistory..."), NULL, "Go to a file visited during this session",
       NULL, CMDID_SESSIONHISTORY },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("HyperSpace"), NULL, "Toggle HyperSpace mode", NULL,
       CMDID_TOGGLEHYPERSPACE },
     { NULL, NULL, NULL, NULL, INVALID }
***************
*** 1095,1130 ****
  
  static TgMenuItemInfo attrMenuItemInfo[] = {
!    { "AttachAttrs", "Alt+a",
       "Attach selected text objects as attributes for the non-text object", NULL,
       CMDID_ATTACHATTRS },
!    { "DetachAttrs", "Alt+t",
       "Detach all attributes of selected objects", NULL,
       CMDID_DETACHATTRS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "EditAttrs...", NULL,
       "Edit attributes of a selected object", NULL,
       CMDID_EDITATTRS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ShowAttr", "Alt+-",
       "Make all attributes of selected objects visible", NULL,
       CMDID_SHOWATTR },
!    { "ShowAttrName", "Alt+n",
       "Make all attribute names of selected objects visible", NULL,
       CMDID_SHOWATTRNAME },
!    { "HideAttr", "Alt+Cntrl+h",
       "Hide all attributes for selected objects", NULL,
       CMDID_HIDEATTR },
!    { "HideAttrName", "Alt+j",
       "Hide all attribute names for selected objects", NULL,
       CMDID_HIDEATTRNAME },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Move/JustfyAttr", "Alt+m",
       "Move/justify an attribute for a selected object", NULL,
       CMDID_MOVEJUSTIFYATTR },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ImportAttrs...", NULL,
       "Import attributes of a selected object from a text file", NULL,
       CMDID_IMPORTATTRS },
!    { "ExportAttrs...", NULL,
       "Export attributes of a selected object to a text file", NULL,
       CMDID_EXPORTATTRS },
--- 1115,1150 ----
  
  static TgMenuItemInfo attrMenuItemInfo[] = {
!    { N_("AttachAttrs"), "Alt+a",
       "Attach selected text objects as attributes for the non-text object", NULL,
       CMDID_ATTACHATTRS },
!    { N_("DetachAttrs"), "Alt+t",
       "Detach all attributes of selected objects", NULL,
       CMDID_DETACHATTRS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("EditAttrs..."), NULL,
       "Edit attributes of a selected object", NULL,
       CMDID_EDITATTRS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("ShowAttr"), "Alt+-",
       "Make all attributes of selected objects visible", NULL,
       CMDID_SHOWATTR },
!    { N_("ShowAttrName"), "Alt+n",
       "Make all attribute names of selected objects visible", NULL,
       CMDID_SHOWATTRNAME },
!    { N_("HideAttr"), "Alt+Cntrl+h",
       "Hide all attributes for selected objects", NULL,
       CMDID_HIDEATTR },
!    { N_("HideAttrName"), "Alt+j",
       "Hide all attribute names for selected objects", NULL,
       CMDID_HIDEATTRNAME },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Move/JustfyAttr"), "Alt+m",
       "Move/justify an attribute for a selected object", NULL,
       CMDID_MOVEJUSTIFYATTR },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("ImportAttrs..."), NULL,
       "Import attributes of a selected object from a text file", NULL,
       CMDID_IMPORTATTRS },
!    { N_("ExportAttrs..."), NULL,
       "Export attributes of a selected object to a text file", NULL,
       CMDID_EXPORTATTRS },
***************
*** 1135,1146 ****
  
  static TgMenuItemInfo fileAttrMenuItemInfo[] = {
!    { "AttachFileAttrs", NULL,
       "Attach selected text objects as file attributes", NULL,
       CMDID_ATTACHFILEATTRS },
!    { "DetachFileAttrs", NULL,
       "Detach all file attributes", NULL,
       CMDID_DETACHFILEATTRS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "EditFileAttrs...", NULL,
       "Edit file attributes", NULL,
       CMDID_EDITFILEATTRS },
--- 1155,1166 ----
  
  static TgMenuItemInfo fileAttrMenuItemInfo[] = {
!    { N_("AttachFileAttrs"), NULL,
       "Attach selected text objects as file attributes", NULL,
       CMDID_ATTACHFILEATTRS },
!    { N_("DetachFileAttrs"), NULL,
       "Detach all file attributes", NULL,
       CMDID_DETACHFILEATTRS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("EditFileAttrs..."), NULL,
       "Edit file attributes", NULL,
       CMDID_EDITFILEATTRS },
***************
*** 1151,1158 ****
  
  static TgMenuItemInfo animateMenuItemInfo[] = {
!    { "AnimateSend", "Alt+e",
       "Animate a little token on a selected poly (not very useful)", NULL,
       CMDID_ANIMATESEND },
!    { "AnimateFlash", "Alt+f",
       "Flash a selected poly (not very useful)", NULL,
       CMDID_ANIMATEFLASH },
--- 1171,1178 ----
  
  static TgMenuItemInfo animateMenuItemInfo[] = {
!    { N_("AnimateSend"), "Alt+e",
       "Animate a little token on a selected poly (not very useful)", NULL,
       CMDID_ANIMATESEND },
!    { N_("AnimateFlash"), "Alt+f",
       "Flash a selected poly (not very useful)", NULL,
       CMDID_ANIMATEFLASH },
***************
*** 1163,1215 ****
  
  static TgMenuItemInfo specialMenuItemInfo[] = {
!    { "MakeSymbolic", "Alt+Cntrl+m",
       "Turn a selected grouped/icon object into a symbol object", NULL,
       CMDID_MAKESYMBOLIC },
!    { "UnMakeSymbolic", "Alt+Cntrl+n",
       "Turn a selected symbol object into a grouped object", NULL,
       CMDID_UNMAKESYMBOLIC },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Instantiate...", "Cntrl+i",
       "Instantiate a building-block object from the current domain", NULL,
       CMDID_INSTANTIATE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "MakeIconic...", "Alt+Cntrl+i",
       "Turn a selected grouped/symbol object into an icon object", NULL,
       CMDID_MAKEICONIC },
!    { "UnMakeIconic", "Alt+Cntrl+j",
       "Turn an icon object into a grouped object", NULL,
       CMDID_UNMAKEICONIC },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Push", "Cntrl+v",
       "Push into (edit) the symbol file which defines the selected icon object",
       NULL, CMDID_PUSH },
!    { "Pop", "Cntrl+k",
       "Pop back to a high lever (reverse of Push)", NULL,
       CMDID_POP },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Attribute", TGMUITEM_SUBMENU,
       "Attribute submenu >>>", &attrMenuInfo, INVALID },
!    { "FileAttribute", TGMUITEM_SUBMENU,
       "File attribute submenu >>>", &fileAttrMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "UpdateSymbols", "Alt+Cntrl+u",
       "Refresh selected icon objects from their definition files", NULL,
       CMDID_UPDATESYMBOLS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Misc", TGMUITEM_SUBMENU,
       "Misc submenu >>>", &animateMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "MergeWithTable...", NULL,
       "Merge selected object with a table file", NULL,
       CMDID_MERGEWITHTABLE },
!    { "ExportToTable...", NULL,
       "Export attributes of selected objects to a table file", NULL,
       CMDID_EXPORTTOTABLE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ExecCmdsFromFile...", NULL, "Execute internal commands from a file", NULL,
!      CMDID_EXECCMDSFROMFILE },
  #ifdef _TGIF_WB
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "WhiteBoard", NULL,
       "Start/Enable the White Board communication", NULL, CMDID_WHITEBOARD },
  #endif /* _TGIF_WB */
--- 1183,1235 ----
  
  static TgMenuItemInfo specialMenuItemInfo[] = {
!    { N_("MakeSymbolic"), "Alt+Cntrl+m",
       "Turn a selected grouped/icon object into a symbol object", NULL,
       CMDID_MAKESYMBOLIC },
!    { N_("UnMakeSymbolic"), "Alt+Cntrl+n",
       "Turn a selected symbol object into a grouped object", NULL,
       CMDID_UNMAKESYMBOLIC },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Instantiate..."), "Cntrl+i",
       "Instantiate a building-block object from the current domain", NULL,
       CMDID_INSTANTIATE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("MakeIconic..."), "Alt+Cntrl+i",
       "Turn a selected grouped/symbol object into an icon object", NULL,
       CMDID_MAKEICONIC },
!    { N_("UnMakeIconic"), "Alt+Cntrl+j",
       "Turn an icon object into a grouped object", NULL,
       CMDID_UNMAKEICONIC },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Push"), "Cntrl+v",
       "Push into (edit) the symbol file which defines the selected icon object",
       NULL, CMDID_PUSH },
!    { N_("Pop"), "Cntrl+k",
       "Pop back to a high lever (reverse of Push)", NULL,
       CMDID_POP },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Attribute"), TGMUITEM_SUBMENU,
       "Attribute submenu >>>", &attrMenuInfo, INVALID },
!    { N_("FileAttribute"), TGMUITEM_SUBMENU,
       "File attribute submenu >>>", &fileAttrMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("UpdateSymbols"), "Alt+Cntrl+u",
       "Refresh selected icon objects from their definition files", NULL,
       CMDID_UPDATESYMBOLS },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Misc"), TGMUITEM_SUBMENU,
       "Misc submenu >>>", &animateMenuInfo, INVALID },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("MergeWithTable..."), NULL,
       "Merge selected object with a table file", NULL,
       CMDID_MERGEWITHTABLE },
!    { N_("ExportToTable..."), NULL,
       "Export attributes of selected objects to a table file", NULL,
       CMDID_EXPORTTOTABLE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("ExecCmdsFromFile..."), NULL, "Execute internal commands from a file",
!      NULL, CMDID_EXECCMDSFROMFILE },
  #ifdef _TGIF_WB
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("WhiteBoard"), NULL,
       "Start/Enable the White Board communication", NULL, CMDID_WHITEBOARD },
  #endif /* _TGIF_WB */
***************
*** 1220,1230 ****
  
  static TgMenuItemInfo helpMenuItemInfo[] = {
!    { "LatestReleaseInfo", NULL,
       "Find out what is the version number of the most recently released tgif",
       NULL, CMDID_LATESTRELEASEINFO },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Copyright", NULL, "Copyright information", NULL, CMDID_COPYRIGHT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "About", NULL,
       "Version information, where to send bug reports, etc.", NULL,
       CMDID_ABOUT },
--- 1240,1250 ----
  
  static TgMenuItemInfo helpMenuItemInfo[] = {
!    { N_("LatestReleaseInfo"), NULL,
       "Find out what is the version number of the most recently released tgif",
       NULL, CMDID_LATESTRELEASEINFO },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Copyright"), NULL, "Copyright information", NULL, CMDID_COPYRIGHT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("About"), NULL,
       "Version information, where to send bug reports, etc.", NULL,
       CMDID_ABOUT },
***************
*** 1237,1303 ****
  
  static TgMenuItemInfo mainMenuItemInfo[] = {
!    { "File", TGMUITEM_PINNABLESUBMENU, "File Menu", &fileMenuInfo, MENU_FILE },
!    { "Edit", TGMUITEM_PINNABLESUBMENU, "Edit Menu", &editMenuInfo, MENU_EDIT },
!    { "Layout", TGMUITEM_PINNABLESUBMENU,
       "Layout Menu", &layoutMenuInfo, MENU_LAYOUT },
!    { "Arrange", TGMUITEM_PINNABLESUBMENU,
       "Arrange Menu", &arrangeMenuInfo, MENU_ARRANGE },
!    { "Properties", TGMUITEM_PINNABLESUBMENU,
       "Properties Menu", &propertiesMenuInfo, MENU_PROPERTIES },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "StackedPage", TGMUITEM_PINNABLESUBMENU,
       "StackedPage Menu", &stackedPageMenuInfo, MENU_STACKEDPAGE },
!    { "TiledPage", TGMUITEM_PINNABLESUBMENU,
       "TiledPage Menu", &tiledPageMenuInfo, MENU_TILEDPAGE },
!    { "PageLayout", TGMUITEM_PINNABLESUBMENU,
       "PageLayout Menu", &pageLayoutMenuInfo, MENU_PAGELAYOUT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "HoriAlign", TGMUITEM_PINNABLESUBMENU,
       "HoriAlign Menu", &horiAlignMenuInfo, MENU_HORIALIGN },
!    { "VertAlign", TGMUITEM_PINNABLESUBMENU,
       "VertAlign Menu", &vertAlignMenuInfo, MENU_VERTALIGN },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Font", TGMUITEM_PINNABLESUBMENU, "Font Menu", &fontMenuInfo, MENU_FONT },
!    { "TextStyle", TGMUITEM_PINNABLESUBMENU,
       "TextStyle Menu", &fontStyleMenuInfo, MENU_STYLE },
!    { "TextSize", TGMUITEM_PINNABLESUBMENU,
       "TextSize Menu", &fontSizeMenuInfo, MENU_SIZE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "LineDash", TGMUITEM_PINNABLESUBMENU,
       "LineDash Menu", &lineDashMenuInfo, MENU_LINEDASH },
!    { "LineStyle", TGMUITEM_PINNABLESUBMENU,
       "LineStyle Menu", &lineStyleMenuInfo, MENU_LINESTYLE },
!    { "LineType", TGMUITEM_PINNABLESUBMENU,
       "LineType Menu", &lineTypeMenuInfo, MENU_LINETYPE },
!    { "LineWidth", TGMUITEM_PINNABLESUBMENU,
       "LineWidth Menu", &lineWidthMenuInfo, MENU_LINEWIDTH },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Fill", TGMUITEM_PINNABLESUBMENU, "Fill Menu", &fillMenuInfo, MENU_FILL },
!    { "Pen", TGMUITEM_PINNABLESUBMENU, "Pen Menu", &penMenuInfo, MENU_PEN },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "MoveMode", TGMUITEM_PINNABLESUBMENU,
       "MoveMode Menu", &moveModeMenuInfo, MENU_MOVEMODE },
!    { "Shape", TGMUITEM_PINNABLESUBMENU,
       "Shape Menu", &shapeMenuInfo, MENU_SHAPE },
!    { "StretchText", TGMUITEM_PINNABLESUBMENU,
       "StretchText Menu", &stretchableTextModeMenuInfo, MENU_STRETCHTEXT },
!    { "TransPattern", TGMUITEM_PINNABLESUBMENU,
       "TransPattern Menu", &transPatModeMenuInfo,
           MENU_TRANSPAT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "ImageProc", TGMUITEM_PINNABLESUBMENU,
       "ImageProc Menu", &imageProcMenuInfo, MENU_IMAGEPROC },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { "Color", TGMUITEM_PINNABLESUBMENU,
       "Color Menu", &colorMenuInfo, MENU_COLOR },
!    { "Navigate", TGMUITEM_PINNABLESUBMENU,
       "Navigate Menu", &navigateMenuInfo, MENU_NAVIGATE },
!    { "Special", TGMUITEM_PINNABLESUBMENU,
       "Special Menu", &specialMenuInfo, MENU_SPECIAL },
  #ifdef _TANGRAM_II
!    { "Tangram-II", TGMUITEM_PINNABLESUBMENU,
       "Tangram-II Menu", &tangram2MenuInfo, MENU_TANGRAM2 },
  #endif /* _TANGRAM_II */
!    { "Help", TGMUITEM_PINNABLESUBMENU, "Help Menu", &helpMenuInfo, MENU_HELP },
     { NULL, NULL, NULL, NULL, INVALID }
  };
--- 1257,1328 ----
  
  static TgMenuItemInfo mainMenuItemInfo[] = {
!    { N_("File"), TGMUITEM_PINNABLESUBMENU, "File Menu", &fileMenuInfo,
!      MENU_FILE },
!    { N_("Edit"), TGMUITEM_PINNABLESUBMENU, "Edit Menu", &editMenuInfo,
!      MENU_EDIT },
!    { N_("Layout"), TGMUITEM_PINNABLESUBMENU,
       "Layout Menu", &layoutMenuInfo, MENU_LAYOUT },
!    { N_("Arrange"), TGMUITEM_PINNABLESUBMENU,
       "Arrange Menu", &arrangeMenuInfo, MENU_ARRANGE },
!    { N_("Properties"), TGMUITEM_PINNABLESUBMENU,
       "Properties Menu", &propertiesMenuInfo, MENU_PROPERTIES },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("StackedPage"), TGMUITEM_PINNABLESUBMENU,
       "StackedPage Menu", &stackedPageMenuInfo, MENU_STACKEDPAGE },
!    { N_("TiledPage"), TGMUITEM_PINNABLESUBMENU,
       "TiledPage Menu", &tiledPageMenuInfo, MENU_TILEDPAGE },
!    { N_("PageLayout"), TGMUITEM_PINNABLESUBMENU,
       "PageLayout Menu", &pageLayoutMenuInfo, MENU_PAGELAYOUT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("HoriAlign"), TGMUITEM_PINNABLESUBMENU,
       "HoriAlign Menu", &horiAlignMenuInfo, MENU_HORIALIGN },
!    { N_("VertAlign"), TGMUITEM_PINNABLESUBMENU,
       "VertAlign Menu", &vertAlignMenuInfo, MENU_VERTALIGN },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Font"), TGMUITEM_PINNABLESUBMENU, "Font Menu", &fontMenuInfo,
!      MENU_FONT },
!    { N_("TextStyle"), TGMUITEM_PINNABLESUBMENU,
       "TextStyle Menu", &fontStyleMenuInfo, MENU_STYLE },
!    { N_("TextSize"), TGMUITEM_PINNABLESUBMENU,
       "TextSize Menu", &fontSizeMenuInfo, MENU_SIZE },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("LineDash"), TGMUITEM_PINNABLESUBMENU,
       "LineDash Menu", &lineDashMenuInfo, MENU_LINEDASH },
!    { N_("LineStyle"), TGMUITEM_PINNABLESUBMENU,
       "LineStyle Menu", &lineStyleMenuInfo, MENU_LINESTYLE },
!    { N_("LineType"), TGMUITEM_PINNABLESUBMENU,
       "LineType Menu", &lineTypeMenuInfo, MENU_LINETYPE },
!    { N_("LineWidth"), TGMUITEM_PINNABLESUBMENU,
       "LineWidth Menu", &lineWidthMenuInfo, MENU_LINEWIDTH },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Fill"), TGMUITEM_PINNABLESUBMENU, "Fill Menu", &fillMenuInfo,
!      MENU_FILL },
!    { N_("Pen"), TGMUITEM_PINNABLESUBMENU, "Pen Menu", &penMenuInfo, MENU_PEN },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("MoveMode"), TGMUITEM_PINNABLESUBMENU,
       "MoveMode Menu", &moveModeMenuInfo, MENU_MOVEMODE },
!    { N_("Shape"), TGMUITEM_PINNABLESUBMENU,
       "Shape Menu", &shapeMenuInfo, MENU_SHAPE },
!    { N_("StretchText"), TGMUITEM_PINNABLESUBMENU,
       "StretchText Menu", &stretchableTextModeMenuInfo, MENU_STRETCHTEXT },
!    { N_("TransPattern"), TGMUITEM_PINNABLESUBMENU,
       "TransPattern Menu", &transPatModeMenuInfo,
           MENU_TRANSPAT },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("ImageProc"), TGMUITEM_PINNABLESUBMENU,
       "ImageProc Menu", &imageProcMenuInfo, MENU_IMAGEPROC },
     { TGMUITEM_SEPARATOR, NULL, NULL, NULL, INVALID },
!    { N_("Color"), TGMUITEM_PINNABLESUBMENU,
       "Color Menu", &colorMenuInfo, MENU_COLOR },
!    { N_("Navigate"), TGMUITEM_PINNABLESUBMENU,
       "Navigate Menu", &navigateMenuInfo, MENU_NAVIGATE },
!    { N_("Special"), TGMUITEM_PINNABLESUBMENU,
       "Special Menu", &specialMenuInfo, MENU_SPECIAL },
  #ifdef _TANGRAM_II
!    { N_("Tangram-II"), TGMUITEM_PINNABLESUBMENU,
       "Tangram-II Menu", &tangram2MenuInfo, MENU_TANGRAM2 },
  #endif /* _TANGRAM_II */
!    { N_("Help"), TGMUITEM_PINNABLESUBMENU, "Help Menu", &helpMenuInfo,
!      MENU_HELP },
     { NULL, NULL, NULL, NULL, INVALID }
  };
***************
*** 1311,1333 ****
  
  static TgMenuItemInfo minimalMenubarMenuItemInfo[] = {
!    { "File", TGMUITEM_PINNABLESUBMENU, "File Menu", &fileMenuInfo, MENU_FILE },
!    { "Edit", TGMUITEM_PINNABLESUBMENU, "Edit Menu", &editMenuInfo, MENU_EDIT },
!    { "Layout", TGMUITEM_PINNABLESUBMENU,
       "Layout Menu", &layoutMenuInfo, MENU_LAYOUT },
!    { "Arrange", TGMUITEM_PINNABLESUBMENU,
       "Arrange Menu", &arrangeMenuInfo, MENU_ARRANGE },
!    { "Properties", TGMUITEM_PINNABLESUBMENU,
       "Properties Menu", &propertiesMenuInfo, MENU_PROPERTIES },
!    { "Color", TGMUITEM_PINNABLESUBMENU,
       "Color Menu", &colorMenuInfo, MENU_COLOR },
!    { "Navigate", TGMUITEM_PINNABLESUBMENU,
       "Navigate Menu", &navigateMenuInfo, MENU_NAVIGATE },
!    { "Special", TGMUITEM_PINNABLESUBMENU,
       "Special Menu", &specialMenuInfo, MENU_SPECIAL },
  #ifdef _TANGRAM_II
!    { "Tangram-II", TGMUITEM_PINNABLESUBMENU,
       "Tangram-II Menu", &tangram2MenuInfo, MENU_TANGRAM2 },
  #endif /* _TANGRAM_II */
!    { "Help", TGMUITEM_PINNABLESUBMENU, "Help Menu", &helpMenuInfo, MENU_HELP },
     { NULL, NULL, NULL, NULL, INVALID }
  };
--- 1336,1361 ----
  
  static TgMenuItemInfo minimalMenubarMenuItemInfo[] = {
!    { N_("File"), TGMUITEM_PINNABLESUBMENU, "File Menu", &fileMenuInfo,
!      MENU_FILE },
!    { N_("Edit"), TGMUITEM_PINNABLESUBMENU, "Edit Menu", &editMenuInfo,
!      MENU_EDIT },
!    { N_("Layout"), TGMUITEM_PINNABLESUBMENU,
       "Layout Menu", &layoutMenuInfo, MENU_LAYOUT },
!    { N_("Arrange"), TGMUITEM_PINNABLESUBMENU,
       "Arrange Menu", &arrangeMenuInfo, MENU_ARRANGE },
!    { N_("Properties"), TGMUITEM_PINNABLESUBMENU,
       "Properties Menu", &propertiesMenuInfo, MENU_PROPERTIES },
!    { N_("Color"), TGMUITEM_PINNABLESUBMENU,
       "Color Menu", &colorMenuInfo, MENU_COLOR },
!    { N_("Navigate"), TGMUITEM_PINNABLESUBMENU,
       "Navigate Menu", &navigateMenuInfo, MENU_NAVIGATE },
!    { N_("Special"), TGMUITEM_PINNABLESUBMENU,
       "Special Menu", &specialMenuInfo, MENU_SPECIAL },
  #ifdef _TANGRAM_II
!    { N_("Tangram-II"), TGMUITEM_PINNABLESUBMENU,
       "Tangram-II Menu", &tangram2MenuInfo, MENU_TANGRAM2 },
  #endif /* _TANGRAM_II */
!    { N_("Help"), TGMUITEM_PINNABLESUBMENU, "Help Menu", &helpMenuInfo,
!      MENU_HELP },
     { NULL, NULL, NULL, NULL, INVALID }
  };
***************
*** 1336,1391 ****
  
  static TgMenuItemInfo maximalMenubarMenuItemInfo[] = {
!    { "File", TGMUITEM_PINNABLESUBMENU, "File Menu", &fileMenuInfo, MENU_FILE },
!    { "Edit", TGMUITEM_PINNABLESUBMENU, "Edit Menu", &editMenuInfo, MENU_EDIT },
!    { "Layout", TGMUITEM_PINNABLESUBMENU,
       "Layout Menu", &layoutMenuInfo, MENU_LAYOUT },
!    { "Arrange", TGMUITEM_PINNABLESUBMENU,
       "Arrange Menu", &arrangeMenuInfo, MENU_ARRANGE },
!    { "Properties", TGMUITEM_PINNABLESUBMENU,
       "Properties Menu", &propertiesMenuInfo, MENU_PROPERTIES },
!    { "MoveMode", TGMUITEM_PINNABLESUBMENU,
       "MoveMode Menu", &moveModeMenuInfo, MENU_MOVEMODE },
!    { "Page", TGMUITEM_PINNABLESUBMENU,
       "Page Menu", &pageMenuInfo, MENU_PAGE },
!    { "PageLayout", TGMUITEM_PINNABLESUBMENU,
       "PageLayout Menu", &pageLayoutMenuInfo, MENU_PAGELAYOUT },
!    { "HoriAlign", TGMUITEM_PINNABLESUBMENU,
       "HoriAlign Menu", &horiAlignMenuInfo, MENU_HORIALIGN },
!    { "VertAlign", TGMUITEM_PINNABLESUBMENU,
       "VertAlign Menu", &vertAlignMenuInfo, MENU_VERTALIGN },
!    { "Font", TGMUITEM_PINNABLESUBMENU, "Font Menu", &fontMenuInfo, MENU_FONT },
!    { "TextStyle", TGMUITEM_PINNABLESUBMENU,
       "TextStyle Menu", &fontStyleMenuInfo, MENU_STYLE },
!    { "TextSize", TGMUITEM_PINNABLESUBMENU,
       "TextSize Menu", &fontSizeMenuInfo, MENU_SIZE },
!    { "Shape", TGMUITEM_PINNABLESUBMENU,
       "Shape Menu", &shapeMenuInfo, MENU_SHAPE },
!    { "StretchText", TGMUITEM_PINNABLESUBMENU,
       "StretchText Menu", &stretchableTextModeMenuInfo, MENU_STRETCHTEXT },
!    { "LineDash", TGMUITEM_PINNABLESUBMENU,
       "LineDash Menu", &lineDashMenuInfo, MENU_LINEDASH },
!    { "LineStyle", TGMUITEM_PINNABLESUBMENU,
       "LineStyle Menu", &lineStyleMenuInfo, MENU_LINESTYLE },
!    { "LineType", TGMUITEM_PINNABLESUBMENU,
       "LineType Menu", &lineTypeMenuInfo, MENU_LINETYPE },
!    { "LineWidth", TGMUITEM_PINNABLESUBMENU,
       "LineWidth Menu", &lineWidthMenuInfo, MENU_LINEWIDTH },
!    { "Fill", TGMUITEM_PINNABLESUBMENU, "Fill Menu", &fillMenuInfo, MENU_FILL },
!    { "Pen", TGMUITEM_PINNABLESUBMENU, "Pen Menu", &penMenuInfo, MENU_PEN },
!    { "TransPattern", TGMUITEM_PINNABLESUBMENU,
       "TransPattern Menu", &transPatModeMenuInfo, MENU_TRANSPAT },
!    { "Color", TGMUITEM_PINNABLESUBMENU,
       "Color Menu", &colorMenuInfo, MENU_COLOR },
!    { "ImageProc", TGMUITEM_PINNABLESUBMENU,
       "ImageProc Menu", &imageProcMenuInfo, MENU_IMAGEPROC },
!    { "Navigate", TGMUITEM_PINNABLESUBMENU,
       "Navigate Menu", &navigateMenuInfo, MENU_NAVIGATE },
!    { "Special", TGMUITEM_PINNABLESUBMENU,
       "Special Menu", &specialMenuInfo, MENU_SPECIAL },
  #ifdef _TANGRAM_II
!    { "Tangram-II", TGMUITEM_PINNABLESUBMENU,
       "Tangram-II Menu", &tangram2MenuInfo, MENU_TANGRAM2 },
  #endif /* _TANGRAM_II */
!    { "Help", TGMUITEM_PINNABLESUBMENU, "Help Menu", &helpMenuInfo, MENU_HELP },
     { NULL, NULL, NULL, NULL, INVALID }
  };
--- 1364,1424 ----
  
  static TgMenuItemInfo maximalMenubarMenuItemInfo[] = {
!    { N_("File"), TGMUITEM_PINNABLESUBMENU, "File Menu", &fileMenuInfo,
!      MENU_FILE },
!    { N_("Edit"), TGMUITEM_PINNABLESUBMENU, "Edit Menu", &editMenuInfo,
!      MENU_EDIT },
!    { N_("Layout"), TGMUITEM_PINNABLESUBMENU,
       "Layout Menu", &layoutMenuInfo, MENU_LAYOUT },
!    { N_("Arrange"), TGMUITEM_PINNABLESUBMENU,
       "Arrange Menu", &arrangeMenuInfo, MENU_ARRANGE },
!    { N_("Properties"), TGMUITEM_PINNABLESUBMENU,
       "Properties Menu", &propertiesMenuInfo, MENU_PROPERTIES },
!    { N_("MoveMode"), TGMUITEM_PINNABLESUBMENU,
       "MoveMode Menu", &moveModeMenuInfo, MENU_MOVEMODE },
!    { N_("Page"), TGMUITEM_PINNABLESUBMENU,
       "Page Menu", &pageMenuInfo, MENU_PAGE },
!    { N_("PageLayout"), TGMUITEM_PINNABLESUBMENU,
       "PageLayout Menu", &pageLayoutMenuInfo, MENU_PAGELAYOUT },
!    { N_("HoriAlign"), TGMUITEM_PINNABLESUBMENU,
       "HoriAlign Menu", &horiAlignMenuInfo, MENU_HORIALIGN },
!    { N_("VertAlign"), TGMUITEM_PINNABLESUBMENU,
       "VertAlign Menu", &vertAlignMenuInfo, MENU_VERTALIGN },
!    { N_("Font"), TGMUITEM_PINNABLESUBMENU, "Font Menu", &fontMenuInfo,
!      MENU_FONT },
!    { N_("TextStyle"), TGMUITEM_PINNABLESUBMENU,
       "TextStyle Menu", &fontStyleMenuInfo, MENU_STYLE },
!    { N_("TextSize"), TGMUITEM_PINNABLESUBMENU,
       "TextSize Menu", &fontSizeMenuInfo, MENU_SIZE },
!    { N_("Shape"), TGMUITEM_PINNABLESUBMENU,
       "Shape Menu", &shapeMenuInfo, MENU_SHAPE },
!    { N_("StretchText"), TGMUITEM_PINNABLESUBMENU,
       "StretchText Menu", &stretchableTextModeMenuInfo, MENU_STRETCHTEXT },
!    { N_("LineDash"), TGMUITEM_PINNABLESUBMENU,
       "LineDash Menu", &lineDashMenuInfo, MENU_LINEDASH },
!    { N_("LineStyle"), TGMUITEM_PINNABLESUBMENU,
       "LineStyle Menu", &lineStyleMenuInfo, MENU_LINESTYLE },
!    { N_("LineType"), TGMUITEM_PINNABLESUBMENU,
       "LineType Menu", &lineTypeMenuInfo, MENU_LINETYPE },
!    { N_("LineWidth"), TGMUITEM_PINNABLESUBMENU,
       "LineWidth Menu", &lineWidthMenuInfo, MENU_LINEWIDTH },
!    { N_("Fill"), TGMUITEM_PINNABLESUBMENU, "Fill Menu", &fillMenuInfo,
!      MENU_FILL },
!    { N_("Pen"), TGMUITEM_PINNABLESUBMENU, "Pen Menu", &penMenuInfo, MENU_PEN },
!    { N_("TransPattern"), TGMUITEM_PINNABLESUBMENU,
       "TransPattern Menu", &transPatModeMenuInfo, MENU_TRANSPAT },
!    { N_("Color"), TGMUITEM_PINNABLESUBMENU,
       "Color Menu", &colorMenuInfo, MENU_COLOR },
!    { N_("ImageProc"), TGMUITEM_PINNABLESUBMENU,
       "ImageProc Menu", &imageProcMenuInfo, MENU_IMAGEPROC },
!    { N_("Navigate"), TGMUITEM_PINNABLESUBMENU,
       "Navigate Menu", &navigateMenuInfo, MENU_NAVIGATE },
!    { N_("Special"), TGMUITEM_PINNABLESUBMENU,
       "Special Menu", &specialMenuInfo, MENU_SPECIAL },
  #ifdef _TANGRAM_II
!    { N_("Tangram-II"), TGMUITEM_PINNABLESUBMENU,
       "Tangram-II Menu", &tangram2MenuInfo, MENU_TANGRAM2 },
  #endif /* _TANGRAM_II */
!    { N_("Help"), TGMUITEM_PINNABLESUBMENU, "Help Menu", &helpMenuInfo,
!      MENU_HELP },
     { NULL, NULL, NULL, NULL, INVALID }
  };
*** names.c.orig	Sun Apr 11 10:47:06 1999
--- names.c	Sun Apr 11 10:47:06 1999
***************
*** 812,815 ****
--- 812,817 ----
           strcat(dirNamesInfo.other_ext_str, ";.tgp");
        }
+       sprintf(gszMsgBox, ";.obj.gz;.tgo.gz;.%s.gz", OBJ_FILE_EXT);
+       strcat(dirNamesInfo.other_ext_str, gszMsgBox);
     } else if (ExtStr != NULL && strcmp(ExtStr, "gif") == 0) {
        strcpy(dirNamesInfo.other_ext_str, ".GIF");
*** navigate.c.orig	Sun Apr 11 10:47:08 1999
--- navigate.c	Sun Apr 11 10:47:08 1999
***************
*** 601,606 ****
        if (buf != NULL) FreeRemoteBuf(buf);
     } else {
        navigatingBackAndForth = TRUE;
!       if (!LoadFile(full_fname, TRUE)) {
           if (do_not_save) {
              SetFileModified(TRUE);
--- 601,610 ----
        if (buf != NULL) FreeRemoteBuf(buf);
     } else {
+       int obj_file=FALSE, gzipped=FALSE;
+ 
        navigatingBackAndForth = TRUE;
!       obj_file = FileNameHasExtension(full_fname, OBJ_FILE_TYPE, &gzipped,
!             NULL);
!       if (!LoadFile(full_fname, obj_file, obj_file && gzipped)) {
           if (do_not_save) {
              SetFileModified(TRUE);
***************
*** 1055,1061 ****
     switch (Which) {
     case NAVIGATE_HOTLIST:
!       NamesAddButton("GOTO", GOTO_BUTTON);
!       NamesAddButton("DELETE", DELETE_BUTTON);
!       NamesAddButton("CLOSE", BUTTON_CANCEL);
        NamesSetStyle(NAMES_EDIT_NAME, NAMES_LOOP_MANY);
        NamesSetCallback((GetEntriesFunc*)GetHotListEntries,
--- 1059,1065 ----
     switch (Which) {
     case NAVIGATE_HOTLIST:
!       NamesAddButton("Goto", GOTO_BUTTON);
!       NamesAddButton("Delete", DELETE_BUTTON);
!       NamesAddButton("Close", BUTTON_CANCEL);
        NamesSetStyle(NAMES_EDIT_NAME, NAMES_LOOP_MANY);
        NamesSetCallback((GetEntriesFunc*)GetHotListEntries,
***************
*** 1064,1069 ****
        break;
     case NAVIGATE_HISTORY:
!       NamesAddButton("GOTO", GOTO_BUTTON);
!       NamesAddButton("CLOSE", BUTTON_CANCEL);
        NamesSetStyle(NAMES_COMPLEX_SELECT_NAME, NAMES_LOOP_MANY);
        NamesSetCallback((GetEntriesFunc*)GetHistoryEntries,
--- 1068,1073 ----
        break;
     case NAVIGATE_HISTORY:
!       NamesAddButton("Goto", GOTO_BUTTON);
!       NamesAddButton("Close", BUTTON_CANCEL);
        NamesSetStyle(NAMES_COMPLEX_SELECT_NAME, NAMES_LOOP_MANY);
        NamesSetCallback((GetEntriesFunc*)GetHistoryEntries,
*** pattern.c.orig	Sun Apr 11 10:47:09 1999
--- pattern.c	Sun Apr 11 10:47:09 1999
***************
*** 1160,1163 ****
--- 1160,1198 ----
  }
  
+ static
+ int GetLineWidthMatch(index, width, aw, ah)
+    int index, width, aw, ah;
+ {
+    int diff=0;
+ 
+    if (width != INVALID && width != curWidthOfLine[index]) {
+       diff += 10*abs(width-curWidthOfLine[index]);
+    }
+    if (aw != INVALID && aw != curArrowHeadW[index]) {
+       diff += abs(aw-curArrowHeadW[index]);
+    }
+    if (ah != INVALID && ah != curArrowHeadH[index]) {
+       diff += abs(ah-curArrowHeadH[index]);
+    }
+    return diff;
+ }
+ 
+ int GetBestLineWidthIndex(width, aw, ah)
+    int width, aw, ah;
+ {
+    int min_diff=0, min_index=0, index=0;
+ 
+    min_diff = GetLineWidthMatch(0, width, aw, ah);
+    for (index=1; index < maxLineWidths; index++) {
+       int diff=GetLineWidthMatch(index, width, aw, ah);
+ 
+       if (diff < min_diff) {
+          min_diff = diff;
+          min_index = index;
+       }
+    }
+    return min_index;
+ }
+ 
  void RefreshLineWidthMenu(menu)
     TgMenu *menu;
***************
*** 1585,1592 ****
        item_info->shortcut_str = NULL;
        switch (i) {
!       case NONEPAT: sprintf(gszMsgBox, "Set pen pattern to NONE"); break;
!       case SOLIDPAT: sprintf(gszMsgBox, "Set pen pattern to SOLID"); break;
!       case BACKPAT: sprintf(gszMsgBox, "Set pen pattern to BACKGROUND"); break;
!       default: sprintf(gszMsgBox, "Set pen pattern to pattern #%1d", i); break;
        }
        item_info->status_str = UtilStrDup(gszMsgBox);
--- 1620,1627 ----
        item_info->shortcut_str = NULL;
        switch (i) {
!       case NONEPAT: sprintf(gszMsgBox, "Set pen to NONE"); break;
!       case SOLIDPAT: sprintf(gszMsgBox, "Set pen to SOLID"); break;
!       case BACKPAT: sprintf(gszMsgBox, "Set pen to BACKGROUND"); break;
!       default: sprintf(gszMsgBox, "Set pen to pattern #%1d", i); break;
        }
        item_info->status_str = UtilStrDup(gszMsgBox);
***************
*** 1829,1836 ****
  
     if (changed) {
!       int ltx, lty, rbx, rby;
  
        SetFileModified(TRUE);
-       ltx = selLtX; lty = selLtY; rbx = selRbX; rby = selRbY;
        UpdSelBBox();
        RedrawAreas(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
--- 1864,1870 ----
  
     if (changed) {
!       int ltx=selLtX, lty=selLtY, rbx=selRbX, rby=selRbY;
  
        SetFileModified(TRUE);
        UpdSelBBox();
        RedrawAreas(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
*** poly.c.orig	Sun Apr 11 10:47:11 1999
--- poly.c	Sun Apr 11 10:47:11 1999
***************
*** 93,100 ****
  int  drawPolyToConnectPins=0;
  
  struct ObjRec *drawPolyHighlightedNode=NULL;
  
- static struct PtRec *lastPtPtr=NULL;
- 
  XPoint *MakePolyVertex(XOff, YOff, NumVs, Vs)
     int XOff, YOff, NumVs;
--- 93,101 ----
  int  drawPolyToConnectPins=0;
  
+ int numPtsInPoly=0;
+ 
+ struct PtRec *lastPtPtr=NULL;
  struct ObjRec *drawPolyHighlightedNode=NULL;
  
  XPoint *MakePolyVertex(XOff, YOff, NumVs, Vs)
     int XOff, YOff, NumVs;
***************
*** 300,303 ****
--- 301,306 ----
        free(lastPtPtr);
     }
+    numPtsInPoly = 0;
+    lastPtPtr = NULL;
  
     poly_ptr->vlist = v;
***************
*** 364,367 ****
--- 367,371 ----
  void ResetCreatePoly()
  {
+    numPtsInPoly = 0;
     lastPtPtr = NULL;
  }
***************
*** 375,378 ****
--- 379,383 ----
     memset(pt_ptr, 0, sizeof(struct PtRec));
     pt_ptr->next = lastPtPtr;
+    numPtsInPoly++;
     lastPtPtr = pt_ptr;
     pt_ptr->x = AbsX;
***************
*** 919,922 ****
--- 924,928 ----
              ABS_Y(lty)-GRID_ABS_SIZE(1), ABS_X(rbx)+GRID_ABS_SIZE(1),
              ABS_Y(rby)+GRID_ABS_SIZE(1));
+       numPtsInPoly = 0;
        lastPtPtr = NULL;
        polyDrawn = FALSE;
***************
*** 966,969 ****
--- 972,976 ----
           GridXY(mouse_x, mouse_y, &grid_x, &grid_y);
        }
+       numPtsInPoly = 1;
        lastPtPtr = (struct PtRec *)malloc(sizeof(struct PtRec));
        if (lastPtPtr == NULL) FailAllocMessage();
***************
*** 989,992 ****
--- 996,1000 ----
  
        more_poly = FALSE;
+       numPtsInPoly = 0;
        lastPtPtr = NULL;
        printf("Please input pairs of points: ");
*** polygon.c.orig	Sun Apr 11 10:47:13 1999
--- polygon.c	Sun Apr 11 10:47:13 1999
***************
*** 68,74 ****
  int polygonDrawn=FALSE;
  
- static struct PtRec *lastPtPtr=NULL;
- static int startPolygonX=0, startPolygonY=0;
- 
  XPoint *MakePolygonVertex(XOff, YOff, NumVs, Vs)
     int XOff, YOff, NumVs;
--- 68,71 ----
***************
*** 464,467 ****
--- 461,466 ----
        free(lastPtPtr);
     }
+    numPtsInPoly = 0;
+    lastPtPtr = NULL;
  
     polygon_ptr->vlist = v;
***************
*** 524,527 ****
--- 523,527 ----
  void ResetCreatePolygon()
  {
+    numPtsInPoly = 0;
     lastPtPtr = NULL;
  }
***************
*** 535,538 ****
--- 535,539 ----
     memset(pt_ptr, 0, sizeof(struct PtRec));
     pt_ptr->next = lastPtPtr;
+    numPtsInPoly++;
     lastPtPtr = pt_ptr;
     pt_ptr->x = AbsX;
***************
*** 554,557 ****
--- 555,559 ----
     KeySym key_sym;
     char s[80], buf[80], w_buf[80], h_buf[80], x_buf[80], y_buf[80];
+    int start_polygon_x=OrigX, start_polygon_y=OrigY;
     int end_x, end_y, grid_x, grid_y, done=FALSE;
     int saved_x, saved_y, closed=FALSE, abort=FALSE;
***************
*** 796,800 ****
                    grid_y);
           }
!          if (grid_x == startPolygonX && grid_y == startPolygonY) {
              if (curSpline != LT_STRAIGHT && splineRubberband) {
                 XDrawLines(mainDisplay, drawWindow, drawGC, sv, sn,
--- 798,802 ----
                    grid_y);
           }
!          if (grid_x == start_polygon_x && grid_y == start_polygon_y) {
              if (curSpline != LT_STRAIGHT && splineRubberband) {
                 XDrawLines(mainDisplay, drawWindow, drawGC, sv, sn,
***************
*** 851,856 ****
                 pt_ptr->next = lastPtPtr;
                 lastPtPtr = pt_ptr;
!                pt_ptr->x = startPolygonX;
!                pt_ptr->y = startPolygonY;
                 done = TRUE;
                 break;
--- 853,858 ----
                 pt_ptr->next = lastPtPtr;
                 lastPtPtr = pt_ptr;
!                pt_ptr->x = start_polygon_x;
!                pt_ptr->y = start_polygon_y;
                 done = TRUE;
                 break;
***************
*** 897,900 ****
--- 899,903 ----
              ABS_Y(lty)-GRID_ABS_SIZE(1), ABS_X(rbx)+GRID_ABS_SIZE(1),
              ABS_Y(rby)+GRID_ABS_SIZE(1));
+       numPtsInPoly = 0;
        lastPtPtr = NULL;
        polygonDrawn = FALSE;
***************
*** 915,922 ****
        mouse_y = button_ev->y;
        GridXY(mouse_x, mouse_y, &grid_x, &grid_y);
        lastPtPtr = (struct PtRec *)malloc(sizeof(struct PtRec));
        if (lastPtPtr == NULL) FailAllocMessage();
!       lastPtPtr->x = startPolygonX = grid_x;
!       lastPtPtr->y = startPolygonY = grid_y;
        lastPtPtr->next = NULL;
        ContinuePolygon(grid_x, grid_y);
--- 918,926 ----
        mouse_y = button_ev->y;
        GridXY(mouse_x, mouse_y, &grid_x, &grid_y);
+       numPtsInPoly = 1;
        lastPtPtr = (struct PtRec *)malloc(sizeof(struct PtRec));
        if (lastPtPtr == NULL) FailAllocMessage();
!       lastPtPtr->x = grid_x;
!       lastPtPtr->y = grid_y;
        lastPtPtr->next = NULL;
        ContinuePolygon(grid_x, grid_y);
***************
*** 960,963 ****
--- 964,968 ----
  
        more_polygon = FALSE;
+       numPtsInPoly = 0;
        lastPtPtr = NULL;
        printf("Please input pairs of points: ");
***************
*** 1075,1078 ****
--- 1080,1084 ----
     if (pt_ptr == NULL) FailAllocMessage();
     pt_ptr->next = lastPtPtr;
+    numPtsInPoly++;
     lastPtPtr = pt_ptr;
     pt_ptr->x = XOff;
***************
*** 1111,1114 ****
--- 1117,1121 ----
           int i;
  
+          numPtsInPoly = 0;
           lastPtPtr = NULL;
           for (i=0; i < 5; i++) {
*** raster.c.orig	Sun Apr 11 10:47:14 1999
--- raster.c	Sun Apr 11 10:47:14 1999
***************
*** 263,266 ****
--- 263,267 ----
  #include "xbm/rot_270.xbm"
  
+ #include "xbm/run.xbm"
  #include "xbm/check.xbm"
  #include "xbm/radio.xbm"
***************
*** 326,329 ****
--- 327,331 ----
  Pixmap shortDashPixmap[MAXDASHES];
  
+ Pixmap runBitmap=None;
  Pixmap checkBitmap=None;
  Pixmap radioBitmap=None;
***************
*** 1006,1009 ****
--- 1008,1014 ----
           (char *)rot_mode_bits, rot_mode_width, rot_mode_height);
  
+    runBitmap = XCreateBitmapFromData(mainDisplay, mainWindow,
+          (char *)run_bits, run_width, run_height);
+ 
     checkBitmap = XCreateBitmapFromData(mainDisplay, mainWindow,
           (char *)check_bits, check_width, check_height);
***************
*** 1156,1159 ****
--- 1161,1165 ----
        XFreePixmap(mainDisplay, shortDashPixmap[i]);
     }
+    XFreePixmap(mainDisplay, runBitmap);
     XFreePixmap(mainDisplay, checkBitmap);
     XFreePixmap(mainDisplay, radioBitmap);
*** rcbox.c.orig	Sun Apr 11 10:47:15 1999
--- rcbox.c	Sun Apr 11 10:47:15 1999
***************
*** 505,511 ****
  }
  
! static
! void CreateRCBoxObj(X1, Y1, X2, Y2)
!    int X1, Y1, X2, Y2;
  {
     struct RCBoxRec *rcbox_ptr;
--- 505,510 ----
  }
  
! void CreateRCBoxObj(X1, Y1, X2, Y2, CreateAbsolute)
!    int X1, Y1, X2, Y2, CreateAbsolute;
  {
     struct RCBoxRec *rcbox_ptr;
***************
*** 544,551 ****
        }
     }
!    obj_ptr->bbox.ltx = obj_ptr->obbox.ltx = obj_ptr->x = ABS_X(ltx);
!    obj_ptr->bbox.lty = obj_ptr->obbox.lty = obj_ptr->y = ABS_Y(lty);
!    obj_ptr->bbox.rbx = obj_ptr->obbox.rbx = ABS_X(rbx);
!    obj_ptr->bbox.rby = obj_ptr->obbox.rby = ABS_Y(rby);
     w = HALF_W(width);
     obj_ptr->bbox.ltx -= w;
--- 543,557 ----
        }
     }
!    if (CreateAbsolute) {
!       obj_ptr->bbox.ltx = obj_ptr->obbox.ltx = obj_ptr->x = ltx;
!       obj_ptr->bbox.lty = obj_ptr->obbox.lty = obj_ptr->y = lty;
!       obj_ptr->bbox.rbx = obj_ptr->obbox.rbx = rbx;
!       obj_ptr->bbox.rby = obj_ptr->obbox.rby = rby;
!    } else {
!       obj_ptr->bbox.ltx = obj_ptr->obbox.ltx = obj_ptr->x = ABS_X(ltx);
!       obj_ptr->bbox.lty = obj_ptr->obbox.lty = obj_ptr->y = ABS_Y(lty);
!       obj_ptr->bbox.rbx = obj_ptr->obbox.rbx = ABS_X(rbx);
!       obj_ptr->bbox.rby = obj_ptr->obbox.rby = ABS_Y(rby);
!    }
     w = HALF_W(width);
     obj_ptr->bbox.ltx -= w;
***************
*** 696,700 ****
     }
     if (!abort && OrigX != grid_x && OrigY != grid_y) {
!       CreateRCBoxObj(OrigX, OrigY, grid_x, grid_y);
        RecordNewObjCmd();
        DrawRCBoxObj(drawWindow, drawOrigX, drawOrigY, topObj);
--- 702,706 ----
     }
     if (!abort && OrigX != grid_x && OrigY != grid_y) {
!       CreateRCBoxObj(OrigX, OrigY, grid_x, grid_y, FALSE);
        RecordNewObjCmd();
        DrawRCBoxObj(drawWindow, drawOrigX, drawOrigY, topObj);
*** remote.c.orig	Sun Apr 11 10:47:17 1999
--- remote.c	Sun Apr 11 10:47:17 1999
***************
*** 61,67 ****
  char *fnameForPostingCGIQuery=NULL;
  char gszLocalPID[MAXSTRING];
  
  static int debugRemote=FALSE;
- static char gunzipCmd[MAXPATHLENGTH+1];
  static char uncompressCmd[MAXPATHLENGTH+1];
  static char httpProxy[MAXPATHLENGTH+1];
--- 61,68 ----
  char *fnameForPostingCGIQuery=NULL;
  char gszLocalPID[MAXSTRING];
+ char gzipCmd[MAXPATHLENGTH+1];
+ char gunzipCmd[MAXPATHLENGTH+1];
  
  static int debugRemote=FALSE;
  static char uncompressCmd[MAXPATHLENGTH+1];
  static char httpProxy[MAXPATHLENGTH+1];
***************
*** 636,639 ****
--- 637,641 ----
     int *pn_buf_sz, *pn_html;
  {
+    FILE *pfp=NULL;
     char *uncompress_cmd=NULL, *tmp_fname=NULL, *cmd=NULL;
     int uncompress_method;
***************
*** 664,700 ****
     cmd = (char*)malloc((strlen(tmp_fname)+strlen(uncompress_cmd)+20) *
           sizeof(char));
!    if (cmd == NULL) {
!       FailAllocMessage();
     } else {
!       FILE *pfp;
  
!       if (strstr(uncompress_cmd, "%s") == NULL) {
!          sprintf(cmd, "%s %s", uncompress_cmd, tmp_fname);
!       } else {
!          sprintf(cmd, uncompress_cmd, tmp_fname);
        }
!       if ((pfp=(FILE*)popen(cmd, "r")) == NULL) {
!          sprintf(gszMsgBox, "Cannot execute '%s'.", cmd);
!          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
!       } else {
!          int buf_sz=0x1000, total=0, chunk_sz=0x1000, bytes_read;
!          char *buf=(char*)malloc((buf_sz+1)*sizeof(char));
! 
!          if (buf == NULL) FailAllocMessage();
!          while (buf != NULL && (bytes_read=fread(&buf[total], sizeof(char),
!                chunk_sz, pfp)) > 0) {
!             total += bytes_read;
!             buf_sz += chunk_sz;
!             buf = (char*)realloc(buf, buf_sz+1);
!          }
!          buf[total] = '\0';
!          pclose(pfp);
!          if (buf != NULL && total > 0) {
!             free(*ppsz_buf);
!             *ppsz_buf = buf;
!             *pn_buf_sz = total;
!          } else if (buf != NULL) {
!             free(buf);
!          }
        }
     }
--- 666,698 ----
     cmd = (char*)malloc((strlen(tmp_fname)+strlen(uncompress_cmd)+20) *
           sizeof(char));
!    if (cmd == NULL) FailAllocMessage();
! 
!    if (strstr(uncompress_cmd, "%s") == NULL) {
!       sprintf(cmd, "%s %s", uncompress_cmd, tmp_fname);
     } else {
!       sprintf(cmd, uncompress_cmd, tmp_fname);
!    }
!    if ((pfp=(FILE*)popen(cmd, "r")) == NULL) {
!       sprintf(gszMsgBox, "Cannot execute '%s'.", cmd);
!       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
!    } else {
!       int buf_sz=0x1000, total=0, chunk_sz=0x1000, bytes_read;
!       char *buf=(char*)malloc((buf_sz+1)*sizeof(char));
  
!       if (buf == NULL) FailAllocMessage();
!       while (buf != NULL && (bytes_read=fread(&buf[total], sizeof(char),
!             chunk_sz, pfp)) > 0) {
!          total += bytes_read;
!          buf_sz += chunk_sz;
!          buf = (char*)realloc(buf, buf_sz+1);
        }
!       buf[total] = '\0';
!       pclose(pfp);
!       if (buf != NULL && total > 0) {
!          free(*ppsz_buf);
!          *ppsz_buf = buf;
!          *pn_buf_sz = total;
!       } else if (buf != NULL) {
!          free(buf);
        }
     }
***************
*** 2014,2018 ****
        navigatingBackAndForth = TRUE;
     }
!    rc_loadfile = LoadFile(tmp_fname, (-1));
     if (!navigating) navigatingBackAndForth = FALSE;
  
--- 2012,2016 ----
        navigatingBackAndForth = TRUE;
     }
!    rc_loadfile = LoadFile(tmp_fname, (-1), FALSE);
     if (!navigating) navigatingBackAndForth = FALSE;
  
***************
*** 2072,2075 ****
--- 2070,2079 ----
        allowLaunchInHyperSpace = TRUE;
     }
+    *gzipCmd = '\0';
+    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"GZipCmd")) == NULL) {
+       strcpy(gzipCmd, "gzip -c");
+    } else {
+       strcpy(gzipCmd, c_ptr);
+    }
     *gunzipCmd = '\0';
     if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"GUnZipCmd")) == NULL) {
*** select.c.orig	Sun Apr 11 10:47:18 1999
--- select.c	Sun Apr 11 10:47:18 1999
***************
*** 1447,1450 ****
--- 1447,1451 ----
     XKeyEvent *key_ev;
  {
+    XButtonEvent button_ev;
     char s[80];
     KeySym key_sym;
***************
*** 1466,1478 ****
        }
     }
     if (topSel==NULL && topVSel==NULL) {
!       XButtonEvent button_ev;
! 
!       button_ev.state = ShiftMask;
!       if (key_sym == XK_Page_Up || key_sym == XK_KP_Page_Up) {
!          ScrollUp(&button_ev);
!       } else if (key_sym == XK_Page_Down || key_sym == XK_KP_Page_Down) {
!          ScrollDown(&button_ev);
!       } else if (key_ev->state & ControlMask) {
           switch (key_sym) {
           case XK_Left: ScrollLeft(&button_ev); break;
--- 1467,1478 ----
        }
     }
+    button_ev.state = ShiftMask;
+    if (key_sym == XK_Page_Up || key_sym == XK_KP_Page_Up) {
+       ScrollUp(&button_ev);
+    } else if (key_sym == XK_Page_Down || key_sym == XK_KP_Page_Down) {
+       ScrollDown(&button_ev);
+    }
     if (topSel==NULL && topVSel==NULL) {
!       if (key_ev->state & ControlMask) {
           switch (key_sym) {
           case XK_Left: ScrollLeft(&button_ev); break;
***************
*** 1817,1820 ****
--- 1817,1822 ----
        return rc;
     }
+    MakeQuiescent();
+ 
     if (curFileDefined) {
        referer_set = TRUE;
***************
*** 1853,1856 ****
--- 1855,1859 ----
        if (buf != NULL) FreeRemoteBuf(buf);
     } else {
+       int obj_file=FALSE, gzipped=FALSE;
        FILE *fp=fopen(file_name, "r");
  
***************
*** 1872,1876 ****
           fclose(fp);
        }
!       if (rc && !LoadFile(file_name, TRUE)) {
           if (do_not_save) SetFileModified(TRUE);
           rc = FALSE;
--- 1875,1882 ----
           fclose(fp);
        }
!       navigatingBackAndForth = TRUE;
!       obj_file = FileNameHasExtension(file_name, OBJ_FILE_TYPE, &gzipped,
!             NULL);
!       if (rc && !LoadFile(file_name, obj_file, obj_file && gzipped)) {
           if (do_not_save) SetFileModified(TRUE);
           rc = FALSE;
*** setup.c.orig	Sun Apr 11 10:47:20 1999
--- setup.c	Sun Apr 11 10:47:20 1999
***************
*** 1451,1456 ****
--- 1451,1470 ----
        if (bitmask & YValue) y_in_cmdline = TRUE;
     }
+ #ifndef _NO_LOCALE_SUPPORT
+ #ifdef _ENABLE_NLS
+    {
+       char prev_locale[MAXSTRING];
  
+       SaveAndSetLocale("", prev_locale);
+       InitFonts();
+       RestoreLocale(prev_locale);
+    }
+ #else /* ~_ENABLE_NLS */
     InitFonts();
+ #endif /* _ENABLE_NLS */
+ #else /* _NO_LOCALE_SUPPORT */
+    InitFonts();
+ #endif /* ~_NO_LOCALE_SUPPORT */
+ 
     initialMenubarWindowH = defaultFontHeight;
     if (msgFontPtr == NULL) {
***************
*** 1706,1712 ****
     InitShape();
  
-    if (PRTGIF) {
-       return;
-    }
     InitExportFilters();
     InitProperties();
--- 1720,1723 ----
***************
*** 1715,1718 ****
--- 1726,1732 ----
     InitMiniLines();
  
+    if (PRTGIF && !cmdLineOpenDisplay) {
+       return;
+    }
  #ifndef _NO_NKF
     InitNKF();
***************
*** 2025,2029 ****
     /* returns FALSE otherwise */
  {
!    if (curChoice == DRAWTEXT) return CreateTextObj(TRUE);
     return FALSE;
  }
--- 2039,2043 ----
     /* returns FALSE otherwise */
  {
!    if (curChoice == DRAWTEXT) return CreateTextObj(TRUE, TRUE);
     return FALSE;
  }
*** shape.c.orig	Sun Apr 11 10:47:21 1999
--- shape.c	Sun Apr 11 10:47:21 1999
***************
*** 886,890 ****
              gShapeBBox.ltx, gShapeBBox.rby-radius_y,
              gShapeBBox.ltx+w, gShapeBBox.rby-radius_y, ARC_CCW,
!             gShapeBBox.ltx, gShapeBBox.rby-diam_y, w, diam_y, 180<<6, 180<<6);
        ResetCreatePoly();
        AddPtToCreatePoly(gShapeBBox.ltx, gShapeBBox.lty+radius_y);
--- 886,891 ----
              gShapeBBox.ltx, gShapeBBox.rby-radius_y,
              gShapeBBox.ltx+w, gShapeBBox.rby-radius_y, ARC_CCW,
!             gShapeBBox.ltx, gShapeBBox.rby-diam_y, w, diam_y, 180<<6, 180<<6,
!             FALSE);
        ResetCreatePoly();
        AddPtToCreatePoly(gShapeBBox.ltx, gShapeBBox.lty+radius_y);
*** special.c.orig	Sun Apr 11 10:47:22 1999
--- special.c	Sun Apr 11 10:47:22 1999
***************
*** 696,704 ****
        sym_ext_len = strlen(sym_ext_str);
  
!       if (FileNameHasExtension(icon_name, OBJ_FILE_TYPE, NULL)) {
           MsgBox("Cannot save as an object file, icon not created.",
                 TOOL_NAME, INFO_MB);
           return FALSE;
!       } else if (FileNameHasExtension(icon_name, SYM_FILE_TYPE, NULL)) {
           strcpy(icon_full_name, icon_name);
           if ((psz=UtilStrRChr(icon_name, '.')) != NULL) {
--- 696,704 ----
        sym_ext_len = strlen(sym_ext_str);
  
!       if (FileNameHasExtension(icon_name, OBJ_FILE_TYPE, NULL, NULL)) {
           MsgBox("Cannot save as an object file, icon not created.",
                 TOOL_NAME, INFO_MB);
           return FALSE;
!       } else if (FileNameHasExtension(icon_name, SYM_FILE_TYPE, NULL, NULL)) {
           strcpy(icon_full_name, icon_name);
           if ((psz=UtilStrRChr(icon_name, '.')) != NULL) {
***************
*** 709,713 ****
              return FALSE;
           }
!       } else if (FileNameHasExtension(icon_name, PIN_FILE_TYPE, NULL)) {
           MsgBox("Cannot save as a pin file, icon not created.",
                 TOOL_NAME, INFO_MB);
--- 709,713 ----
              return FALSE;
           }
!       } else if (FileNameHasExtension(icon_name, PIN_FILE_TYPE, NULL, NULL)) {
           MsgBox("Cannot save as a pin file, icon not created.",
                 TOOL_NAME, INFO_MB);
*** stream.c.orig	Sun Apr 11 10:47:24 1999
--- stream.c	Sun Apr 11 10:47:24 1999
***************
*** 432,436 ****
     char *c_ptr=NULL, *line_ptr=(&buf[start_index]);
     int content_len=(-1), just_lf=IsJustLF(line_ptr);
!    int found_boundary=FALSE, inc=(just_lf?1:2);
  
     memset(pici, 0, sizeof(ImageContentInfo));
--- 432,437 ----
     char *c_ptr=NULL, *line_ptr=(&buf[start_index]);
     int content_len=(-1), just_lf=IsJustLF(line_ptr);
!    int found_boundary=FALSE, inc=(just_lf?1:2), first_line=TRUE;
!    int faked_found_boundary=FALSE, seen_none_blank_line=FALSE;
  
     memset(pici, 0, sizeof(ImageContentInfo));
***************
*** 443,446 ****
--- 444,454 ----
           if (*line_ptr == ' ' || *line_ptr == '\t') {
              /* ignore */
+          } else if (first_line && *line_ptr == '\0') {
+             /*
+              * it may not have the boundary line, just pretend that the
+              *       boundary line is found
+              */
+             found_boundary = TRUE;
+             faked_found_boundary = TRUE;
           } else {
              if (strcmp(line_ptr, gpszBoundary) == 0) {
***************
*** 447,451 ****
--- 455,461 ----
                 found_boundary = TRUE;
              }
+             seen_none_blank_line = TRUE;
           }
+          first_line = FALSE;
           *c_ptr = (just_lf ? '\n' : '\r');
           line_ptr = (&c_ptr[inc]);
***************
*** 452,456 ****
           continue;
        }
!       if (c_ptr == line_ptr) {
           /* reach the end of header, now decide if the header is good */
  
--- 462,466 ----
           continue;
        }
!       if (c_ptr == line_ptr && seen_none_blank_line) {
           /* reach the end of header, now decide if the header is good */
  
***************
*** 491,497 ****
        }
        *c_ptr = '\0';
!       if (*line_ptr == ' ' || *line_ptr == '\t') {
           /* ignore */
        } else {
           colon_ptr = strchr(line_ptr, ':');
           if (colon_ptr != NULL) {
--- 501,509 ----
        }
        *c_ptr = '\0';
!       if (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == '\0') {
           /* ignore */
        } else {
+          seen_none_blank_line = TRUE;
+ 
           colon_ptr = strchr(line_ptr, ':');
           if (colon_ptr != NULL) {
***************
*** 521,524 ****
--- 533,540 ----
              }
              *colon_ptr = ':';
+          } else if (faked_found_boundary) {
+             if (strcmp(line_ptr, gpszBoundary) == 0) {
+                faked_found_boundary = FALSE;
+             }
           }
        }
***************
*** 543,547 ****
  
           if (tmp_fname != NULL) {
!             int i=0, left_over=0;
              char *dest=NULL, *src=NULL;
  
--- 559,563 ----
  
           if (tmp_fname != NULL) {
!             int left_over=0;
              char *dest=NULL, *src=NULL;
  
***************
*** 564,571 ****
              dest = (&buf[gnStartIndex]);
              src = (&buf[gnStartIndex+ici.header_len+ici.content_len]);
!             for (i=0; i < left_over; i++) {
!                *dest++ = *src++;
              }
-             *pn_buf_len = gnStartIndex + left_over;
           }
        }
--- 580,596 ----
              dest = (&buf[gnStartIndex]);
              src = (&buf[gnStartIndex+ici.header_len+ici.content_len]);
!             if (left_over >= 5 && UtilStrNCaseCmp(src, "HTTP/", 5) == 0) {
!                dest = buf;
!                memcpy(dest, src, left_over*sizeof(char));
!                *pn_buf_len = left_over;
!                ResetMultipartReplace(FALSE);
!                ScanHeader(buf);
!                if (!gnMultipartReplace) {
!                   return;
!                }
!             } else {
!                memcpy(dest, src, left_over*sizeof(char));
!                *pn_buf_len = gnStartIndex + left_over;
              }
           }
        }
*** testdrive.c.orig	Sun Apr 11 10:47:25 1999
--- testdrive.c	Sun Apr 11 10:47:25 1999
***************
*** 122,125 ****
--- 122,196 ----
  }
  
+ #define DO_CMD(cmd) ExecACommandFromBuffer(cmd,NULL)
+ 
+ static
+ void ScriptDemo()
+ {
+    MakeQuiescent(); /* select nothing, edit nothing */
+ 
+    if (BeginExecCommandsFromBuffer()) {
+       int i=0;
+ 
+       /* set current color to 'blue' */
+       DO_CMD("set_selected_obj_color(\"blue\")");
+       /* create a 200 pixels by 100 pixels blue box */
+       DO_CMD("create_box_obj(100,100,300,200)");
+       /* select the top object, which is the box object */
+       DO_CMD("select_top_obj()");
+       /* name the box object "the_box" */
+       DO_CMD("add_attr_to_selected_obj(\"name\",\"the_box\",100,100)");
+       /* hide all the attributes of the box object */
+       DO_CMD("call_simple_shortcut(\"HideAttr\")");
+       /* unselect everything */
+       DO_CMD("unselect_all_obj()");
+ 
+       /* set current text justification to center justified */
+       DO_CMD("set_selected_text_just(\"center\")");
+       /* set current text font to Helvetica Bold */
+       DO_CMD("set_selected_text_font(\"Helvetica-Bold\")");
+       /* set current text size to 14 */
+       DO_CMD("set_selected_text_size(14)");
+       /* create a text object that sits on top the blue box */
+       DO_CMD("create_text_obj(200,100,\"My Box\")");
+ 
+       /* select the box object */
+       DO_CMD("select_obj_by_name(\"the_box\")");
+       /* sleep for 500ms */
+       DO_CMD("sleep(NULL,500)");
+       /* change the box to 'green' */
+       DO_CMD("set_selected_obj_color(\"green\")");
+ 
+       /* cycle through all the fill patterns */
+       for (i=31; i >= 0; i--) {
+          char buf[80];
+ 
+          sprintf(buf, "set_selected_obj_fill(%1d)", i);
+          DO_CMD(buf);
+       }
+       /* sleep for another 500ms */
+       DO_CMD("sleep(NULL,500)");
+       /* change the box to 'red' */
+       DO_CMD("set_selected_obj_color(\"red\")");
+       /* sleep for another 500ms */
+       DO_CMD("sleep(NULL,500)");
+ 
+       /* lock the box */
+       DO_CMD("call_simple_shortcut(\"Lock\")");
+ 
+       /* select the top object, which is the text object */
+       DO_CMD("select_top_obj()");
+       /* also select the box */
+       DO_CMD("select_additional_obj(\"the_box\")");
+       /* align the text object so that it sits in the middle of the box */
+       DO_CMD("call_simple_shortcut(\"AlignObjsMiddle\")");
+       /* unlock the box */
+       DO_CMD("call_simple_shortcut(\"UnLock\")");
+       /* unselect everything */
+       DO_CMD("unselect_all_obj()");
+ 
+       EndExecCommandsFromBuffer();
+    }
+ }
+ 
  int main(argc, argv)
     int argc;
***************
*** 184,187 ****
--- 255,260 ----
           }
           printf("\n");
+       } else if (strcmp(s, "Anim") == 0) {
+          ScriptDemo();
        }
  
*** text.c.orig	Sun Apr 11 10:47:26 1999
--- text.c	Sun Apr 11 10:47:26 1999
***************
*** 854,859 ****
  }
  
! int CreateTextObj(nDeactivateIM)
!    int nDeactivateIM;
     /* returns TRUE if something got created */
     /* returns FALSE otherwise */
--- 854,859 ----
  }
  
! int CreateTextObj(nDeactivateIM, nRedraw)
!    int nDeactivateIM, nRedraw;
     /* returns TRUE if something got created */
     /* returns FALSE otherwise */
***************
*** 1083,1091 ****
           }
        }
!       RedrawAreas(botObj, beforeEditTextInfo.bbox.ltx-GRID_ABS_SIZE(2),
!             beforeEditTextInfo.bbox.lty-GRID_ABS_SIZE(2),
!             beforeEditTextInfo.bbox.rbx+GRID_ABS_SIZE(2),
!             beforeEditTextInfo.bbox.rby+GRID_ABS_SIZE(2), ltx-GRID_ABS_SIZE(2),
!             lty-GRID_ABS_SIZE(2), rbx+GRID_ABS_SIZE(2), rby+GRID_ABS_SIZE(2));
     } else {
        int x=0;
--- 1083,1094 ----
           }
        }
!       if (nRedraw) {
!          RedrawAreas(botObj, beforeEditTextInfo.bbox.ltx-GRID_ABS_SIZE(2),
!                beforeEditTextInfo.bbox.lty-GRID_ABS_SIZE(2),
!                beforeEditTextInfo.bbox.rbx+GRID_ABS_SIZE(2),
!                beforeEditTextInfo.bbox.rby+GRID_ABS_SIZE(2),
!                ltx-GRID_ABS_SIZE(2), lty-GRID_ABS_SIZE(2), rbx+GRID_ABS_SIZE(2),
!                rby+GRID_ABS_SIZE(2));
!       }
     } else {
        int x=0;
***************
*** 1096,1104 ****
        case JUST_R: x = textOrigX-textW+textAbsMinLBearing; break;
        }
!       RedrawAreas(botObj, ltx-GRID_ABS_SIZE(2), lty-GRID_ABS_SIZE(2),
!             rbx+GRID_ABS_SIZE(2), rby+GRID_ABS_SIZE(2), ABS_X(x-2),
!             ABS_Y(textOrigY-2),
!             ABS_X(x+textW-textAbsMinLBearing+textAbsMaxRExtra+3),
!             ABS_Y(textOrigY+textH+3));
     }
     textOrigX = textOrigY = textCurX = textCurY = ABS_SIZE(20);
--- 1099,1109 ----
        case JUST_R: x = textOrigX-textW+textAbsMinLBearing; break;
        }
!       if (nRedraw) {
!          RedrawAreas(botObj, ltx-GRID_ABS_SIZE(2), lty-GRID_ABS_SIZE(2),
!                rbx+GRID_ABS_SIZE(2), rby+GRID_ABS_SIZE(2), ABS_X(x-2),
!                ABS_Y(textOrigY-2),
!                ABS_X(x+textW-textAbsMinLBearing+textAbsMaxRExtra+3),
!                ABS_Y(textOrigY+textH+3));
!       }
     }
     textOrigX = textOrigY = textCurX = textCurY = ABS_SIZE(20);
***************
*** 1123,1132 ****
        RotateObjClockWise(topObj);
        rotationIncrement = saved_rotation_increment;
!       RedrawAreas(botObj, saved_ltx-GRID_ABS_SIZE(1),
!             saved_lty-GRID_ABS_SIZE(1), saved_rbx+GRID_ABS_SIZE(1),
!             saved_rby+GRID_ABS_SIZE(1), topObj->bbox.ltx-GRID_ABS_SIZE(1),
!             topObj->bbox.lty-GRID_ABS_SIZE(1),
!             topObj->bbox.rbx+GRID_ABS_SIZE(1),
!             topObj->bbox.rby+GRID_ABS_SIZE(1));
     }
     curTextIsNew = FALSE;
--- 1128,1139 ----
        RotateObjClockWise(topObj);
        rotationIncrement = saved_rotation_increment;
!       if (nRedraw) {
!          RedrawAreas(botObj, saved_ltx-GRID_ABS_SIZE(1),
!                saved_lty-GRID_ABS_SIZE(1), saved_rbx+GRID_ABS_SIZE(1),
!                saved_rby+GRID_ABS_SIZE(1), topObj->bbox.ltx-GRID_ABS_SIZE(1),
!                topObj->bbox.lty-GRID_ABS_SIZE(1),
!                topObj->bbox.rbx+GRID_ABS_SIZE(1),
!                topObj->bbox.rby+GRID_ABS_SIZE(1));
!       }
     }
     curTextIsNew = FALSE;
***************
*** 1867,1871 ****
              }
           } else {
!             CreateTextObj(TRUE); /* end editing on the old text */
              curTextModified = FALSE;
           }
--- 1874,1878 ----
              }
           } else {
!             CreateTextObj(TRUE, TRUE); /* end editing on the old text */
              curTextModified = FALSE;
           }
***************
*** 2427,2431 ****
        return;
     }
!    CreateTextObj(TRUE);
     curTextModified = FALSE;
  
--- 2434,2438 ----
        return;
     }
!    CreateTextObj(TRUE, TRUE);
     curTextModified = FALSE;
  
***************
*** 5153,5160 ****
  {
     int abs_x=0, abs_y=0, x_off=0, y_off=0;
  
!    if (curChoice == DRAWTEXT) {
        escPressed = FALSE;
!       CreateTextObj(TRUE);
        curTextModified = FALSE;
     }
--- 5160,5173 ----
  {
     int abs_x=0, abs_y=0, x_off=0, y_off=0;
+    int update_highlighted_text_bboxes=FALSE;
  
!    if (curChoice == DRAWTEXT && textCursorShown) {
!       if (textHighlight) {
!          update_highlighted_text_bboxes = TRUE;
!       } else {
!          EraseTextCursor();
!       }
        escPressed = FALSE;
!       CreateTextObj(TRUE, TRUE);
        curTextModified = FALSE;
     }
***************
*** 5165,5169 ****
        return;
     }
!    if (curStrBlock != NULL) UpdateHighLightedTextBBoxes(TRUE);
     HandleClickOnText(FALSE, TRUE, x_off, y_off, FALSE, curTextObj, FALSE, TRUE,
           TRUE, (Time)0);
--- 5178,5184 ----
        return;
     }
!    if (update_highlighted_text_bboxes && curStrBlock != NULL) {
!       UpdateHighLightedTextBBoxes(TRUE);
!    }
     HandleClickOnText(FALSE, TRUE, x_off, y_off, FALSE, curTextObj, FALSE, TRUE,
           TRUE, (Time)0);
*** tgif.c.orig	Sun Apr 11 10:47:29 1999
--- tgif.c	Sun Apr 11 10:47:29 1999
***************
*** 147,158 ****
     int read_status, obj_file=TRUE;
     FILE *fp=NULL;
!    int tmp_linenum;
  
!    if (FileNameHasExtension(FileName, OBJ_FILE_TYPE, NULL)) {
        strcpy(full_name, FileName);
!    } else if (FileNameHasExtension(FileName, SYM_FILE_TYPE, NULL)) {
        strcpy(full_name, FileName);
        obj_file = FALSE;
!    } else if (FileNameHasExtension(FileName, PIN_FILE_TYPE, NULL)) {
        strcpy(full_name, FileName);
        obj_file = FALSE;
--- 147,158 ----
     int read_status, obj_file=TRUE;
     FILE *fp=NULL;
!    int tmp_linenum=0, gzipped=FALSE;
  
!    if (FileNameHasExtension(FileName, OBJ_FILE_TYPE, &gzipped, NULL)) {
        strcpy(full_name, FileName);
!    } else if (FileNameHasExtension(FileName, SYM_FILE_TYPE, NULL, NULL)) {
        strcpy(full_name, FileName);
        obj_file = FALSE;
!    } else if (FileNameHasExtension(FileName, PIN_FILE_TYPE, NULL, NULL)) {
        strcpy(full_name, FileName);
        obj_file = FALSE;
*** wb.c.orig	Sun Apr 11 10:47:30 1999
--- wb.c	Sun Apr 11 10:47:30 1999
***************
*** 36,39 ****
--- 36,45 ----
  #include "tgifdefs.h"
  
+ #ifdef _TGIF_WB2
+ #ifdef _HAS_STREAMS_SUPPORT
+ #include <stropts.h>
+ #endif /* _HAS_STREAMS_SUPPORT */
+ #endif /* _TGIF_WB2 */
+ 
  #include "auxtext.e"
  #include "drawing.e"
***************
*** 52,55 ****
--- 58,63 ----
  #include "util.e"
  #include "wb.e"
+ #include "wb_buff.e"
+ #include "wb_mcast.e"
  
  struct WhiteBoardRec	gstWBInfo;
***************
*** 58,61 ****
--- 66,75 ----
  int	cmdLineWhiteBoardListenOnly=FALSE;
  
+ #ifdef _TGIF_WB2
+ static struct sigaction	act_IO;
+ static sigset_t		sinal;
+ static int		localNrCmd=0;
+ #endif /* _TGIF_WB2 */
+ 
  /* =================== Remote Related Functions =================== */
  
***************
*** 130,134 ****
     gstWBInfo.listening = TRUE;
  
!    sprintf(gstWBInfo.listen_fname, "%sTgifXXXXXX", TMP_DIR);
     mktemp(gstWBInfo.listen_fname);
     unlink(gstWBInfo.listen_fname);
--- 144,148 ----
     gstWBInfo.listening = TRUE;
  
!    sprintf(gstWBInfo.listen_fname, "%sTgifLXXXXXX", TMP_DIR);
     mktemp(gstWBInfo.listen_fname);
     unlink(gstWBInfo.listen_fname);
***************
*** 138,141 ****
--- 152,156 ----
        return FALSE;
     }
+ #ifdef _FAKE_WB_HTTP_STYLE
     gstWBInfo.listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     if (gstWBInfo.listen_socket == (-1)) {
***************
*** 156,159 ****
--- 171,176 ----
     }
     listen(gstWBInfo.listen_socket, 1);
+ #endif /* _FAKE_WB_HTTP_STYLE */
+ 
     return TRUE;
  }
***************
*** 196,202 ****
--- 213,280 ----
  #endif /* _TGIF_DBG_WB2 */
  
+ int WBHasReadData(pn_flag, pn_retry)
+    int *pn_flag, *pn_retry;
+ {
+ #ifdef _TGIF_DBG_WB2
+    if (gstWBInfo.listening && gstWBInfo.listen_socket != (-1)) {
+       /*
+        * Receives one command at a time -- just like HTTP.
+        */
+       int csd=(-1);
+ 
+       if ((csd=AcceptWBSocket()) != (-1)) {
+          *pn_retry = FALSE;
+          *pn_flag = csd;
+          return TRUE
+       }
+    }
+    return FALSE;
+ #else /* ~_TGIF_DBG_WB2 */
+    /* leave *pn_retry alone */
+    return (buff_items(gstWBInfo.bd_commands) > 0);
+ #endif /* _TGIF_DBG_WB2 */
+ }
+ 
+ int RecvWBData(flag, ppsz_buf, pn_buf_sz)
+    int flag, *pn_buf_sz;
+    char **ppsz_buf;
+ {
+ #ifdef _TGIF_DBG_WB2
+    char *buf=NULL;
+    int buf_sz=0, csd=flag;
+    int status=HttpDoRead(csd, &buf, &buf_sz);
+ 
+    shutdown(csd, 2);
+    close(csd);
+ 
+    if (status == TG_REMOTE_STATUS_OK && buf_sz > 0 &&
+          buf != NULL && *buf != '\0') {
+       fprintf(stderr, "Got %1d bytes!\n", buf_sz);
+       *ppsz_buf = buf;
+       *pn_buf_sz = buf_sz;
+ 
+       return TRUE;
+    }
+    if (buf != NULL) FreeRemoteBuf(buf);
+ 
+    *ppsz_buf = NULL;
+    *pn_buf_sz = 0;
+ 
+    return FALSE;
+ #else /* ~_TGIF_DBG_WB2 */
+    *ppsz_buf = (char*)malloc(WB_PACK*sizeof(char));
+    if (*ppsz_buf == NULL) FailAllocMessage();
+    *pn_buf_sz = WB_PACK;
+ 
+    buff_rem(gstWBInfo.bd_commands, *ppsz_buf);
+ 
+    return TRUE;
+ #endif /* _TGIF_DBG_WB2 */
+ }
+ 
  int SendWBData(pszWBData)
     char *pszWBData;
  {
+ #ifdef NOT_DEFINED
     int status=TG_REMOTE_STATUS_OK, n_socket=0;
  
***************
*** 220,223 ****
--- 298,312 ----
        close(n_socket);
     }
+ #endif /* NOT_DEFINED */
+ 
+    struct WbMessage CmdSend;
+ 
+    memset(&CmdSend, 0, sizeof(CmdSend));
+    memcpy(CmdSend.WbCmd, pszWBData, strlen(pszWBData));
+    memcpy(CmdSend.IDIP, gszLocalPID, MAXSTRING);
+    CmdSend.NSeq = localNrCmd++;
+    PCM_sendto(gstWBInfo.MCastSock, (char*)(&CmdSend), sizeof(struct WbMessage),
+          0, (struct sockaddr *)(&PCM_sockaddr), sizeof(PCM_sockaddr));
+ 
     return TRUE;
  }
***************
*** 831,834 ****
--- 920,986 ----
  }
  
+ /* =================== SIGPOLL Handler function =================== */
+ 
+ #ifdef _TGIF_WB2
+ static
+ void IO_SignalHandler()
+    /*
+     * This function handles the IO signal generated by packet throught socket.
+     */
+ {
+    struct WbMessage cmd_received;
+    char buf[WB_PACK], aux[WB_PACK], *psz_content=NULL, *psz_content_type=NULL;
+    char h_from[100], h_pid[100], h_ip[100], id[300], *WbData=NULL;
+    int content_sz=0;
+  
+    deserializingFile = TRUE;
+  
+    WbData = (char*)malloc(sizeof(struct WbMessage));
+ 
+    if (PCM_recv(gstWBInfo.MCastSock, WbData, sizeof(struct WbMessage), 0) < 0) {
+       free(WbData) ;
+       deserializingFile = FALSE;
+       return ;
+    }
+    memcpy(&cmd_received, WbData, sizeof(struct WbMessage));
+    memcpy(buf, cmd_received.WbCmd, WB_PACK);
+    /*
+     * verifica se a mensagem nao eh dele proprio
+     * (pode ser feito de outra maneira?)
+     */
+    sscanf(buf, "%s %s\t%s\r\n", h_from, h_pid, h_ip);
+    sprintf(id, "%s\t%s", h_pid, h_ip);
+    printf("Id = %s\n",id);
+    if(strcmp(id, gszLocalPID) == 0) {
+       free(WbData);
+       deserializingFile = FALSE;
+       return;
+    }
+    /* Verifica se pode processar o comando agora, ou se deve armazenar */
+    if(!gstWBInfo.CanProcessRemoteCmd) {
+       strcpy(aux, buf);
+       buff_ins(gstWBInfo.bd_commands, aux);
+       free(WbData);
+       deserializingFile = FALSE;
+       return;
+    }
+    if (cmd_received.NSeq >= localNrCmd) {
+       localNrCmd = cmd_received.NSeq + 1;
+    }
+    if ((psz_content=HttpExtractText(buf, &content_sz, NULL,
+          &psz_content_type)) != NULL) {
+       ProcessRemoteCmd(psz_content, content_sz);
+       FreeRemoteBuf(psz_content);
+    }
+    if (psz_content_type != NULL) {
+       UtilFree(psz_content_type);
+    }
+    FreeRemoteBuf(buf);
+    free(WbData);
+    deserializingFile = FALSE;
+    return;
+ }
+ #endif /* _TGIF_WB2 */
+ 
  /* =================== Init and CleanUp Functions =================== */
  
***************
*** 842,845 ****
--- 994,1001 ----
  int InitWhiteBoard()
  {
+ #ifdef _TGIF_WB2
+    char logfile[MAXPATHLENGTH];
+ #endif /* _TGIF_WB2 */
+ 
     memset(&gstWBInfo, 0, sizeof(struct WhiteBoardRec));
  
***************
*** 869,875 ****
        }
     }
  #endif /* _TGIF_DBG_WB2 */
     if (gstWBInfo.do_whiteboard) {
!       sprintf(gstWBInfo.send_fname, "%sTgifXXXXXX", TMP_DIR);
        mktemp(gstWBInfo.send_fname);
        unlink(gstWBInfo.send_fname);
--- 1025,1032 ----
        }
     }
+    /* fim do trecho */
  #endif /* _TGIF_DBG_WB2 */
     if (gstWBInfo.do_whiteboard) {
!       sprintf(gstWBInfo.send_fname, "%sTgifSXXXXXX", TMP_DIR);
        mktemp(gstWBInfo.send_fname);
        unlink(gstWBInfo.send_fname);
***************
*** 879,884 ****
--- 1036,1068 ----
           exit(-1);
        }
+       /* Creation of multicast socket */
+       sprintf(logfile, "%snome.txt", TMP_DIR);
+       PCM_initialize(logfile);
+       PCM_setoption(SM_INTERVAL,3);
+ 
+       PCM_conf_recv = 1;
+       PCM_conf_send = 1;
+       gstWBInfo.MCastSock = PCM_joinGroup("225.0.0.5", 5000);
+ 
+       gstWBInfo.bd_commands = buff_init (10, WB_PACK, UNSORTED, NULL );
+ 
+       /* Installation and setup of signal Handler para SIGPOLL */
+ 
+       sigemptyset(&sinal);
+ 
+       sigaddset(&sinal,SIGPOLL);
+ 
+       act_IO.sa_handler=IO_SignalHandler;
+ 
+       sigaction(SIGPOLL, &act_IO, NULL);
+ 
+ #ifdef I_SETSIG
+       if (ioctl(gstWBInfo.MCastSock, I_SETSIG, S_RDNORM) < 0) perror("ioctl");
+ #endif /* I_SETSIG */
+ 
+       if (fcntl(gstWBInfo.MCastSock, F_SETFL, O_NONBLOCK) < 0) perror("fcntl");
     }
  #endif /* _TGIF_WB2 */
+ 
     return TRUE;
  }
*** wb_buff.c.orig	Sun Apr 11 10:47:31 1999
--- wb_buff.c	Sun Apr 11 10:47:31 1999
***************
*** 0 ****
--- 1,482 ----
+ /*
+  * Author:      Magnos Martinello, <magnos@land.ufrj.br> in April, 1999.
+  *
+  * @(#)$Header: /mm/src/tgif/v4/RCS/wb_buff.c,v 4.0 1999/04/09 16:09:22 william Exp $
+  */
+ 
+ #define _INCLUDE_FROM_WB_BUFF_C_
+ 
+ #include "tgifdefs.h"
+ 
+ #ifdef PTHREAD
+ #include <pthread.h>
+ #endif
+ 
+ #include "wb_buff.e"
+ 
+ /*
+   Structure of each component from the buffer
+ */
+ typedef struct item_s {
+    void *data;
+    struct item_s *prev;
+    struct item_s *next;
+ } item_t;
+ 
+ /*******************************************************************
+   Header:
+    - Maximum number of items in the buffer
+    - Size of each item
+    - Number of items in the buffer
+    - SORTED/UNSORTED insertion
+    - Pointer to first item of the queue
+    - Pointer to last item of the queue
+      (Item is inserted in the start pointer and removed from the end pointer)
+    - Function to compare two items of the buffer
+ *******************************************************************/
+ typedef struct {
+    int nitems;
+    int size; 
+    int n;
+    int option;
+ #ifdef PTHREAD
+    pthread_mutex_t *mp;
+ #endif
+    item_t *start;
+    item_t *end;
+    int (*compar)(const void *, const void *);
+ } header_t;
+ 
+ header_t *table[MAXTABLE];
+ #ifdef PTHREAD
+ pthread_mutex_t table_mp;
+ #endif
+ 
+ #ifdef _TGIF_WB2
+ 
+ /***********************************************************************
+  * This function creates a new buffer and returns its descriptor as    *
+  * an integer                                                          *
+  **********************************************************************/
+ int buff_init (int n, int size, int option, int (*compar)(const void *,
+ const void *))
+ {
+   header_t *header;
+   item_t *item, *auxitem;
+   int aux;
+   static int last_used_desc = MAXTABLE - 1;
+ 
+   /* If option is invalid then return error */
+   if (((option & SORTED)==SORTED) && ((option & UNSORTED)==UNSORTED))
+     return(-1);
+ 
+   /* If insertion is sorted and no comparison function has been assigned,
+      then return error */
+   if ((option == SORTED) && (compar == NULL))
+     return(-1);
+ 
+   /* Check for valid size and number of items */
+   if ((n <= 0) || (size <= 0))
+     return(-1);
+ 
+   /* Looks for an empty position in the Descriptor Table */
+ #ifdef PTHREAD
+   pthread_mutex_lock(&table_mp);
+ #endif
+   aux = last_used_desc;
+   last_used_desc = (last_used_desc + 1) % MAXTABLE;
+   while ((table[last_used_desc] != NULL) && (aux != last_used_desc))
+     last_used_desc = (last_used_desc + 1) % MAXTABLE;
+   if (!(table[last_used_desc] == NULL)){
+ #ifdef PTHREAD
+     pthread_mutex_unlock(&table_mp);
+ #endif
+     return(-1);
+   }
+ #ifdef PTHREAD
+   pthread_mutex_unlock(&table_mp);
+ #endif
+ 
+   /* Create a new header and store its pointer in the descriptor table */
+   header = (header_t *) malloc (sizeof(header_t));
+   if (header == NULL)
+     return(-1);
+   table[last_used_desc] = header;
+ 
+   /* Set values for attributes in the header */
+   header->nitems = n;
+   header->size = size;
+   header->n = 0;
+ #ifdef PTHREAD
+   header->mp = malloc(sizeof(pthread_mutex_t));
+   pthread_mutex_init(header->mp, NULL);
+ #endif
+   header->option = option;
+   header->compar = compar;
+   header->end = (item_t *) malloc (sizeof(item_t));
+   if (header->end == NULL)
+     return(-1);
+ 
+   header->end->data = malloc (size);
+   auxitem = header->end;
+   for (aux = 1; aux < n; aux++) {
+     item = (item_t *) malloc (sizeof(item_t));
+     item->data = malloc (size);
+     if ((item == NULL) || (item->data == NULL))
+       return(-1);
+     item->prev = auxitem;
+     auxitem->next = item;
+     auxitem = item;
+   }
+   item->next = header->end;
+   header->end->prev = item;
+ 
+   header->start = header->end;
+ 
+   return last_used_desc;
+ }
+ 
+ /***********************************************************************
+  * This function inserts a new item in the buffer especified by its    *
+  * descriptor. The insertion may be sorted or not, depending on the    *
+  * option set during the buffer initialization. It returns a negative  *
+  * integer if the insertion wasn't successful.                         *
+  **********************************************************************/
+ int buff_ins (int bd, const void *buffer)
+ {
+   header_t *header;
+   item_t *item, *newitem, *auxitem;
+ 
+   if (table[bd] == NULL)
+     return(-1);
+ 
+   header = table[bd];
+ 
+ #ifdef PTHREAD
+   pthread_mutex_lock(header->mp);
+ #endif
+ 
+   if (header->n == header->nitems){
+ #ifdef PTHREAD
+     pthread_mutex_unlock(header->mp);
+ #endif
+     return(-1);
+   }
+ 
+   /* Unsorted insertion or empty buffer */
+   if (((header->option & UNSORTED) == UNSORTED) || (header->n == 0)){
+     memcpy(header->start->data, buffer, header->size);
+     header->start = header->start->next;
+   }
+   else /* Sorted buffer */
+   if ((header->option & SORTED) == SORTED){
+ 
+     /* Search position where new item will be inserted according to
+        comparison function previously specified                     */
+     /* Search is made from begining to end and form end to begining */
+     item = header->end;
+     auxitem = header->start->prev;
+     while (((item != header->start) &&
+ (header->compar(item->data,buffer)<= 0)) &&
+     ((auxitem != header->end) &&
+ (header->compar(auxitem->data,buffer)>0))){
+       item = item->next;
+       auxitem = auxitem->prev;
+     }
+ 
+     /* Decide wich pointer points to the correct position */
+     if (header->compar(auxitem->data, buffer)<=0)
+       item = auxitem->next;
+ 
+     if ((header->option & DUPLICATED) != DUPLICATED)
+       if (header->compar(item->prev->data, buffer)==0){
+ #ifdef PTHREAD
+         pthread_mutex_unlock(header->mp);
+ #endif
+ 	return(-1);
+     }
+ 
+     /* If new item is the greatest then simply copy it to the fisrt
+        avaiable position in the buffer                             */
+     if (item == header->start) {
+       memcpy (item->data, buffer, header->size);
+       header->start = header->start->next;
+       header->n++;
+ #ifdef PTHREAD
+       pthread_mutex_unlock(header->mp);
+ #endif
+       return(0);
+     }
+ 
+     /* Create the new item */
+     newitem = (item_t *) malloc (sizeof(item_t));
+     newitem->data = malloc (header->size);
+     memcpy(newitem->data, buffer, header->size);
+ 
+     /* Set pointers */
+     item->prev->next = newitem;
+     newitem->next = item;
+     newitem->prev = item->prev;
+     item->prev = newitem;
+ 
+     if (header->compar(buffer, header->end->data) < 0)
+       header->end = newitem;
+ 
+     newitem = header->start;
+     newitem->prev->next = newitem->next;
+     newitem->next->prev = newitem->prev;
+     header->start = header->start->next;
+ 
+     free(newitem->data);
+     free(newitem);
+   }
+ 
+   header->n++;
+ #ifdef PTHREAD
+   pthread_mutex_unlock(header->mp);
+ #endif
+   return(0);
+ }
+ 
+ /***********************************************************************
+  * This function removes an item from the buffer especified by its     *
+  * descriptor. The data stored in the item is copied to a pointer      *
+  * especified by the user. It returns a negative integer if an error   *
+  * occurs                                                              *
+  **********************************************************************/
+ int buff_rem (int bd, void *buffer)
+ {
+   header_t *header;
+ 
+   if (table[bd] == NULL)
+     return(-1);
+ 
+   header = table[bd];
+ 
+ #ifdef PTHREAD
+   pthread_mutex_lock(header->mp);
+ #endif 
+ 
+   if (header->n == 0){
+ #ifdef PTHREAD
+     pthread_mutex_unlock(header->mp);
+ #endif
+     return(-1);
+   }
+ 
+   memcpy(buffer, header->end->data, header->size);
+   header->end = header->end->next;
+   header->n--;
+ 
+ #ifdef PTHREAD
+   pthread_mutex_unlock(header->mp);
+ #endif
+ 
+   return(0);
+ }
+ 
+ /***********************************************************************
+  * This function disposes memory occupied by the buffer.               *
+  **********************************************************************/
+ int buff_destroy (int bd)
+ {
+   item_t *item;
+   int i;
+ 
+   if (table[bd] == NULL)
+     return(-1);
+ 
+   item = table[bd]->start;
+   for (i = 0; i < table[bd]->n - 1; i++) {
+     free(item->data);
+     item = item->next;
+     free(item->prev);
+   }
+   free(item->data);
+   free(item);
+ 
+ #ifdef PTHREAD
+   pthread_mutex_destroy(table[bd]->mp);
+ #endif
+   free(table[bd]);
+ 
+   return(0);
+ }
+ 
+ /***********************************************************************
+  * This function makes all items avaiable for insertion                *
+  **********************************************************************/
+ int buff_empty (int bd)
+ {
+   header_t *header;
+ 
+   if (table[bd] == NULL)
+     return(-1);
+ 
+   header = table[bd];
+ #ifdef PTHREAD
+   pthread_mutex_lock(header->mp);
+ #endif
+   header->n = 0;
+   header->end = header->start;
+ #ifdef PTHREAD
+   pthread_mutex_unlock(header->mp);
+ #endif
+ 
+   return(0);
+ }
+ 
+ /***********************************************************************
+  * This function makes the first n items avaiable for insertion. It    *
+  * returns the number of items disposed.                               *
+  **********************************************************************/
+ int buff_emptyn (int bd, int n)
+ {
+   header_t *header;
+   int nitems, i;
+ 
+   if (table[bd] == NULL)
+     return(-1);
+ 
+   header = table[bd];
+ #ifdef PTHREAD
+   pthread_mutex_lock(header->mp);
+ #endif
+   nitems = header->n;
+   i = 0;
+   while ( (header->n > 0) && (i < n)) {
+     i++;
+     header->n--;
+     header->end = header->end->next;
+   }
+ 
+ #ifdef PTHREAD
+   pthread_mutex_unlock(header->mp);
+ #endif
+ 
+   return((nitems<n?nitems:n));
+ }
+ 
+ /***********************************************************************
+  * This function returns the number of active items in the buffer      *
+  **********************************************************************/
+ int buff_items (int bd)  {
+ 
+   if (table[bd] == NULL)
+     return -1;
+   else
+     return table[bd]->n;
+ }
+ 
+ /***********************************************************************
+  * This function concatenates two buffers, creating a new unsorted     *
+  * insertion buffer                                                    *
+  **********************************************************************/
+ int buff_conc (int bd1, int bd2)
+ {
+   header_t *hd1, *hd2;
+   item_t *item;
+   int nbd, i;
+   char *buffer;
+ 
+   if ( (table[bd1] == NULL) || (table[bd2] == NULL))
+     return(-1);
+ 
+   hd1 = table[bd1];
+   hd2 = table[bd2];
+ 
+   if (hd1->size != hd2->size)
+     return(-1);
+ 
+   nbd = buff_init (hd1->n + hd2->n, hd1->size, 0, hd1->compar);
+   buffer = (char*) malloc (hd1->size);
+ 
+   item = hd1->end;
+   i = 0;
+   while (i < hd1->n)
+   {
+     i++;
+     memcpy(buffer, item->data, hd1->size);
+     buff_ins(nbd, buffer);
+     item = item->next;
+   }
+ 
+   item = hd2->end;
+   i = 0;
+   while (i < hd2->n)
+   {
+     i++;
+     memcpy(buffer, item->data, hd1->size);
+     buff_ins(nbd, buffer);
+     item = item->next;
+   }
+ 
+   free (buffer);
+ 
+   return(nbd);
+ }
+ 
+ /***********************************************************************
+  * This function sorts a buffer according to a comparison function     *
+  * pointed to by compar                                                *
+  **********************************************************************/
+ int buff_sort (int bd, int (*compar)(const void *, const void *))
+ {
+   header_t *header;
+   char *buffer;
+   int i, n;
+   item_t *item;
+ 
+   if (table[bd] == NULL)
+     return(-1);
+ 
+   header = table[bd];
+ 
+ #ifdef PTHREAD
+   pthread_mutex_lock(header->mp);
+ #endif
+ 
+   if ((header->option & SORTED) == SORTED){
+ #ifdef PTHREAD
+     pthread_mutex_unlock(header->mp);
+ #endif
+     return(0);
+   }
+ 
+   if (header->compar == NULL){
+ #ifdef PTHREAD
+     pthread_mutex_unlock(header->mp);
+ #endif
+     return(-1);
+   }
+ 
+   n = header->n;
+   buffer = (char*) malloc (n * header->size);
+   i = 0;
+   item = header->end;
+   while (i < n){
+     memcpy(buffer + i * header->size, item->data, header->size);
+     item = item->next;
+     i++;
+   }
+ 
+   qsort (buffer, n, header->size, compar);
+ 
+   i = 0;
+   item = header->end;
+   while (i < n){
+     memcpy(item->data, buffer + i * header->size, header->size);
+     item = item->next;
+     i++;
+   }
+ 
+   free (buffer);
+ 
+ #ifdef PTHREAD
+   pthread_mutex_unlock(header->mp);
+ #endif
+ 
+   return(0);
+ }
+ 
+ #endif /* _TGIF_WB2 */
*** wb_mcast.c.orig	Sun Apr 11 10:47:32 1999
--- wb_mcast.c	Sun Apr 11 10:47:32 1999
***************
*** 0 ****
--- 1,769 ----
+ /*
+  * Author:      Raphael S. de Moraes <raphael@land.ufrj.br> in April, 1999
+  *
+  * @(#)$Header: /mm/src/tgif/v4/RCS/wb_mcast.c,v 4.3 1999/04/11 14:13:23 william Exp $
+  */
+ 
+ #define _INCLUDE_FROM_WB_MCAST_C_
+ 
+ #include "tgifdefs.h"
+ 
+ #include <sys/uio.h>
+ #include <pwd.h>
+ 
+ #include "wb_mcast.e"
+ 
+ struct PCM_session_message PCM_SM[SM_TABLE_SIZE];
+ struct PCM_pack_struct PCM_hist[HIST_SIZE];
+ int PCM_socket=0;
+ int PCM_port=0;
+ char PCM_group[GROUP_NAME_SIZE];
+ struct sockaddr_in PCM_sockaddr;
+ 
+ FILE *PCM_logfp=NULL;
+ int PCM_myIP=0;
+ int PCM_myPID=0;
+ int PCM_Nseq=0;
+ int PCM_pos_hist=0;
+ int PCM_TSM=0, PCM_Tfunc=0;
+ int PCM_tcount=0, PCM_old_tcount=0;
+ int PCM_Nretrans=0;
+ float PCM_conf_recv=(float)0, PCM_conf_send=(float)0;
+ 
+ void (*PCM_func)()=NULL;
+ 
+ #ifdef _TGIF_WB2
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_initialize(char *logfile)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_initialize(logfile)
+ 	char *logfile;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	struct in_addr in;
+ 
+ 	PCM_initialize_SM(PCM_SM);
+ 	PCM_initialize_hist();
+ 	PCM_Nseq = 0;
+ 	PCM_pos_hist = 0;
+ 	PCM_tcount = 0;
+ 	PCM_Nretrans = 0;
+ 
+ 	PCM_conf_send = CONF_SEND;
+ 	PCM_conf_recv = CONF_RECV;
+ 
+ 	/* Pegar meu IP */
+ 	PCM_myIP = gethostid();
+ 	in.s_addr = PCM_myIP;
+ 		
+ 	/* Pegar meu PID */
+ 	PCM_myPID = getpid();
+ 
+ 	PCM_timer_run(PCM_TSM, PCM_send_SM);
+ 	
+        	/*if ((PCM_logfp = fopen(logfile,"wb"))==NULL)
+ 	{
+ 		printf("O arquivo de log nao pode ser criado\n");
+ 		exit(1);
+ 	}*/
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_setoption(int OptionName,int NewValue)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_setoption(OptionName, NewValue)
+ 	int OptionName, NewValue;
+ #endif /* ARGS_DECL_USED */
+ {
+        switch (OptionName)
+        case SM_INTERVAL : {
+                           PCM_TSM = NewValue;
+ 			  break;
+ 	                  };
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_terminate(void)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_terminate()
+ #endif /* ARGS_DECL_USED */
+ {
+        	fclose(PCM_logfp);
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ int PCM_joinGroup(char *group, int port)
+ #else /* ~ARGS_DECL_USED */
+ int PCM_joinGroup(group, port)
+ 	char *group;
+ 	int port;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	u_char loop;
+ 	int s;
+ 	u_char TimeToLive;
+ 	struct sockaddr_in groupHost,groupStruct;
+ 	struct ip_mreq mreq;
+ 
+ 	TimeToLive = DEFAULT_MULTICAST_TTL_VALUE;
+ 
+ 	groupHost.sin_family = AF_INET;
+ 	groupHost.sin_port = htons(port);
+ 	groupHost.sin_addr.s_addr = htonl(INADDR_ANY);
+ 
+ 	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
+ 	{
+ 		printf("Impossivel criar socket\n");
+ 		exit(1);
+ 	}
+ 
+ 	PCM_reusePort(s);
+ 	if ((bind(s,(struct sockaddr *)&groupHost, sizeof(groupHost)) == -1))
+ 	{
+ 		printf("Erro no bind\n");
+ 		exit(1);
+ 	}
+ 
+ 	PCM_setTTLvalue(s, &TimeToLive);
+ 	loop = 1;
+ 	PCM_setLoopback(s,loop);
+ 
+ 	if ((groupStruct.sin_addr.s_addr = inet_addr(group)) == -1)
+ 		printf("Erro no inet_addr\n");
+ 
+ 	mreq.imr_multiaddr = groupStruct.sin_addr;
+ 	mreq.imr_interface.s_addr = INADDR_ANY;
+ 
+ 	if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq,
+ 		sizeof(mreq)) == -1)
+ 	{
+ 		printf("Erro no join do grupo\n");
+ 		exit(1);
+ 	}
+ 
+ 	PCM_socket = s;
+ 	strcpy(PCM_group,group);
+ 	PCM_port = port;
+ 
+ 	PCM_sockaddr.sin_family = AF_INET;
+ 	PCM_sockaddr.sin_port = PCM_port;
+ 	PCM_sockaddr.sin_addr.s_addr = inet_addr(PCM_group);
+ 
+ 	return s;
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_leaveGroup(int sock, char *group)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_leaveGroup(sock, group)
+ 	int sock;
+ 	char *group;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	struct sockaddr_in groupStruct;
+ 	struct ip_mreq dreq;
+ 
+ 	if ((groupStruct.sin_addr.s_addr = inet_addr(group)) == -1)
+ 		printf("Erro no inet_addr\n");
+ 
+ 	dreq.imr_multiaddr = groupStruct.sin_addr;
+ 	dreq.imr_interface.s_addr = INADDR_ANY;
+ 
+ 	if (setsockopt(sock,IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&dreq,
+ 		sizeof(dreq)) == -1)
+ 	{
+ 		printf("Erro na saida do grupo\n");
+ 		exit(1);
+ 	}
+ 
+ 	close(sock);
+ 	printf("Numero total de retransmissoes: %d\n",PCM_Nretrans);
+ 	printf("Processo saindo do grupo multicast %s\n",group);
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_reusePort(int s)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_reusePort(s)
+ 	int s;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	int one = 1;
+ 
+ 	if (setsockopt(s,SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) == -1)
+ 	{
+ 		printf("Erro em setsockopt, SO_REUSEPORT\n");
+ 		exit(1);
+ 	}
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_setTTLvalue(int s, u_char *i)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_setTTLvalue(s, i)
+ 	int s;
+ 	u_char *i;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	if (setsockopt(s,IPPROTO_IP, IP_MULTICAST_TTL, (char *)i,
+ 		sizeof(u_char)) == -1)
+ 	{
+ 		printf("Erro setando valor de TTL\n");
+ 	}
+ 	
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_setLoopback(int s, u_char loop)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_setLoopback(s, loop)
+ 	int s;
+ 	u_char loop;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	if (setsockopt(s,IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loop,
+ 		sizeof(u_char)) == -1)
+ 	{
+ 		printf("Erro setando valor de loopback\n");
+ 	}
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_timer_run(int sec, void (*func)())
+ #else /* ~ARGS_DECL_USED */
+ void PCM_timer_run(sec, func)
+ 	int sec;
+ 	void (*func)();
+ #endif /* ARGS_DECL_USED */
+ {
+ 	struct sigaction act;
+ 	struct itimerval value;
+ 	
+ 	PCM_func = func;
+ 	PCM_old_tcount = PCM_tcount;
+ 	PCM_Tfunc = sec;
+ 	
+ 	value.it_interval.tv_sec = sec;
+ 	value.it_interval.tv_usec = 0;
+ 	value.it_value.tv_sec = sec;
+ 	value.it_value.tv_usec = 0;
+ 	
+ 	act.sa_handler = PCM_func;
+ 	sigaction(SIGALRM, &act, NULL);
+ 	setitimer(ITIMER_REAL,&value,NULL);
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_event(void)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_event()
+ #endif /* ARGS_DECL_USED */
+ {
+ 	PCM_tcount++;
+ 	
+ 	if ((PCM_tcount - PCM_old_tcount)==PCM_Tfunc)
+ 	{
+ 		(*PCM_func)();
+ 		PCM_old_tcount = PCM_tcount;
+ 	}
+ 	if ((PCM_tcount % PCM_TSM)==0) PCM_send_SM();
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_log_packet(struct PCM_pack_struct *Pack, enum PCM_pack_type ptype)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_log_packet(Pack, ptype)
+ 	struct PCM_pack_struct *Pack;
+ 	enum PCM_pack_type ptype;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	/*
+ 	struct PCM_log_struct log;
+ 		
+ 	// Armazena informacoes sobre o pacote recebido em arquivo
+ 	log.IP = Pack->IP_origem;
+ 	log.PID = Pack->PID_origem;
+ 	log.Nseq = Pack->Nseq;
+ 	log.time = time(NULL);
+ 	log.ptype = ptype;
+ 	
+ 	if (fwrite(&log, sizeof(struct PCM_log_struct),1,PCM_logfp) != 1)
+ 	{
+ 		printf("Erro na escrita em arquivo de log\n");
+ 	}
+ 	*/
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ int PCM_cache(struct PCM_pack_struct *Pack)
+ #else /* ~ARGS_DECL_USED */
+ int PCM_cache(Pack)
+ 	struct PCM_pack_struct *Pack;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	int i,encontrou;
+ 	
+ 	i = 0;
+ 	encontrou = 0;
+ 	
+ 	/* Armazena pacote recebido no historico de pacotes */
+ 	while ((i<HIST_SIZE) && (!encontrou))
+ 	{
+ 		if ((PCM_hist[i].IP_origem == Pack->IP_origem) &&
+ 		    (PCM_hist[i].PID_origem == Pack->PID_origem) &&
+ 		    (PCM_hist[i].Nseq == Pack->Nseq)) encontrou = 1;
+ 		else i++;    
+ 	}
+ 	
+ 	if (!encontrou)
+ 	{
+ 		i = PCM_pos_hist;
+ 		PCM_pos_hist = (int)((PCM_pos_hist+1) % HIST_SIZE);
+ 		PCM_hist[i].IP_origem = Pack->IP_origem;
+ 		PCM_hist[i].PID_origem = Pack->PID_origem;
+ 		PCM_hist[i].Nseq = Pack->Nseq;
+ 		memcpy(PCM_hist[i].Data,Pack->Data,DATASIZE);
+ 		return 1;
+ 	}
+ 	else return -1;
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ int PCM_sendto(int Socket, char *Buffer, int Bufsize, int flag,
+ 		struct sockaddr *Dest, int Size)
+ #else /* ~ARGS_DECL_USED */
+ int PCM_sendto(Socket, Buffer, Bufsize, flag, Dest, Size)
+ 	int Socket;
+ 	char *Buffer;
+ 	int Bufsize;
+ 	int flag;
+ 	struct sockaddr *Dest;
+ 	int Size;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	int val,size;
+ 	struct PCM_pack_struct Pack;
+ 	char SendBuffer[PACKSIZE];
+ 
+ 
+ 	if (!PCM_good_toss(PCM_conf_send))
+ 	  {
+ 	    return -1;
+ 	  }
+ 
+ 	memset(SendBuffer,'\0',PACKSIZE);	
+ 	Pack.IP_origem = PCM_myIP;
+ 	Pack.PID_origem = PCM_myPID;
+ 	Pack.Nseq = PCM_Nseq;
+ 	memcpy(Pack.Data, Buffer, Bufsize);	
+ 	size = PCM_copy_pack_buffer(&Pack,SendBuffer);
+ 	
+ 	val = sendto(Socket, SendBuffer, size, flag, Dest, Size);
+ 	val = PCM_cache(&Pack);
+ 	PCM_update_SM(&Pack);
+ 	PCM_log_packet(&Pack,TRANSMIT);
+ 	PCM_Nseq++;
+ 	return val;
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ int PCM_recv(int Socket, char *Buffer, int Bufsize, int flag)
+ #else /* ~ARGS_DECL_USED */
+ int PCM_recv(Socket, Buffer, Bufsize, flag)
+ 	int Socket;
+ 	char *Buffer;
+ 	int Bufsize;
+ 	int flag;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	int val,size;
+ 	struct PCM_pack_struct Pack;
+ 	char ReceiveBuffer[PACKSIZE];
+ 	struct PCM_header_struct header;
+ 	
+ 	val = recv(Socket, ReceiveBuffer, PACKSIZE, flag);
+ 
+ 	memcpy(&header,ReceiveBuffer,sizeof(header));
+ 
+        	if ((header.IP == PCM_myIP)&&(header.PID == PCM_myPID)) return -1;
+ 
+ 	if (!PCM_good_toss(PCM_conf_recv))
+ 	  {
+ 	    if (header.pnature == DATAPACK) printf("Perdi pacote...\n");
+ 	    else printf("Perdi SM...\n");
+ 	    return -1;
+ 	  }
+ 
+ 	if (header.pnature == DATAPACK)
+ 	{
+ 		size = PCM_copy_buffer_pack(&Pack,ReceiveBuffer);
+ 		memcpy(Buffer, Pack.Data, Bufsize);
+ 		val = PCM_cache(&Pack);
+ 		PCM_update_SM(&Pack);
+ 		PCM_log_packet(&Pack,RECEIVE);
+ 	}
+ 	else if (header.pnature == SMPACK)
+ 	{
+ 	        printf("Recebendo SM...\n");
+ 		PCM_get_SM(ReceiveBuffer);
+ 		val = -1;
+ 	}
+ 	return val;
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_update_SM(struct PCM_pack_struct *Pack)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_update_SM(Pack)
+ 	struct PCM_pack_struct *Pack;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	int encontrou,i,j,k;
+ 	
+ 	encontrou = 0;
+ 	i = 0;
+ 	
+ 	while((!encontrou) && (i<SM_TABLE_SIZE))
+ 	{
+ 		if ((PCM_SM[i].IP == Pack->IP_origem) 
+ 			&& (PCM_SM[i].PID == Pack->PID_origem)) encontrou=1;
+ 		else if ((PCM_SM[i].IP == 0) && (PCM_SM[i].PID == 0))
+ 		{
+ 			PCM_SM[i].First = Pack->Nseq;
+ 			PCM_SM[i].Last = Pack->Nseq;
+ 			encontrou=1;
+ 		}
+ 		else i++;
+ 	}
+ 	
+ 	/*
+          * Nao ha espaco na SM (mais de SM_TABLE_SIZE membros no grupo
+          *	multicast)
+          */
+ 	if (!encontrou) exit(1);
+ 	
+ 	PCM_SM[i].IP = Pack->IP_origem;
+ 	PCM_SM[i].PID = Pack->PID_origem;
+ 	
+ 	if ((Pack->Nseq - PCM_SM[i].Last)==1) PCM_SM[i].Last = Pack->Nseq;
+ 	
+ 	else if ((Pack->Nseq - PCM_SM[i].Last)>1)
+ 	{
+ 		k = 0;
+ 		for (j=PCM_SM[i].Last+1;j<Pack->Nseq;j++)
+ 		{
+ 			while ((PCM_SM[i].Lost[k]!=-1)&&(k<MAX_LOST)) k++;
+ 			PCM_SM[i].Lost[k]=j;
+ 			PCM_SM[i].Num_lost++;
+ 		}
+ 		PCM_SM[i].Last = Pack->Nseq;
+ 	}
+ 	
+ 	else if (Pack->Nseq < PCM_SM[i].Last)
+ 	{
+ 		encontrou = 0;
+ 		for (j=0;(j<MAX_LOST) && (!encontrou);j++)
+ 			if (PCM_SM[i].Lost[j] == Pack->Nseq)
+ 			{
+ 				PCM_SM[i].Lost[j]=-1;
+ 				PCM_SM[i].Num_lost--;
+ 				encontrou=1;
+ 			}
+ 	}
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_initialize_SM(struct PCM_session_message *SM)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_initialize_SM(SM)
+ 	struct PCM_session_message *SM;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	int i,j;
+ 	
+ 	for (i=0;i<SM_TABLE_SIZE;i++)
+ 	{
+ 		SM[i].IP = 0;
+ 		SM[i].PID = 0;
+ 		SM[i].First = -1;
+ 		SM[i].Last = -1;
+ 		SM[i].Num_lost = 0;
+ 		for (j=0;j<MAX_LOST;j++) SM[i].Lost[j]=-1;
+ 	}	
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_send_SM(void)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_send_SM()
+ #endif /* ARGS_DECL_USED */
+ {
+         int size;
+ 	char SendBuffer[SMSIZE];
+ 
+ 	memset(SendBuffer,'\0',SMSIZE);
+ 	size = PCM_copy_SM_buffer(PCM_SM,SendBuffer);
+ 	
+ 	sendto(PCM_socket,SendBuffer,size,0,
+ 		(struct sockaddr *)&PCM_sockaddr,sizeof(PCM_sockaddr));
+ }		
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_get_SM(char *Buffer)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_get_SM(Buffer)
+ 	char *Buffer;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	struct PCM_session_message SM_AUX[SM_TABLE_SIZE];
+ 	int encontrou,i,j,k,Lost;
+ 	int size;
+ 	
+ 	j=0;
+ 	PCM_initialize_SM(SM_AUX);
+ 	size = PCM_copy_buffer_SM(SM_AUX,Buffer);
+ 
+ 	while (PCM_SM[j].IP != 0)
+ 	{
+ 		i=0;
+ 		encontrou=0;
+ 		while((i<SM_TABLE_SIZE) && (!encontrou))
+ 		{
+ 			if ((PCM_SM[j].IP == SM_AUX[i].IP)
+ 				&& (PCM_SM[j].PID == SM_AUX[i].PID)) encontrou=1;
+ 			else i++;	
+ 		}
+ 		
+ 		if (encontrou)
+ 		{
+ 			for (k=0;k<MAX_LOST;k++)
+ 			{
+ 				Lost = SM_AUX[i].Lost[k];
+ 				if ((Lost != -1) && (PCM_SM[j].Last >= Lost))
+ 				{
+ 					PCM_retrans(SM_AUX[i].IP,SM_AUX[i].PID,Lost);
+ 				}
+ 			}
+ 		
+ 			if (PCM_SM[j].Last > SM_AUX[i].Last)
+ 			{
+ 				for (k=SM_AUX[i].Last+1;k<=PCM_SM[j].Last;k++)
+ 				  {
+ 					PCM_retrans(SM_AUX[i].IP,SM_AUX[i].PID,k);
+ 				  }
+ 			}
+ 		}
+ 		
+ 		j++;
+ 	}
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_retrans(int IP, int PID, int Nseq)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_retrans(IP, PID, Nseq)
+ 	int IP, PID, Nseq;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	int encontrou,i,size;
+ 	char SendBuffer[PACKSIZE];
+ 	struct PCM_pack_struct Pack;
+ 	
+ 	if (!PCM_good_toss(PCM_conf_send))
+ 	  {
+ 	    return;
+ 	  }
+ 
+ 	encontrou = 0;
+ 	i = 0;
+ 	
+ 	printf ("Pedido de retrans para %d %d %d\n",IP,PID,Nseq);
+ 	while ((!encontrou) && (i<HIST_SIZE))
+ 	{
+ 		if ((PCM_hist[i].IP_origem == IP) && (PCM_hist[i].PID_origem == PID)
+ 			&& (PCM_hist[i].Nseq == Nseq)) encontrou=1;
+ 		else i++;	
+ 	}
+ 	
+ 	if (!encontrou)
+ 	  {
+ 	    printf("Nao possuo mais dado pedido no CACHE!\n");
+ 	    return;
+ 	  }
+ 	  
+ 	PCM_Nretrans++;
+ 	
+ 	memset(SendBuffer,'\0',PACKSIZE);
+ 	Pack.IP_origem = IP;
+ 	Pack.PID_origem = PID;
+ 	Pack.Nseq = Nseq;
+ 	memcpy(Pack.Data, PCM_hist[i].Data, DATASIZE);
+ 	size = PCM_copy_pack_buffer(&Pack,SendBuffer);
+ 	
+ 	printf("Retransmitindo pacote...\n");
+ 	sendto(PCM_socket,SendBuffer,size,0,
+ 		(struct sockaddr *)&PCM_sockaddr,sizeof(PCM_sockaddr));
+ 	PCM_log_packet(&Pack,RETRANSMIT);
+ 
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ void PCM_initialize_hist(void)
+ #else /* ~ARGS_DECL_USED */
+ void PCM_initialize_hist()
+ #endif /* ARGS_DECL_USED */
+ {
+ 	int i;
+ 	for (i=0;i<HIST_SIZE;i++)
+ 	{
+ 		PCM_hist[i].IP_origem = 0;
+ 		PCM_hist[i].PID_origem = 0;
+ 		PCM_hist[i].Nseq = 0;
+ 	}
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ int PCM_good_toss(float ratio)
+ #else /* ~ARGS_DECL_USED */
+ int PCM_good_toss(ratio)
+ 	float ratio;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	float valor;
+ 	srand(time(NULL));
+ 	valor = (float)rand()/RAND_MAX;
+ 	
+ 	if (valor <= ratio) return 1;
+ 	else return 0;
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ int PCM_copy_SM_buffer(struct PCM_session_message *SM, char *buffer)
+ #else /* ~ARGS_DECL_USED */
+ int PCM_copy_SM_buffer(SM, buffer)
+ 	struct PCM_session_message *SM;
+ 	char *buffer;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	int PosBuffer;
+ 	int i,j;
+ 	struct PCM_header_struct header;
+ 	
+ 	PosBuffer = 0;
+ 	i = 0;
+ 	while (SM[i].IP != 0) i++;	
+ 	header.pnature = SMPACK;
+ 	header.Num_blocs = i;
+ 	header.IP = PCM_myIP;
+ 	header.PID = PCM_myPID;
+ 	header.timer = time(NULL);
+ 	
+ 	memcpy(buffer,&header,sizeof(header));
+ 	PosBuffer = PosBuffer + sizeof(header);
+ 		
+ 	for (i=0;i<header.Num_blocs;i++)
+ 	{
+ 		memcpy(&buffer[PosBuffer],&SM[i],sizeof(int)*5);
+ 		PosBuffer = PosBuffer + sizeof(int)*5;
+ 		
+ 		for (j=0;j<MAX_LOST;j++)
+ 		{
+ 			if (SM[i].Lost[j] != -1)
+ 			{
+ 				memcpy(&buffer[PosBuffer],&SM[i].Lost[j],sizeof(int));
+ 				PosBuffer = PosBuffer + sizeof(int);
+ 			}
+ 		}
+ 	}
+ 	
+ 	return PosBuffer;
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ int PCM_copy_buffer_SM(struct PCM_session_message *SM, char *buffer)
+ #else /* ~ARGS_DECL_USED */
+ int PCM_copy_buffer_SM(SM, buffer)
+ 	struct PCM_session_message *SM;
+ 	char *buffer;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	int PosBuffer;
+ 	int i,j;
+ 	struct PCM_header_struct header;
+ 	
+ 	PosBuffer = 0;
+ 	memcpy(&header,buffer,sizeof(header));
+ 	PosBuffer = PosBuffer + sizeof(header);
+ 	
+ 	for (i=0;i<header.Num_blocs;i++)
+ 	{
+ 		memcpy(&SM[i],&buffer[PosBuffer],sizeof(int)*5);
+ 		PosBuffer = PosBuffer + sizeof(int)*5;	
+ 
+ 		for (j=0;j<SM[i].Num_lost;j++)
+ 		{
+ 			memcpy(&SM[i].Lost[j],&buffer[PosBuffer],sizeof(int));
+ 			PosBuffer = PosBuffer + sizeof(int);
+ 		}
+ 	}
+ 		
+ 	return PosBuffer;
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ int PCM_copy_pack_buffer(struct PCM_pack_struct *Pack, char *buffer)
+ #else /* ~ARGS_DECL_USED */
+ int PCM_copy_pack_buffer(Pack, buffer)
+ 	struct PCM_pack_struct *Pack;
+ 	char *buffer;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	int PosBuffer;
+ 	struct PCM_header_struct header;
+ 	
+ 	PosBuffer = 0;
+ 	header.pnature = DATAPACK;
+ 	header.Num_blocs = 1;
+ 	header.IP = PCM_myIP;
+ 	header.PID = PCM_myPID;
+ 	header.timer = time(NULL);
+ 	
+ 	memcpy(buffer,&header,sizeof(header));
+ 	PosBuffer = PosBuffer + sizeof(header);
+ 		
+ 	memcpy(&buffer[PosBuffer],Pack,sizeof(int)*3);
+ 	PosBuffer = PosBuffer + sizeof(int)*3;
+ 	
+ 	memcpy(&buffer[PosBuffer],Pack->Data,DATASIZE);
+ 	PosBuffer = PosBuffer + DATASIZE;
+ 	
+ 	return PosBuffer;
+ }
+ 
+ #ifdef ARGS_DECL_USED
+ int PCM_copy_buffer_pack(struct PCM_pack_struct *Pack, char *buffer)
+ #else /* ~ARGS_DECL_USED */
+ int PCM_copy_buffer_pack(Pack, buffer)
+ 	struct PCM_pack_struct *Pack;
+ 	char *buffer;
+ #endif /* ARGS_DECL_USED */
+ {
+ 	int PosBuffer;
+ 	struct PCM_header_struct header;
+ 	
+ 	PosBuffer = 0;
+ 	
+ 	memcpy(&header,buffer,sizeof(header));
+ 	PosBuffer = PosBuffer + sizeof(header);
+ 		
+ 	memcpy(Pack,&buffer[PosBuffer],sizeof(int)*3);
+ 	PosBuffer = PosBuffer + sizeof(int)*3;
+ 	
+ 	memcpy(Pack->Data,&buffer[PosBuffer],DATASIZE);
+ 	PosBuffer = PosBuffer + DATASIZE;
+ 	
+ 	return PosBuffer;
+ }
+ 
+ #endif /* _TGIF_WB2 */
*** xprtfltr.c.orig	Sun Apr 11 10:47:33 1999
--- xprtfltr.c	Sun Apr 11 10:47:33 1999
***************
*** 34,44 ****
  #define _INCLUDE_FROM_XPRTFLTR_C_
  
- #ifndef _NO_DL_SUPPORT
- #include <dlfcn.h>
- #ifndef RTLD_GLOBAL
- #define RTLD_GLOBAL 0
- #endif /* ~RTLD_GLOBAL */
- #endif /* ~_NO_DL_SUPPORT */
- 
  #include "tgifdefs.h"
  #include "expfdefs.h"
--- 34,37 ----
*** arc.e.orig	Sun Apr 11 10:47:35 1999
--- arc.e	Sun Apr 11 10:47:35 1999
***************
*** 67,71 ****
  			                         int x2, int y2, int dir,
  			                         int ltx, int lty, int w, int h,
! 			                         int angle1, int angle2));
  extern void	DrawArc ARGS_DECL((XEvent *));
  extern void	SaveArcObj ARGS_DECL((FILE *, struct ObjRec *));
--- 67,72 ----
  			                         int x2, int y2, int dir,
  			                         int ltx, int lty, int w, int h,
! 			                         int angle1, int angle2,
! 			                         int CreateAbsolute));
  extern void	DrawArc ARGS_DECL((XEvent *));
  extern void	SaveArcObj ARGS_DECL((FILE *, struct ObjRec *));
*** convxim.e.orig	Sun Apr 11 10:47:36 1999
--- convxim.e	Sun Apr 11 10:47:36 1999
***************
*** 48,56 ****
  
  extern void	XIMSetICFocus ARGS_DECL((Display*, Window));
! extern void	XIMNextEvent ARGS_DECL((Display *, Window, XEvent *));
! extern int	XIMLookupString ARGS_DECL((XKeyEvent *, char *, int, KeySym *,
! 		                           XIMStatus *));
  extern void	XIMUnsetICFocus ARGS_DECL((void));
  extern void	XIMClose ARGS_DECL((void));
  
  #ifdef _INCLUDE_FROM_CONVXIM_C_
--- 48,58 ----
  
  extern void	XIMSetICFocus ARGS_DECL((Display*, Window));
! extern void	XIMNextEvent ARGS_DECL((Display*, Window, XEvent*));
! extern int	XIMLookupString ARGS_DECL((XKeyEvent*, char*, int, KeySym*,
! 		                           XIMStatus*));
  extern void	XIMUnsetICFocus ARGS_DECL((void));
  extern void	XIMClose ARGS_DECL((void));
+ extern void	XIMSetConvOverSpot ARGS_DECL((Bool));
+ extern void	XIMTellCursorPosition ARGS_DECL((Display*, Window, int, int));
  
  #ifdef _INCLUDE_FROM_CONVXIM_C_
*** cutpaste.e.orig	Sun Apr 11 10:47:37 1999
--- cutpaste.e	Sun Apr 11 10:47:37 1999
***************
*** 43,46 ****
--- 43,47 ----
  #endif /*_INCLUDE_FROM_CUTPASTE_C_*/
  
+ extern int	WriteBufToCutBuffer ARGS_DECL((char *buf, int buf_sz));
  extern int	CopyToCutBuffer ARGS_DECL((void));
  extern int	CopyPlainTextAsObject ARGS_DECL((void));
***************
*** 80,83 ****
--- 81,87 ----
  extern int	EditIniSection ARGS_DECL((char *pszTitle, char *pszSection,
  		                          char *pszIniFile, AfterLoopFunc*));
+ extern char	*SelectFromIniSection ARGS_DECL((char *pszTitle,
+ 		                                 char *pszSection,
+ 		                                 char *pszIniFile));
  
  #ifdef _INCLUDE_FROM_CUTPASTE_C_
*** dialog.e.orig	Sun Apr 11 10:47:37 1999
--- dialog.e	Sun Apr 11 10:47:37 1999
***************
*** 49,57 ****
  			                          int SnapToGrid));
  extern unsigned int	PickAPoint ARGS_DECL((int *OrigX, int *OrigY, Cursor));
- extern int		MsgBox ARGS_DECL((char *Message, char *Title,
- 			                  int IconAndBtns));
- extern int		Dialog ARGS_DECL((char *Message, char *Comment,
- 			                  char *ReturnStr));
  
  #ifdef _INCLUDE_FROM_DIALOG_C_
  #undef extern
--- 49,62 ----
  			                          int SnapToGrid));
  extern unsigned int	PickAPoint ARGS_DECL((int *OrigX, int *OrigY, Cursor));
  
+ extern void	CalcFormatStringInBox ARGS_DECL((char *buf, XFontStruct*,
+ 		                                 int format_box_w,
+ 		                                 int *pn_num_lines,
+ 		                                 int *pn_max_w, int *pn_max_h,
+ 		                                 char **ppsz_formated_buf));
+ extern int	MsgBox ARGS_DECL((char *Message, char *Title, int IconAndBtns));
+ extern int	Dialog ARGS_DECL((char *Message, char *Comment,
+ 		                  char *ReturnStr));
+ 
  #ifdef _INCLUDE_FROM_DIALOG_C_
  #undef extern
*** drawing.e.orig	Sun Apr 11 10:47:38 1999
--- drawing.e	Sun Apr 11 10:47:38 1999
***************
*** 51,54 ****
--- 51,55 ----
  extern int	userDisableRedraw;
  extern int	executingCommands;
+ extern int	gnDisableShortcuts; /* used by ExecCmdsFromFile() */
  
  #ifdef _INCLUDE_FROM_DRAWING_C_
***************
*** 62,65 ****
--- 63,67 ----
  extern int	HideInterrupt ARGS_DECL((void));
  extern void	RedrawDummyWindow1 ARGS_DECL((void));
+ extern void	RedrawDummyWindow2 ARGS_DECL((void));
  extern void	DummiesEventHandler ARGS_DECL((XEvent *));
  extern int	ESCPressed ARGS_DECL((void));
*** exec.e.orig	Sun Apr 11 10:47:40 1999
--- exec.e	Sun Apr 11 10:47:40 1999
***************
*** 76,79 ****
--- 76,82 ----
  extern void	ExecCmdsFromFile ARGS_DECL((char*));
  extern void	StartExecCmdsFromFile ARGS_DECL((void));
+ extern int	BeginExecCommandsFromBuffer ARGS_DECL((void));
+ extern int	ExecACommandFromBuffer ARGS_DECL((char *buf, int *pn_quit));
+ extern void	EndExecCommandsFromBuffer ARGS_DECL((void));
  extern void	CleanUpExec ARGS_DECL((void));
  extern void	InitExec ARGS_DECL((void));
*** file.e.orig	Sun Apr 11 10:47:41 1999
--- file.e	Sun Apr 11 10:47:41 1999
***************
*** 138,141 ****
--- 138,142 ----
  extern void	SaveObj ARGS_DECL((FILE*, struct ObjRec *ObjPtr, int Level));
  extern int	FileNameHasExtension ARGS_DECL((char *file_name, int file_type,
+ 		                                int *pn_gzipped,
  		                                int *pn_no_name));
  extern void	RemoveFileNameExtension ARGS_DECL((char*));
***************
*** 170,174 ****
  extern int	SetFileBgPixmap ARGS_DECL((void));
  extern void	CheckFileAttrsInLoad ARGS_DECL((void));
! extern int	LoadFile ARGS_DECL((char *FileName, int ObjFile));
  extern void	DumpPatFill ARGS_DECL((FILE *, int Fill, int CellSize,
  		                       struct BBRec, int Indent, int EOL));
--- 171,176 ----
  extern int	SetFileBgPixmap ARGS_DECL((void));
  extern void	CheckFileAttrsInLoad ARGS_DECL((void));
! extern int	LoadFile ARGS_DECL((char *FileName, int ObjFile,
! 		                    int GzippedObjFile));
  extern void	DumpPatFill ARGS_DECL((FILE *, int Fill, int CellSize,
  		                       struct BBRec, int Indent, int EOL));
*** font.e.orig	Sun Apr 11 10:47:42 1999
--- font.e	Sun Apr 11 10:47:42 1999
***************
*** 66,69 ****
--- 66,71 ----
  extern int	menuFontDes;
  
+ extern XFontSet	menuFontSet;
+ 
  extern XFontStruct	* boldMsgFontPtr;
  extern int	boldMsgFontWidth;
***************
*** 122,125 ****
--- 124,128 ----
  		                         char *pszCur));
  extern char	* GetShowFontChar ARGS_DECL((int FontIndex));
+ extern char	* GetCurFontInfoStr ARGS_DECL((char *retstr));
  extern void	GetPSFontStr ARGS_DECL((int FontIndex, int Style, char *));
  extern void	SetTextExtentsInfo ARGS_DECL((TextExtentsInfo*));
***************
*** 139,142 ****
--- 142,147 ----
  extern int	GetFontIndex ARGS_DECL((char *FontStr, int Style,
  		                        int MustFind));
+ extern int	GetFontAndStyle ARGS_DECL((char *FontStr, int *pnFont,
+ 		                           int *pnStyle, int MustFind));
  extern void	PrTgifInitBaseFonts ARGS_DECL((void));
  extern int	GetCurSzUnit ARGS_DECL((void));
***************
*** 186,189 ****
--- 191,195 ----
  extern int	ChangeObjVSpace ARGS_DECL((struct ObjRec *, int VSpace));
  extern void	ChangeVSpace ARGS_DECL((int VSpace));
+ extern void	ChangeAllSelRealSzUnit ARGS_DECL((int sz_unit, int HighLight));
  extern void	SetSelFontSize ARGS_DECL((char*));
  extern void	CleanUpFonts ARGS_DECL((void));
*** mainloop.e.orig	Sun Apr 11 10:47:43 1999
--- mainloop.e	Sun Apr 11 10:47:43 1999
***************
*** 64,67 ****
--- 64,70 ----
  		                           void (*CleanUpRoutine)(),
  		                           void *userdata));
+ extern void	SaveAndSetLocale ARGS_DECL((char *new_locale,
+ 		                            char *prev_locale));
+ extern void	RestoreLocale ARGS_DECL((char *prev_locale));
  extern void	DeallocStrings ARGS_DECL((char **Func,
  		                char **Str1, char **Menu1,
***************
*** 70,73 ****
--- 73,78 ----
  extern void	CleanUp ARGS_DECL((void));
  extern void	ExposeEventHandler ARGS_DECL((XEvent *, int Recursive));
+ extern int	GzipFile ARGS_DECL((char *fname, char *gzipped_fname));
+ extern char	*GunzipFileIntoTemp ARGS_DECL((char *gzipped_fname));
  extern int	JustInit ARGS_DECL((char *pszFile, int *pnNeedToCheckAutoExec));
  extern int	TryProcessAnXEvent ARGS_DECL((int *pnNeedToCheckAutoExec));
*** pattern.e.orig	Sun Apr 11 10:47:44 1999
--- pattern.e	Sun Apr 11 10:47:44 1999
***************
*** 84,87 ****
--- 84,88 ----
  
  extern void	ChangeAllSelLineWidth ARGS_DECL((int Index, int HighLight));
+ extern int	GetBestLineWidthIndex ARGS_DECL((int width, int aw, int ah));
  extern void	RefreshLineWidthMenu ARGS_DECL((TgMenu*));
  extern TgMenu	*CreateLineWidthMenu ARGS_DECL((TgMenu*, int X, int Y,
*** poly.e.orig	Sun Apr 11 10:47:45 1999
--- poly.e	Sun Apr 11 10:47:45 1999
***************
*** 55,58 ****
--- 55,61 ----
  extern int	drawPolyToConnectPins;
  
+ extern int	numPtsInPoly;
+ 
+ extern struct PtRec	*lastPtPtr;
  extern struct ObjRec	* drawPolyHighlightedNode;
  
*** raster.e.orig	Sun Apr 11 10:47:46 1999
--- raster.e	Sun Apr 11 10:47:46 1999
***************
*** 83,86 ****
--- 83,87 ----
  extern Pixmap	shortDashPixmap[];
  
+ extern Pixmap	runBitmap;
  extern Pixmap	checkBitmap;
  extern Pixmap	radioBitmap;
*** rcbox.e.orig	Sun Apr 11 10:47:47 1999
--- rcbox.e	Sun Apr 11 10:47:47 1999
***************
*** 48,51 ****
--- 48,53 ----
  extern void	DumpRCBoxObj ARGS_DECL((FILE *, struct ObjRec *));
  extern int	NeedsToCacheRCBoxObj ARGS_DECL((struct ObjRec *));
+ extern void	CreateRCBoxObj ARGS_DECL((int X1, int Y1, int X2, int Y2,
+ 		                          int CreateAbsolute));
  extern void	DrawRCBoxObj ARGS_DECL((Window, int XOff, int YOff,
  		                        struct ObjRec *));
*** remote.e.orig	Sun Apr 11 10:47:48 1999
--- remote.e	Sun Apr 11 10:47:48 1999
***************
*** 39,42 ****
--- 39,44 ----
  extern char	*fnameForPostingCGIQuery;
  extern char	gszLocalPID[];
+ extern char	gzipCmd[];
+ extern char	gunzipCmd[];
  
  #ifdef _INCLUDE_FROM_REMOTE_C_
*** text.e.orig	Sun Apr 11 10:47:48 1999
--- text.e	Sun Apr 11 10:47:49 1999
***************
*** 86,90 ****
  extern void	UpdateTextInfoChoices ARGS_DECL((int forced));
  extern int	RestoreEditTextSize ARGS_DECL((struct ObjRec *, int restore));
! extern int	CreateTextObj ARGS_DECL((int nDeactivateIM));
  extern int	AtBeginningOfInheritedAttrValue ARGS_DECL((struct ObjRec *,
  		                                           StrBlockInfo*, int));
--- 86,90 ----
  extern void	UpdateTextInfoChoices ARGS_DECL((int forced));
  extern int	RestoreEditTextSize ARGS_DECL((struct ObjRec *, int restore));
! extern int	CreateTextObj ARGS_DECL((int nDeactivateIM, int nRedraw));
  extern int	AtBeginningOfInheritedAttrValue ARGS_DECL((struct ObjRec *,
  		                                           StrBlockInfo*, int));
*** wb.e.orig	Sun Apr 11 10:47:50 1999
--- wb.e	Sun Apr 11 10:47:50 1999
***************
*** 35,38 ****
--- 35,40 ----
  #define _WB_E_
  
+ #define WB_PACK 51200
+ 
  typedef struct WhiteBoardRec {
     int	do_whiteboard;
***************
*** 51,58 ****
     int	listen_socket;
  
!    struct CmdRec *first_cmd, *last_cmd, *cur_cmd;
!    struct CmdRec *first_stopped_cmd; /* don't know how to use this yet! */
  } *WhiteBoardPtr;
  
  extern struct WhiteBoardRec	gstWBInfo;
  
--- 53,84 ----
     int	listen_socket;
  
!    int	MCastSock;
!    int	bd_commands;
!    int	CanProcessRemoteCmd;
! 
!    struct CmdRec	*first_cmd, *last_cmd, *cur_cmd;
!    /* don't know how to use first_stopped_cmd yet! */
!    struct CmdRec	*first_stopped_cmd;
  } *WhiteBoardPtr;
  
+ typedef struct Comand{
+    struct CmdRec	*cmd;
+    char	Id[MAXSTRING];
+    int	Nseq;
+    int	CmdInconsistent;
+ }*comandoPtr;
+ 
+ typedef struct ComandNode{
+    struct Comand	cmd_node;
+    struct ComandNode	*next, *prev;
+ }*comandnodePtr;
+ 
+ typedef struct WbMessage{
+    int	Size;
+    int	NSeq;
+    char	IDIP[MAXSTRING];
+    char	WbCmd[WB_PACK];
+ }wbmsgPtr;
+ 
  extern struct WhiteBoardRec	gstWBInfo;
  
***************
*** 73,76 ****
--- 99,106 ----
  #endif /* _TGIF_DBG_WB2 */
  
+ extern int	WBHasReadData ARGS_DECL((int *pn_flag, int *pn_retry));
+ extern int	RecvWBData ARGS_DECL((
+ 			int flag, /* *pn_flag of WBHasReadData() */
+ 			char **ppsz_buf, int *pn_buf_sz));
  extern int	SendWBData ARGS_DECL((char *pszWBData));
  
***************
*** 79,85 ****
  /* =================== Cmd Related Functions =================== */
  
! extern char	* SerializeCmd ARGS_DECL((int CmdType, struct SubCmdRec *,
!                                      struct SelRec *Top, struct SelRec *Bot,
!                                      int NumObjs));
  extern void	SerializeFreeBuf ARGS_DECL((char *psz_buf));
  
--- 109,115 ----
  /* =================== Cmd Related Functions =================== */
  
! extern char	*SerializeCmd ARGS_DECL((int CmdType, struct SubCmdRec *,
!                                          struct SelRec *Top, struct SelRec *Bot,
!                                          int NumObjs));
  extern void	SerializeFreeBuf ARGS_DECL((char *psz_buf));
  
*** wb_buff.e.orig	Sun Apr 11 10:47:50 1999
--- wb_buff.e	Sun Apr 11 10:47:50 1999
***************
*** 0 ****
--- 1,54 ----
+ /*
+  * Author:      Magnos Martinello, <magnos@land.ufrj.br> in April, 1999.
+  *
+  * @(#)$Header: /mm/src/tgif/v4/RCS/wb_buff.e,v 4.0 1999/04/09 16:09:22 william Exp $
+  */
+ 
+ #ifndef _WB_BUFF_E_
+ #define _WB_BUFF_E_
+ 
+ /* Comentario Principal */
+ 
+ #define MAXTABLE   100  /* Maximum number of active buffers */
+ #define DUPLICATED 4
+ #define SORTED     2
+ #define UNSORTED   1
+ 
+ #ifdef _INCLUDE_FROM_WB_BUFF_C_
+ #undef extern
+ #define extern
+ #endif /*_INCLUDE_FROM_WB_BUFF_C_*/
+ 
+ #ifdef _TGIF_WB2
+ 
+ extern int	buff_init ARGS_DECL((
+ 			int n, int size, int option,
+ 			int (*compar)(const void *, const void *)));
+ 
+ extern int	buff_ins ARGS_DECL((int bd, const void *buffer));
+ 
+ extern int	buff_rem ARGS_DECL((int bd, void *buffer));
+ 
+ extern int	buff_destroy ARGS_DECL((int bd));
+ 
+ extern int	buff_empty ARGS_DECL((int bd));
+ 
+ extern int	buff_emptyn ARGS_DECL((int bd, int n));
+ 
+ extern int	buff_items ARGS_DECL((int bd));
+ 
+ extern int	buff_conc ARGS_DECL((int bd1, int bd2));
+ 
+ extern int	buff_sort ARGS_DECL((
+ 			int bd, int (*compar)(const void *, const void *)));
+ 
+ #endif /* _TGIF_WB2 */
+ 
+ #ifdef _INCLUDE_FROM_WB_BUFF_C_
+ #undef extern
+ #ifndef _NO_RECURSIVE_EXTERN
+ #define extern extern
+ #endif /* ~_NO_RECURSIVE_EXTERN */
+ #endif /*_INCLUDE_FROM_WB_BUFF_C_*/
+ 
+ #endif /*_WB_BUFF_E_*/
*** wb_mcast.e.orig	Sun Apr 11 10:47:51 1999
--- wb_mcast.e	Sun Apr 11 10:47:51 1999
***************
*** 0 ****
--- 1,142 ----
+ /*
+  * Author:      Raphael S. de Moraes <raphael@land.ufrj.br> in April, 1999.
+  *
+  * @(#)$Header: /mm/src/tgif/v4/RCS/wb_mcast.e,v 4.2 1999/04/11 14:13:23 william Exp $
+  */
+ 
+ #ifndef _WB_MCAST_E_
+ #define _WB_MCAST_E_
+ 
+ #define DEFAULT_MULTICAST_TTL_VALUE	255
+ 
+ #ifndef INADDR_NONE
+ #define INADDR_NONE	0xffffffff
+ #endif
+ 
+ #define PACKSIZE	51496
+ #define DATASIZE	51464
+ #define SMSIZE		8420
+ #define HIST_SIZE	1000
+ #define SM_TABLE_SIZE	20
+ #define GROUP_NAME_SIZE	16
+ #define MAX_LOST	100
+ #define FILENAME        10
+ 
+ /* Options */
+ #define SM_INTERVAL     0
+ 
+ /* Para simular read nao confiavel */
+ #define CONF_RECV	0.85
+ #define CONF_SEND       0.85
+ 
+ enum PCM_pack_type {TRANSMIT, RECEIVE, RETRANSMIT, NOVALUE};
+ enum PCM_pack_nature {SMPACK, DATAPACK, NACK};
+ 
+ struct PCM_pack_struct
+ {
+ 	int IP_origem;
+ 	int PID_origem;
+ 	int Nseq;
+ 	char Data[DATASIZE];
+ };
+ 
+ struct PCM_session_message
+ {
+ 	int IP;
+ 	int PID;
+ 	int First;
+ 	int Last;
+ 	int Num_lost;
+ 	int Lost[MAX_LOST];
+ };
+ 
+ struct PCM_log_struct
+ {
+ 	int IP;
+ 	int PID;
+ 	int Nseq;
+ 	time_t time;
+ 	enum PCM_pack_type ptype;
+ };
+ 
+ struct PCM_header_struct
+ {
+ 	enum PCM_pack_nature pnature;
+ 	int Num_blocs;
+ 	int IP;
+ 	int PID;
+         time_t timer;
+ };
+ 
+ extern struct PCM_session_message	PCM_SM[SM_TABLE_SIZE];
+ extern struct PCM_pack_struct	PCM_hist[HIST_SIZE];
+ extern int	PCM_socket;
+ extern int	PCM_port;
+ extern char	PCM_group[GROUP_NAME_SIZE];
+ extern struct sockaddr_in	PCM_sockaddr;
+ 
+ extern FILE	*PCM_logfp;
+ extern int	PCM_myIP;
+ extern int	PCM_myPID;
+ extern int	PCM_Nseq;
+ extern int	PCM_pos_hist;
+ extern int	PCM_TSM,PCM_Tfunc;
+ extern int	PCM_tcount, PCM_old_tcount;
+ extern int	PCM_Nretrans;
+ extern float	PCM_conf_recv, PCM_conf_send;
+ 
+ extern void	(*PCM_func)();
+ 
+ #ifdef _INCLUDE_FROM_WB_MCAST_C_
+ #undef extern
+ #define extern
+ #endif /*_INCLUDE_FROM_WB_MCAST_C_*/
+ 
+ #ifdef _TGIF_WB2
+ 
+ extern int	PCM_joinGroup ARGS_DECL((char *group, int port));
+ extern void	PCM_leaveGroup ARGS_DECL((int sock, char *group));
+ extern void	PCM_reusePort ARGS_DECL((int s));
+ extern void	PCM_setTTLvalue ARGS_DECL((int s, u_char *i));
+ extern void	PCM_setLoopback ARGS_DECL((int s, u_char loop));
+ extern int	PCM_sendto ARGS_DECL((
+ 			int Socket, char *Buffer, int Bufsize, int flag,
+ 			struct sockaddr *Dest, int Size));
+ extern int	PCM_recv ARGS_DECL((
+ 			int Socket, char *Buffer, int Bufsize, int flag));		
+ extern void	PCM_timer_run ARGS_DECL((int sec, void (*func)()));
+ extern void	PCM_event ARGS_DECL((void));
+ extern void	PCM_log_packet ARGS_DECL((
+ 			struct PCM_pack_struct *Pack,
+ 			enum PCM_pack_type ptype));
+ extern int	PCM_cache ARGS_DECL((struct PCM_pack_struct *Pack));
+ extern int	PCM_good_toss ARGS_DECL((float ratio));
+ 
+ extern void	PCM_initialize ARGS_DECL((char *logfile));
+ extern void	PCM_setoption ARGS_DECL((int OptionName,int NewValue));
+ extern void	PCM_terminate ARGS_DECL((void));
+ extern void	PCM_update_SM ARGS_DECL((struct PCM_pack_struct *Pack));
+ extern void	PCM_initialize_SM ARGS_DECL((struct PCM_session_message *SM));
+ extern void	PCM_send_SM ARGS_DECL((void));
+ extern void	PCM_get_SM ARGS_DECL((char *Buffer));
+ extern void	PCM_retrans ARGS_DECL((int IP, int PID, int Nseq));
+ extern void	PCM_initialize_hist ARGS_DECL((void));
+ extern int	PCM_copy_SM_buffer ARGS_DECL((
+ 			struct PCM_session_message *SM, char *buffer));
+ extern int	PCM_copy_buffer_SM ARGS_DECL((
+ 			struct PCM_session_message *SM, char *buffer));
+ extern int	PCM_copy_pack_buffer ARGS_DECL((
+ 			struct PCM_pack_struct *Pack, char *buffer));
+ extern int	PCM_copy_buffer_pack ARGS_DECL((
+ 			struct PCM_pack_struct *Pack, char *buffer));
+ 
+ #endif /* _TGIF_WB2 */
+ 
+ #ifdef _INCLUDE_FROM_WB_MCAST_C_
+ #undef extern
+ #ifndef _NO_RECURSIVE_EXTERN
+ #define extern extern
+ #endif /* ~_NO_RECURSIVE_EXTERN */
+ #endif /*_INCLUDE_FROM_WB_MCAST_C_*/
+ 
+ #endif /*_WB_MCAST_E*/
*** const.h.orig	Sun Apr 11 10:47:52 1999
--- const.h	Sun Apr 11 10:47:52 1999
***************
*** 40,52 ****
     /* just in case ANSI or C++ doesn't handle function prototypes well */
  #define ARGS_DECL(args) ()
! #else
  #define ARGS_DECL(args) args
! #endif
! #else
  #define ARGS_DECL(args) ()
! #endif
  
  #include "tgif_dbg.h"
  
  #define TOOL_NAME "Tgif"
  
--- 40,66 ----
     /* just in case ANSI or C++ doesn't handle function prototypes well */
  #define ARGS_DECL(args) ()
! #undef ARGS_DECL_USED
! #else /* ~_NO_PROTO */
  #define ARGS_DECL(args) args
! #undef ARGS_DECL_USED
! #define ARGS_DECL_USED 1
! #endif /* _NO_PROTO */
! #else /* ~(__STDC__ || defined(__cplusplus) || defined(c_plusplus)) */
  #define ARGS_DECL(args) ()
! #undef ARGS_DECL_USED
! #endif /* __STDC__ || defined(__cplusplus) || defined(c_plusplus) */
  
  #include "tgif_dbg.h"
  
+ #ifndef _NO_LOCALE_SUPPORT
+ #ifdef _ENABLE_NLS
+ #define _(text)  gettext(text)
+ #define N_(text) text
+ #else /* ~_ENABLE_NLS */
+ #define _(text)  text
+ #define N_(text) text
+ #endif /* _ENABLE_NLS */
+ #endif /* ~_NO_LOCALE_SUPPORT */
+ 
  #define TOOL_NAME "Tgif"
  
***************
*** 53,57 ****
  #ifndef NULL
  #define NULL 0
! #endif
  
  #ifndef TRUE
--- 67,71 ----
  #ifndef NULL
  #define NULL 0
! #endif /* ~NULL */
  
  #ifndef TRUE
***************
*** 58,62 ****
  #define FALSE 0
  #define TRUE 1
! #endif
  
  #define INVALID (-1)
--- 72,76 ----
  #define FALSE 0
  #define TRUE 1
! #endif /* ~TRUE */
  
  #define INVALID (-1)
***************
*** 70,74 ****
  #define DIR_SEP '/'
  #define DIR_SEP_STR "/"
! #endif
  
  #define SINGLECOLOR (FALSE)
--- 84,88 ----
  #define DIR_SEP '/'
  #define DIR_SEP_STR "/"
! #endif /* WIN32 */
  
  #define SINGLECOLOR (FALSE)
***************
*** 80,92 ****
  #define max(A,B) (((A)>(B)) ? (A) : (B))
  #define min(A,B) (((A)>(B)) ? (B) : (A))
! #endif
  
  #ifndef round
  #define round(X) (((X) >= 0) ? (int)((X)+0.5) : (int)((X)-0.5))
! #endif
  
  #ifndef M_PI
  #define M_PI 3.14159265358979323846
! #endif
  
  #define INT_TOL (1.0e-5)
--- 94,106 ----
  #define max(A,B) (((A)>(B)) ? (A) : (B))
  #define min(A,B) (((A)>(B)) ? (B) : (A))
! #endif /* ~max */
  
  #ifndef round
  #define round(X) (((X) >= 0) ? (int)((X)+0.5) : (int)((X)-0.5))
! #endif /* ~round */
  
  #ifndef M_PI
  #define M_PI 3.14159265358979323846
! #endif /* ~M_PI */
  
  #define INT_TOL (1.0e-5)
***************
*** 661,675 ****
  #ifdef sun
  #define PUT_A_POINT(dpy,win,gc,x,y) XDrawPoint(dpy,win,gc,x,y)
! #else
  #ifdef ultrix
  #define PUT_A_POINT(dpy,win,gc,x,y) XDrawPoint(dpy,win,gc,x,y)
! #else
  #ifdef _USE_XDRAWPOINT_TO_PUT_A_POINT
  #define PUT_A_POINT(dpy,win,gc,x,y) XDrawPoint(dpy,win,gc,x,y)
! #else
  #define PUT_A_POINT(dpy,win,gc,x,y) XDrawLine(dpy,win,gc,x,y,x,y)
! #endif
! #endif
! #endif
  
  /* file stuff */
--- 675,689 ----
  #ifdef sun
  #define PUT_A_POINT(dpy,win,gc,x,y) XDrawPoint(dpy,win,gc,x,y)
! #else /* ~sun */
  #ifdef ultrix
  #define PUT_A_POINT(dpy,win,gc,x,y) XDrawPoint(dpy,win,gc,x,y)
! #else /* ~ultrix */
  #ifdef _USE_XDRAWPOINT_TO_PUT_A_POINT
  #define PUT_A_POINT(dpy,win,gc,x,y) XDrawPoint(dpy,win,gc,x,y)
! #else /* ~_USE_XDRAWPOINT_TO_PUT_A_POINT */
  #define PUT_A_POINT(dpy,win,gc,x,y) XDrawLine(dpy,win,gc,x,y,x,y)
! #endif /* _USE_XDRAWPOINT_TO_PUT_A_POINT */
! #endif /* ultrix */
! #endif /* sun */
  
  /* file stuff */
*** patchlvl.h.orig	Sun Apr 11 10:47:53 1999
--- patchlvl.h	Sun Apr 11 10:47:53 1999
***************
*** 35,39 ****
  #define _TGIF_PATCHLEVEL_H_
  
! #define TGIF_PATCHLEVEL 4
  
  #endif /*_TGIF_PATCHLEVEL_H_*/
--- 35,39 ----
  #define _TGIF_PATCHLEVEL_H_
  
! #define TGIF_PATCHLEVEL 5
  
  #endif /*_TGIF_PATCHLEVEL_H_*/
*** tgifdefs.h.orig	Sun Apr 11 10:47:54 1999
--- tgifdefs.h	Sun Apr 11 10:47:54 1999
***************
*** 103,106 ****
--- 103,113 ----
  #endif /* __NetBSD__ */
  
+ #ifndef _NO_DL_SUPPORT
+ #include <dlfcn.h>
+ #ifndef RTLD_GLOBAL
+ #define RTLD_GLOBAL 0
+ #endif /* ~RTLD_GLOBAL */
+ #endif /* ~_NO_DL_SUPPORT */
+ 
  #include <math.h>
  #include <stdio.h>
***************
*** 112,115 ****
--- 119,128 ----
  #include <errno.h>
  
+ #ifndef _NO_LOCALE_SUPPORT
+ #ifdef _ENABLE_NLS
+ #include <libintl.h>
+ #endif /* _ENABLE_NLS */
+ #endif /* ~_NO_LOCALE_SUPPORT */
+ 
  #include <X11/Xlib.h>
  #include <X11/Xatom.h>
***************
*** 118,121 ****
--- 131,138 ----
  #include <X11/cursorfont.h>
  
+ #ifndef _NO_LOCALE_SUPPORT
+ #include <X11/Xlocale.h>
+ #endif /* ~_NO_LOCALE_SUPPORT */
+ 
  #include "const.h"
  #include "types.h"
*** Makefile.noimake.orig	Sun Apr 11 10:47:55 1999
--- Makefile.noimake	Sun Apr 11 10:47:55 1999
***************
*** 100,103 ****
--- 100,106 ----
  		  -D_BACKGROUND_DONT_FORK -D_USE_XDRAWPOINT_TO_PUT_A_POINT
  
+ #-D_ENABLE_NLS
+ #   Include the above line if you want to enable NLS (Native Language
+ #   Support).
  #-D_DONT_USE_PORTABLE_LOCALE
  #   Include the above line if don't want to use the portable locale.
***************
*** 157,160 ****
--- 160,168 ----
  #   by Renato Santana <renato@nce.ufrj.br>.  This flag is being
  #   obsoleted by the people at ufrj.br.  Please do not use it for tgif-4.x.
+ #-D_TGIF_WB2
+ #   Include the above line if you want to include the whiteboard feature
+ #   by Magnos Martinello <magnos@land.ufrj.br> and Raphael S. de Moraes
+ #   <raphael@land.ufrj.br>.  This code is highly experimental and only
+ #   runs on Solaris.
  #-DBSD_COMP
  #   Include the above line if you are compiling on a Solaris (or
*** Imakefile.orig	Sun Apr 11 10:47:56 1999
--- Imakefile	Sun Apr 11 10:47:57 1999
***************
*** 53,57 ****
                    $(MOREDEFINES)
  
! TGIFVERSION	= 4.1.4
  
  XCOMM Things to try to add to the DEFINES line above:
--- 53,57 ----
                    $(MOREDEFINES)
  
! TGIFVERSION	= 4.1.5
  
  XCOMM Things to try to add to the DEFINES line above:
***************
*** 67,72 ****
  XCOMM    SCO:     -DPRINT_CMD=\""lp -o raw -o nobanner"\"
  
  XCOMM -D_DONT_USE_PORTABLE_LOCALE
! XCOMM    Include the above line if don't want to use the portable locale.
  XCOMM    (Portable locale is "C" for all locale categories.)
  XCOMM -D_NO_RECURSIVE_EXTERN
--- 67,75 ----
  XCOMM    SCO:     -DPRINT_CMD=\""lp -o raw -o nobanner"\"
  
+ XCOMM -D_ENABLE_NLS
+ XCOMM    Include the above line if you want to enable NLS (Native Language
+ XCOMM    Support).
  XCOMM -D_DONT_USE_PORTABLE_LOCALE
! XCOMM    Include the above line if you don't want to use the portable locale.
  XCOMM    (Portable locale is "C" for all locale categories.)
  XCOMM -D_NO_RECURSIVE_EXTERN
***************
*** 124,127 ****
--- 127,135 ----
  XCOMM    by Renato Santana <renato@nce.ufrj.br>.  This flag is being
  XCOMM    obsoleted by the people at ufrj.br.  Please do not use it for tgif-4.x.
+ XCOMM -D_TGIF_WB2
+ XCOMM    Include the above line if you want to include the whiteboard feature
+ XCOMM    by Magnos Martinello <magnos@land.ufrj.br> and Raphael S. de Moraes
+ XCOMM    <raphael@land.ufrj.br>.  This code is highly experimental and only
+ XCOMM    runs on Solaris.
  XCOMM -DBSD_COMP
  XCOMM    Include the above line if you are compiling on a Solaris (or
***************
*** 233,237 ****
  	util.o \
  	version.o vms_comp.o \
! 	wb.o wb1.o wb2.o wb3.o \
  	xbitmap.o xpixmap.o xprtfltr.o
  
--- 241,245 ----
  	util.o \
  	version.o vms_comp.o \
! 	wb.o wb1.o wb2.o wb3.o wb_buff.o wb_mcast.o \
  	xbitmap.o xpixmap.o xprtfltr.o
  
***************
*** 312,316 ****
  		$(OBJDEMO) \
  		$(SYMDEMO) \
! 		$(MISCTAR)
  	rm -rf tgif-$(TGIFVERSION)
  	mkdir tgif-$(TGIFVERSION)
--- 320,325 ----
  		$(OBJDEMO) \
  		$(SYMDEMO) \
! 		$(MISCTAR) \
! 		po
  	rm -rf tgif-$(TGIFVERSION)
  	mkdir tgif-$(TGIFVERSION)
*** Tgif.tmpl.orig	Sun Apr 11 10:47:57 1999
--- Tgif.tmpl	Sun Apr 11 10:47:58 1999
***************
*** 49,53 ****
--- 49,55 ----
  XCOMM TGIFDIR	= /u/halfmoon/lib/X11/tgif
  TGIFDIR		= $(LIBDIR)/tgif
+ LOCALEDIR	= /usr/share/locale
  DIRDEFINES	= -DTGIF_PATH=\"$(TGIFDIR)\" -DPSFILE_MOD=0664 \@@\
+                   -DLOCALEDIR=\"$(LOCALEDIR)\" \@@\
                    -DTELEPORT_ATTR=\"warp_to=\" -DTMP_DIR=\"/tmp/\" \@@\
                    -DLAUNCH_ATTR=\"launch=\" -DEXEC_ATTR=\"exec=\"
*** tgif.man.orig	Sun Apr 11 10:47:59 1999
--- tgif.man	Sun Apr 11 10:47:59 1999
***************
*** 9,13 ****
  .\"
  .\"
! .TH tgif n "Version 4.1 Patchlevel 3 and Above" "Tgif"
  .\"
  .SH NAME
--- 9,13 ----
  .\"
  .\"
! .TH tgif n "Version 4.1 Patchlevel 5 and Above" "Tgif"
  .\"
  .SH NAME
***************
*** 1408,1411 ****
--- 1408,1419 ----
  above for the specification of object names.
  .TP
+ .I select_top_obj()
+ This command silently (no highlighting handles) selects the top object.
+ This command fails if there is no object in the current page.
+ .TP
+ .I delete_selected_obj()
+ This command deletes all selected objects.
+ This command fails if no object is selected.
+ .TP
  .I unselect_all_obj()
  This command de-selects all selected objects.  If the select_obj_by_name()
***************
*** 1500,1503 ****
--- 1508,1512 ----
  .I set_selected_obj_color(<color_str>)
  This command changes the color of the selected object to <color_str>.
+ If no object is selected, the current color will be changed to <color_str>.
  .TP
  .I set_selected_obj_fill(<fill_index>)
***************
*** 1505,1508 ****
--- 1514,1519 ----
  <fill_index>, which must be between 0 (for
  no fill) and 31.
+ If no object is selected, the current fill pattern will be changed to
+ <fill_index>.
  .TP
  .I set_selected_obj_pen(<pen_index>)
***************
*** 1509,1518 ****
  This command changes the pen of the selected object to <pen_index>,
  which must be between 0 (for no pen) and 31.
  .TP
  .I set_selected_obj_line_width(<width>,<arrow_w>,<arrow_h>)
! This command changes the line width, arrow width, and arrow_h of the
  selected object to <width>, <arrow_w>, and <arrow_h>,
  respectively.  If <arrow_w> or <arrow_h> is -1, the
  arrow width or arrow height, respectively, is not changed.
  .TP
  .I set_selected_obj_spline(<spline_type>)
--- 1520,1535 ----
  This command changes the pen of the selected object to <pen_index>,
  which must be between 0 (for no pen) and 31.
+ If no object is selected, the current pen will be changed to
+ <pen_index>.
  .TP
  .I set_selected_obj_line_width(<width>,<arrow_w>,<arrow_h>)
! This command changes the line width, arrow width, and arrow height of the
  selected object to <width>, <arrow_w>, and <arrow_h>,
  respectively.  If <arrow_w> or <arrow_h> is -1, the
  arrow width or arrow height, respectively, is not changed.
+ If no object is selected, the current line width will be changed to
+ the one that matches <width>, <arrow_w>, and <arrow_h> most closely.
+ (Closeness is measured such that the difference is width is counted
+ 10 times the diffference in arrow width and arrow height.)
  .TP
  .I set_selected_obj_spline(<spline_type>)
***************
*** 1520,1523 ****
--- 1537,1542 ----
  <spline_type>, which can be \fIstraight\fR, \fIspline\fR, or
  \fIinterpolated\fR.
+ If no object is selected, the current spline type will be changed to
+ <spline_type>.
  .TP
  .I set_selected_obj_arrow(<arrow_type>)
***************
*** 1525,1528 ****
--- 1544,1549 ----
  <arrow_type>, which can be \fInone\fR, \fIright\fR, \fIleft\fR, or
  \fIdouble\fR.
+ If no object is selected, the current arrow type will be changed to
+ <arrow_type>.
  .TP
  .I set_selected_obj_dash(<dash_index>)
***************
*** 1529,1539 ****
  This command changes the dash type of the selected object to
  <dash_index>, which must be between 0 (solid) and 8.
  .TP
  .I set_selected_obj_trans_pat(<trans_pat>)
- This command changes the pattern transparency of the selected object to
  This command changes selected object to have opaque pattern if <trans_pat>
  is 0; it changes selected object to have transparent pattern if
  <trans_pat> is any other numeric value.
  .TP
  .I inc(<attr_name>,<expr>)
  This command increment <attr_name> by the expression
--- 1550,1605 ----
  This command changes the dash type of the selected object to
  <dash_index>, which must be between 0 (solid) and 8.
+ If no object is selected, the current dash type will be changed to
+ <dash_index>.
  .TP
  .I set_selected_obj_trans_pat(<trans_pat>)
  This command changes selected object to have opaque pattern if <trans_pat>
  is 0; it changes selected object to have transparent pattern if
  <trans_pat> is any other numeric value.
+ If no object is selected, the current fill and pen pattern will be
+ opaque if <trans_pat> is 0 and will be transparent if
+ <trans_pat> is any other numeric value.
  .TP
+ .I set_selected_obj_rcb_radius(<rcb_radius>)
+ This command changes the rcbox radius of the selected object to <rcb_radius>,
+ which must be greater or equal to 4.
+ If no object is selected, the current rcbox radius will be changed to
+ <rcb_radius>.
+ .TP
+ .I set_selected_text_vspace(<vspace>)
+ This command changes the text vspace of the selected object to <vspace>.
+ If no object is selected, the current text vspace will be changed to <vspace>.
+ .TP
+ .I set_selected_text_just(<justification>)
+ This command changes the text justification of the selected object to
+ <justification>, which can be \fIleft\fR, \fIcenter\fR, or
+ \fIright\fR.
+ If no object is selected, the current text justification will be changed to
+ <justification>.
+ .TP
+ .I set_selected_text_font(<ps_font_name>)
+ This command changes the font and text style of the selected object to match
+ <ps_font_name>.  Examples of valid <ps_font_name> can be found when one
+ selects CopyProperties() from the Properties Menu.  The item listed under
+ \fItext font\fR is a valid <ps_font_name>.
+ If no object is selected, the current font and text style will be changed to
+ match <ps_font_name>.
+ This command fails if no match can be found,
+ .TP
+ .I set_selected_text_size(<size>)
+ This command changes the text size of the selected object to
+ <size>.  If <size> ends with the substring "pt", then point size is
+ used instead of text size.  If such as size cannot be found in the
+ Size Menu, the closest size in the Size Menu will be used.
+ If no object is selected, the current text size will be changed to
+ <size> or the closest size.
+ .TP
+ .I set_selected_text_underline(<underline>)
+ This command removes text underline from the selected object if
+ <underline> is 0; it underlines text in the selected object if
+ <underline> is any other numeric value.
+ If no object is selected, the current text underline will be changed
+ accordingly.
+ .TP
  .I inc(<attr_name>,<expr>)
  This command increment <attr_name> by the expression
***************
*** 1591,1594 ****
--- 1657,1663 ----
  This command copies <string> into the attribute specified by <attr_name>.
  .TP
+ .I copy_string_to_cut_buffer(<string>)
+ This command copies <string> into the cut buffer.
+ .TP
  .I strcat(<attr_name>,<string>)
  This command appends <string> to the attribute specified by <attr_name>.
***************
*** 1704,1707 ****
--- 1773,1779 ----
  the attribute will be placed below the lower left corner or the object.
  .TP
+ .I delete_attr_from_selected_obj(<attr_name>)
+ This command deletes an attribute named <attr_name> from a selected object.
+ .TP
  .I user_end_an_edge(<attr_name>,<abs_x>,<abs_y>)
  This command starts a polyline/open-spline at (<abs_x>,<abs_y>),
***************
*** 2048,2051 ****
--- 2120,2130 ----
  placed in the attribute specified by <attr_name>.
  .TP
+ .I select_from_ini_section(<attr_name>,<title>,<section>,<ini_path>)
+ This command brings up a list to select an entry from the section specified
+ by <section> in the file specified by the full path <ini_path>.
+ If nothing is selected, the attribute specified by <attr_name> will be
+ cleared.  Otherwise, the selected entry will be written into the
+ attribute specified by <attr_name>.
+ .TP
  .I append_line_into_attr(<attr_name>,<string>)
  This command appends the line specified by <string> to the attribute
***************
*** 2064,2067 ****
--- 2143,2218 ----
  specified by <attr_name> and deletes all other lines of the attribute
  if the attribute contains multiple lines.
+ .TP
+ .I create_text_obj(<abs_x>,<abs_baseline_y>,<string>)
+ This command creates a text object at the location (<abs_x>,<abs_baseline_y>)
+ with the text specified by <string>.
+ .TP
+ .I create_box_obj(<abs_ltx>,<abs_lty>,<abs_rbx>,<abs_rby>)
+ This command creates a rectangle defined by (<abs_ltx>,<abs_lty>)
+ and (<abs_rbx>,<abs_rby>).
+ .TP
+ .I create_corner_oval_obj(<abs_ltx>,<abs_lty>,<abs_rbx>,<abs_rby>)
+ This command creates a corner oval defined by (<abs_ltx>,<abs_lty>)
+ and (<abs_rbx>,<abs_rby>).
+ .TP
+ .I create_center_oval_obj(<abs_x>,<abs_y>,<radius>)
+ This command creates a center oval centered at (<abs_x>,<abs_y>)
+ with radius specified by <radius>.
+ .TP
+ .I create_edge_oval_obj(<abs_ltx>,<abs_lty>,<abs_rbx>,<abs_rby>)
+ This command creates an edge oval defined by (<abs_ltx>,<abs_lty>)
+ and (<abs_rbx>,<abs_rby>).
+ .TP
+ .I create_rcbox_obj(<abs_ltx>,<abs_lty>,<abs_rbx>,<abs_rby>)
+ This command creates a rounded-corner rectangle defined by
+ (<abs_ltx>,<abs_lty>) and (<abs_rbx>,<abs_rby>).
+ .TP
+ .I create_arc_obj(<abs_x>,<abs_y>,<radius>,<dir>,<angle1>,<angle2>)
+ This command creates an arc centered at (<abs_x>,<abs_y>)
+ with radius, direction, start angle, and end angle specified by
+ <radius>, <dir>, <angle1>, and <angle2>, respectively.  The
+ <radius>, <dir>, <angle1>, and <angle2> are specified in the same way
+ as they are specified in the SpecifyAnArc()
+ command under the CreateObject Submenu of the Edit Menu.
+ <dir> can be "+" or "-" where "+" is clockwise.
+ <angle1> and <angle2> are in degrees with 0 degree at the 12 o'clock
+ position.
+ .TP
+ .I create_first_vertex(<abs_x>,<abs_y>)
+ This command is used in conjunction with the create_next_vertex()
+ and create_poly_obj() commands to create a polyline/open-spline object.
+ It can also be used in conjunction with the create_next_vertex()
+ and create_polygon_obj() commands to create a polygon/closed-spline object.
+ This command sets the starting point of the polyline/open-spline
+ object or the polygon/closed-spline object to be
+ at (<abs_x>,<abs_y>).
+ .TP
+ .I create_next_vertex(<abs_x>,<abs_y>)
+ This command is used in conjunction with the create_first_vertex()
+ and create_poly_obj() commands to create a polyline/open-spline object.
+ It can also be used in conjunction with the create_first_vertex()
+ and create_polygon_obj() commands to create a polygon/closed-spline object.
+ This command sets the next vertex of the polyline/open-spline
+ object or the polygon/closed-spline object to be
+ at (<abs_x>,<abs_y>).
+ .TP
+ .I create_poly_obj()
+ This command is used in conjunction with the create_first_vertex()
+ and create_next_vertex() commands to create a polyline/open-spline object.
+ .TP
+ .I create_polygon_obj()
+ This command is used in conjunction with the create_first_vertex()
+ and create_next_vertex() commands to create a polygon/closed-spline object.
+ .TP
+ .I start_create_group_obj()
+ This command is used in conjunction with the create_group_obj() command
+ to create a grouped object.
+ This command marks the beginning of the group.
+ .TP
+ .I create_group_obj()
+ This command is used in conjunction with the start_create_group_obj() command
+ to create a grouped object.
+ This command groups all objects created since the last start_create_group_obj()
+ call into a grouped object.
  .\"
  .SH ARITHMETIC EXPRESSIONS
***************
*** 2862,2866 ****
  .TP
  .I Tgif.InitialFontSize: NUMBER
! This specifies the size of the start-up font.  The default is 17.
  .TP
  .I Tgif.MsgFontSizeIndex: [0,1,2,3,4,5]
--- 3013,3017 ----
  .TP
  .I Tgif.InitialFontSize: NUMBER
! This specifies the size of the start-up font.  The default is 14.
  .TP
  .I Tgif.MsgFontSizeIndex: [0,1,2,3,4,5]
***************
*** 2869,2873 ****
  .I Tgif.MsgFontSize: NUMBER
  This specifies the size of the font used for messages, menues,
! and popup windows.  The default is 17.
  .TP
  .I Tgif.RulerFontSize: NUMBER
--- 3020,3024 ----
  .I Tgif.MsgFontSize: NUMBER
  This specifies the size of the font used for messages, menues,
! and popup windows.  The default is 14.
  .TP
  .I Tgif.RulerFontSize: NUMBER
***************
*** 3660,3665 ****
  The default is false (or never).
  .TP
  .I Tgif.GUnZipCmd: STRING
! The STRING specifies a command used to unzip a zipped \fIremote\fR tgif file
  (with extension .obj.gz or .sym.gz) into a tgif file.  The command \fImust\fR
  produce output into its stdout.  If the command contains a \fI%s\fR
--- 3811,3823 ----
  The default is false (or never).
  .TP
+ .I Tgif.GZipCmd: STRING
+ The STRING specifies a command used to gzip a .obj file.
+ The command \fImust\fR produce output into its stdout.
+ If the command contains a \fI%s\fR substring, the \fI%s\fR will be replace
+ by the full path name of a temporary copy of the .obj file.
+ The default is "gzip -c".
+ .TP
  .I Tgif.GUnZipCmd: STRING
! The STRING specifies a command used to unzip a zipped tgif file
  (with extension .obj.gz or .sym.gz) into a tgif file.  The command \fImust\fR
  produce output into its stdout.  If the command contains a \fI%s\fR
***************
*** 3760,3764 ****
  The STRING specifies a font to be used as the default font for the
  Status Window, menus, dialogboxes, etc.
! The default is "-*-courier-medium-r-normal-*-17-*-*-*-*-*-iso8859-1".
  .TP
  .I Tgif.DefFixedWidthRulerFont: STRING
--- 3918,3922 ----
  The STRING specifies a font to be used as the default font for the
  Status Window, menus, dialogboxes, etc.
! The default is "-*-courier-medium-r-normal-*-14-*-*-*-*-*-iso8859-1".
  .TP
  .I Tgif.DefFixedWidthRulerFont: STRING
***************
*** 3768,3772 ****
  .TP
  .I Tgif.MenuFont: STRING
! This is not implemented, yet.
  .TP
  .I Tgif.BoldMsgFont: STRING
--- 3926,3931 ----
  .TP
  .I Tgif.MenuFont: STRING
! The STRING specifies a font to be used in menus.
! If this X default is not specified, the default font is used in menus.
  .TP
  .I Tgif.BoldMsgFont: STRING
***************
*** 3774,3778 ****
  If this X default is not specified but Tgif.MenuFont is specifed,
  this will take on the value of Tgif.MenuFont.
! If this X default and Tgif.MenuFont are not specified, the default font is used.
  .TP
  .I Tgif.MsgFont: STRING
--- 3933,3938 ----
  If this X default is not specified but Tgif.MenuFont is specifed,
  this will take on the value of Tgif.MenuFont.
! If this X default and Tgif.MenuFont are not specified, the default font is used
! in bold messages.
  .TP
  .I Tgif.MsgFont: STRING
***************
*** 3779,3783 ****
  The STRING specifies a thin font to be used in the Status Window and
  dialogboxes.
! If this X default is not specified, the default font is used.
  .TP
  .I Tgif.BggenToXpm: STRING
--- 3939,3943 ----
  The STRING specifies a thin font to be used in the Status Window and
  dialogboxes.
! If this X default is not specified, the default font is used in messages.
  .TP
  .I Tgif.BggenToXpm: STRING
***************
*** 4089,4092 ****
--- 4249,4262 ----
  3D borders.
  The default is true.
+ .TP
+ .I Tgif.MenuFontSet: STRING
+ This X default is only used if tgif is compiled with the _ENABLE_NLS
+ compiler option.  The STRING specifies a list of fonts to be used in menus.
+ The default is
+ "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*,-*-*-medium-r-*--12-*-*-*-*-*-*-*".
+ .TP
+ .I Tgif.LocaleDir: STRING
+ This X default is only used if tgif is compiled with the _ENABLE_NLS
+ compiler option.  The STRING specifies a full path name of a locale directory.
  .\"
  .SH ENVIRONMENT VARIABLE
***************
*** 4136,4140 ****
  perform the same function as the Prolog driver.  The extra code present
  in this file (and not present in tgif.c) is used to illustrate how
! the in-memory objects and attributes can be traversed.
  .\"
  .SH SEE ALSO
--- 4306,4311 ----
  perform the same function as the Prolog driver.  The extra code present
  in this file (and not present in tgif.c) is used to illustrate how
! the in-memory objects and attributes can be traversed and how new
! objects can be created and manipulated.
  .\"
  .SH SEE ALSO
*** HISTORY.orig	Sun Apr 11 10:48:01 1999
--- HISTORY	Sun Apr 11 10:48:01 1999
***************
*** 1,2 ****
--- 1,51 ----
+ -----------------------> tgif-4.1.4 => tgif-4.1.5 <-----------------------
+ Here's a short list of added features/bug fixes.
+ 
+ 1)  Fix bugs with breaking multiple text objects.  Thanks to
+     Kouya SHIMURA <kouya@flab.fujitsu.co.jp> for the patch.
+ 2)  Add NLS support for menus (can be turned on by the _ENABLE_NLS compiler
+     define).  A new X default, Tgif.MenuFontSet is added to have menus in
+     a native language.  A new X default, Tgif.LocaleDir, is added to override
+     the compile time locale directory specified in Tgif.tmpl.  Japanese menu
+     support is provided in the po/ja subdirectory.  Thanks to Jun Nishii
+     <jun@flatout.org> for the patch.  Please see po/README for more
+     information about the tgifintl release.
+ 3)  Fix bugs with overthespot for the xim input method.  Thanks to
+     Shoji Matsumoto <shom@i.h.kyoto-u.ac.jp> for the patch.
+ 4)  Open/Save/Import gzipped obj files.  Add Tgif.GUnZipCmd and Tgif.GZipCmd
+     X defaults so that the user can override the default "gunzip -c" and
+     "gzip -c" commands.
+ 5)  Add the following internal commands to make it a little easier for
+     third party code to drive tgif.  Please see the updated man pages for
+     the details of these commands.  "Testdrive.c" is updated to show how
+     some of these internal commands can be used to create and manipulate
+     objects from the test driver when Animate() is selected from the
+     Return Submenu of the File Menu.
+ 
+         select_top_obj()
+         delete_selected_obj()
+         set_selected_obj_rcb_radius(<rcb_radius>)
+         set_selected_text_vspace(<vspace>)
+         set_selected_text_just(<justification>)
+         set_selected_text_font(<ps_font_name>)
+         set_selected_text_size(<size>)
+         set_selected_text_underline(<underline>)
+         copy_string_to_cut_buffer(<string>)
+         delete_attr_from_selected_obj(<attr_name>)
+         select_from_ini_section(<attr_name>,<title>,<section>,<ini_path>)
+         create_text_obj(<abs_x>,<abs_baseline_y>,<string>)
+         create_box_obj(<abs_ltx>,<abs_lty>,<abs_rbx>,<abs_rby>)
+         create_corner_oval_obj(<abs_ltx>,<abs_lty>,<abs_rbx>,<abs_rby>)
+         create_center_oval_obj(<abs_x>,<abs_y>,<radius>)
+         create_edge_oval_obj(<abs_ltx>,<abs_lty>,<abs_rbx>,<abs_rby>)
+         create_rcbox_obj(<abs_ltx>,<abs_lty>,<abs_rbx>,<abs_rby>)
+         create_arc_obj(<abs_x>,<abs_y>,<radius>,<dir>,<angle1>,<angle2>)
+         create_first_vertex(<abs_x>,<abs_y>)
+         create_next_vertex(<abs_x>,<abs_y>)
+         create_poly_obj()
+         create_polygon_obj()
+         start_create_group_obj()
+         create_group_obj()
+ 
  -----------------------> tgif-4.1.3 => tgif-4.1.4 <-----------------------
  Here's a short list of added features/bug fixes.
*** xbm/run.xbm.orig	Sun Apr 11 10:48:02 1999
--- xbm/run.xbm	Sun Apr 11 10:48:02 1999
***************
*** 0 ****
--- 1,11 ----
+ /*
+  * @(#)$Header: /mm/src/tgif/v4/xbm/RCS/run.xbm,v 4.1 1999/04/03 18:13:16 william Exp $
+  */
+ #define run_width 16
+ #define run_height 16
+ #define run_x_hot 0
+ #define run_y_hot 0
+ static unsigned char run_bits[] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x04, 0x80, 0x04, 0x00, 0x03,
+    0x00, 0x07, 0x00, 0x0b, 0x80, 0x13, 0x60, 0x03, 0x00, 0x07, 0x00, 0x0b,
+    0xc0, 0x10, 0x30, 0x0c, 0x00, 0x00, 0xfe, 0x03};
*** tgif.Xdefaults.orig	Sun Apr 11 10:48:03 1999
--- tgif.Xdefaults	Sun Apr 11 10:48:03 1999
***************
*** 266,269 ****
--- 266,270 ----
  !Tgif.QueryZoomInPoint:		no_select
  !
+ Tgif.GZipCmd:			gzip -c
  Tgif.GUnZipCmd:			gunzip -c
  !Tgif.HttpProxy:		<host>:<port>
***************
*** 401,402 ****
--- 402,409 ----
  Tgif.UseImagePixelsForTrueColorExport:	false
  Tgif.DialogboxUse3DBorder:	true
+ !
+ ! Tgif.MenuFontSet and Tgif.LocaleDir are only useful if tgif is
+ !	compiled with the _ENABLE_NLS compiler option.
+ !
+ !Tgif.MenuFontSet:		a14,k14,r14
+ !Tgif.LocaleDir:		/usr/share/lib
*** make.comdep.orig	Sun Apr 11 10:48:04 1999
--- make.comdep	Sun Apr 11 10:48:04 1999
***************
*** 48,52 ****
  		choose.e cutpaste.e cursor.e dialog.e file.e font.e \
  		mainloop.e mainmenu.e menu.e msg.e names.e raster.e rect.e \
! 		remote.e scroll.e setup.e util.e 
  cli_xcin$(O) :	tgifdefs.h const.h tgif_dbg.h types.h cli_xcin.e 
  cmd$(O) :	tgifdefs.h const.h tgif_dbg.h types.h attr.e choice.e cmd.e \
--- 48,52 ----
  		choose.e cutpaste.e cursor.e dialog.e file.e font.e \
  		mainloop.e mainmenu.e menu.e msg.e names.e raster.e rect.e \
! 		remote.e scroll.e setup.e util.e $(XBM)check.xbm 
  cli_xcin$(O) :	tgifdefs.h const.h tgif_dbg.h types.h cli_xcin.e 
  cmd$(O) :	tgifdefs.h const.h tgif_dbg.h types.h attr.e choice.e cmd.e \
***************
*** 62,66 ****
  		dialog.e msg.e text.e 
  convxim$(O) :	tgifdefs.h const.h tgif_dbg.h types.h convkinput.e convxim.e \
! 		font.e msg.e setup.e util.e 
  cursor$(O) :	tgifdefs.h const.h tgif_dbg.h types.h choice.e color.e \
  		cursor.e setup.e xbitmap.e $(XBM)null.xbm $(XBM)nullmask.xbm \
--- 62,66 ----
  		dialog.e msg.e text.e 
  convxim$(O) :	tgifdefs.h const.h tgif_dbg.h types.h convkinput.e convxim.e \
! 		font.e miniline.e msg.e setup.e util.e 
  cursor$(O) :	tgifdefs.h const.h tgif_dbg.h types.h choice.e color.e \
  		cursor.e setup.e xbitmap.e $(XBM)null.xbm $(XBM)nullmask.xbm \
***************
*** 86,91 ****
  		polygon.e raster.e rcbox.e rect.e remote.e ruler.e scroll.e \
  		select.e setup.e shape.e shortcut.e special.e stk.e stream.e \
! 		stretch.e text.e util.e xbitmap.e xpixmap.e $(XBM)intr.xbm \
! 		$(XBM)trek.xbm 
  dup$(O) :	tgifdefs.h const.h tgif_dbg.h types.h attr.e auxtext.e \
  		choice.e cmd.e drawing.e dup.e grid.e mark.e move.e msg.e \
--- 86,91 ----
  		polygon.e raster.e rcbox.e rect.e remote.e ruler.e scroll.e \
  		select.e setup.e shape.e shortcut.e special.e stk.e stream.e \
! 		stretch.e tangram2.e text.e util.e xbitmap.e xpixmap.e \
! 		$(XBM)intr.xbm $(XBM)trek.xbm $(XBM)run.xbm 
  dup$(O) :	tgifdefs.h const.h tgif_dbg.h types.h attr.e auxtext.e \
  		choice.e cmd.e drawing.e dup.e grid.e mark.e move.e msg.e \
***************
*** 105,115 ****
  		xbitmap.e 
  exec$(O) :	tgifdefs.h const.h tgif_dbg.h types.h patchlvl.h expfdefs.h \
! 		cmdids.h align.e attr.e auxtext.e cmd.e color.e choice.e \
! 		cursor.e cutpaste.e dialog.e drawing.e dup.e edit.e eps.e \
! 		exec.e expr.e file.e font.e grid.e import.e ini.e mainloop.e \
! 		menu.e miniline.e move.e msg.e names.e navigate.e obj.e \
! 		pattern.e poly.e raster.e remote.e select.e setup.e \
! 		shortcut.e special.e stk.e stretch.e tcp.e text.e util.e \
! 		version.e wb.e xbitmap.e xpixmap.e xprtfltr.e 
  expr$(O) :	tgifdefs.h const.h tgif_dbg.h types.h dialog.e expr.e msg.e \
  		setup.e util.e 
--- 105,116 ----
  		xbitmap.e 
  exec$(O) :	tgifdefs.h const.h tgif_dbg.h types.h patchlvl.h expfdefs.h \
! 		cmdids.h align.e arc.e attr.e auxtext.e box.e cmd.e color.e \
! 		choice.e cursor.e cutpaste.e dialog.e drawing.e dup.e edit.e \
! 		eps.e exec.e expr.e file.e font.e grid.e import.e ini.e \
! 		mainloop.e menu.e miniline.e move.e msg.e names.e navigate.e \
! 		obj.e oval.e pattern.e poly.e polygon.e raster.e rcbox.e \
! 		rect.e remote.e select.e setup.e shortcut.e special.e stk.e \
! 		stretch.e tangram2.e tcp.e text.e util.e version.e wb.e \
! 		xbitmap.e xpixmap.e xprtfltr.e 
  expr$(O) :	tgifdefs.h const.h tgif_dbg.h types.h dialog.e expr.e msg.e \
  		setup.e util.e 
***************
*** 166,171 ****
  		msg.e names.e navigate.e obj.e page.e pin.e ps.e raster.e \
  		remote.e ruler.e scroll.e select.e setup.e shape.e shortcut.e \
! 		stk.e text.e util.e version.e wb.e xbitmap.e xpixmap.e \
! 		xprtfltr.e 
  mainmenu$(O) :	tgifdefs.h const.h tgif_dbg.h types.h align.e choice.e \
  		color.e cursor.e edit.e file.e font.e grid.e help.e imgproc.e \
--- 167,172 ----
  		msg.e names.e navigate.e obj.e page.e pin.e ps.e raster.e \
  		remote.e ruler.e scroll.e select.e setup.e shape.e shortcut.e \
! 		stk.e tangram2.e text.e util.e version.e wb.e xbitmap.e \
! 		xpixmap.e xprtfltr.e 
  mainmenu$(O) :	tgifdefs.h const.h tgif_dbg.h types.h align.e choice.e \
  		color.e cursor.e edit.e file.e font.e grid.e help.e imgproc.e \
***************
*** 172,176 ****
  		mainloop.e mainmenu.e menu.e menuinfo.e msg.e navigate.e \
  		obj.e page.e pattern.e raster.e setup.e shape.e special.e \
! 		stretch.e text.e util.e 
  mark$(O) :	tgifdefs.h const.h tgif_dbg.h types.h choice.e exec.e mark.e \
  		obj.e raster.e rect.e setup.e select.e 
--- 173,177 ----
  		mainloop.e mainmenu.e menu.e menuinfo.e msg.e navigate.e \
  		obj.e page.e pattern.e raster.e setup.e shape.e special.e \
! 		stretch.e tangram2.e text.e util.e 
  mark$(O) :	tgifdefs.h const.h tgif_dbg.h types.h choice.e exec.e mark.e \
  		obj.e raster.e rect.e setup.e select.e 
***************
*** 180,189 ****
  		mainmenu.e menu.e menuinfo.e move.e msg.e names.e navigate.e \
  		obj.e page.e pattern.e raster.e rect.e remote.e select.e \
! 		setup.e shape.e special.e stk.e text.e util.e version.e \
! 		$(XBM)check.xbm $(XBM)submenu.xbm 
  menuinfo$(O) :	tgifdefs.h const.h tgif_dbg.h types.h cmdids.h align.e \
  		color.e edit.e file.e font.e grid.e help.e menu.e menuinfo.e \
  		navigate.e page.e pattern.e raster.e scroll.e shape.e \
! 		stream.e text.e xbitmap.e 
  miniline$(O) :	tgifdefs.h const.h tgif_dbg.h types.h auxtext.e choice.e \
  		color.e dialog.e drawing.e dup.e file.e font.e inmethod.e \
--- 181,190 ----
  		mainmenu.e menu.e menuinfo.e move.e msg.e names.e navigate.e \
  		obj.e page.e pattern.e raster.e rect.e remote.e select.e \
! 		setup.e shape.e special.e stk.e tangram2.e text.e util.e \
! 		version.e $(XBM)check.xbm $(XBM)submenu.xbm 
  menuinfo$(O) :	tgifdefs.h const.h tgif_dbg.h types.h cmdids.h align.e \
  		color.e edit.e file.e font.e grid.e help.e menu.e menuinfo.e \
  		navigate.e page.e pattern.e raster.e scroll.e shape.e \
! 		stream.e tangram2.e text.e xbitmap.e 
  miniline$(O) :	tgifdefs.h const.h tgif_dbg.h types.h auxtext.e choice.e \
  		color.e dialog.e drawing.e dup.e file.e font.e inmethod.e \
***************
*** 306,314 ****
  		$(XBM)stretch.xbm $(XBM)nstretch.xbm $(XBM)pattrans.xbm \
  		$(XBM)patopaq.xbm $(XBM)rot_0.xbm $(XBM)rot_90.xbm \
! 		$(XBM)rot_180.xbm $(XBM)rot_270.xbm $(XBM)check.xbm \
! 		$(XBM)radio.xbm $(XBM)submenu.xbm $(XBM)gsubmenu.xbm \
! 		$(XBM)redraw.xbm $(XBM)btn1.xbm $(XBM)btn2.xbm $(XBM)btn3.xbm \
! 		$(XBM)stop.xbm $(XBM)question.xbm $(XBM)info.xbm \
! 		$(XBM)dialog.xbm 
  rcbox$(O) :	tgifdefs.h const.h tgif_dbg.h types.h attr.e auxtext.e box.e \
  		cmd.e color.e cursor.e cutpaste.e drawing.e file.e grid.e \
--- 307,315 ----
  		$(XBM)stretch.xbm $(XBM)nstretch.xbm $(XBM)pattrans.xbm \
  		$(XBM)patopaq.xbm $(XBM)rot_0.xbm $(XBM)rot_90.xbm \
! 		$(XBM)rot_180.xbm $(XBM)rot_270.xbm $(XBM)run.xbm \
! 		$(XBM)check.xbm $(XBM)radio.xbm $(XBM)submenu.xbm \
! 		$(XBM)gsubmenu.xbm $(XBM)redraw.xbm $(XBM)btn1.xbm \
! 		$(XBM)btn2.xbm $(XBM)btn3.xbm $(XBM)stop.xbm \
! 		$(XBM)question.xbm $(XBM)info.xbm $(XBM)dialog.xbm 
  rcbox$(O) :	tgifdefs.h const.h tgif_dbg.h types.h attr.e auxtext.e box.e \
  		cmd.e color.e cursor.e cutpaste.e drawing.e file.e grid.e \
***************
*** 341,346 ****
  		nkf.e page.e pattern.e pin.e poly.e ps.e raster.e remote.e \
  		ruler.e scroll.e select.e setup.e shape.e shortcut.e spline.e \
! 		stk.e stretch.e text.e util.e version.e wb.e xbitmap.e \
! 		xpixmap.e xprtfltr.e tgificon.xbm $(XBM)btn1.xbm 
  shape$(O) :	tgifdefs.h const.h tgif_dbg.h types.h cmdids.h arc.e attr.e \
  		auxtext.e box.e cmd.e color.e cursor.e dialog.e drawing.e \
--- 342,347 ----
  		nkf.e page.e pattern.e pin.e poly.e ps.e raster.e remote.e \
  		ruler.e scroll.e select.e setup.e shape.e shortcut.e spline.e \
! 		stk.e stretch.e tangram2.e text.e util.e version.e wb.e \
! 		xbitmap.e xpixmap.e xprtfltr.e tgificon.xbm $(XBM)btn1.xbm 
  shape$(O) :	tgifdefs.h const.h tgif_dbg.h types.h cmdids.h arc.e attr.e \
  		auxtext.e box.e cmd.e color.e cursor.e dialog.e drawing.e \
***************
*** 350,354 ****
  		text.e util.e 
  shortcut$(O) :	tgifdefs.h const.h tgif_dbg.h types.h cmdids.h msg.e setup.e \
! 		shortcut.e 
  special$(O) :	tgifdefs.h const.h tgif_dbg.h types.h animate.e attr.e \
  		auxtext.e choice.e cmd.e color.e cutpaste.e cursor.e dialog.e \
--- 351,355 ----
  		text.e util.e 
  shortcut$(O) :	tgifdefs.h const.h tgif_dbg.h types.h cmdids.h msg.e setup.e \
! 		shortcut.e tangram2.e 
  special$(O) :	tgifdefs.h const.h tgif_dbg.h types.h animate.e attr.e \
  		auxtext.e choice.e cmd.e color.e cutpaste.e cursor.e dialog.e \
***************
*** 373,378 ****
  		msg.e obj.e poly.e raster.e rect.e ruler.e select.e setup.e \
  		spline.e stretch.e text.e util.e xbitmap.e xpixmap.e 
! tangram2$(O) :	tgifdefs.h const.h tgif_dbg.h types.h dialog.e menu.e msg.e \
! 		tangram2.e util.e 
  tcp$(O) :	tgifdefs.h const.h tgif_dbg.h types.h remote.e tcp.e util.e 
  testdrive$(O) :	tgifdefs.h const.h tgif_dbg.h types.h mainloop.e msg.e obj.e \
--- 374,379 ----
  		msg.e obj.e poly.e raster.e rect.e ruler.e select.e setup.e \
  		spline.e stretch.e text.e util.e xbitmap.e xpixmap.e 
! tangram2$(O) :	tgifdefs.h const.h tgif_dbg.h types.h dialog.e exec.e menu.e \
! 		msg.e obj.e select.e tangram2.e util.e 
  tcp$(O) :	tgifdefs.h const.h tgif_dbg.h types.h remote.e tcp.e util.e 
  testdrive$(O) :	tgifdefs.h const.h tgif_dbg.h types.h mainloop.e msg.e obj.e \
***************
*** 394,401 ****
  wb$(O) :	tgifdefs.h const.h tgif_dbg.h types.h auxtext.e drawing.e \
  		cmd.e dialog.e file.e grid.e http.e mark.e msg.e obj.e \
! 		remote.e select.e stk.e tcp.e util.e wb.e 
  wb1$(O) :	tgifdefs.h const.h tgif_dbg.h types.h 
  wb2$(O) :	tgifdefs.h const.h tgif_dbg.h types.h 
  wb3$(O) :	tgifdefs.h const.h tgif_dbg.h types.h 
  xbitmap$(O) :	tgifdefs.h const.h tgif_dbg.h types.h expfdefs.h cmdids.h \
  		attr.e auxtext.e choice.e cmd.e color.e cursor.e cutpaste.e \
--- 395,405 ----
  wb$(O) :	tgifdefs.h const.h tgif_dbg.h types.h auxtext.e drawing.e \
  		cmd.e dialog.e file.e grid.e http.e mark.e msg.e obj.e \
! 		remote.e select.e stk.e tcp.e util.e wb.e wb_buff.e \
! 		wb_mcast.e 
  wb1$(O) :	tgifdefs.h const.h tgif_dbg.h types.h 
  wb2$(O) :	tgifdefs.h const.h tgif_dbg.h types.h 
  wb3$(O) :	tgifdefs.h const.h tgif_dbg.h types.h 
+ wb_buff$(O) :	tgifdefs.h const.h tgif_dbg.h types.h wb_buff.e 
+ wb_mcast$(O) :	tgifdefs.h const.h tgif_dbg.h types.h wb_mcast.e 
  xbitmap$(O) :	tgifdefs.h const.h tgif_dbg.h types.h expfdefs.h cmdids.h \
  		attr.e auxtext.e choice.e cmd.e color.e cursor.e cutpaste.e \
*** make.common.orig	Sun Apr 11 10:48:05 1999
--- make.common	Sun Apr 11 10:48:05 1999
***************
*** 28,32 ****
          util$(O) \
          version$(O) vms_comp$(O) \
!         wb$(O) wb1$(O) wb2$(O) wb3$(O) \
          xbitmap$(O) xpixmap$(O) xprtfltr$(O)
  
--- 28,32 ----
          util$(O) \
          version$(O) vms_comp$(O) \
!         wb$(O) wb1$(O) wb2$(O) wb3$(O) wb_buff$(O) wb_mcast$(O) \
          xbitmap$(O) xpixmap$(O) xprtfltr$(O)
  
*** Tgif.tmpl-freebsd.orig	Sun Apr 11 10:48:06 1999
--- Tgif.tmpl-freebsd	Sun Apr 11 10:48:06 1999
***************
*** 49,53 ****
--- 49,55 ----
  XCOMM TGIFDIR	= /u/halfmoon/lib/X11/tgif
  TGIFDIR		= $(LIBDIR)/tgif
+ LOCALEDIR	= /usr/share/locale
  DIRDEFINES	= -DTGIF_PATH=\"$(TGIFDIR)\" -DPSFILE_MOD=0664 \@@\
+                   -DLOCALEDIR=\"$(LOCALEDIR)\" \@@\
                    -DTELEPORT_ATTR=\"warp_to=\" -DTMP_DIR=\"/tmp/\" \@@\
                    -DLAUNCH_ATTR=\"launch=\" -DEXEC_ATTR=\"exec=\"
*** Tgif.tmpl-hpux.orig	Sun Apr 11 10:48:07 1999
--- Tgif.tmpl-hpux	Sun Apr 11 10:48:07 1999
***************
*** 49,53 ****
--- 49,55 ----
  XCOMM TGIFDIR	= /u/halfmoon/lib/X11/tgif
  TGIFDIR		= $(LIBDIR)/tgif
+ LOCALEDIR	= /usr/lib/locale
  DIRDEFINES	= -DTGIF_PATH=\"$(TGIFDIR)\" -DPSFILE_MOD=0664 \@@\
+                   -DLOCALEDIR=\"$(LOCALEDIR)\" \@@\
                    -DTELEPORT_ATTR=\"warp_to=\" -DTMP_DIR=\"/tmp/\" \@@\
                    -DLAUNCH_ATTR=\"launch=\" -DEXEC_ATTR=\"exec=\"
*** Tgif.tmpl-irix.orig	Sun Apr 11 10:48:08 1999
--- Tgif.tmpl-irix	Sun Apr 11 10:48:08 1999
***************
*** 53,57 ****
--- 53,59 ----
  XCOMM TGIFDIR	= /u/halfmoon/lib/X11/tgif
  TGIFDIR		= $(LIBDIR)/tgif
+ LOCALEDIR	= /usr/lib/locale
  DIRDEFINES	= -DTGIF_PATH=\"$(TGIFDIR)\" -DPSFILE_MOD=0664 \@@\
+                   -DLOCALEDIR=\"$(LOCALEDIR)\" \@@\
                    -DTELEPORT_ATTR=\"warp_to=\" -DTMP_DIR=\"/tmp/\" \@@\
                    -DLAUNCH_ATTR=\"launch=\" -DEXEC_ATTR=\"exec=\"
*** Tgif.tmpl-linux.orig	Sun Apr 11 10:48:09 1999
--- Tgif.tmpl-linux	Sun Apr 11 10:48:09 1999
***************
*** 49,53 ****
--- 49,55 ----
  XCOMM TGIFDIR	= /u/halfmoon/lib/X11/tgif
  TGIFDIR		= $(LIBDIR)/tgif
+ LOCALEDIR	= /usr/share/locale
  DIRDEFINES	= -DTGIF_PATH=\"$(TGIFDIR)\" -DPSFILE_MOD=0664 \@@\
+                   -DLOCALEDIR=\"$(LOCALEDIR)\" \@@\
                    -DTELEPORT_ATTR=\"warp_to=\" -DTMP_DIR=\"/tmp/\" \@@\
                    -DLAUNCH_ATTR=\"launch=\" -DEXEC_ATTR=\"exec=\"
*** Tgif.tmpl-netbsd.orig	Sun Apr 11 10:48:10 1999
--- Tgif.tmpl-netbsd	Sun Apr 11 10:48:10 1999
***************
*** 49,53 ****
--- 49,55 ----
  XCOMM TGIFDIR	= /u/halfmoon/lib/X11/tgif
  TGIFDIR		= $(LIBDIR)/tgif
+ LOCALEDIR	= /usr/share/locale
  DIRDEFINES	= -DTGIF_PATH=\"$(TGIFDIR)\" -DPSFILE_MOD=0664 \@@\
+                   -DLOCALEDIR=\"$(LOCALEDIR)\" \@@\
                    -DTELEPORT_ATTR=\"warp_to=\" -DTMP_DIR=\"/tmp/\" \@@\
                    -DLAUNCH_ATTR=\"launch=\" -DEXEC_ATTR=\"exec=\"
*** Tgif.tmpl-osf1.orig	Sun Apr 11 10:48:11 1999
--- Tgif.tmpl-osf1	Sun Apr 11 10:48:11 1999
***************
*** 49,53 ****
--- 49,55 ----
  XCOMM TGIFDIR	= /u/halfmoon/lib/X11/tgif
  TGIFDIR		= $(LIBDIR)/tgif
+ LOCALEDIR	= /usr/lib/nls
  DIRDEFINES	= -DTGIF_PATH=\"$(TGIFDIR)\" -DPSFILE_MOD=0664 \@@\
+                   -DLOCALEDIR=\"$(LOCALEDIR)\" \@@\
                    -DTELEPORT_ATTR=\"warp_to=\" -DTMP_DIR=\"/tmp/\" \@@\
                    -DLAUNCH_ATTR=\"launch=\" -DEXEC_ATTR=\"exec=\"
*** Tgif.tmpl-solaris.orig	Sun Apr 11 10:48:12 1999
--- Tgif.tmpl-solaris	Sun Apr 11 10:48:12 1999
***************
*** 55,59 ****
--- 55,61 ----
  XCOMM TGIFDIR	= /u/halfmoon/lib/X11/tgif
  TGIFDIR		= $(LIBDIR)/tgif
+ LOCALEDIR	= /usr/lib/locale
  DIRDEFINES	= -DTGIF_PATH=\"$(TGIFDIR)\" -DPSFILE_MOD=0664 \@@\
+                   -DLOCALEDIR=\"$(LOCALEDIR)\" \@@\
                    -DTELEPORT_ATTR=\"warp_to=\" -DTMP_DIR=\"/tmp/\" \@@\
                    -DLAUNCH_ATTR=\"launch=\" -DEXEC_ATTR=\"exec=\"
***************
*** 63,67 ****
                    -DTEXT_FILE_EXT=\"txt\" -DPIN_FILE_EXT=\"pin\"
  MISCDEFINES	= -D_BACKGROUND_DONT_FORK -D_USE_XDRAWPOINT_TO_PUT_A_POINT
! MOREDEFINES	=
  
  XCOMM ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--- 65,69 ----
                    -DTEXT_FILE_EXT=\"txt\" -DPIN_FILE_EXT=\"pin\"
  MISCDEFINES	= -D_BACKGROUND_DONT_FORK -D_USE_XDRAWPOINT_TO_PUT_A_POINT
! MOREDEFINES	= -D_HAS_STREAMS_SUPPORT
  
  XCOMM ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
***************
*** 72,76 ****
  LOCAL_LIBRARIES	= $(XLIB)
  XCOMM LOCAL_LIBRARIES	= $(XMULIB) $(XTOOLLIB) $(XLIB)
! SYS_LIBRARIES	= -ldl -lm
  XCOMM SYS_LIBRARIES	= -lm
  
--- 74,78 ----
  LOCAL_LIBRARIES	= $(XLIB)
  XCOMM LOCAL_LIBRARIES	= $(XMULIB) $(XTOOLLIB) $(XLIB)
! SYS_LIBRARIES	= -lintl -ldl -lm
  XCOMM SYS_LIBRARIES	= -lm
  
