Blame lib/Xm/XmTabList.c

Packit b099d7
/*
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
 */
Packit b099d7
/*
Packit b099d7
 * HISTORY
Packit b099d7
 */
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#ifdef REV_INFO
Packit b099d7
#ifndef lint
Packit b099d7
static char rcsid[] = "$TOG: XmTabList.c /main/9 1999/04/27 17:49:59 samborn $"
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
Packit b099d7
#ifndef X_NOT_STDC_ENV
Packit b099d7
#include <stdlib.h>
Packit b099d7
#endif
Packit b099d7
#include <string.h>
Packit b099d7
#include <ctype.h>
Packit b099d7
Packit b099d7
#include <Xm/XmosP.h>		/* For ALLOCATE/DEALLOCATE_LOCAL */
Packit b099d7
#include "MessagesI.h"
Packit b099d7
#include "ResIndI.h"
Packit b099d7
#include "XmI.h"
Packit b099d7
#include "XmRenderTI.h"
Packit b099d7
#include "XmStringI.h"
Packit b099d7
#include "XmTabListI.h"
Packit b099d7
Packit b099d7
/* Warning Messages */
Packit b099d7
#define NEGATIVE_VALUE_MSG		_XmMMsgXmTabList_0000
Packit b099d7
Packit b099d7
/********    Static Function Declarations    ********/
Packit b099d7
Packit b099d7
static XmTab GetNthTab(XmTabList tl,
Packit b099d7
		       int pos,
Packit b099d7
		       XmTab cur_tab,
Packit b099d7
		       int cur_pos); 
Packit b099d7
Packit b099d7
Packit b099d7
/********    End Static Function Declarations    ********/
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * This function returns the tab in tl at position pos.  It starts searching
Packit b099d7
 * either from the start of the tablist or from cur_tab if cur_pos is closer to 
Packit b099d7
 * pos than zero and cur_tab is not NULL.
Packit b099d7
 */
Packit b099d7
static XmTab
Packit b099d7
GetNthTab(XmTabList tl, int pos, XmTab cur_tab, int cur_pos)
Packit b099d7
{
Packit b099d7
  XmTab		prev_tab;
Packit b099d7
  unsigned int 	count;
Packit b099d7
  int		i;
Packit b099d7
  
Packit b099d7
  if (pos == 0) return(_XmTabLStart(tl));
Packit b099d7
  
Packit b099d7
  count = _XmTabLCount(tl);
Packit b099d7
  
Packit b099d7
  if (abs(pos) >= count)
Packit b099d7
  {
Packit b099d7
    if (pos > 0) return(_XmTabPrev(_XmTabLStart(tl)));
Packit b099d7
    else return(_XmTabLStart(tl));
Packit b099d7
 }
Packit b099d7
Packit b099d7
  /* Convert pos and cur_pos to positives less than count */
Packit b099d7
  if (pos < 0) pos += count;
Packit b099d7
  cur_pos %= count;
Packit b099d7
  if (cur_pos < 0) cur_pos += count;
Packit b099d7
    
Packit b099d7
  if (pos == cur_pos) return(cur_tab);
Packit b099d7
Packit b099d7
  /* Is start or cur_tab closer? */
Packit b099d7
  if ((cur_tab != NULL) &&
Packit b099d7
      ((pos > cur_pos/2) || (pos < (count + cur_pos)/2)))
Packit b099d7
    {
Packit b099d7
      prev_tab = cur_tab;
Packit b099d7
      i = pos - cur_pos;
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      prev_tab = _XmTabLStart(tl);
Packit b099d7
      i = (pos < count/2) ? pos : pos - count;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  switch (i/abs(i))
Packit b099d7
    {
Packit b099d7
    case 1:
Packit b099d7
      for (; i > 0; i--)
Packit b099d7
	prev_tab = _XmTabNext(prev_tab);
Packit b099d7
      break;
Packit b099d7
	  
Packit b099d7
    case -1:
Packit b099d7
      for (; i < 0; i++)
Packit b099d7
	prev_tab = _XmTabPrev(prev_tab);
Packit b099d7
      break;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  return(prev_tab);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * A tablist is a doubly linked ring of tabs. 
Packit b099d7
 */
Packit b099d7
XmTabList
Packit b099d7
XmTabListInsertTabs(XmTabList oldlist, 
Packit b099d7
		    XmTab *tabs,
Packit b099d7
		    Cardinal tab_count,
Packit b099d7
		    int position)
Packit b099d7
{
Packit b099d7
  XmTabList	tl;
Packit b099d7
  int		i;
Packit b099d7
  XmTab		prev_tab, tab, next_tab;
Packit b099d7
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if ((tabs == NULL) || (tab_count == 0)) {
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	return(oldlist);
Packit b099d7
  }
Packit b099d7
Packit b099d7
  if (oldlist == NULL)
Packit b099d7
    {
Packit b099d7
      tl = (XmTabList)XtMalloc(sizeof(_XmTabListRec));
Packit b099d7
  
Packit b099d7
      _XmTabLCount(tl) = tab_count;
Packit b099d7
      
Packit b099d7
      prev_tab = _XmTabCopy(tabs[0]);
Packit b099d7
Packit b099d7
      _XmTabLStart(tl) = prev_tab;
Packit b099d7
Packit b099d7
      for (i = 1; i < tab_count; i++)
Packit b099d7
	{
Packit b099d7
	  tab = _XmTabCopy(tabs[i]);
Packit b099d7
	  
Packit b099d7
	  _XmTabPrev(tab) = prev_tab;
Packit b099d7
	  _XmTabNext(prev_tab) = tab;
Packit b099d7
	  prev_tab = tab;
Packit b099d7
	}
Packit b099d7
      
Packit b099d7
      _XmTabNext(prev_tab) = _XmTabLStart(tl);
Packit b099d7
      _XmTabPrev(_XmTabLStart(tl)) = prev_tab;
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      tl = XmTabListCopy(oldlist, 0, 0);
Packit b099d7
      
Packit b099d7
      /* Hook in first tab */
Packit b099d7
      tab = _XmTabCopy(tabs[0]);
Packit b099d7
Packit b099d7
      prev_tab = GetNthTab(tl, position, NULL, 0);
Packit b099d7
      
Packit b099d7
      if (position == 0) _XmTabLStart(tl) = tab;
Packit b099d7
Packit b099d7
      next_tab = _XmTabNext(prev_tab);
Packit b099d7
      
Packit b099d7
      _XmTabNext(prev_tab) = tab;
Packit b099d7
      _XmTabPrev(tab) = prev_tab;
Packit b099d7
      prev_tab = tab;
Packit b099d7
Packit b099d7
      /* Hook in rest of tabs. */
Packit b099d7
      for (i = 1; i < tab_count; i++)
Packit b099d7
	{
Packit b099d7
	  tab = _XmTabCopy(tabs[i]);
Packit b099d7
	  _XmTabNext(prev_tab) = tab;
Packit b099d7
	  _XmTabPrev(tab) = prev_tab;
Packit b099d7
	  prev_tab = tab;
Packit b099d7
	}	  
Packit b099d7
      
Packit b099d7
      /* Complete circle */
Packit b099d7
      _XmTabNext(prev_tab) = next_tab;
Packit b099d7
      _XmTabPrev(next_tab) = prev_tab;
Packit b099d7
Packit b099d7
      _XmTabLCount(tl) += tab_count;
Packit b099d7
Packit b099d7
      XmTabListFree( oldlist );
Packit b099d7
    }
Packit b099d7
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  return(tl);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
Widget
Packit b099d7
_XmCreateTabList(Widget parent,
Packit b099d7
		 String name,	/* unused */
Packit b099d7
		 ArgList arglist, /* unused */
Packit b099d7
		 Cardinal argcount) /* unused */
Packit b099d7
{
Packit b099d7
  XmRendition	rend = (XmRendition)parent;
Packit b099d7
  XmTabList	tl = NULL;
Packit b099d7
  
Packit b099d7
  if (_XmRendTabs(rend) == NULL) 
Packit b099d7
    {
Packit b099d7
      tl = (XmTabList)XtMalloc(sizeof(_XmTabListRec));
Packit b099d7
      bzero((char *)tl, sizeof(_XmTabListRec));
Packit b099d7
      _XmRendTabs(rend) = tl;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  return((Widget)tl);
Packit b099d7
}
Packit b099d7
Packit b099d7
/* 
Packit b099d7
 * This copying routine also works with the internal marking scheming used
Packit b099d7
 * by the insert and replace routines. 
Packit b099d7
 */
Packit b099d7
XmTabList
Packit b099d7
XmTabListCopy(XmTabList tablist,
Packit b099d7
	      int offset,
Packit b099d7
	      Cardinal count)
Packit b099d7
{
Packit b099d7
  XmTabList	tl;
Packit b099d7
  XmTab		old_tab, tab, next_tab;
Packit b099d7
  unsigned int	i;
Packit b099d7
  
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (tablist == NULL) {
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	return(NULL);
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  tl = (XmTabList)XtMalloc(sizeof(_XmTabListRec));
Packit b099d7
  
Packit b099d7
  /* Zero count implies copy from offset to end/beginning */
Packit b099d7
  if (count == 0) count = (_XmTabLCount(tablist) - abs(offset));
Packit b099d7
Packit b099d7
  if (count > _XmTabLCount(tablist)) count = _XmTabLCount(tablist);
Packit b099d7
  
Packit b099d7
  old_tab = GetNthTab(tablist, offset, NULL, 0);
Packit b099d7
Packit b099d7
  /* If marked, routine called by insert/replace. Don't copy. */
Packit b099d7
  tab = _XmTabMark(old_tab) ? old_tab : _XmTabCopy(old_tab);
Packit b099d7
  
Packit b099d7
  /* Add first. */
Packit b099d7
  _XmTabLCount(tl) = count;
Packit b099d7
  _XmTabLStart(tl) = tab;
Packit b099d7
Packit b099d7
  /* Add rest. */
Packit b099d7
  for (i = 1; i < count; i++)
Packit b099d7
    {
Packit b099d7
      old_tab = (offset >= 0) ? _XmTabNext(old_tab) : _XmTabPrev(old_tab);
Packit b099d7
      /* See above.  Don't copy if marked. */
Packit b099d7
      next_tab = _XmTabMark(old_tab)? old_tab : _XmTabCopy(old_tab);
Packit b099d7
  
Packit b099d7
      _XmTabNext(tab) = next_tab;
Packit b099d7
	
Packit b099d7
      _XmTabPrev(next_tab) = tab;
Packit b099d7
	
Packit b099d7
      tab = next_tab;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  /* Complete circle. */
Packit b099d7
  _XmTabNext(tab) = _XmTabLStart(tl);
Packit b099d7
  _XmTabPrev(_XmTabLStart(tl)) = tab;
Packit b099d7
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  return(tl);
Packit b099d7
}
Packit b099d7
Packit b099d7
/* 
Packit b099d7
 * Marked tabs have mark cleared but aren't actually freed.
Packit b099d7
 */
Packit b099d7
void
Packit b099d7
XmTabListFree(XmTabList tablist)
Packit b099d7
{
Packit b099d7
  int	i;
Packit b099d7
  XmTab	tab, next;
Packit b099d7
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (tablist == NULL) {
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	return;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  tab = _XmTabLStart(tablist);
Packit b099d7
  
Packit b099d7
  for (i = 1; i < _XmTabLCount(tablist); i++)
Packit b099d7
    {
Packit b099d7
      next = _XmTabNext(tab);
Packit b099d7
      
Packit b099d7
      if (_XmTabMark(tab)) _XmTabMark(tab) = FALSE;
Packit b099d7
      else XmTabFree(tab);
Packit b099d7
Packit b099d7
      tab = next;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  if (_XmTabMark(tab)) _XmTabMark(tab) = FALSE;
Packit b099d7
  else XmTabFree(tab);
Packit b099d7
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  XtFree((char *)tablist);
Packit b099d7
}
Packit b099d7
Packit b099d7
Cardinal
Packit b099d7
XmTabListTabCount(XmTabList tablist)
Packit b099d7
{
Packit b099d7
  Cardinal ret_val;
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (tablist == NULL) {
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	return 0;
Packit b099d7
  }
Packit b099d7
Packit b099d7
  ret_val = _XmTabLCount(tablist);
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  return ret_val;
Packit b099d7
}
Packit b099d7
Packit b099d7
XmTab
Packit b099d7
XmTabListGetTab(XmTabList tablist,
Packit b099d7
		Cardinal position)
Packit b099d7
{
Packit b099d7
   XmTab ret_val;
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (tablist == NULL || abs(position) >= _XmTabLCount(tablist)) {
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	return((XmTab)NULL);
Packit b099d7
  }
Packit b099d7
Packit b099d7
  ret_val = _XmTabCopy(GetNthTab(tablist, position, NULL, 0));
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  return ret_val;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * This routine uses the mark bit of tabs so that replaced tabs can
Packit b099d7
 * be copied upon replacement and not copied when the rest of the tabs
Packit b099d7
 * are copied or freed when the old tabs are freed.
Packit b099d7
 */
Packit b099d7
XmTabList
Packit b099d7
XmTabListReplacePositions(XmTabList oldlist,
Packit b099d7
			  Cardinal *position_list,
Packit b099d7
			  XmTab *tabs,
Packit b099d7
			  Cardinal tab_count)
Packit b099d7
{
Packit b099d7
  unsigned int	i;
Packit b099d7
  unsigned int	cur_pos;
Packit b099d7
  XmTab		cur_tab, tab, prev, next;
Packit b099d7
  XmTabList	tl;
Packit b099d7
  
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if ((oldlist == NULL) ||
Packit b099d7
      (position_list == NULL) ||
Packit b099d7
      (tabs == NULL) || (tab_count == 0)) {
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    return(oldlist);
Packit b099d7
  }
Packit b099d7
Packit b099d7
  tl = (XmTabList)XtMalloc(sizeof(_XmTabListRec));
Packit b099d7
  _XmTabLCount(tl) = _XmTabLCount(oldlist);
Packit b099d7
  cur_tab = _XmTabLStart(tl) = _XmTabLStart(oldlist);
Packit b099d7
  cur_pos = 0;
Packit b099d7
Packit b099d7
  /* Make the replacement in the old list, then copy and free. */
Packit b099d7
  for (i = 0; i < tab_count; i++)
Packit b099d7
    {
Packit b099d7
      cur_tab = GetNthTab(tl, position_list[i],
Packit b099d7
			  cur_tab, cur_pos);
Packit b099d7
      cur_pos = position_list[i];
Packit b099d7
      
Packit b099d7
      prev = _XmTabPrev(cur_tab);
Packit b099d7
      next = _XmTabNext(cur_tab);
Packit b099d7
      
Packit b099d7
      /* replace tab copying */
Packit b099d7
      tab = _XmTabCopy(tabs[i]);
Packit b099d7
      
Packit b099d7
      if (prev == cur_tab) { /* only one tab in list */
Packit b099d7
	_XmTabPrev(tab) = _XmTabNext(tab) = tab;
Packit b099d7
      } else {
Packit b099d7
	_XmTabNext(prev) = tab;
Packit b099d7
	_XmTabPrev(tab) = prev;
Packit b099d7
	_XmTabNext(tab) = next;
Packit b099d7
	_XmTabPrev(next) = tab;
Packit b099d7
      }
Packit b099d7
      if (cur_tab == _XmTabLStart(tl))
Packit b099d7
	_XmTabLStart(tl) = tab;
Packit b099d7
Packit b099d7
      XmTabFree(cur_tab);
Packit b099d7
      cur_tab = tab;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  XtFree((char *)oldlist);
Packit b099d7
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  return(tl);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * This routine uses a mark/sweep algorithm.
Packit b099d7
 * A pass over position_list is made to mark tabs for removal without
Packit b099d7
 * disturbing their positions.
Packit b099d7
 * Then a pass is made over the oldlist removing marked tabs.
Packit b099d7
 * A final pass is made to copy the remaining tabs.
Packit b099d7
 */
Packit b099d7
XmTabList
Packit b099d7
XmTabListRemoveTabs(XmTabList oldlist,
Packit b099d7
		    Cardinal *position_list,
Packit b099d7
		    Cardinal position_count)
Packit b099d7
{
Packit b099d7
  XmTab		cur_tab, tab, prev, next;
Packit b099d7
  int		cur_pos, i;
Packit b099d7
  XmTabList	tl;
Packit b099d7
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if ((oldlist == NULL) ||
Packit b099d7
      (position_list == NULL) ||
Packit b099d7
      (position_count == 0)) {
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    return(oldlist);
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  cur_tab = _XmTabLStart(oldlist);
Packit b099d7
  cur_pos = 0;
Packit b099d7
Packit b099d7
  /* Get position, set mark */
Packit b099d7
  for (i = 0; i < position_count; i++)
Packit b099d7
    {
Packit b099d7
      cur_tab = GetNthTab(oldlist, position_list[i],
Packit b099d7
			  cur_tab, cur_pos);
Packit b099d7
      cur_pos = position_list[i];
Packit b099d7
      _XmTabMark(cur_tab) = TRUE;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  /* Free marked tabs */
Packit b099d7
  for (tab = _XmTabNext(_XmTabLStart(oldlist));
Packit b099d7
       tab != _XmTabLStart(oldlist);
Packit b099d7
       tab = next)
Packit b099d7
    {
Packit b099d7
      if (_XmTabMark(tab))
Packit b099d7
	{
Packit b099d7
	  prev = _XmTabPrev(tab);
Packit b099d7
	  next = _XmTabNext(tab);
Packit b099d7
	  
Packit b099d7
	  _XmTabNext(prev) = next;
Packit b099d7
	  _XmTabPrev(next) = prev;
Packit b099d7
Packit b099d7
	  XmTabFree(tab);
Packit b099d7
	  _XmTabLCount(oldlist) --;
Packit b099d7
	}
Packit b099d7
      else
Packit b099d7
	  next = _XmTabNext(tab);
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  /* tab is now at start. */
Packit b099d7
  if (_XmTabMark(tab))
Packit b099d7
    {
Packit b099d7
      if (tab == _XmTabNext(tab))
Packit b099d7
	/* We've deleted all the tabs. */
Packit b099d7
	{
Packit b099d7
	  _XmTabLCount(oldlist) = 1;
Packit b099d7
	  _XmTabMark(tab) = FALSE;
Packit b099d7
	  XmTabListFree(oldlist);
Packit b099d7
	  _XmProcessUnlock();
Packit b099d7
	  return((XmTabList)NULL);
Packit b099d7
	}
Packit b099d7
      
Packit b099d7
      _XmTabLStart(oldlist) = _XmTabNext(tab);
Packit b099d7
Packit b099d7
      prev = _XmTabPrev(tab);
Packit b099d7
      next = _XmTabNext(tab);
Packit b099d7
      
Packit b099d7
      _XmTabNext(prev) = next;
Packit b099d7
      _XmTabPrev(next) = prev;
Packit b099d7
      
Packit b099d7
      XmTabFree(tab);
Packit b099d7
      _XmTabLCount(oldlist) --;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  tl = XmTabListCopy(oldlist, 0, 0);
Packit b099d7
  XmTabListFree(oldlist);
Packit b099d7
  
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  return(tl);
Packit b099d7
}
Packit b099d7
Packit b099d7
XmTab
Packit b099d7
XmTabCreate(float value,
Packit b099d7
	    unsigned char units,
Packit b099d7
	    XmOffsetModel offset_model,
Packit b099d7
	    unsigned char alignment,
Packit b099d7
	    char *decimal)
Packit b099d7
{
Packit b099d7
  XmTab 	tab;
Packit b099d7
Packit b099d7
  _XmProcessLock();
Packit b099d7
  tab = (XmTab)XtMalloc(sizeof(_XmTabRec));
Packit b099d7
  
Packit b099d7
  _XmTabMark(tab) = FALSE;
Packit b099d7
  if (value >= 0) 
Packit b099d7
    {
Packit b099d7
      _XmTabValue(tab) = value;
Packit b099d7
    }
Packit b099d7
  else 
Packit b099d7
    {
Packit b099d7
      _XmTabValue(tab) = 0.0;
Packit b099d7
      XmeWarning(NULL, NEGATIVE_VALUE_MSG);
Packit b099d7
    }
Packit b099d7
  _XmTabUnits(tab) = units;
Packit b099d7
  _XmTabModel(tab) = offset_model;
Packit b099d7
  _XmTabAlign(tab) = alignment;
Packit b099d7
  _XmTabDecimal(tab) = XtNewString(decimal);
Packit b099d7
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  return(tab);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
Widget
Packit b099d7
_XmCreateTab(Widget parent,
Packit b099d7
	     String name,	/* unused */
Packit b099d7
	     ArgList arglist,
Packit b099d7
	     Cardinal argcount)
Packit b099d7
{
Packit b099d7
  static XrmQuark quarks[] = {0, 0, 0, 0, 0};
Packit b099d7
Packit b099d7
  XmTabList	tl = (XmTabList)parent;
Packit b099d7
  XrmQuark	qarg;
Packit b099d7
  float	        value = 0.0;
Packit b099d7
  unsigned char	units = XmPIXELS;
Packit b099d7
  XmOffsetModel	model = XmABSOLUTE;
Packit b099d7
  unsigned char	alignment = XmALIGNMENT_BEGINNING;
Packit b099d7
  char 		*decimal = ".";
Packit b099d7
  XmTab		tab, start;
Packit b099d7
  int		i;
Packit b099d7
  
Packit b099d7
  /* Init quark list */
Packit b099d7
  if (quarks[0] == 0)
Packit b099d7
    {
Packit b099d7
      quarks[0] = XrmPermStringToQuark(XmNtabValue);
Packit b099d7
      quarks[1] = XrmPermStringToQuark(XmNunitType);
Packit b099d7
      quarks[2] = XrmPermStringToQuark(XmNoffsetModel);
Packit b099d7
      quarks[3] = XrmPermStringToQuark(XmNalignment);
Packit b099d7
      quarks[4] = XrmPermStringToQuark(XmNdecimal);
Packit b099d7
    }
Packit b099d7
Packit b099d7
  /* Get arguments from arglist */
Packit b099d7
  for (i = 0; i < argcount; i++)
Packit b099d7
    {
Packit b099d7
      qarg = XrmStringToQuark(arglist[i].name);
Packit b099d7
      
Packit b099d7
      if (qarg == quarks[0])
Packit b099d7
	value = (float)arglist[i].value;
Packit b099d7
      else if (qarg == quarks[1])
Packit b099d7
	units = (unsigned char)arglist[i].value;
Packit b099d7
      else if (qarg == quarks[2])
Packit b099d7
	model = (XmOffsetModel)arglist[i].value;
Packit b099d7
      else if (qarg == quarks[3])
Packit b099d7
	alignment = (unsigned char)arglist[i].value;
Packit b099d7
      else if (qarg == quarks[4])
Packit b099d7
	decimal = (char *)arglist[i].value;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  tab = XmTabCreate(value, units, model, alignment, decimal);
Packit b099d7
  
Packit b099d7
  if (_XmTabLCount(tl) == 0)
Packit b099d7
    {
Packit b099d7
      _XmTabLStart(tl) = tab;
Packit b099d7
      _XmTabPrev(tab) = tab;
Packit b099d7
      _XmTabNext(tab) = tab;
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      start = _XmTabLStart(tl);
Packit b099d7
      _XmTabNext(tab) = start;
Packit b099d7
      _XmTabPrev(tab) = _XmTabPrev(start);
Packit b099d7
      _XmTabNext(_XmTabPrev(start)) = tab;
Packit b099d7
      _XmTabPrev(start) = tab;
Packit b099d7
    }  
Packit b099d7
Packit b099d7
  _XmTabLCount(tl)++;
Packit b099d7
Packit b099d7
  return((Widget)NULL);
Packit b099d7
}
Packit b099d7
Packit b099d7
void
Packit b099d7
XmTabFree(XmTab tab)
Packit b099d7
{
Packit b099d7
  if (tab == NULL) return;
Packit b099d7
  
Packit b099d7
  XtFree(_XmTabDecimal(tab));
Packit b099d7
  XtFree((char *)tab);
Packit b099d7
}
Packit b099d7
Packit b099d7
float
Packit b099d7
XmTabGetValues(XmTab tab,
Packit b099d7
	       unsigned char *units,
Packit b099d7
	       XmOffsetModel *offset,
Packit b099d7
	       unsigned char *alignment,
Packit b099d7
	       char **decimal)
Packit b099d7
{
Packit b099d7
  float ret_val;
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (units != NULL) *units = _XmTabUnits(tab);
Packit b099d7
  if (offset != NULL) *offset = _XmTabModel(tab);
Packit b099d7
  if (alignment != NULL) *alignment = _XmTabAlign(tab);
Packit b099d7
  if (decimal != NULL) *decimal = _XmTabDecimal(tab);
Packit b099d7
  
Packit b099d7
  ret_val = _XmTabValue(tab);
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  return ret_val;
Packit b099d7
}
Packit b099d7
Packit b099d7
void
Packit b099d7
XmTabSetValue(XmTab tab,
Packit b099d7
	      float value)
Packit b099d7
{
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (value >= 0) _XmTabValue(tab) = value;
Packit b099d7
  else XmeWarning(NULL, NEGATIVE_VALUE_MSG);
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
}
Packit b099d7
Packit b099d7
XmTab
Packit b099d7
_XmTabCopy(XmTab tab)
Packit b099d7
{
Packit b099d7
  XmTab	new_tab;
Packit b099d7
  
Packit b099d7
  new_tab = (XmTab)XtMalloc(sizeof(_XmTabRec));
Packit b099d7
  
Packit b099d7
  memcpy((char *)new_tab, (char *)tab, sizeof(_XmTabRec));
Packit b099d7
  
Packit b099d7
  _XmTabMark(new_tab) = FALSE;
Packit b099d7
  _XmTabDecimal(new_tab) = XtNewString(_XmTabDecimal(tab));
Packit b099d7
  
Packit b099d7
  return(new_tab);
Packit b099d7
}
Packit b099d7
Packit b099d7
/***********
Packit b099d7
 * _XmTabListGetPosition 
Packit b099d7
 * returns the x pixel coordinate of the specified tab.
Packit b099d7
 **********/
Packit b099d7
Position
Packit b099d7
_XmTabListGetPosition(
Packit b099d7
	Screen * screen,
Packit b099d7
        XmTabList tab_list,
Packit b099d7
        unsigned char unit_type,
Packit b099d7
        Cardinal tab_position)
Packit b099d7
{
Packit b099d7
    XmTab tab ;
Packit b099d7
    Position xpos = 0 ;
Packit b099d7
    unsigned char units; 
Packit b099d7
    XmOffsetModel offset; 
Packit b099d7
Packit b099d7
    tab = XmTabListGetTab(tab_list, tab_position);
Packit b099d7
Packit b099d7
    if (tab) {
Packit b099d7
	xpos = (Position) XmTabGetValues(tab, 
Packit b099d7
					 &units, 
Packit b099d7
					 &offset, 
Packit b099d7
					 NULL, 
Packit b099d7
					 NULL);
Packit b099d7
	xpos = _XmConvertUnits(screen, XmHORIZONTAL, units, xpos, unit_type);
Packit b099d7
	/* a little bit of recursivity here */
Packit b099d7
	if ((offset == XmRELATIVE) && tab_position){
Packit b099d7
	    xpos += _XmTabListGetPosition(screen, tab_list, unit_type,
Packit b099d7
					  tab_position-1);
Packit b099d7
	}
Packit b099d7
	XmTabFree(tab) ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return xpos ;
Packit b099d7
}
Packit b099d7
Packit b099d7
#ifdef _XmDEBUG_XMTABLIST
Packit b099d7
Packit b099d7
static char *
Packit b099d7
units_image(XtEnum units)
Packit b099d7
{
Packit b099d7
  static char buf[100];
Packit b099d7
Packit b099d7
  switch (units)
Packit b099d7
    {
Packit b099d7
    case XmPIXELS:
Packit b099d7
      return "px";
Packit b099d7
    case Xm100TH_MILLIMETERS:
Packit b099d7
      return "100mm";
Packit b099d7
    case Xm1000TH_INCHES:
Packit b099d7
      return "1000in";
Packit b099d7
    case Xm100TH_POINTS:
Packit b099d7
      return "100pt";
Packit b099d7
    case Xm100TH_FONT_UNITS:
Packit b099d7
      return "100fu";
Packit b099d7
    case XmINCHES:
Packit b099d7
      return "in";
Packit b099d7
    case XmCENTIMETERS:
Packit b099d7
      return "cm";
Packit b099d7
    case XmMILLIMETERS:
Packit b099d7
      return "mm";
Packit b099d7
    case XmPOINTS:
Packit b099d7
      return "pt";
Packit b099d7
    case XmFONT_UNITS:
Packit b099d7
      return "fu";
Packit b099d7
    default:
Packit b099d7
      sprintf(buf, "<Unknown units %d>", units);
Packit b099d7
      return buf;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
static char *
Packit b099d7
model_image(XmOffsetModel model)
Packit b099d7
{
Packit b099d7
  static char buf[100];
Packit b099d7
Packit b099d7
  switch (model)
Packit b099d7
    {
Packit b099d7
    case XmABSOLUTE:
Packit b099d7
      return "abs.";
Packit b099d7
    case XmRELATIVE:
Packit b099d7
      return "rel.";
Packit b099d7
    default:
Packit b099d7
      sprintf(buf, "<Unknown model %d>", model);
Packit b099d7
      return buf;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
static char *
Packit b099d7
alignment_image(XtEnum alignment)
Packit b099d7
{
Packit b099d7
  static char buf[100];
Packit b099d7
Packit b099d7
  switch (alignment)
Packit b099d7
    {
Packit b099d7
    case XmALIGNMENT_BEGINNING:
Packit b099d7
      return "beginning";
Packit b099d7
    case XmALIGNMENT_CENTER:
Packit b099d7
      return "center";
Packit b099d7
    case XmALIGNMENT_END:
Packit b099d7
      return "end";
Packit b099d7
    default:
Packit b099d7
      sprintf(buf, "<Unknown alignment %d>", alignment);
Packit b099d7
      return buf;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
void 
Packit b099d7
_Xm_dump_tab(XmTab tab)
Packit b099d7
{
Packit b099d7
  unsigned int mark = _XmTabMark(tab);
Packit b099d7
  /* unsigned int ref_count = ((_XmTab)tab)->ref_count; */
Packit b099d7
  float value = _XmTabValue(tab);
Packit b099d7
  unsigned char units = _XmTabUnits(tab);
Packit b099d7
  XmOffsetModel model = _XmTabModel(tab);
Packit b099d7
  unsigned char alignment = _XmTabAlign(tab);
Packit b099d7
  char *decimal = _XmTabDecimal(tab);
Packit b099d7
  XmTab next = _XmTabNext(tab);
Packit b099d7
  XmTab prev = _XmTabPrev(tab);
Packit b099d7
Packit b099d7
  printf ("%p: %f %s, %s from %s '%s', %p %p, %d\n",
Packit b099d7
	  tab, value, units_image(units), 
Packit b099d7
	  model_image(model), alignment_image(alignment), 
Packit b099d7
	  decimal, next, prev, mark);
Packit b099d7
}
Packit b099d7
Packit b099d7
void
Packit b099d7
_Xm_dump_tablist(XmTabList list)
Packit b099d7
{
Packit b099d7
  int i;
Packit b099d7
  int count = _XmTabLCount(list);
Packit b099d7
  XmTab tab = _XmTabLStart(list);
Packit b099d7
Packit b099d7
  printf("(XmTabList)%p: count %d, start %p.\n", list, count, tab);
Packit b099d7
  for (i = 0; i < count; i++)
Packit b099d7
    {
Packit b099d7
      printf ("  #%d> ", i);
Packit b099d7
      _Xm_dump_tab(tab);
Packit b099d7
      tab = _XmTabNext(tab);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
#endif /* _XmDEBUG_XMTABLIST */