diff options
Diffstat (limited to 'vendor/x11iraf/obm/ObmW/TableUtil.c')
-rw-r--r-- | vendor/x11iraf/obm/ObmW/TableUtil.c | 919 |
1 files changed, 919 insertions, 0 deletions
diff --git a/vendor/x11iraf/obm/ObmW/TableUtil.c b/vendor/x11iraf/obm/ObmW/TableUtil.c new file mode 100644 index 00000000..27fa3129 --- /dev/null +++ b/vendor/x11iraf/obm/ObmW/TableUtil.c @@ -0,0 +1,919 @@ +/*********************************************************************** + + Table widget + Copyright by Vladimir T. Romanovski + All rights reserved. + +This library is designed for free, non-commercial software creation. +It is changeable and can be improved. The author would greatly appreciate +any advice, new components and patches of the existing programs. +Commercial usage is also possible with participation of the author. + + romsky@hp1.oea.ihep.su (Russia) + romsky@munin.ucsf.edu (USA) + +*************************************************************************/ + +#include <X11/Xraw/TableUtil.h> +#include <X11/Xraw/xraw_table.h> + +#ifdef EBUG_XRAW_MALLOC +#include <dbmalloc/malloc.h> +#endif + +/************************************************************************ + * + * TABLE IS A GRID OF POINTER BINDED NODES + * + ************************************************************************/ + +#define null (XawTableNode)NULL +#define FREE(t) if((t) != null)XtFree((char*)(t)) + +static void vert_tab_node_insert(f,s,p) + register XawTableNode f; /* insert after */ + register XawTableNode s; /* insert before */ + register XawTableNode p; /* to be inserted */ +{ + if (f != null) f->b = p; + if (s != null) s->t = p; + if (p != null) {p->t = f; p->b = s;} +} + +static void horiz_tab_node_insert(f,s,p) + register XawTableNode f; /* insert after */ + register XawTableNode s; /* insert before */ + register XawTableNode p; /* to be inserted */ +{ + if (f != null) f->r = p; + if (s != null) s->l = p; + if (p != null) {p->l = f; p->r = s;} +} + +static void vert_tab_node_reject(p) + register XawTableNode p; +{ + if (p == null) return; + + if (p->t != null) p->t->b = p->b; + if (p->b != null) p->b->t = p->t; +} + +static void horiz_tab_node_reject(p) + register XawTableNode p; +{ + if (p == null) return; + + if (p->r != null) p->r->l = p->l; + if (p->l != null) p->l->r = p->r; +} + +/* ARGSUSED */ +static XawTableProc del_cell (w, i, j, call_data, client_data) + XtPointer w; + int i; + int j; + XtPointer call_data; + XtPointer client_data; +{ + XtFree((char*)call_data); + return False; +} + +/* +** Function name : row_delete +** +** Description : delete row which the node belongs to +** Input : pointer to the node +** Output : void +*/ + +void +#if NeedFunctionPrototypes +row_delete (XtPointer f) +#else +row_delete(f) + XtPointer f; +#endif +{ + register XawTableNode p = (XawTableNode) f; + + if (p == null) + return; + + /* Go to left edge */ + for(; p->l != null; p=p->l ) + /*EMPTY*/; + + /* Go to right with dettaching cell */ + for(; p->r != null; p=p->r){ + vert_tab_node_reject(p->l); + FREE(p->l); + } + + /* Detach last but one cell in the row */ + if (p->l != null){ + vert_tab_node_reject(p->l); + FREE(p->l); + } + + /* Detach very last cell in the row */ + vert_tab_node_reject(p); + FREE(p); +} + +/* +** Function name : column_delete +** +** Description : delete column which the node belongs to +** Input : pointer to the node +** Output : void +*/ + +void +#if NeedFunctionPrototypes +column_delete (XtPointer f) +#else +column_delete(f) + XtPointer f; +#endif +{ + register XawTableNode p = (XawTableNode) f; + + if (p == null) + return; + + /* Go up to the edge */ + for(; p->t != null; p=p->t ) + /*EMPTY*/; + + /* Go down with dettaching cell */ + for(; p->b != null; p=p->b){ + horiz_tab_node_reject(p->t); + FREE(p->t); + } + + /* Detach bottom but one cell in the column */ + if (p->t != null){ + horiz_tab_node_reject(p->t); + FREE(p->t); + } + + /* Detach very bottom cell in the column */ + horiz_tab_node_reject(p); + FREE(p); +} + + + +/* +** Function name : row_insert_after +** +** Description : insert row down to the row which the node belongs to +** Input : poiter to the node, size of node +** Output : True if successful +*/ + +Boolean +#if NeedFunctionPrototypes +row_insert_after (XtPointer d, int node_size) +#else +row_insert_after(d, node_size) + XtPointer d; + int node_size; +#endif +{ + register XawTableNode f = (XawTableNode) d; + register XawTableNode p; + XawTableNode left; + + if (f == null) + return False; + + /* go left till row edge */ + for(; f->l != null; f=f->l ) + /*EMPTY*/; + + /* save very left node */ + left = f; + + /* go right and attach new cells via vertical ponters */ + for(; f->r != null; f=f->r){ + if( (p = (XawTableNode) XtMalloc (node_size)) == null){ + for(; left != f; left = left->r){ + vert_tab_node_reject(left->b); + FREE(left->b); + } + return False; + } + vert_tab_node_insert(f, f->b, p); + } + + /* attach vertically very right cell */ + if( (p = (XawTableNode) XtMalloc (node_size)) == null){ + for(; left != f; left = left->r){ + vert_tab_node_reject(left->b); + FREE(left->b); + } + return False; + } + vert_tab_node_insert(f, f->b, p); + + /* if only one column */ + if ( f->l == null ) { + f->b->l = f->b->r = null; + return True; + } + + /* attach horizontally very right cell */ + horiz_tab_node_insert(f->l->b,null,f->b); + + /* bind via horizontal ponters */ + for(f=f->l; f->l != null; f=f->l ) + horiz_tab_node_insert(f->l->b,f->r->b,f->b); + + /* attach horizontally very left cell */ + horiz_tab_node_insert(null,f->r->b,f->b); + + return True; +} + +/* +** Function name : row_insert_before +** +** Description : the same as previous, but only on top from row +** Input : pointer to the node, size of node +** Output : True if successful +*/ + +Boolean +#if NeedFunctionPrototypes +row_insert_before (XtPointer d, int node_size) +#else +row_insert_before(d, node_size) + XtPointer d; + int node_size; +#endif +{ + register XawTableNode f = (XawTableNode) d; + register XawTableNode p; + XawTableNode left; + + if (f == null) + return False; + + /* go left till row edge */ + for(; f->l != null; f=f->l ) + /*EMPTY*/; + + /* save very left node */ + left = f; + + /* go right and attach new cells via vertical ponters */ + for(; f->r != null; f=f->r){ + if( (p = (XawTableNode) XtMalloc (node_size)) == null){ + for(; left != f; left = left->r){ + vert_tab_node_reject(left->t); + FREE(left->t); + } + return False; + } + vert_tab_node_insert(f->t, f, p); + } + + /* attach vertically very right cell */ + if( (p = (XawTableNode) XtMalloc (node_size)) == null){ + for(; left != f; left = left->r){ + vert_tab_node_reject(left->t); + FREE(left->t); + } + return False; + } + vert_tab_node_insert(f->t, f, p); + + /* if only one column */ + if ( f->l == null ) { + f->t->l = f->t->r = null; + return True; + } + + /* attach horizontally very right cell */ + horiz_tab_node_insert(f->l->t,null,f->t); + + /* bind via horizontal ponters */ + for(f=f->l; f->l != null; f=f->l ) + horiz_tab_node_insert(f->l->t,f->r->t,f->t); + + /* attach horizontally very left cell */ + horiz_tab_node_insert(null,f->r->t,f->t); + + return True; +} + +/* +** Function name : column_insert_after +** +** Description : insert column right to the column which the node belongs to +** Input : pointer to the node, size of node +** Output : True if successful +[<*/ + +Boolean +#if NeedFunctionPrototypes +column_insert_after (XtPointer d, int node_size) +#else +column_insert_after(d, node_size) + XtPointer d; + int node_size; +#endif +{ + register XawTableNode f = (XawTableNode) d; + register XawTableNode p; + XawTableNode top; + + if (f == null) + return False; + + /* go top till column edge */ + for(; f->t != null; f=f->t ) + /*EMPTY*/; + + /* save very top node */ + top = f; + + /* go down and attach new cells via horizontal ponters */ + for(; f->b != null; f=f->b){ + if( (p = (XawTableNode) XtMalloc (node_size)) == null){ + for(; top != f; top = top->b){ + horiz_tab_node_reject(top->r); + FREE(top->r); + } + return False; + } + horiz_tab_node_insert(f, f->r, p); + } + + /* attach horizontally very down cell */ + if( (p = (XawTableNode) XtMalloc (node_size)) == null){ + for(; top != f; top = top->b){ + horiz_tab_node_reject(top->r); + FREE(top->r); + } + return False; + } + + horiz_tab_node_insert(f, f->r, p); + + /* if only one row */ + if ( f->t == null ) { + f->r->t = f->r->b = null; + return True; + } + + /* attach vertically very down cell */ + vert_tab_node_insert(f->t->r,null,f->r); + + /* bind via vertical ponters */ + for(f=f->t; f->t != null; f=f->t ) + vert_tab_node_insert(f->t->r,f->b->r,f->r); + + /* attach vertically very top cell */ + vert_tab_node_insert(null,f->b->r,f->r); + + return True; +} + +/* +** Function name : column_insert_before +** +** Description : the same as previous, but only to left from column +** Input : pointer to node, size of node +** Output : True if successful +*/ + +Boolean +#if NeedFunctionPrototypes +column_insert_before (XtPointer d, int node_size) +#else +column_insert_before(d, node_size) + XtPointer d; + int node_size; +#endif +{ + register XawTableNode f = (XawTableNode)d; + register XawTableNode p; + XawTableNode top; + + if (f == null) + return False; + + /* go top till column top */ + for(; f->t != null; f=f->t ) + /*EMPTY*/; + + /* save very top node */ + top = f; + + /* go down and attach new cells via horizontal ponters */ + for(; f->b != null; f=f->b){ + if( (p = (XawTableNode) XtMalloc (node_size)) == null){ + for(; top != f; top = top->b){ + horiz_tab_node_reject(top->l); + FREE(top->l); + } + return False; + } + horiz_tab_node_insert(f->l, f, p); + } + + /* attach horizontally very down cell */ + if( (p = (XawTableNode) XtMalloc (node_size)) == null){ + for(; top != f; top = top->b){ + horiz_tab_node_reject(top->l); + FREE(top->l); + } + return False; + } + horiz_tab_node_insert(f->l, f, p); + + /* if only one row */ + if ( f->t == null ) { + f->l->t = f->l->b = null; + return True; + } + + /* attach vertically very down cell */ + vert_tab_node_insert(f->t->l, null, f->l); + + /* bind via vertical ponters */ + for(f=f->t; f->t != null; f=f->t ) + vert_tab_node_insert(f->t->l, f->b->l, f->l); + + /* attach vertically very top cell */ + vert_tab_node_insert(null, f->b->l, f->l); + + return True; +} + +/* +** Function name : get_table +** +** Description : spot the node (0,0) in the table +** Input : pointer to any node in table +** Output : pointer to the node (0,0) +*/ + +XtPointer +#if NeedFunctionPrototypes +get_table (XtPointer f) +#else +get_table(f) + XtPointer f; +#endif +{ + register XawTableNode p = (XawTableNode) f; + + if (p == null) + return (XtPointer)NULL; + + for(; p->t != null; p=p->t) + /*EMPTY*/; + + for(; p->l != null; p=p->l) + /*EMPTY*/; + + return (XtPointer)p; +} + +/* +** Function name : get_cell +** +** Description : spot the node (i,j) regarding to given node +** Input : pointer to the node, column, row (may be negative) +** Output : pointer to the node or NULL +*/ + +XtPointer +#if NeedFunctionPrototypes +get_cell (XtPointer f, register int i, register int j) +#else +get_cell (f, i, j) + XtPointer f; + register int i; + register int j; +#endif +{ + register XawTableNode p = (XawTableNode) f; + + if (p == null) + return (XtPointer)NULL; + + if (i > 0) { + for(; i>0; i--) + if (p != null) p = p->b; + else return (XtPointer)NULL; + } else { + for(; i<0; i++) + if (p != null) p = p->t; + else return (XtPointer)NULL; + } + + if (j > 0) { + for(; j>0; j--) + if (p != null) p = p->r; + else return (XtPointer)NULL; + } else { + for(; j<0; j++) + if (p != null) p = p->l; + else return (XtPointer)NULL; + } + + return (XtPointer)p; +} + +#if 0 +static Boolean go_row(w, proc, p, begin_column, end_column, i, j, client_data) + XtPointer w; + XawTableProc proc; + XawTableNode p; /* p == get_cell(table, ... , begin_column) */ + int begin_column; + int end_column; + int *i; /* returned */ + int *j; /* returned */ + XtPointer client_data; +{ + for ((*j) = begin_column; ((*j) <= end_column) && (p != null); (*j)++) + { + XawTableProc sp = p; + p = p->r; + + if (proc(w, *i, *j, (XtPointer)sp, client_data)) + return True; + } + + return False; +} +#endif + +/* +** Function name : go_table +** +** Description : invoke given rutine for every node in given region +** Input : rutine, begin/end rows, begin/end columns... +** Output : True if given rutine returned True for a node, +** numbers of row and column for that node + */ + +Boolean +#if NeedFunctionPrototypes +go_table ( + XtPointer w, + XawTableProc proc, + XtPointer table, + int begin_row, + int end_row, + int begin_column, + int end_column, + int direction, + register int *i, /* returned */ + register int *j, /* returned */ + XtPointer client_data) +#else +go_table(w, proc, table, begin_row, end_row, begin_column, end_column, + direction, i, j, client_data) + XtPointer w; + XawTableProc proc; + XtPointer table; + int begin_row; + int end_row; + int begin_column; + int end_column; + int direction; + register int *i; /* returned */ + register int *j; /* returned */ + XtPointer client_data; +#endif +{ + register XawTableNode p; + register XawTableNode n; + + table = get_table(table); + + switch (direction) { + case XawTABLE_DOWN_RIGHT : + p = (XawTableNode)get_cell(table, begin_row, begin_column); + + for (*j = begin_column; *j <= end_column && p != null; (*j)++) + { + register XawTableNode sp = p; /* protect against deallocated node !! */ + p = p->r; + + for (*i = begin_row, n = sp; *i <= end_row && n != null; (*i)++) + { + register XawTableNode sn = n; /* protect against deallocated node !! */ + n = n->b; + + if (proc(w, *i, *j, (XtPointer)sn, client_data)) + return True; + } + } + break; + case XawTABLE_RIGHT_DOWN : + default : + p = (XawTableNode)get_cell(table, begin_row, begin_column); + + for (*i = begin_row; *i <= end_row && p != null; (*i)++) + { + register XawTableNode sp = p; /* protect against deallocated node !! */ + p = p->b; + + for (*j = begin_column, n = sp; *j <= end_column && n != null; (*j)++) + { + register XawTableNode sn = n; /* protect against deallocated node !! */ + n = n->r; + + if (proc(w, *i, *j, (XtPointer)sn, client_data)) + return True; + } + } + break; + } + return False; +} + +/* +** Function name : get_table_size +** +** Description : define dimention on the table +** Input : pointer to any node in the table +** Output : void +*/ + +void +#if NeedFunctionPrototypes +get_table_size (XtPointer f, + register int *i, /* returned */ + register int *j) /* returned */ +#else +get_table_size(f,i,j) + XtPointer f; + register int *i; /* returned */ + register int *j; /* returned */ +#endif +{ + register XawTableNode p = (XawTableNode)f; + if (p == null){ + *i = 0; + *j = 0; + } + + p = (XawTableNode)get_table(f); + + for (*i = 1; p->b != null; p = p->b, (*i)++) + /*EMPTY*/; + + for (*j = 1; p->r != null; p = p->r, (*j)++) + /*EMPTY*/; +} + +/* +** Function name : delete_table +** +** Description : destroy table +** Input : pointer to any node in the table +** Output : void +*/ + +void +#if NeedFunctionPrototypes +delete_table (XtPointer f) +#else +delete_table(f) + XtPointer f; +#endif +{ + register XawTableNode p = (XawTableNode)f; + int i,j; + int end_row, end_column; + + if (p == null) + return; + + p = (XawTableNode)get_table(f); + get_table_size((XtPointer)p, (int*)&end_row, (int*)&end_column); + (void)go_table(NULL, (XawTableProc)del_cell, (XtPointer)p, + 0, (int)(end_row-1), 0, (int)(end_column-1), + XawTABLE_RIGHT_DOWN, + (int*)&i, (int*)&j, NULL); +} + +/* +** Function name : get_cell_positions +** +** Description : define number of row & column for node +** Input : pointer to the node +** Output : void +*/ + +void +#if NeedFunctionPrototypes +get_cell_positions (XtPointer f, + register int *i, /* returned */ + register int *j) /* returned */ +#else +get_cell_positions(f, i, j) + XtPointer f; + register int *i; /* returned */ + register int *j; /* returned */ +#endif +{ + register XawTableNode p = (XawTableNode)f; + if ( p == null ) + return; + + if ( i != (int*)NULL ) { + for (*i = 0; p->t != null; p = p->t, (*i)++) + /*EMPTY*/; + } + + if ( j != (int*)NULL ) { + for (*j = 0; p->l != null; p = p->l, (*j)++) + /*EMPTY*/; + } +} + +/* +** Function name : create_table +** +** Description : create the table +** Input : row & column dimestions, size of node +** Output : pointer to the node (0,0) +*/ + +XtPointer +#if NeedFunctionPrototypes +create_table ( int rows, int columns, int node_size) +#else +create_table(rows, columns, node_size) + int rows; + int columns; + int node_size; +#endif +{ + register XawTableNode *area; + register XawTableNode p; + register int i,j; + XawTableNode table; + + if (rows == 0 || columns == 0) + return (XtPointer)NULL; + else{ + register XawTableNode *s; + + /* allocate temporary two-dimension array to make first node's binding */ + if ( (s = area = (XawTableNode*) + XtCalloc ((unsigned)(rows * columns), sizeof(XawTableNode))) == NULL) + return (XtPointer)NULL; + + /* allocate nodes */ + for (i = 0, j = rows*columns; i < j; i++) + if((*s++ = (XawTableNode) XtMalloc (node_size)) == NULL){ + int h; + for (h = 0, s = area; h < i; h++) + XtFree((char*)*s++); + + XtFree((char*)area); + return (XtPointer)NULL; + } + } + +#define a(i,j) (XawTableNode)*(area + (i)*columns + (j)) + + /* initialize the boundary nodes */ + for (i = 0; i < rows; i++) { + p = a(i,0); p->l = null; + p = a(i,columns-1); p->r = null; + } + for (j = 0; j < columns; j++) { + p = a(0,j); p->t = null; + p = a(rows-1,j); p->b = null; + } + +#undef a +#define a(i,j) (( (i)>=0 && (i)<rows ) && ( (j)>=0 && (j)<columns ) ? \ + (XawTableNode)*(area + (i)*columns + (j)) : null) + + /* make internode's binding */ + for (i = 0; i < rows; i++) { + for (j = i % 2; j < columns; j += 2) { + horiz_tab_node_insert(a(i,j-1), a(i,j+1), a(i,j)); + vert_tab_node_insert (a(i-1,j), a(i+1,j), a(i,j)); + } + } + +#undef a + + table = *area; + XtFree((char*)area); + return (XtPointer)table; +} + + +#ifdef EBUG_XRAW_MALLOC +/* ARGSUSED */ +static Boolean check_cell (w, row, column, call_data, client_data) + XtPointer w; /* unused */ + int row; + int column; + XtPointer call_data; + XtPointer client_data; +{ + register XawTableNode p = (XawTableNode)call_data; + int real_row, real_column; + char *halt = NULL;; + + get_cell_positions(p, &real_row, &real_column); + + if (real_row != row){ + XtWarning("check_table: wrong initial table row size"); + *halt = '\0'; + } + + if (real_column != column){ + XtWarning("check_table: wrong initial table column size"); + *halt = '\0'; + } + + if (p->l != null) + if (p->l->r != p) { + XtWarning("check_table: wrong cell"); + *halt = '\0'; + } + if (p->r != null) + if (p->r->l != p) { + XtWarning("check_table: wrong cell"); + *halt = '\0'; + } + if (p->t != null) + if (p->t->b != p) { + XtWarning("check_table: wrong cell"); + *halt = '\0'; + } + if (p->b != null) + if (p->b->t != p) { + XtWarning("check_table: wrong cell"); + *halt = '\0'; + } + + return False; +} + + + +void +#if NeedFunctionPrototypes +_check_table (XtPointer f, int rows, int columns) +#else +_check_table (f, rows, columns) + XtPointer f; + int rows; + int columns; +#endif +{ + register XawTableNode table = (XawTableNode)f; + int real_rows, real_columns; + register int i,j; + char *halt = NULL; + + if (f == NULL && (rows == 0 || columns == 0)) + return; + + if (table != get_table(f)){ + XtWarning("check_table: wrong initial table cell"); + *halt = '\0'; + } + + get_table_size (f, &real_rows, &real_columns); + + if (real_rows != rows){ + XtWarning("check_table: wrong initial table row size"); + *halt = '\0'; + } + + if (real_columns != columns){ + XtWarning("check_table: wrong initial table column size"); + *halt = '\0'; + } + + + (void) go_table (NULL, check_cell, table, + 0, rows-1, 0, columns-1, + XawTABLE_RIGHT_DOWN, + &real_rows, &real_columns, (XtPointer)NULL); + +} +#endif /* EBUG_XRAW_MALLOC */ + +#undef null +#undef FREE + |