/* * Motif * * Copyright (c) 1987-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these librararies and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA * */ #include #include #include typedef struct _XmTabbedStackListRec { int allocated; int used; XmTabAttributes tabs; } XmTabbedStackListRec; #define XmLIST_GROWTH_FACTOR 10 #define XiXmStringCopy(s) (((s) == (XmString)NULL) ? NULL : XmStringCopy(s)) #define XiXmStringCompare(s1,s2) (((s1) == (s2)) ? True \ : ((s1) != NULL && (s2) != NULL) \ ? XmStringCompare(s1,s2) : False) #define XiXmStringFree(s) if((s)!=(XmString)NULL)XmStringFree(s);else(s)=NULL /* * Function: * TabListCreate(void) * Description: * Allocates and initializes an empty XmTabbedStackList structure and returns * a pointer to the structure. * Input: * None. * Output: * XmTabbedStackList - an empty allocated XiTablist */ XmTabbedStackList #ifndef _NO_PROTO XmTabbedStackListCreate(void) #else XmTabbedStackListCreate() #endif { XmTabbedStackList tabList; /* * Allocate the structure and zero it. Then give it back to the * caller. */ tabList = (XmTabbedStackList) XtMalloc(sizeof(XmTabbedStackListRec)); tabList->allocated = tabList->used = 0; tabList->tabs = (XmTabAttributes) NULL; return( tabList ); } /* * Function: * XmTabbedStackListCopy(tab_list) * Description: * This makes a copy of the given XmTabbedStackList and returns the * copy. * Input: * tab_list : XmTabbedStackList - the XmTabbedStackList to copy * Output: * XmTabbedStackList - the copy of the given list */ XmTabbedStackList #ifndef _NO_PROTO XmTabbedStackListCopy(XmTabbedStackList tab_list) #else XmTabbedStackListCopy(tab_list) XmTabbedStackList tab_list; #endif { XmTabbedStackList newList; int i; /* * First if they gave us nothing, then lets return nothing to * them. */ if( tab_list == NULL ) return( NULL ); /* * Now allocate the new structure and set its allocated and used * to the number of items we need. */ newList = (XmTabbedStackList) XtMalloc(sizeof(XmTabbedStackListRec)); newList->allocated = newList->used = tab_list->used; /* * Now check if we have any items and if not just zero the * data, else we will have to copy item by item. */ if( newList->used == 0 ) { newList->tabs = (XmTabAttributes) NULL; } else { /* * First allocate the memory for all the entries. and then copy * item by item the list. */ newList->tabs = (XmTabAttributes) XtMalloc(sizeof(XmTabAttributeRec) * newList->used); for( i = 0; i < newList->used; ++i ) { newList->tabs[i].label_string = XiXmStringCopy(tab_list->tabs[i].label_string); newList->tabs[i].label_pixmap = tab_list->tabs[i].label_pixmap; newList->tabs[i].string_direction = tab_list->tabs[i].string_direction; newList->tabs[i].pixmap_placement = tab_list->tabs[i].pixmap_placement; newList->tabs[i].label_alignment = tab_list->tabs[i].label_alignment; newList->tabs[i].foreground = tab_list->tabs[i].foreground; newList->tabs[i].background = tab_list->tabs[i].background; newList->tabs[i].background_pixmap = tab_list->tabs[i].background_pixmap; newList->tabs[i].sensitive = tab_list->tabs[i].sensitive; newList->tabs[i].value_mode = XmTAB_VALUE_COPY; } } return( newList ); } /* * Function: * XmTabbedStackListFree(tab_list) * Description: * Deallocates the memory associated with the given tab list. * Input: * tab_list : XiTablist - the XmTabbedStackList to deallocate * Output: * None. */ void #ifndef _NO_PROTO XmTabbedStackListFree(XmTabbedStackList tab_list) #else XmTabbedStackListFree(tab_list) XmTabbedStackList tab_list; #endif { int i; /* * If we do not have anything to deallocate the lets just * get out of here. */ if( tab_list == NULL ) return; /* * If we have used items then lets walk through the list and * deallocate anything we have to. */ if( tab_list->used != 0 ) { for( i = 0; i < tab_list->used; ++i ) { if( tab_list->tabs[i].value_mode == XmTAB_VALUE_SHARE ) continue; XiXmStringFree(tab_list->tabs[i].label_string); } } /* * If we have any allocated slots lets deallocate them and finally * deallocate the parent structure. */ if( tab_list->allocated != 0 ) { XtFree((XtPointer) tab_list->tabs); } XtFree((XtPointer) tab_list); } /* * Function: * XmTabbedStackListRemove(tab_list, position) * Description: * Remove and deallocate the tab at the specified position in * the list. * Input: * tab_list : XmTabbedStackList - the XmTabbedStackList to work with * position : int - the position of the tab to remove * Output: * None. */ void #ifndef _NO_PROTO XmTabbedStackListRemove(XmTabbedStackList tab_list, int position) #else XmTabbedStackListRemove(tab_list, position) XmTabbedStackList tab_list; int position; #endif { XmTabAttributes to, from; int count; if( tab_list == NULL || position < 0 || (position > 0 && position >= tab_list->used) ) { return; } to = &(tab_list->tabs[position]); /* * Now deallocate the data associated with this tab, if needed. */ if( to->value_mode == XmTAB_VALUE_COPY ) { XmStringFree(to->label_string); } /* * Now decrement the number of used slots and shift down any slots * above the one that is being deleted. */ tab_list->used--; if( position != tab_list->used ) { from = &(tab_list->tabs[position+1]); count = tab_list->used - position; memmove((XtPointer) to, (XtPointer) from, sizeof(XmTabAttributeRec) * count); } } /* * Function: * XmTabbedStackListInsert(tab_list, position, mask, attributes) * Description: * Adds a tab with the specified attributes to the given * XmTabbedStackList. * Input: * tab_list : XmTabbedStackList - the XmTabbedStackList to add the new tab to * position : int - the position to place the new tab at * mask : XtValueMask - the mask of attributes to set on the * new tab * attributes : XmTabAttributes - the list of attributes to set on the * new tab * Output: * int - the position of the new tab in the list */ int #ifndef _NO_PROTO XmTabbedStackListInsert(XmTabbedStackList tab_list, int position, XtValueMask mask, XmTabAttributes attributes) #else XmTabbedStackListInsert(tab_list, position, mask, attributes) XmTabbedStackList tab_list; int position; XtValueMask mask; XmTabAttributes attributes; #endif { XmTabAttributes newTab; /* * First let's see if they gave us a valid XmTabbedStackList and position * and if not let's just leave. */ if( tab_list == NULL || position < XmTAB_LAST_POSITION || (position > 0 && position >= tab_list->used) ) return XmTAB_NOT_FOUND; /* * Now lets add our new tab to the list in the correct position. * If the list is not large enough to hold our new tab we will * grow the list. */ if( tab_list->allocated == tab_list->used ) { /* * Our list is not large enough to take another tab, so lets * grow the list by XmLIST_GROWTH_FACTOR. */ tab_list->allocated += XmLIST_GROWTH_FACTOR; tab_list->tabs = (XmTabAttributes) XtRealloc((XtPointer) tab_list->tabs, sizeof(XmTabAttributeRec) * tab_list->allocated); } /* * Once here we know that the list is large enough to hold our new * item so now lets move any existing items up to make room for our * new kiddie. */ if( position == XmTAB_LAST_POSITION ) { newTab = &(tab_list->tabs[tab_list->used]); position = tab_list->used; } else { XmTabAttributes to, from; int count; from = &(tab_list->tabs[position]); to = &(tab_list->tabs[position+1]); count = tab_list->used - position; memmove(to, from, sizeof(XmTabAttributeRec) * count); newTab = &(tab_list->tabs[position]); } tab_list->used++; /* * Now lets initialize the new tab. After that we will take a look * at the mask and see what attributes were customized. */ newTab->label_string = (XmString) NULL; newTab->string_direction = XmSTRING_DIRECTION_L_TO_R; newTab->label_pixmap = XmUNSPECIFIED_PIXMAP; newTab->label_alignment = XmALIGNMENT_CENTER; newTab->pixmap_placement = XmPIXMAP_RIGHT; newTab->foreground = XmCOLOR_DYNAMIC; newTab->background = XmCOLOR_DYNAMIC; newTab->background_pixmap = XmPIXMAP_DYNAMIC; newTab->sensitive = True; newTab->value_mode = XmTAB_VALUE_COPY; if( mask & XmTAB_VALUE_MODE ) { newTab->value_mode = attributes->value_mode; } if( mask & XmTAB_LABEL_STRING ) { if( newTab->value_mode == XmTAB_VALUE_COPY ) { newTab->label_string = XiXmStringCopy(attributes->label_string); } else { newTab->label_string = attributes->label_string; } } if( mask & XmTAB_STRING_DIRECTION ) { newTab->string_direction = attributes->string_direction; } if( mask & XmTAB_LABEL_PIXMAP ) { newTab->label_pixmap = attributes->label_pixmap; } if( mask & XmTAB_PIXMAP_PLACEMENT ) { newTab->pixmap_placement = attributes->pixmap_placement; } if( mask & XmTAB_BACKGROUND ) { newTab->background = attributes->background; } if( mask & XmTAB_BACKGROUND_PIXMAP ) { newTab->background_pixmap = attributes->background_pixmap; } if( mask * XmTAB_SENSITIVE ) { newTab->sensitive = attributes->sensitive; } if( mask & XmTAB_FOREGROUND ) { newTab->foreground = attributes->foreground; } if( mask & XmTAB_LABEL_ALIGNMENT ) { newTab->label_alignment = attributes->label_alignment; } return( position ); } /* * Function: * XmTabbedStackListAppend(tab_list, mask, attributes) * Description: * Appends a new tab with the given attributes. * Input: * tab_list : XmTabbedStackList - the XmTabbedStackList to append a tab to * mask : XtValueMask - the mask of attributes to set on the * new tab * attributes : XmTabAttributes - the list of attributes to set on the * new tab * Output: * int - the position of the new tab */ int #ifndef _NO_PROTO XmTabbedStackListAppend(XmTabbedStackList tab_list, XtValueMask mask, XmTabAttributes attributes) #else XmTabbedStackListAppend(tab_list, mask, attributes) XmTabbedStackList tab_list; XtValueMask mask; XmTabAttributes attributes; #endif { /* * So we cheat a little here. All we need to do is call insert and * lets that function know that we want it at the end of the list. */ return( XmTabbedStackListInsert(tab_list, XmTAB_LAST_POSITION, mask, attributes) ); } /* * Function: * XmTabbedStackListModify(tab_list, position, mask, attributes) * Description: * Change the specified attributes for the tab at the given position * in the given XmTabbedStackList. * Input: * tab_list : XmTabbedStackList - the XmTabbedStackList that contains the * tab to modify. * position : int - the index of the tab to modify * mask : XtValueMask - the mask of attributes to modify * attributes : XmTabAttributes - the list of attributes to modify * Output: * None. */ void #ifndef _NO_PROTO XmTabbedStackListModify(XmTabbedStackList tab_list, int position, XtValueMask mask, XmTabAttributes attributes) #else XmTabbedStackListModify(tab_list, position, mask, attributes) XmTabbedStackList tab_list; int position; XtValueMask mask; XmTabAttributes attributes; #endif { XmTabAttributes tab; /* * First lets see if they gave us anything valid to work with and * if they did not lets vacate the premises. */ if( tab_list == NULL || position < 0 || position >= tab_list->used ) { return; } tab = &(tab_list->tabs[position]); /* * Now lets check the various flags and see what we need to * change. */ if( mask & XmTAB_VALUE_MODE && tab->value_mode != attributes->value_mode && attributes->value_mode == XmTAB_VALUE_COPY ) { /* * Can only change this mode from share to copy, NOT from copy * to share. */ tab->value_mode = attributes->value_mode; tab->label_string = XiXmStringCopy(attributes->label_string); } if( mask & XmTAB_LABEL_STRING ) { if( tab->value_mode == XmTAB_VALUE_COPY ) { XiXmStringFree(tab->label_string); tab->label_string = XiXmStringCopy(attributes->label_string); } else { tab->label_string = attributes->label_string; } } if( mask & XmTAB_STRING_DIRECTION ) { tab->string_direction = attributes->string_direction; } if( mask & XmTAB_LABEL_PIXMAP ) { tab->label_pixmap = attributes->label_pixmap; } if( mask & XmTAB_PIXMAP_PLACEMENT ) { tab->pixmap_placement = attributes->pixmap_placement; } if( mask & XmTAB_BACKGROUND ) { tab->background = attributes->background; } if( mask & XmTAB_BACKGROUND_PIXMAP ) { tab->background_pixmap = attributes->background_pixmap; } if( mask & XmTAB_SENSITIVE ) { tab->sensitive = attributes->sensitive; } if( mask & XmTAB_FOREGROUND ) { tab->foreground = attributes->foreground; } if( mask & XmTAB_LABEL_ALIGNMENT ) { tab->label_alignment = attributes->label_alignment; } } /* * Function: * XmTabbedStackListQuery(tab_list, position, mask, attributes) * Description: * Retrieve attributes from the specified tab. (NOTE: This may be * a copy out, depends on value_mode, so be sure to free * this when done.) * Input: * tab_list : XmTabbedStackList - the tab list that contains the tab * position : int - the tab index to query * attributes : XmTabAttributes - the attributes returned. * Output: * None. */ void #ifndef _NO_PROTO XmTabbedStackListQuery(XmTabbedStackList tab_list, int position, XmTabAttributes attributes) #else XmTabbedStackListQuery(tab_list, position, attributes) XmTabbedStackList tab_list; int position; XmTabAttributes attributes; #endif { XmTabAttributes tab; /* * Make sure that we have valid data and if not "asta la vesta, baby" * I have NO idea how to spell that. */ if( tab_list == NULL || position < 0 || position >= tab_list->used ) { return; } tab = &(tab_list->tabs[position]); if( tab->value_mode == XmTAB_VALUE_COPY ) { attributes->label_string = XiXmStringCopy(tab->label_string); } else { attributes->label_string = tab->label_string; } attributes->label_pixmap = tab->label_pixmap; attributes->string_direction = tab->string_direction; attributes->label_alignment = tab->label_alignment; attributes->pixmap_placement = tab->pixmap_placement; attributes->background = tab->background; attributes->background_pixmap = tab->background_pixmap; attributes->sensitive = tab->sensitive; attributes->foreground = tab->foreground; attributes->value_mode = tab->value_mode; } /* * Function: * XmTabbedStackListFind(tab_list, label_string) * Description: * Finds the first tab whose label_string matches the given * and returns its index. * Input: * tab_list : XmTabbedStackList - the XmTabbedStackList to search * label_string : XmString - the label_string to search for * Output: * int - the index of the tab found, or XmTAB_NOT_FOUND if * a match is not found. */ int #ifndef _NO_PROTO XmTabbedStackListFind(XmTabbedStackList tab_list, XmString label_string) #else XmTabbedStackListFind(tab_list, label_string) XmTabbedStackList tab_list; XmString label_string; #endif { int i; if( tab_list == NULL ) return( XmTAB_NOT_FOUND ); for( i = 0; i < tab_list->used; ++i ) { if( XiXmStringCompare(tab_list->tabs[i].label_string, label_string) ) { return( i ); } } return( XmTAB_NOT_FOUND ); } /* * Function: * XmTabbedStackListSimpleRemove(tab_list, label_string) * Description: * Removes the first tab from the given XmTabbedStackList that matches the * given label string. * Input: * tab_list : XmTabbedStackList - tab list to remove the item from * label_string : XmString - the label string to match * Output: * None. */ void #ifndef _NO_PROTO XmTabbedStackListSimpleRemove(XmTabbedStackList tab_list, XmString label_string) #else XmTabbedStackListSimpleRemove(tab_list, label_string) XmTabbedStackList tab_list; XmString label_string; #endif { int position = XmTabbedStackListFind(tab_list, label_string); if( position != XmTAB_NOT_FOUND ) XmTabbedStackListRemove(tab_list, position); } /* * Function: * XmTabbedStackListSimpleInsert(tab_list, position, label_string) * Description: * Inserts a new tab with the specified label string at the * specified position. * Input: * tab_list : XmTabbedStackList - the XmTabbedStackList to add a tab to * position : int - the position to put the tab at * label_string : XmString - the label for the new tab * Output: * int - the position of the new tab */ int #ifndef _NO_PROTO XmTabbedStackListSimpleInsert(XmTabbedStackList tab_list, int position, XmString label_string) #else XmTabbedStackListSimpleInsert(tab_list, position, label_string) XmTabbedStackList tab_list; int position; XmString label_string; #endif { XmTabAttributeRec attributes; attributes.label_string = label_string; return( XmTabbedStackListInsert(tab_list, position, XmTAB_LABEL_STRING, &attributes) ); } /* * Function: * XmTabbedStackListSimpleAppend(tab_list, label_string) * Description: * Append a new tab to the given tab list with the specified label * string. * Input: * tab_list : XmTabbedStackList - the XmTabbedStackList to append a tab to * label_string : XmString - the label for the new tab * Output: * int - the position of the new tab */ int #ifndef _NO_PROTO XmTabbedStackListSimpleAppend(XmTabbedStackList tab_list, XmString label_string) #else XmTabbedStackListSimpleAppend(tab_list, label_string) XmTabbedStackList tab_list; XmString label_string; #endif { XmTabAttributeRec attributes; attributes.label_string = label_string; return( XmTabbedStackListAppend(tab_list, XmTAB_LABEL_STRING, &attributes) ); } /* * Function: * XmTabbedStackListsimpleModify(tab_list, position, label_string) * Description: * Changes the label string for the specified tab. * Input: * tab_list : XmTabbedStackList - the XmTabbedStackList that contains the tab to * change * position : int - the tab to change * label_string : XmString - the new value of the label string * Output: * None. */ /* ARGSUSED */ void #ifndef _NO_PROTO XmTabbedStackListSimpleModify(XmTabbedStackList tab_list, int position, XmString label_string) #else XmTabbedStackListSimpleModify(tab_list, position, label_string) XmTabbedStackList tab_list; int position; XmString label_string; #endif { XmTabAttributeRec attributes; XmTabbedStackListModify(tab_list, position, XmTAB_LABEL_STRING, &attributes); } /* * Function: * XmTabbedStackListSimpleQuery(tab_list, position) * Description: * Query the label string from the specified tab * Input: * tab_list : XmTabbedStackList - the XmTabbedStackList to query * position : int - the tab to query * Output: * XmString - the label for the given tab (NOTE: this is a copy * so please free when you are done) */ XmString #ifndef _NO_PROTO XmTabbedStackListSimpleQuery(XmTabbedStackList tab_list, int position) #else XmTabbedStackListSimpleQuery(tab_list, position) XmTabbedStackList tab_list; int position; #endif { XmTabAttributeRec attributes; XmTabbedStackListQuery(tab_list, position, &attributes); if( attributes.value_mode != XmTAB_VALUE_COPY ) { attributes.label_string = XiXmStringCopy(attributes.label_string); } return( attributes.label_string ); } /* * Function: * XmTabAttributesFree(attributes) * Description: * This deallocates any memory that the attribute structure is * using. This does not free the attribute structure. * Input: * attributes : XiAttributes - the structure whose contants should be * deallocated. * Output: * None. */ void #ifndef _NO_PROTO XmTabAttributesFree(XmTabAttributes attributes) #else XmTabAttributesFree(attributes) XmTabAttributes attributes; #endif { if( attributes->value_mode == XmTAB_VALUE_COPY ) { XiXmStringFree(attributes->label_string); } } /* * Function: * _XmTabbedStackListCount(tab_list) * Description: * Returns the number of entries in the given XmTabbedStackList. * Input: * tab_list : XmTabbedStackList - the tab list whose entries to count * Output: * int - the number of items in the given XmTabbedStackList */ int #ifndef _NO_PROTO _XmTabbedStackListCount(XmTabbedStackList tab_list) #else _XmTabbedStackListCount(tab_list) XmTabbedStackList tab_list; #endif { if( tab_list == NULL ) return( 0 ); return( tab_list->used ); } /* * Function: * _XmTabbedStackListGet(tab_list, position) * Description: * Returns a pointer to the given element in the XmTabbedStackList. Use * with caution as it returns a pointer to live memory. * Input: * tab_list : XmTabbedStackList - the tab list to index into * int : Position - the index of the tab you want * Output: * XmTabAttributes - a pointer to the specified tab */ XmTabAttributes #ifndef _NO_PROTO _XmTabbedStackListGet(XmTabbedStackList tab_list, int position) #else _XmTabbedStackListGet(tab_list, position) XmTabbedStackList tab_list; int position; #endif { XmTabAttributes tab; /* * Make sure that we have valid data and if not "asta la vesta, baby" * I have NO idea how to spell that. */ if( tab_list == NULL || position < 0 || position >= tab_list->used ) { return( NULL ); } tab = &(tab_list->tabs[position]); return( tab ); } XmTabAttributes #ifndef _NO_PROTO _XmTabbedStackListArray(XmTabbedStackList tab_list) #else _XmTabbedStackListArray(tab_list) XmTabbedStackList tab_list; #endif { /* * Make sure that we have valid data and if not "asta la vesta, baby" * I have NO idea how to spell that. */ if( tab_list == NULL ) { return( NULL ); } return( tab_list->tabs ); } /* * Function: * XmTabbedStackListCompare(XmTabbedStackList list1, XmTabbedStackList list2) * Description: * Compares to tab lists to see if they are logically * equivalent. * Input: * list1 : XmTabbedStackList - tab list to compare * list2 : XmTabbedStackList - tab list to compare * Output: * XmTabResult - indicates the differences it any */ XmTabResult #ifndef _NO_PROTO XmTabbedStackListCompare(XmTabbedStackList list1, XmTabbedStackList list2) #else XmTabbedStackListCompare(list1, list2) XmTabbedStackList list1, list2; #endif { XmTabResult result = XmTAB_CMP_EQUAL; int i; if( (list1 == NULL && list2 != NULL) || (list1 != NULL && list2 == NULL) || list1->used != list2->used ) return( XmTAB_CMP_SIZE ); for( i = 0; i < list1->used; ++i ) { if( list1->tabs[i].label_pixmap != list2->tabs[i].label_pixmap || !XiXmStringCompare(list1->tabs[i].label_string, list2->tabs[i].label_string) || list1->tabs[i].pixmap_placement != list2->tabs[i].pixmap_placement ) { return( XmTAB_CMP_SIZE ); } if( list1->tabs[i].string_direction != list2->tabs[i].string_direction || list1->tabs[i].label_alignment != list2->tabs[i].label_alignment || list1->tabs[i].foreground != list2->tabs[i].foreground || list1->tabs[i].background != list2->tabs[i].background || list1->tabs[i].sensitive != list2->tabs[i].sensitive || list1->tabs[i].background_pixmap != list2->tabs[i].background_pixmap ) { result = XmTAB_CMP_VISUAL; } } return( result ); }