Example #1
0
void
ResizeScrollBar(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    if (screen->scrollWidget != 0) {
	int height = screen->fullVwin.height + screen->border * 2;
	int width = screen->scrollWidget->core.width;
	int ypos = -ScrollBarBorder(xw);
#ifdef SCROLLBAR_RIGHT
	int xpos = ((xw->misc.useRight)
		    ? (screen->fullVwin.fullwidth -
		       screen->scrollWidget->core.width -
		       BorderWidth(screen->scrollWidget))
		    : -ScrollBarBorder(xw));
#else
	int xpos = -ScrollBarBorder(xw);
#endif

	TRACE(("ResizeScrollBar at %d,%d %dx%d\n", ypos, xpos, height, width));

	XtConfigureWidget(
			     screen->scrollWidget,
			     (Position) xpos,
			     (Position) ypos,
			     (Dimension) width,
			     (Dimension) height,
			     BorderWidth(screen->scrollWidget));
	ScrollBarDrawThumb(screen->scrollWidget);
    }
}
Example #2
0
void
ScrollBarOn(XtermWidget xw, Bool init)
{
    TScreen *screen = TScreenOf(xw);

    if (screen->fullVwin.sb_info.width || IsIcon(screen))
	return;

    TRACE(("ScrollBarOn(init %s)\n", BtoS(init)));
    if (init) {			/* then create it only */
	if (screen->scrollWidget == 0) {
	    /* make it a dummy size and resize later */
	    screen->scrollWidget = CreateScrollBar(xw,
						   -ScrollBarBorder(xw),
						   -ScrollBarBorder(xw),
						   5);
	    if (screen->scrollWidget == NULL) {
		Bell(xw, XkbBI_MinorError, 0);
	    }
	}
    } else if (!screen->scrollWidget || !XtIsRealized((Widget) xw)) {
	Bell(xw, XkbBI_MinorError, 0);
	Bell(xw, XkbBI_MinorError, 0);
    } else {

	ResizeScrollBar(xw);
	xtermAddInput(screen->scrollWidget);
	XtRealizeWidget(screen->scrollWidget);
	TRACE_TRANS("scrollbar", screen->scrollWidget);

	screen->fullVwin.sb_info.rv_cached = False;

	screen->fullVwin.sb_info.width = (screen->scrollWidget->core.width
					  + BorderWidth(screen->scrollWidget));

	TRACE(("setting scrollbar width %d = %d + %d\n",
	       screen->fullVwin.sb_info.width,
	       screen->scrollWidget->core.width,
	       BorderWidth(screen->scrollWidget)));

	ScrollBarDrawThumb(screen->scrollWidget);
	DoResizeScreen(xw);

#ifdef SCROLLBAR_RIGHT
	updateRightScrollbar(xw);
#endif

	XtMapWidget(screen->scrollWidget);
	update_scrollbar();
	if (screen->visbuf) {
	    xtermClear(xw);
	    Redraw();
	}
    }
}
Example #3
0
/*
 * Adjust the scrollbar position if we're asked to turn on scrollbars for the
 * first time (or after resizing) after the xterm is already running.  That
 * makes the window grow after we've initially configured the scrollbar's
 * position.  (There must be a better way).
 */
void
updateRightScrollbar(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    if (xw->misc.useRight
	&& screen->fullVwin.fullwidth < xw->core.width)
	XtVaSetValues(screen->scrollWidget,
		      XtNx, screen->fullVwin.fullwidth - BorderWidth(screen->scrollWidget),
		      (XtPointer) 0);
}
Example #4
0
File: handler.c Project: aosm/X11
void
Popup(Widget w, XtGrabKind grab_kind)
{
  int x_root,y_root,y_pos,garbage;
  unsigned int mask;
  Window junk_window;

  XQueryPointer(XtDisplay(w), XtWindow(w), &junk_window, &junk_window,
		&x_root, &y_root, &garbage, &garbage, &mask);

  y_pos = OFF_OF_TOP - Height(w)/2 - BorderWidth(w);
  PositionCenter(w, x_root, y_root, y_pos, 0, 2, 2);
  XtPopup(w, grab_kind);
}
Example #5
0
static void
dumpSvgHeader(XtermWidget xw, FILE *fp)
{
    TScreen *s = TScreenOf(xw);

    rows = s->bot_marg - s->top_marg + 1;
    cols = MaxCols(s);
    bw = BorderWidth(xw);
    ib = s->border;

    fputs("<?xml version='1.0' encoding='UTF-8'?>\n", fp);
    fputs("<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'\n", fp);
    fputs("  'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>\n", fp);
    fputs("<svg xmlns='http://www.w3.org/2000/svg'\n", fp);
    fputs(" version='1.1' baseProfile='full'\n", fp);
    fprintf(fp, " viewBox='0 0 %d %d'>\n", 2 * (bw + ib) + cols * CELLW, 2 *
	    (bw + ib) +
	    rows * CELLH);
    fprintf(fp, " <desc>%s Screen Dump</desc>\n", xtermVersion());
    fprintf(fp,
	    " <g font-size='%.2f' font-family='monospace, monospace'>\n",
	    0.80 * CELLH);
}
Example #6
0
File: misc.c Project: aosm/X11apps
FILE *
Format(ManpageGlobals * man_globals, char * entry)
{
  FILE * file = NULL;
#ifdef HAS_MKSTEMP
  int fd;
#endif
  Widget manpage = man_globals->manpagewidgets.manpage;
  char cmdbuf[BUFSIZ], tmp[BUFSIZ], filename[BUFSIZ], error_buf[BUFSIZ];
  char path[BUFSIZ], sect[BUFSIZ];
  XEvent event;
  Position x,y;			/* location to pop up the
				   "would you like to save" widget. */

#ifndef HAS_MKSTEMP
  if ( !UncompressUnformatted(man_globals, entry, filename) ) {
#else
  if ( !UncompressUnformatted(man_globals, entry, filename, &file) ) {
#endif
    /* We Really could not find it, this should never happen, yea right. */
    snprintf(error_buf, sizeof(error_buf),
	     "Could not open manual page, %s", entry);
    PopupWarning(man_globals, error_buf);
    XtPopdown( XtParent(man_globals->standby) );
    return(NULL);
  }

#ifndef HAS_MKSTEMP
  if ((file = fopen(filename, "r")) != NULL) {
#else
  if (file != NULL) {
#endif
    char line[BUFSIZ];

    if (fgets(line, sizeof(line), file) != NULL) {
	if (strncmp(line, ".so ", 4) == 0) {
	  line[strlen(line) - 1] = '\0';
	  fclose(file);
	  unlink(filename);
	  if (line[4] != '/') {
	    char *ptr = NULL;

	    strcpy(tmp, entry);
	    if ((ptr = rindex(tmp, '/')) != NULL) {
	      *ptr = '\0';
	      if ((ptr = rindex(tmp, '/')) != NULL)
		ptr[1] = '\0';
	    }
	  }
	  else
	    *tmp = '\0';
	  snprintf(filename, sizeof(filename), "%s%s", tmp, line + 4);

	  return (Format(man_globals, filename));
	}
    }
    fclose(file);
  }

  Popup(XtParent(man_globals->standby), XtGrabExclusive);
  while ( !XCheckTypedWindowEvent(XtDisplay(man_globals->standby),
				  XtWindow(man_globals->standby),
				  Expose, &event) );
  XtDispatchEvent( &event );
  XFlush(XtDisplay(man_globals->standby));

  strcpy(tmp,MANTEMP);		          /* Get a temp file. */
#ifndef HAS_MKSTEMP
  (void) mktemp(tmp);
#else
  fd = mkstemp(tmp);
  file = fdopen(fd, "r");
#endif
  strcpy(man_globals->tempfile, tmp);

  ParseEntry(entry, path, sect, NULL);

#ifndef HANDLE_ROFFSEQ
#ifndef HAS_MKSTEMP
  snprintf(cmdbuf, sizeof(cmdbuf), "cd %s ; %s %s %s > %s %s", path, TBL,
	  filename, FORMAT, man_globals->tempfile, "2> /dev/null");
#else
  snprintf(cmdbuf, sizeof(cmdbuf), "cd %s ; %s %s %s >> %s %s", path, TBL,
	  filename, FORMAT, man_globals->tempfile, "2> /dev/null");
#endif
#else
  /* Handle more flexible way of specifying the formatting pipeline */
  if (! ConstructCommand(cmdbuf, path, filename, man_globals->tempfile)) {
     sprintf(error_buf, "Constructed command was too long!");
     PopupWarning(man_globals, error_buf);
     file = NULL;
  }
  else
#endif /* HANDLE_ROFFSEQ */

  if(system(cmdbuf) != 0) {	/* execute search. */
    snprintf(error_buf, sizeof(error_buf),
	    "Something went wrong trying to run the command: %s", cmdbuf);
    PopupWarning(man_globals, error_buf);
    file = NULL;
  }
  else {
#ifndef HAS_MKSTEMP
    if ((file = fopen(man_globals->tempfile,"r")) == NULL) {
      sprintf(error_buf, "Something went wrong in retrieving the %s",
	      "temp file, try cleaning up /tmp");
      PopupWarning(man_globals, error_buf);
    }
    else {
#endif

      XtPopdown( XtParent(man_globals->standby) );

      if ( (man_globals->save == NULL) ||
	   (man_globals->manpagewidgets.manpage == NULL) )
	unlink(man_globals->tempfile);
      else {
	char * ptr, catdir[BUFSIZ];

	/*
	 * If the catdir is writeable then ask the user if he/she wants to
	 * write the man page to it.
	 */

	strcpy(catdir, man_globals->save_file);
	if ( (ptr = rindex(catdir, '/')) != NULL) {
	  *ptr = '\0';

	  if ( access(catdir, W_OK) != 0 )
	    unlink(man_globals->tempfile);
	  else {
	    x = (Position) Width(man_globals->manpagewidgets.manpage)/2;
	    y = (Position) Height(man_globals->manpagewidgets.manpage)/2;
	    XtTranslateCoords(manpage, x, y, &x, &y);
	    PositionCenter( man_globals->save, (int) x, (int) y, 0, 0, 0, 0);
	    XtPopup( man_globals->save, XtGrabExclusive);
	  }
	}
	else
	  unlink(man_globals->tempfile);
      }
#ifndef HAS_MKSTEMP
    }
#endif
  }

 /*
  * If the original was compressed or in another format, delete temporary file.
  */
  if (man_globals->deletetempfile) 
    unlink(filename);

  return(file);
}

#ifdef HANDLE_ROFFSEQ
/*      Function Name: ConstructCommand
 *      Description: Constructs the pipeline of commands necessary to format
 *                   a manual page.
 *      Arguments: cmdbuf - the buffer into which to write the command
 *                 path - the directory in which the original man page resides
 *                 filename - the (uncompressed) manpage source file
 *                 tempfile - the name of a temporary file to direct the final
 *                  output of the pipeline into
 *      Returns: TRUE if the command fit into the buffer, FALSE if it would
 *               be too long (more than BUFSIZ characters)
 */
static Boolean
ConstructCommand(cmdbuf, path, filename, tempfile)
   char *cmdbuf, *path, *filename, *tempfile;
{
   /* The original code did the following to produce a command line:
    *   sprintf(cmdbuf,"cd %s ; %s %s %s > %s %s", path, TBL,
    *      filename, FORMAT, man_globals->tempfile, "2> /dev/null");
    * We are more flexible and follow more or less the algorithm used
    * by the Linux man command:
    *  + Obtain a string of letters from the following sources in order
    *    of preference:
    *    + a command line option (not implemented in xman; it's probably not
    *      useful)
    *    + the first line of the manpage source, if it is of the form:
    *      '\" <string>
    *    + the MANROFFSEQ environment variable
    *    + a default string; this is "".
    *  + Interpret the string as a pipeline of filters:
    *    + e = eqn   g = grap   p = pic   t = tbl   v = vgrind   r = refer
    *  + zsoelim is always run as the first preprocessor in any case.
    *
    * Strictly speaking we should save a catpage iff the string comes
    * from the file or is the default.
    *
    * You'll notice that we format a man page into ASCII text output and then
    * attempt to interpret things like L^HL as bold and so forth. This
    * is so obviously the Wrong Thing it's untrue.
    */
   char *c = cmdbuf;           /* current posn in buffer */
   int left = BUFSIZ;          /* space left in buffer */
   int used;
   char *fmt;
   FILE *file;
   char fmtbuf[128];
   int gotfmt = 0;             /* set to 1 if we got a directive from source */
   char *fname = NULL;
#ifdef __UNIXOS2__
   int i;
#endif

   fmt = NULL;
   /* If you have a command line option that gives a setting for fmt,
      set it here. */

   if (!fmt) {
      /* This is the tricky bit: extract a format string from the source file
       * Annoyingly, filename might be relative or absolute. We cheat and
       * use system to get the thing to a known absoute filename.
       */
      if (filename[0] == '/') {
         fname = filename;
      } else {
         fname = malloc(strlen(path) + 1 + strlen(filename) + 1);
         if (!fname)
            return FALSE;
         sprintf(fname, "%s/%s", path, filename);
      }
      if ((file = fopen(fname, "r")) &&
          (fgets(fmtbuf, sizeof(fmtbuf), file)) &&
          (!memcmp(fmtbuf, "'\\\" ", 4))) {
                              /* that's squote-backslash-dquote-space */
         int len;
         fmt = fmtbuf + 3;
         len = strlen(fmt);
         if (len && (fmt[len-1] == '\n')) {
            fmt[len-1] = 0;
            gotfmt++;
         }
      }
      if (fname && fname != filename)
         free(fname);
      if (!gotfmt)                                /* not there or some error */
      {
         fmt = getenv("MANROFFSEQ");
      }
   }

   if (!fmt)
   {
      fmt = DEFAULT_MANROFFSEQ;
   }


   /* Start with the first fixed part of the command line */
#ifdef __UNIXOS2__
   for (i = 0; i < strlen(path); i++) {
     if (path[i] == '/')
       path[i] = '\\';
   }
   used = snprintf(c, left, "cd %s & %s %s ", path, ZSOELIM, filename);
#else
   used = snprintf(c, left, "cd %s; %s %s ", path, ZSOELIM, filename);
#endif
   left -= used;
   c += used;
   if (left <= 1)
      return (FALSE);

   /* Now add preprocessors of the form '| processor' */
   for ( ; *fmt; fmt++)
   {
      char *filter;
      switch (*fmt)
      {
         case 'e':
            filter = EQN;
            break;
         case 'g':
            filter = GRAP;
            break;
         case 'p':
            filter = PIC;
            break;
         case 't':
            filter = TBL;
            break;
         case 'v':
            filter = VGRIND;
            break;
         case 'r':
            filter = REFER;
            break;
         default:
            filter = NULL;
            break;
      }
      if (filter)
      {
         used = snprintf(c, left, " | %s ", filter);
         left -= used;
         c += used;
         if (left <= 1)
            return (FALSE);
      }
   }

   /* Now add the fixed trailing part 'formatprog > tempfile 2> /dev/null' */
#ifdef __UNIXOS2__
   used = snprintf(c, left, " | %s > %s 2>NUL", FORMAT, tempfile);
#else
#ifndef HAS_MKSTEMP
   used = snprintf(c, left, " | %s > %s 2>/dev/null", FORMAT, tempfile);
#else
   used = snprintf(c, left, " | %s >> %s 2>/dev/null", FORMAT, tempfile);
#endif
#endif /* __UNIXOS2__ */
   left -= used;
   if (left <= 1)
      return (FALSE);

   return (TRUE);
}
#endif /* HANDLE_ROFFSEQ */

/*	Function Name: UncompressUnformatted
 *	Description: Finds an uncompressed unformatted manual page.
 *	Arguments: man_globals - the psuedo global structure.
 *                 entry - the manual page entry.
 * RETURNED        filename - location to put the name of the file.
 *	Returns: TRUE if the file was found.
 */

static Boolean
#ifndef HAS_MKSTEMP
UncompressUnformatted(ManpageGlobals * man_globals, char * entry,
		      char * filename)
#else
UncompressUnformatted(ManpageGlobals * man_globals, char * entry,
		      char * filename, FILE **file)
#endif
{
  char path[BUFSIZ], page[BUFSIZ], section[BUFSIZ], input[BUFSIZ];
  int len_cat = strlen(CAT), len_man = strlen(MAN);
#if defined(SMAN) && defined(SFORMAT)
  int len_sman = strlen(SMAN);
#endif

  ParseEntry(entry, path, section, page);

  man_globals->bzip2 = FALSE;
  man_globals->lzma = FALSE;

#if defined(__OpenBSD__) || defined(__NetBSD__)
  /*
   * look for uncompressed file in machine subdir first
   */
  snprintf(filename, BUFSIZ, "%s/%s%s/%s/%s", path, MAN,
	  section + len_cat, MACHINE, page);
  if ( access( filename, R_OK ) == 0 ) {
    man_globals->compress = FALSE;
    man_globals->gzip = FALSE;
    man_globals->deletetempfile = FALSE;
    snprintf(man_globals->save_file, sizeof(man_globals->save_file),
    	     "%s/%s%s/%s/%s", path, CAT, section + len_cat, MACHINE, page);
    return(TRUE);
  }
 /*
  * Then for compressed files in an uncompressed directory.
  */
  snprintf(input, sizeof(input), "%s.%s", filename, COMPRESSION_EXTENSION);
#ifndef HAS_MKSTEMP
  if ( UncompressNamed(man_globals, input, filename) ) {
#else
  if ( UncompressNamed(man_globals, input, filename, file) ) {
#endif
    man_globals->compress = TRUE;
    man_globals->deletetempfile = TRUE;
    snprintf(man_globals->save_file, sizeof(man_globals->save_file),
	     "%s/%s%s/%s.%s", path, CAT, section + len_cat, page, 
	     COMPRESSION_EXTENSION);
    return(TRUE);
  }
#ifdef GZIP_EXTENSION
  else {
    snprintf(input, sizeof(input), "%s.%s", filename, GZIP_EXTENSION);
#ifndef HAS_MKSTEMP
    if ( UncompressNamed(man_globals, input, filename) ) {
#else
    if ( UncompressNamed(man_globals, input, filename, file) ) {
#endif
      man_globals->compress = TRUE;
      man_globals->gzip = TRUE;
      man_globals->deletetempfile = TRUE;
      snprintf(man_globals->save_file, sizeof(man_globals->save_file),
	       "%s/%s%s/%s.%s", path, CAT, section + len_cat, page,
	       GZIP_EXTENSION);
      return(TRUE);
    }
  }
#endif /* GZIP_EXTENSION */
#endif /* __OpenBSD__ || __NetBSD__ */

#ifdef BZIP2_EXTENSION
 {
    sprintf(input, "%s.%s", filename, BZIP2_EXTENSION);
#ifndef HAS_MKSTEMP
    if ( UncompressNamed(man_globals, input, filename) ) {
#else
    if ( UncompressNamed(man_globals, input, filename, file) ) {
#endif
      man_globals->compress = TRUE;
      man_globals->gzip = FALSE;
      man_globals->bzip2 = TRUE;
      sprintf(man_globals->save_file, "%s/%s%s/%s.%s", path,
	      CAT, section + len_cat, page, BZIP2_EXTENSION);
      return(TRUE);
    }
  }
#endif /* BZIP2_EXTENSION */

#ifdef LZMA_EXTENSION
 {
    sprintf(input, "%s.%s", filename, LZMA_EXTENSION);
#ifndef HAS_MKSTEMP
    if ( UncompressNamed(man_globals, input, filename) ) {
#else
    if ( UncompressNamed(man_globals, input, filename, file) ) {
#endif
      man_globals->compress = TRUE;
      man_globals->gzip = FALSE;
      man_globals->lzma = TRUE;
      sprintf(man_globals->save_file, "%s/%s%s/%s.%s", path,
	      CAT, section + len_cat, page, LZMA_EXTENSION);
      return(TRUE);
    }
  }
#endif /* LZMA_EXTENSION */

/*
 * Look for uncompressed file first.
 */

  snprintf(filename, BUFSIZ, "%s/%s%s/%s", path, MAN, section + len_man, page);
  if ( access( filename, R_OK ) == 0 ) {
    man_globals->compress = FALSE;
    man_globals->gzip = FALSE;
    man_globals->deletetempfile = FALSE;
    snprintf(man_globals->save_file, sizeof(man_globals->save_file), 
	     "%s/%s%s/%s", path, CAT, section + len_cat, page);
    return(TRUE);
  }

#if defined(SMAN) && defined(SFORMAT)
 /*
  * Look for uncompressed sgml file next.
  */

  snprintf(input, BUFSIZ, "%s/%s%s/%s", path, SMAN, section + len_sman, page);
#ifndef HAS_MKSTEMP
  if ( SgmlToRoffNamed(man_globals, input, filename) ) {
#else
  if ( SgmlToRoffNamed(man_globals, input, filename, file) ) {
#endif
    man_globals->compress = FALSE;
    man_globals->gzip = FALSE;
    man_globals->deletetempfile = TRUE;
    snprintf(man_globals->save_file, sizeof(man_globals->save_file),
            "%s/%s%s/%s", path, CAT, section + len_cat, page);
    return(TRUE);
  }
#endif

/*
 * Then for compressed files in an uncompressed directory.
 */

  snprintf(input, sizeof(input), "%s.%s", filename, COMPRESSION_EXTENSION);
#ifndef HAS_MKSTEMP
  if ( UncompressNamed(man_globals, input, filename) ) {
#else
  if ( UncompressNamed(man_globals, input, filename, file) ) {
#endif
    man_globals->compress = TRUE;
    man_globals->deletetempfile = TRUE;
    snprintf(man_globals->save_file, sizeof(man_globals->save_file),
	     "%s/%s%s/%s.%s", path, CAT, section + len_cat, page, 
	     COMPRESSION_EXTENSION);
    return(TRUE);
  }
#ifdef GZIP_EXTENSION
  else {
    snprintf(input, sizeof(input), "%s.%s", filename, GZIP_EXTENSION);
#ifndef HAS_MKSTEMP
    if ( UncompressNamed(man_globals, input, filename) ) {
#else
    if ( UncompressNamed(man_globals, input, filename, file) ) {
#endif	
      man_globals->compress = TRUE;
      man_globals->gzip = TRUE;
      man_globals->deletetempfile = TRUE;
      snprintf(man_globals->save_file, sizeof(man_globals->save_file),
	       "%s/%s%s/%s.%s", path, CAT, section + len_cat, page, 
	       GZIP_EXTENSION);
      return(TRUE);
    }
  }
#endif

#ifdef BZIP2_EXTENSION
  {
    sprintf(input, "%s.%s", filename, BZIP2_EXTENSION);
#ifndef HAS_MKSTEMP
    if ( UncompressNamed(man_globals, input, filename) ) {
#else
    if ( UncompressNamed(man_globals, input, filename, file) ) {
#endif	
      man_globals->compress = TRUE;
      man_globals->gzip = TRUE;
      sprintf(man_globals->save_file, "%s/%s%s/%s.%s", path,
	      CAT, section + len_cat, page, BZIP2_EXTENSION);
      return(TRUE);
    }
  }
#endif

#ifdef LZMA_EXTENSION
  {
    sprintf(input, "%s.%s", filename, LZMA_EXTENSION);
#ifndef HAS_MKSTEMP
    if ( UncompressNamed(man_globals, input, filename) ) {
#else
    if ( UncompressNamed(man_globals, input, filename, file) ) {
#endif	
      man_globals->compress = TRUE;
      man_globals->lzma = TRUE;
      sprintf(man_globals->save_file, "%s/%s%s/%s.%s", path,
	      CAT, section + len_cat, page, LZMA_EXTENSION);
      return(TRUE);
    }
  }
#endif

/*
 * And lastly files in a compressed directory.
 */

  snprintf(input, sizeof(input), "%s/%s%s.%s/%s", path,
	  MAN, section + len_man, COMPRESSION_EXTENSION, page);
#ifndef HAS_MKSTEMP
  if ( UncompressNamed(man_globals, input, filename) ) {
#else
  if ( UncompressNamed(man_globals, input, filename, file) ) {
#endif
    man_globals->compress = TRUE;
    man_globals->deletetempfile = TRUE;
    snprintf(man_globals->save_file, sizeof(man_globals->save_file),
	     "%s/%s%s.%s/%s", path, CAT, section + len_cat, 
    	     COMPRESSION_EXTENSION, page);
    return(TRUE);
  }
  return(FALSE);
}

/*	Function Name: AddCursor
 *	Description: This function adds the cursor to the window.
 *	Arguments: w - the widget to add the cursor to.
 *                 cursor - the cursor to add to this widget.
 *	Returns: none
 */

void
AddCursor(Widget w, Cursor cursor)
{
  XColor colors[2];
  Arg args[10];
  Cardinal num_args = 0;
  Colormap c_map;

  if (!XtIsRealized(w)) {
    PopupWarning(NULL, "Widget is not realized, no cursor added.\n");
    return;
  }

  XtSetArg( args[num_args], XtNcolormap, &c_map); num_args++;
  XtGetValues( w, args, num_args);

  colors[0].pixel = resources.cursors.fg_color;
  colors[1].pixel = resources.cursors.bg_color;

  XQueryColors (XtDisplay(w), c_map, colors, 2);
  XRecolorCursor(XtDisplay(w), cursor, colors, colors+1);
  XDefineCursor(XtDisplay(w),XtWindow(w),cursor);
}

/*	Function Name: ChangeLabel
 *	Description: This function changes the label field of the
 *                   given widget to the string in str.
 *	Arguments: w - the widget.
 *                 str - the string to change the label to.
 *	Returns: none
 */

void
ChangeLabel(Widget w, char * str)
{
  Arg arglist[3];		/* An argument list. */

  if (w == NULL) return;

  XtSetArg(arglist[0], XtNlabel, str);

/* shouldn't really have to do this. */
  XtSetArg(arglist[1], XtNwidth, 0);
  XtSetArg(arglist[2], XtNheight, 0);

  XtSetValues(w, arglist, (Cardinal) 1);
}

/*
 * In an ideal world this would be part of the XToolkit, and I would not
 * have to do it, but such is life sometimes.  Perhaps in X11R3.
 */

/*	Function Name: PositionCenter
 *	Description: This function positions the given widgets center
 *                   in the following location.
 *	Arguments: widget - the widget widget to postion
 *                 x,y - The location for the center of the widget
 *                 above - number of pixels above center to locate this widget
 *                 left - number of pixels left of center to locate this widget
 *                 h_space, v_space - how close to get to the edges of the
 *                                    parent window.
 *	Returns: none
 *      Note:  This should only be used with a popup widget that has override
 *             redirect set.
 */

void
PositionCenter(Widget widget, int x, int y, int above, int left, int v_space, int h_space)
{
  Arg wargs[2];
  int x_temp,y_temp;		/* location of the new window. */
  int parent_height,parent_width; /* Height and width of the parent widget or
				   the root window if it has no parent. */

  x_temp = x - left - Width(widget) / 2 + BorderWidth(widget);
  y_temp = y - above -  Height(widget) / 2 + BorderWidth(widget);

  parent_height = HeightOfScreen(XtScreen(widget));
  parent_width = WidthOfScreen(XtScreen(widget));

/*
 * Check to make sure that all edges are within the viewable part of the
 * root window, and if not then force them to be.
 */

  if (x_temp < h_space)
    x_temp = v_space;
  if (y_temp < v_space)
    (y_temp = 2);

  if ( y_temp + Height(widget) + v_space > parent_height )
      y_temp = parent_height - Height(widget) - v_space;

  if ( x_temp + Width(widget) + h_space > parent_width )
      x_temp = parent_width - Width(widget) - h_space;

  XtSetArg(wargs[0], XtNx, x_temp);
  XtSetArg(wargs[1], XtNy, y_temp);
  XtSetValues(widget, wargs, 2);
}

/*	Function Name: ParseEntry(entry, path, sect, page)
 *	Description: Parses the manual pages entry filenames.
 *	Arguments: str - the full path name.
 *                 path - the path name.      RETURNED
 *                 sect - the section name.   RETURNED
 *                 page - the page name.      RETURNED
 *	Returns: none.
 */

void
ParseEntry(char *entry, char *path, char *sect, char *page)
{
  char *c, temp[BUFSIZ];

  strcpy(temp, entry);

  c = rindex(temp, '/');
  if (c == NULL)
    PrintError("index failure in ParseEntry.");
  *c++ = '\0';
  if (page != NULL)
    strcpy(page, c);

  c = rindex(temp, '/');
  if (c == NULL)
    PrintError("index failure in ParseEntry.");
  *c++ = '\0';
#if defined(SFORMAT) && defined(SMAN)
  /* sgmltoroff sometimes puts an extra ./ in the path to .so entries */
  if (strcmp(c, ".") == 0) {
      c = rindex(temp, '/');
      if (c == NULL)
	  PrintError("index failure in ParseEntry.");
      *c++ = '\0';
  }
#endif      
#if defined(__OpenBSD__) || defined(__NetBSD__)
  /* Skip machine subdirectory if present */
  if (strcmp(c, MACHINE) == 0) {
      c = rindex(temp, '/');
      if (c == NULL)
	  PrintError("index failure in ParseEntry.");
      *c++ = '\0';
  }
#endif
  if (sect != NULL)
    strcpy(sect, c);

  if (path != NULL)
    strcpy(path, temp);
}

/*      Function Name: GetGlobals
 *      Description: Gets the psuedo globals associated with the
 *                   manpage associated with this widget.
 *      Arguments: w - a widget in the manpage.
 *      Returns: the psuedo globals.
 *      Notes: initial_widget is a globals variable.
 *             manglobals_context is a global variable.
 */

ManpageGlobals *
GetGlobals(Widget w)
{
  Widget temp;
  caddr_t data;

  while ( (temp = XtParent(w)) != initial_widget && (temp != NULL))
    w = temp;

  if (temp == NULL)
    XtAppError(XtWidgetToApplicationContext(w),
	       "Xman: Could not locate widget in tree, exiting");

  if (XFindContext(XtDisplay(w), XtWindow(w),
		   manglobals_context, &data) != XCSUCCESS)
    XtAppError(XtWidgetToApplicationContext(w),
	       "Xman: Could not find global data, exiting");

  return( (ManpageGlobals *) data);
}

/*      Function Name: SaveGlobals
 *      Description: Saves the psuedo globals on the widget passed
 *                   to this function, although GetGlobals assumes that
 *                   the data is associated with the popup child of topBox.
 *      Arguments: w - the widget to associate the data with.
 *                 globals - data to associate with this widget.
 *      Returns: none.
 *      Notes: WIDGET MUST BE REALIZED.
 *             manglobals_context is a global variable.
 */

void
SaveGlobals(Widget w, ManpageGlobals * globals)
{
  if (XSaveContext(XtDisplay(w), XtWindow(w), manglobals_context,
		   (caddr_t) globals) != XCSUCCESS)
    XtAppError(XtWidgetToApplicationContext(w),
	       "Xman: Could not save global data, are you out of memory?");
}

/*      Function Name: RemoveGlobals
 *      Description: Removes the psuedo globals from the widget passed
 *                   to this function.
 *      Arguments: w - the widget to remove the data from.
 *      Returns: none.
 *      Notes: WIDGET MUST BE REALIZED.
 *             manglobals_context is a global variable.
 */

void
RemoveGlobals(Widget w)
{
  if (XDeleteContext(XtDisplay(w), XtWindow(w),
		     manglobals_context) != XCSUCCESS)
    XtAppError(XtWidgetToApplicationContext(w),
	       "Xman: Could not remove global data?");
}