From fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 8 Jul 2015 20:46:52 -0400 Subject: Initial commit --- vendor/x11iraf/obm/ObmW/Table.c | 4594 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 4594 insertions(+) create mode 100644 vendor/x11iraf/obm/ObmW/Table.c (limited to 'vendor/x11iraf/obm/ObmW/Table.c') diff --git a/vendor/x11iraf/obm/ObmW/Table.c b/vendor/x11iraf/obm/ObmW/Table.c new file mode 100644 index 00000000..ecb6e8e8 --- /dev/null +++ b/vendor/x11iraf/obm/ObmW/Table.c @@ -0,0 +1,4594 @@ +/*********************************************************************** + + 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 +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef EBUG_XRAW_MALLOC +#include +#endif + +#define MULTI_LINE_TABLE 32767 + + +#undef CELL_IN /* */ + +#ifdef MIN +#undef MIN +#endif +#define MIN(a,b) ((a)<(b) ? (a) : (b)) + +#ifdef MAX +#undef MAX +#endif +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +#define CALLOC(num,type) (num * sizeof(type) <= 0 ? (type*)NULL : \ + (type*)XtMalloc((Cardinal)(num) * (Cardinal)sizeof(type))) + +#define NOT_A_CUT_BUFFER (-1) + +#define MAXCUT 30000 +#define EDIT(w) (((XawTableWidget) w)->table.edit) +#define InRange(n,a,b) MAX(a,MIN(n,b)) + +#define LEFT_EDGE(tw) (((XawTableWidget)tw)->table.internal_width + \ + ((XawTableWidget)tw)->table.label_shadow_thickness) + +#define TOP_EDGE(tw) (((XawTableWidget)tw)->table.internal_height + \ + ((XawTableWidget)tw)->table.label_shadow_thickness) + +#define CELL(field) cell->field +#define STUFF(w) ((XawTableWidget)w)->table.table_stuff +#define COLUMNS(w) ((XawTableWidget)w)->table.columns +#define ROWS(w) ((XawTableWidget)w)->table.rows +#define GET_CELL_LABEL ((CELL(label) == NULL ? Dummy : CELL(label))) + +#define COLUMN_DATA(tw) ((XawTableColumnRec*)tw->table.column_data) +#define COLUMN_WIDTH(tw,column) \ +(tw->table.literal ? \ + ( \ + (COLUMN_DATA(tw)[column].flag & _CL_width) ?\ + COLUMN_DATA(tw)[column].width : \ + tw->table.column_default_width \ + ) \ + * tw->table.literal_width + \ + 2 * tw->table.internal_width \ + : \ + ( \ + (COLUMN_DATA(tw)[column].flag & _CL_width) ?\ + COLUMN_DATA(tw)[column].width : \ + tw->table.column_default_width \ + ) \ +/* _COLUMN_WIDTH_ */) + + +#define MANAGE_EDIT(tw) \ + if ( ! XtIsManaged(EDIT(tw))) \ + { \ + XtManageChild (EDIT(tw)); \ + XtSetKeyboardFocus ((Widget)tw, EDIT(tw)); \ + } + + +#define UNMANAGE_EDIT(tw) \ + if ( XtIsManaged(EDIT(tw))) \ + { \ + XtUnmanageChild (tw->table.edit); \ + XtSetKeyboardFocus((Widget)tw, (Widget)None); \ + } + + +#define DO_CALLBACK(w,callback,data) \ + if (XtCallbackHasSome == XtHasCallbacks(w, callback)) \ + XtCallCallbacks (w, callback, (XtPointer)&data) + + +#define IsEditInRowColumn(tw, row, column) \ + (XtIsManaged(EDIT(tw)) && (row == tw->table.edit_row) \ + && (column == tw->table.edit_column)) + + + +#define REJECT (-1) +#define ACCEPT (0) + +#define CHECK_TABLE(tw) \ + _check_table ((XtPointer)STUFF(tw), ROWS(tw), COLUMNS(tw)); \ + CheckAllLabels(tw) + + + +typedef struct _XawTableCellRec { + /* Node communication entity */ + XawTableNodeRec node; + /* Cell label entity */ + char *label; + Position label_x; + Dimension label_width; + Dimension label_len; + /* Cell colour entity */ + Boolean highlight; + Boolean special_colour; + Pixel fore; + Pixel back; + GC normal; + GC reverse; + GC top; + GC bottom; + +}XawTableCellRec; + +#define _CL_width (1L<<0) +#define _CL_font (1L<<1) +#define _CL_label (1L<<2) +#define _CL_justify (1L<<3) +#define _CL_background (1L<<4) +#define _CL_foreground (1L<<5) + +typedef struct _XawTableColumnRec { + int flag; + int width; + XFontStruct *font; + char *label; + XtJustify justify; + Pixel background; + Pixel foreground; + GC normal; + GC reverse; + GC top; + GC bottom; +}XawTableColumnRec; + + +#ifdef CRAY +#define WORD64 +#endif + +/**************************************************************** + * + * Full class record constant + * + ****************************************************************/ + +/* Private Data */ + +static void Def_pixel(); +static void Def_scroll(); +static void Def_column_default_width(); +static void Def_literal_width(); +static void Def_shadow_thickness(); + +#define Offset(field) XtOffsetOf(TableRec, field) + +static XtResource resources[] = { + { + XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), + Offset(table.foreground), XtRString, XtDefaultForeground + }, + { + XtNeditForeground, XtCForeground, XtRPixel, sizeof(Pixel), + Offset(table.edit_fore), XtRCallProc, (XtPointer)Def_pixel + }, + { + XtNeditBackground, XtCBackground, XtRPixel, sizeof(Pixel), + Offset(table.edit_back), XtRCallProc, (XtPointer)Def_pixel + }, + { + XtNrowForeground, XtCForeground, XtRPixel, sizeof(Pixel), + Offset(table.row_fore), XtRCallProc, (XtPointer)Def_pixel + }, + { + XtNcolumnForeground, XtCForeground, XtRPixel, sizeof(Pixel), + Offset(table.column_fore), XtRCallProc, (XtPointer)Def_pixel + }, + { + XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), + Offset(table.font), XtRString, XtDefaultFont + }, + { + XtNliteral, XtCLiteral, XtRBoolean, sizeof(Boolean), + Offset(table.literal), XtRImmediate, (XtPointer)False + }, + { + XtNrowOriented, XtCRowOriented, XtRBoolean, sizeof(Boolean), + Offset(table.row_oriented), XtRImmediate, (XtPointer)True + }, + { + XtNmaskNumber, XtCMaskNumber, XtRInt, sizeof(int), + Offset(table.mask_number), XtRImmediate, (XtPointer)7 + }, + { + XtNcolumns, XtCColumns, XtRInt, sizeof(int), + Offset(table.columns), XtRImmediate, (XtPointer)1 + }, + { + XtNrows, XtCRows, XtRInt, sizeof(int), + Offset(table.rows), XtRImmediate, (XtPointer)1 + }, + { + XtNtableMargin, XtCTableMargin, XtRDimension, sizeof(Dimension), + Offset(table.tab_margin), XtRImmediate, (XtPointer)2 + }, + { + XtNrowMargin, XtCRowMargin, XtRDimension, sizeof(Dimension), + Offset(table.row_margin), XtRImmediate, (XtPointer)1 + }, + { + XtNcolumnMargin, XtCColumnMargin, XtRDimension, sizeof(Dimension), + Offset(table.col_margin), XtRImmediate, (XtPointer)1 + }, + { + XtNlabelShadowWidth, XtCLabelShadowWidth, XtRDimension, + sizeof(Dimension), Offset(table.label_shadow_thickness), XtRImmediate, + (XtPointer)1 + }, + { + XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify), + Offset(table.justify), XtRImmediate, (XtPointer)XtJustifyCenter + }, + { + XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension), + Offset(table.internal_width), XtRImmediate, (XtPointer)4 + }, + { + XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension), + Offset(table.internal_height), XtRImmediate, (XtPointer)2 + }, + { + XtNencoding, XtCEncoding, XtRUnsignedChar, sizeof(unsigned char), + Offset(table.encoding), XtRImmediate, (XtPointer)XawTextEncoding8bit + }, + { + XtNshadowWidth, XtCShadowWidth, XtRDimension, sizeof(Dimension), + Offset(container.shadow_thickness), XtRCallProc, + (XtPointer) Def_shadow_thickness + }, + { + XtNvetricalScroll, XtCScroll, XtRWidget, sizeof(Widget), + Offset(table.v_scroll), XtRCallProc, (XtPointer)Def_scroll + }, + { + XtNhorizontalScroll, XtCScroll, XtRWidget, sizeof(Widget), + Offset(table.h_scroll), XtRCallProc, (XtPointer)Def_scroll + }, + { + XtNrowHeight, XtCRowHeight, XtRInt, sizeof(int), + Offset(table.row_height), XtRImmediate, (XtPointer)0 + }, + { + XtNdefaultWidth, XtCDefaultWidth, XtRInt, sizeof(int), + Offset(table.column_default_width), XtRCallProc, + (XtPointer) Def_column_default_width + }, + { + XtNeditable, XtCEditable, XtRBoolean, sizeof(Boolean), + Offset(table.editable), XtRImmediate, (XtPointer) FALSE + }, + { + XtNliteralWidth, XtCLiteralWidth, XtRInt, sizeof(int), + Offset(table.literal_width), XtRCallProc, (XtPointer) Def_literal_width + }, + + /* ALLOWANCE CALLBACKS */ + { + XtNallowAddColumn, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.allow_add_column), XtRCallback, NULL + }, + { + XtNallowAddRow, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.allow_add_row), XtRCallback, NULL + }, + { + XtNallowDeleteColumn, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.allow_delete_column), XtRCallback, NULL + }, + { + XtNallowDeleteRow, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.allow_delete_row), XtRCallback, NULL + }, + { + XtNallowDeleteTable, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.allow_delete_table), XtRCallback, NULL + }, + /* INFORMATION CALLBACKS */ + + { + XtNaddColumn, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.add_column), XtRCallback, NULL + }, + { + XtNaddRow, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.add_row), XtRCallback, NULL + }, + { + XtNcreateTable, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.create_table), XtRCallback, NULL + }, + { + XtNchangedCell, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.changed_cell), XtRCallback, NULL + }, + { + XtNchangedColumnWidth, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.changed_column_width), XtRCallback, NULL + }, + { + XtNchangedRowHeight, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.changed_row_height), XtRCallback, NULL + }, + { + XtNdeleteColumn, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.delete_column), XtRCallback, NULL + }, + { + XtNdeleteRow, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.delete_row), XtRCallback, NULL + }, + { + XtNdeleteTable, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.delete_table), XtRCallback, NULL + }, + { + XtNwhatCell, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(table.what_cell), XtRCallback, NULL + }, +}; + +#define PRINTF_BOOL(a) ((a) ? "TRUE":"FALSE") +#define PRINTF_NULL(a) ((a)==NULL ? "NULL":"not NULL") + +static void Def_pixel(w, offset, value) + Widget w; + int offset; + XrmValue *value; +{ + XawTableWidget tw = (XawTableWidget)w; + static Pixel pix = 0; + + + if ( offset == (int)Offset(table.edit_fore)) + pix = tw->table.foreground; + else if ( offset == (int)Offset(table.edit_back)) + { + if (!FetchPixel(w, "#d0d000", &pix)) + pix = WhitePixelOfScreen(XtScreen(w)); + } + else + pix = tw->core.background_pixel; + + value->addr = (XtPointer)& pix; +} + +/* ARGSUSED */ +static void Def_scroll(w, offset, value) + Widget w; + int offset; + XrmValue *value; +{ + static Widget view; + + for (view = XtParent(w); + (view != (Widget)NULL) && (!XtIsSubclass(view, viewportWidgetClass)); + view = XtParent(view)) + /* EMPTY */; + + if (view) + { + if (offset == Offset(table.v_scroll)) + { + if (((view = XtNameToWidget(view, "vertical")) == (Widget)NULL) + || !XtIsSubclass(view, scrollbarWidgetClass)) + view = (Widget)NULL; + } + else + if (offset == Offset(table.h_scroll)) + { + if (((view = XtNameToWidget(view, "horizontal")) == (Widget)NULL) + || !XtIsSubclass(view, scrollbarWidgetClass)) + view = (Widget)NULL; + } + } + + value->addr = (XtPointer)&view; +} + +/* ARGSUSED */ +static void Def_column_default_width(w, offset, value) + Widget w; + int offset; + XrmValue *value; +{ + XawTableWidget tw = (XawTableWidget) w; + static int column_default_width; + + if (tw->table.literal) + column_default_width = 10; + else + column_default_width = 60; + + value->addr = (XtPointer)&column_default_width; +} + +#ifndef WORD64 +#define TXT_16 XChar2b +#else +#define TXT_16 char +#endif + +/* ARGSUSED */ +static void Def_literal_width(w, offset, value) + Widget w; + int offset; + XrmValue *value; +{ + XawTableWidget tw = (XawTableWidget) w; + static int literal_width; + + if (tw->table.encoding) + tw->table.literal_width = XTextWidth16(tw->table.font, (TXT_16*)"mmm", 3); + else + tw->table.literal_width = XTextWidth(tw->table.font, "mmm", 3); + + tw->table.literal_width /= 3; + + value->addr = (XtPointer)& literal_width; +} + +/* ARGSUSED */ +static void Def_shadow_thickness(w, offset, value) + Widget w; + int offset; + XrmValue *value; +{ + Widget parent = XtParent (w); + static Dimension shadow_thickness; + + /* + if (XtIsSubclass (parent, scrolledTableWidgetClass) || + XtIsSubclass (parent, viewportWidgetClass)) + */ + if (XtIsSubclass (parent, viewportWidgetClass)) + shadow_thickness = 0; + else + shadow_thickness = 2; + + value->addr = (XtPointer)& shadow_thickness; +} + + +#undef offset + +static void MultipleChangeGC(); +static void Initialize(); +static void Realize(); +static void Resize(); +static void Redisplay(); +static void Destroy(); + +static Boolean SetValues(); + +static void WalkForCells(); +static void LoseSelection(); + +static void CallEdit(); +static void InsertSelection(); +static void StoreBuffer(); +static void WhatCell(); +static void KeyReturn(); +static void HighlightCell(); +static void UnhighlightCell(); +static void DoingNothing(); + +static char* DummyString(); + +static Boolean InitCell(); + +static XtGeometryResult QueryGeometry(); +static XtGeometryResult GeometryManager(); + +static XtActionsRec actions[] = { + {"call-edit", (XtActionProc)CallEdit }, + {"insert-selection", (XtActionProc)InsertSelection}, + {"store-in-buffer", (XtActionProc)StoreBuffer }, + {"what_cell", (XtActionProc)WhatCell }, + {"key_return", (XtActionProc)KeyReturn }, + {"highlight", (XtActionProc)HighlightCell }, + {"unhighlight", (XtActionProc)UnhighlightCell}, + {"no-op", (XtActionProc)DoingNothing } +}; + +static char translations[] = + "Ctrl: what_cell() \n\ + : call-edit() \n\ + : insert-selection(PRIMARY, CUT_BUFFER0) \n\ + : highlight() store-in-buffer(PRIMARY,CUT_BUFFER0) "; + +static char edit_translations[] = + " Return: key_return() \n\ + Linefeed: key_return() \n\ + Down: no-op(r) \n\ + Up: no-op(r) "; + +static char* Dummy = ""; + + +#define SuperClass ((ContainerWidgetClass)&containerClassRec) + +TableClassRec tableClassRec = { + { /* core_class fields */ + /* superclass */ (WidgetClass) SuperClass, + /* class_name */ "Table", + /* widget_size */ sizeof(TableRec), + /* classInitialize */ NULL, + /* class_partInitialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ Initialize, + /* initialize_hook */ NULL, + /* realize */ Realize, + /* actions */ actions, + /* num_actions */ XtNumber(actions), + /* resources */ resources, + /* num_resources */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ TRUE, + /* compress_exposure */ FALSE, + /* compress_enterleave */ TRUE, + /* visible_interest */ TRUE, + /* destroy */ Destroy, + /* resize */ Resize, + /* expose */ Redisplay, + /* set_values */ SetValues, + /* set_values_hook */ NULL, + /* set_values_almost */ XtInheritSetValuesAlmost, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* version */ XtVersion, + /* callback_private */ NULL, + /* tm_table */ translations, + /* query_geometry */ QueryGeometry, + /* display_accelerator */ XtInheritDisplayAccelerator, + /* extension */ NULL + }, + /* Composite class part */ + { + /* geometry manager */ GeometryManager, + /* change_managed */ XtInheritChangeManaged, + /* insert_child */ XtInheritInsertChild, + /* delete_child */ XtInheritDeleteChild, + /* extension */ NULL, + }, + /* Constraint class part */ + { + /* subresources */ NULL, + /* subresource_count */ 0, + /* constraint_size */ 0, + /* initialize */ NULL, + /* destroy */ NULL, + /* set_values */ NULL, + /* extension */ NULL, + }, + /* Container class part */ + { + /* ignore */ 0, + }, + { /* Table class fields initialization */ + /* ignore */ 0 + } +}; + +WidgetClass tableWidgetClass = (WidgetClass)&tableClassRec; + + +/**************************************************************** + * + * Private procedures + * + ****************************************************************/ +#define NORMAL_INDEX(fore, back) \ + (int)(((int)fore * (int)back) & tw->table.mask_hash_table) + +#define SHADOW_INDEX(back) (int)(((int)back) & tw->table.mask_hash_table) + +#define GET_NORMAL(tw,i) (tw->table.normal_hash_table+(i)) +#define GET_SHADOW(tw,i) (tw->table.shadow_hash_table+(i)) + +#define NEXT(i) (int)((i+1) & tw->table.mask_hash_table) + +static int MaskStaticArray[] = { + 0x1, 0x3, 0x7, 0xF, + 0x1F, 0x3F, 0x7F, 0xFF, + 0x1FF, 0x3FF, 0x7FF, 0xFFF + }; + +static NormalReverseGC* GetNormalGC(w, fore, back, font) + Widget w; + Pixel fore; + Pixel back; + Font font; +{ + register XawTableWidget tw = (XawTableWidget)w; + int i = NORMAL_INDEX(fore, back); + + while (GET_NORMAL(tw,i)->used > 0) + { + + if (GET_NORMAL(tw,i)->fore == fore && GET_NORMAL(tw,i)->back == back) + { + GET_NORMAL(tw,i)->used++; + return GET_NORMAL(tw,i); + } + i = NEXT(i); + } + + if (GET_NORMAL(tw,i)->used == 0) + { + XtGCMask mask; + XGCValues values; + Display *dpy = XtDisplay(w); + Window win = XtIsRealized(w) ? XtWindow(w) : XDefaultRootWindow(dpy); + + + mask = GCForeground | GCBackground | GCFont; + values.foreground = fore; + values.background = back; + values.font = font; + + GET_NORMAL(tw,i)->normal = XCreateGC(dpy, win, mask, &values); + values.foreground = back; + values.background = fore; + GET_NORMAL(tw,i)->reverse = XCreateGC(dpy, win, mask, &values); + + GET_NORMAL(tw,i)->used = 1; + GET_NORMAL(tw,i)->fore = fore; + GET_NORMAL(tw,i)->back = back; + + return GET_NORMAL(tw,i); + } + + return (NormalReverseGC*)NULL; +} + +static void GetGCByForeground(w, gc, fore) + Widget w; + GC *gc; + Pixel fore; +{ + XGCValues values; + + values.foreground = fore; + (*gc) = XtGetGC(w, GCForeground, &values); +} + + +static ShadowGC* GetShadowGC(w, back) + Widget w; + Pixel back; +{ + register XawTableWidget tw = (XawTableWidget)w; + int i = SHADOW_INDEX(back); + + while (GET_SHADOW(tw,i)->used > 0) + { + if (GET_SHADOW(tw,i)->back == back) + { + GET_SHADOW(tw,i)->used++; + return GET_SHADOW(tw,i); + } + i = NEXT(i); + } + + if (GET_SHADOW(tw,i)->used == 0) + { + Pixel top; + Pixel bottom; + + GET_SHADOW(tw,i)->used = 1; + GET_SHADOW(tw,i)->back = back; + + (void)TopShadowColor(w, back, &top); + (void)BottomShadowColor(w, back, &bottom); +#ifdef CELL_IN + GetGCByForeground(w, (GC*)&GET_SHADOW(tw,i)->bottom, top); + GetGCByForeground(w, (GC*)&GET_SHADOW(tw,i)->top, bottom); +#else + GetGCByForeground(w, (GC*)&GET_SHADOW(tw,i)->bottom, bottom); + GetGCByForeground(w, (GC*)&GET_SHADOW(tw,i)->top, top); +#endif + return GET_SHADOW(tw,i); + } + + return (ShadowGC*)NULL; +} + +static void ReleaseNormalGC(w, fore, back) + Widget w; + Pixel fore; + Pixel back; +{ + register XawTableWidget tw = (XawTableWidget)w; + int i = NORMAL_INDEX(fore, back); + + while (GET_NORMAL(tw,i)->used > 0) + { + if ( GET_NORMAL(tw,i)->fore == fore && GET_NORMAL(tw,i)->back == back) + { + if (--GET_NORMAL(tw,i)->used == 0) { + XFreeGC(XtDisplay(w), GET_NORMAL(tw,i)->normal); + XFreeGC(XtDisplay(w), GET_NORMAL(tw,i)->reverse); + } + break; + } + + i = NEXT(i); + } +} + +static void ReleaseShadowGC(w, back) + Widget w; + Pixel back; +{ + register XawTableWidget tw = (XawTableWidget)w; + int i = SHADOW_INDEX(back); + + while (GET_SHADOW(tw,i)->used > 0) + { + if ( GET_SHADOW(tw,i)->back == back) + { + if (--GET_SHADOW(tw,i)->used == 0) + { + XtReleaseGC(w, GET_SHADOW(tw,i)->top); + XtReleaseGC(w, GET_SHADOW(tw,i)->bottom); + } + break; + } + i = NEXT(i); + } +} + +static void MultipleChangeGC(w, fore, back, font, normal, reverse) + Widget w; + Pixel *fore; + Pixel *back; + Font *font; + GC *normal; + GC *reverse; +{ + XtGCMask mask; + XGCValues values; + + if (normal != (GC*)NULL){ + mask = (XtGCMask)0; + if (fore != (Pixel*)NULL) { + mask |= GCForeground; + values.foreground = *fore; + } + if (back != (Pixel*)NULL) { + mask |= GCBackground; + values.background = *back; + } + if (font != (Font*)NULL) { + mask |= GCFont; + values.font = *font; + } + XChangeGC(XtDisplay(w), *normal, mask, &values); + } + + if (reverse != (GC*)NULL){ + mask = (XtGCMask)0; + if (fore != (Pixel*)NULL) { + mask |= GCForeground; + values.foreground = *back; /* reverse */ + } + if (back != (Pixel*)NULL) { + mask |= GCBackground; + values.background = *fore; /* reverse */ + } + if (font != (Font*)NULL) { + mask |= GCFont; + values.font = *font; + } + XChangeGC(XtDisplay(w), *reverse, mask, &values); + } +} + +#ifndef WORD64 + +#define TXT16 XChar2b + +#else + +#define TXT16 char + +static XChar2b *buf2b; +static int buf2blen = 0; + +#define XTextWidth16 _XawTableWidth16 +#define XDrawString16 _XawTableDraw16 + +#endif /* WORD64 */ + + +static void CalculatePreferredSize(w, width, height) + Widget w; + Dimension *width; + Dimension *height; +{ + register XawTableWidget tw = (XawTableWidget)w; + register int wid; + register int hei; + int i; + + /* + * Calculate preferred width + */ + + wid = 2 * (tw->table.tab_margin + tw->container.shadow_thickness); + wid += COLUMNS(tw) ? (COLUMNS(tw) - 1) * tw->table.col_margin : 0; + wid += 2 * COLUMNS(tw) * tw->table.label_shadow_thickness; + + for(i = 0 ; i < COLUMNS(tw); i++) + wid += (Dimension)COLUMN_WIDTH(tw,i); + + /* + * Calculate preferred height + */ + + hei = 2 * (tw->table.tab_margin + tw->container.shadow_thickness); + hei += ROWS(tw) ? (ROWS(tw) - 1) * tw->table.row_margin : 0; + hei += ROWS(tw) * tw->table.row_height; + hei += 2 * ROWS(tw) * tw->table.label_shadow_thickness; + + tw->table.prefer_width = wid; + tw->table.prefer_height = hei; + + if (width) *width = wid; + if (height) *height = hei; + +} + +static Position GetX(tw,j) + register XawTableWidget tw; + int j; +{ + register TablePart* table = (TablePart*)&tw->table; + register Position x; + + x = j * (table->col_margin + 2 * table->label_shadow_thickness) + + (table->tab_margin + tw->container.shadow_thickness); + + for(; j > 0 ; j--) + { + register int tmp = j - 1; + x += (Position)COLUMN_WIDTH(tw, tmp); + } + return x; +} + +static Position GetY(tw,i) + XawTableWidget tw; + int i; +{ + return(i * (tw->table.row_margin + tw->table.row_height + + 2 * tw->table.label_shadow_thickness) + + (tw->table.tab_margin + tw->container.shadow_thickness)); +} + + +/* + * Calculate width and height of displayed text in pixels + */ + +static void SetLabelHeight(tw) + XawTableWidget tw; +{ + register XFontStruct *fs = tw->table.font; + int row_height = tw->table.row_height; + + if (tw->table.row_height < 1) + tw->table.row_height = (fs->max_bounds.ascent + + fs->max_bounds.descent + + 2 * tw->table.internal_height); + if (row_height != tw->table.row_height) + { + XawTableCallbackStruct callback_str; + callback_str.reason = XawTABLE_CHANGED_ROW_HEIGHT; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = (XawTableCell)NULL; + callback_str.new_cell = (XawTableCell)NULL; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK((Widget)tw, XtNchangedRowHeight, callback_str); + } +} + +static void SetLiteralWidth(tw) + XawTableWidget tw; +{ + if (tw->table.encoding) + tw->table.literal_width = XTextWidth16(tw->table.font, (TXT16*)"mmm", 3); + else + tw->table.literal_width = XTextWidth(tw->table.font, "mmm", 3); + + tw->table.literal_width /= 3; +} + + +static void SetLabelWidth(tw,i,j) + XawTableWidget tw; + int i,j; +{ + register XFontStruct *fs = tw->table.font; + XawTableCell cell; + + cell = (XawTableCell)get_cell(STUFF(tw),i,j); + + if (CELL(label) == NULL) { + CELL(label_len) = 0; + CELL(label_width) = 0; + } else { + CELL(label_len) = strlen(CELL(label)); + if (tw->table.encoding) + CELL(label_width) = + XTextWidth16(fs, (TXT16*)CELL(label), (int) CELL(label_len)/2); + else + CELL(label_width) = + XTextWidth(fs, CELL(label), (int) CELL(label_len)); + } +} + + +static void CreateTableCellGC(w) + Widget w; +{ + Display *dpy = XtDisplay(w); + Drawable d = XtWindow(w); + XawTableWidget tw = (XawTableWidget)w; + + tw->table.normal = XCreateGC(dpy, d, (XtGCMask)0, (XGCValues*)NULL); + tw->table.reverse = XCreateGC(dpy, d, (XtGCMask)0, (XGCValues*)NULL); + + MultipleChangeGC(w, + (Pixel*)&tw->table.foreground, + (Pixel*)&tw->core.background_pixel, + (Font*)&tw->table.font->fid, + (GC*)&tw->table.normal, + (GC*)&tw->table.reverse); + +} + +static void DrawColumns(tw, b_column, e_column) + XawTableWidget tw; + int b_column, e_column; +{ + int j,y; + + y = (int)GetY(tw,0); + for(j = MAX(b_column,0); j <= MIN(e_column, COLUMNS(tw) - 2); j++) + { + XFillRectangle(XtDisplay((Widget)tw), + XtWindow((Widget)tw), + tw->table.column_gc, + (int) (GetX(tw,j+1) - tw->table.col_margin), + y, + (unsigned int) tw->table.col_margin, + (unsigned int)(tw->table.prefer_height-(2*y))); + + } +} + +static void DrawRows(tw, b_row, e_row) + XawTableWidget tw; + int b_row, e_row; +{ + int i,x; + + x = (int)GetX(tw,0); + for(i = MAX(b_row, 0); i <= MIN(e_row, ROWS(tw) - 2); i++) + { + XFillRectangle(XtDisplay((Widget)tw), + XtWindow((Widget)tw), + tw->table.row_gc, + x, + (int) (GetY(tw,i+1) - tw->table.row_margin), + (unsigned int) (tw->table.prefer_width-(2*x)), + (unsigned int) tw->table.row_margin); + + } +} + +static void DrawCage(tw, b_row, e_row, b_column, e_column) + XawTableWidget tw; + int b_row, e_row, b_column, e_column; +{ + int i,j; + Display* dpy = XtDisplay((Widget)tw); + Window win = XtWindow((Widget)tw); + + if (tw->table.row_oriented) + { + if (tw->table.col_margin > (Dimension)0) + { + DrawRows(tw, b_row - 1, e_row); + + for(i = b_row; i <= MIN(e_row,ROWS(tw) - 1); i++) + { + int y = (int) GetY(tw,i); + + for(j = MAX(b_column - 1, 0); j <= MIN(e_column, COLUMNS(tw) - 2); j++) + { + XFillRectangle (dpy, + win, + tw->table.column_gc, + (int) (GetX(tw, j + 1) - tw->table.col_margin), + y, + (unsigned int) tw->table.col_margin, + (unsigned int) (tw->table.row_height + + 2 * tw->table.label_shadow_thickness)); + + } + } + } + } + else + { + if (tw->table.row_margin > (Dimension)0) + { + DrawColumns(tw, b_column - 1, e_column); + + for(j = b_column; j <= MIN(e_column, COLUMNS(tw) - 1); j++) + { + int x = (int) GetX(tw,j); + + for(i = MAX(b_row - 1, 0); i <= MIN(e_row, ROWS(tw) - 2); i++) + { + XFillRectangle(XtDisplay((Widget)tw), + XtWindow((Widget)tw), + tw->table.row_gc, + x, + (int) (GetY(tw,i+1) - tw->table.row_margin), + (unsigned int) (COLUMN_WIDTH(tw,j) + + 2 * tw->table.label_shadow_thickness), + (unsigned int) tw->table.row_margin); + } + } + } + } +} + +static void Reposition(tw, cell, i, j) + register XawTableWidget tw; + XawTableCell cell; + int i,j; +{ + Position newPos; + XtJustify justify; + + if (cell == NULL) + cell = (XawTableCell)get_cell(STUFF(tw),i,j); + + if (COLUMN_DATA(tw)[j].flag & _CL_justify) + justify = COLUMN_DATA(tw)[j].justify; + else + justify = tw->table.justify; + + switch (justify) { + case XtJustifyLeft : newPos = tw->table.internal_width; + break; + case XtJustifyRight : newPos = (COLUMN_WIDTH(tw,j) - + CELL(label_width) - + tw->table.internal_width); + break; + case XtJustifyCenter : + default : newPos = (COLUMN_WIDTH(tw,j) - + CELL(label_width)) / 2; + break; + } + + CELL(label_x) = MAX(newPos, tw->table.internal_width); +} + +/* ARGSUSED */ +static Boolean DeleteCell(p, i, j, call_data, client_data) + XtPointer p; + int i; /* unused */ + int j; /* unused */ + XtPointer call_data; + XtPointer client_data; /* unused */ +{ + Widget w = (Widget) p; + XawTableCell cell = (XawTableCell)call_data; + + + if (CELL(label) != (char*)NULL) + XtFree(CELL(label)); + + if (CELL(special_colour)) + { + ReleaseNormalGC(w, CELL(fore), CELL(back)); + ReleaseShadowGC(w, CELL(back)); + } + return False; +} + + +static void UpdateTable(tw) + XawTableWidget tw; +{ + Dimension width; + Dimension height; + + if (tw->table.no_refigure > 0) + return; + + CalculatePreferredSize((Widget)tw, &width, &height); + + tw->table.was_resized = False; + + (void)XtMakeResizeRequest((Widget)tw, width, height, + (Dimension*)NULL, (Dimension*)NULL); + if (tw->table.was_resized == False) + { + tw->table.was_resized = True; + (*tableClassRec.core_class.resize) ((Widget)tw); + } +} + + +static int SetTableSize(w, rows, columns) + Widget w; + int rows; + int columns; +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCallbackStruct callback_str; + int i; + + if (rows < 0 || columns < 0) { + String subs[1]; + Cardinal num_subs = 1; + subs[0] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "SetTableSize", "SetTableSize","XawToolkitError", + "rows or columns for a new table in TableWidget '%s' less then zero", + subs, &num_subs); + return REJECT; + } + + if (STUFF(tw)) + { + callback_str.reason = XawTABLE_ALLOW_DELETE_TABLE; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = STUFF(tw); + callback_str.new_cell = STUFF(tw); + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNallowDeleteTable, callback_str); + + if (callback_str.do_it != True) + return REJECT; + + callback_str.reason = XawTABLE_DELETE_TABLE; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = STUFF(tw); + callback_str.new_cell = STUFF(tw); + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK (w, XtNdeleteTable, callback_str); + + WalkForCells (w, (XawTableProc)DeleteCell, + 0, ROWS(tw)-1, 0, COLUMNS(tw)-1); + + delete_table ((XtPointer)STUFF(tw)); + + STUFF(tw) = (XawTableCell)NULL; + ROWS(tw) = 0; + COLUMNS(tw) = 0; + } + + if (rows == 0 || columns == 0) + return ACCEPT; + + STUFF(tw) = (XawTableCell) + create_table(rows, columns, sizeof(XawTableCellRec)); + + if (STUFF(tw) == (XawTableCell)NULL) + return ACCEPT; + + ROWS(tw) = rows; + COLUMNS(tw) = columns; + + WalkForCells((Widget)tw, (XawTableProc)InitCell, 0, rows-1, 0, columns-1); + + if (COLUMNS(tw)) { + tw->table.column_data = (XawTableColumn) + XtRealloc((XtPointer)COLUMN_DATA(tw), + (Cardinal)(COLUMNS(tw) * sizeof(XawTableColumnRec))); + for (i = 0; i < COLUMNS(tw); i++) + COLUMN_DATA(tw)[i].flag = 0; + } + else { + XtFree((XtPointer)tw->table.column_data); + tw->table.column_data = NULL; + } + + callback_str.reason = XawTABLE_CREATE_TABLE; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = (XawTableCell)NULL; + callback_str.new_cell = (XawTableCell)NULL; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNcreateTable, callback_str); + + return ACCEPT; +} + + +/* ARGSUSED */ +static void Initialize(request, new, args, num_args) + Widget request; + Widget new; + ArgList args; + Cardinal *num_args; +{ + register XawTableWidget tw = (XawTableWidget) new; + Dimension width; + Dimension height; + int i; + + tw->table.no_refigure = 0; + tw->table.no_redraw = 0; + tw->table.num_selections = 0; + tw->table.cell_own = (XawTableCell)NULL; + STUFF(tw) = (XawTableCell)NULL; + tw->table.normal = (GC)NULL; + tw->table.reverse = (GC)NULL; + + COLUMNS(tw) = MAX (COLUMNS(tw), 0); + ROWS(tw) = MAX (ROWS(tw), 0); + + if (COLUMNS(tw)) { + tw->table.column_data = (XawTableColumn) + CALLOC (COLUMNS(tw), XawTableColumnRec); + for (i = 0; i < COLUMNS(tw); i++) + COLUMN_DATA(tw)[i].flag = 0; + } + else + tw->table.column_data = NULL; + + SetLiteralWidth(tw); + + EDIT(tw) = XtVaCreateWidget + ("edit", asciiTextWidgetClass, new, + XtNeditType, XawtextEdit, + XtNforeground, tw->table.edit_fore, + XtNbackground, tw->table.edit_back, + XtNborderWidth, (XtArgVal)0, + XtNleftMargin, 2, + XtNrightMargin, 2, + XtNtopMargin, 0, /* to be fixed in future */ + XtNbottomMargin, 0, /* to be fixed in future */ + XtNuseStringInPlace, False, + XtNfont, tw->table.font, + XtNuserData, (XtArgVal)new, + NULL); + + XtOverrideTranslations(EDIT(tw), XtParseTranslationTable(edit_translations)); + + GetGCByForeground (new, (GC*)&tw->table.row_gc, tw->table.row_fore); + GetGCByForeground (new, (GC*)&tw->table.column_gc, tw->table.column_fore); + + if ((COLUMNS(tw) > 0) && (ROWS(tw) > 0)) + { + if (REJECT == SetTableSize(new, ROWS(tw), COLUMNS(tw))) + { + ROWS(tw) = 0; + COLUMNS(tw) = 0; + STUFF(tw) = (XawTableCell)NULL; + } + } + + if ((tw->table.mask_number < 0) + || (tw->table.mask_number >= XtNumber(MaskStaticArray))) + tw->table.mask_number = 7; + + tw->table.mask_hash_table = MaskStaticArray[tw->table.mask_number]; + + tw->table.normal_hash_table = + CALLOC(tw->table.mask_hash_table, NormalReverseGC); + + tw->table.shadow_hash_table = CALLOC(tw->table.mask_hash_table, ShadowGC); + + for(i = 0; i < tw->table.mask_hash_table; i++) + { + GET_NORMAL(tw,i)->used = 0; + GET_NORMAL(tw,i)->normal = (GC)NULL; + GET_NORMAL(tw,i)->reverse = (GC)NULL; + GET_SHADOW(tw,i)->used = 0; + GET_SHADOW(tw,i)->top = (GC)NULL; + GET_SHADOW(tw,i)->bottom = (GC)NULL; + } + + SetLabelHeight(tw); + + CalculatePreferredSize(new, &width, &height); + + if (new->core.width == 0) new->core.width = width; + if (new->core.height == 0) new->core.height = height; +} + + +static void Realize(w, valueMask, attributes) + Widget w; + XtValueMask *valueMask; + XSetWindowAttributes *attributes; +{ + XawTableWidget tw = (XawTableWidget) w; + ShadowGC *shadow; + + (*SuperClass->core_class.realize) (w, valueMask, attributes); + + CreateTableCellGC(w); + + shadow = GetShadowGC(w, tw->table.edit_back); + tw->table.edit_top = shadow->top; + tw->table.edit_bottom = shadow->bottom; + + shadow = GetShadowGC(w, tw->core.background_pixel); + tw->table.top = shadow->top; + tw->table.bottom = shadow->bottom; + + XtRealizeWidget(EDIT(w)); +} + +/* ARGSUSED */ +static Boolean MatchLabel(w, i, j, call_data, client_data) + Widget w; /* unused */ + int i; /* unused */ + int j; /* unused */ + XtPointer call_data; + XtPointer client_data; +{ + XawTableCell cell = (XawTableCell)call_data; + XrmQuark* templ = (XrmQuark*)client_data; + + return ((*templ) == XrmStringToQuark (GET_CELL_LABEL)); +} + +/* ARGSUSED */ +static Boolean InitCell(p, i, j, call_data, client_data) + XtPointer p; /* unused */ + int i; /* unused */ + int j; /* unused */ + XtPointer call_data; + XtPointer client_data; /* unused */ +{ + XawTableCell cell = (XawTableCell)call_data; + + CELL(label) = DummyString(); + CELL(label_len) = 0; + CELL(label_width) = 0; + CELL(highlight) = False; + CELL(special_colour) = False; + CELL(normal) = (GC)NULL; + CELL(reverse) = (GC)NULL; + CELL(top) = (GC)NULL; + CELL(bottom) = (GC)NULL; + + return False; +} + +/* + * + * Shadow drawing around cell + * + */ +static void PaintShadow(w, i, j, x, y, cell) + Widget w; + int i; + int j; + Position x; + Position y; + XawTableCell cell; +{ + XawTableWidget tw = (XawTableWidget) w; + + if (tw->table.label_shadow_thickness != (Dimension)0) { + GC top,bottom; + + if (IsEditInRowColumn(tw,i,j)) + { + top = tw->table.edit_bottom; + bottom = tw->table.edit_top; + } + else if (CELL(special_colour)) + { + top = CELL(top); + bottom = CELL(bottom); + }else { + top = tw->table.top; + bottom = tw->table.bottom; + } + + XawDrawFrame(w, + x, + y, + (Dimension)(COLUMN_WIDTH(tw,j) + + 2 * tw->table.label_shadow_thickness), + (Dimension)(tw->table.row_height + + 2 * tw->table.label_shadow_thickness), + XawRAISED, + tw->table.label_shadow_thickness, + top, + bottom); + } + +} + +/* ARGSUSED */ +static void PaintLabel(w, i, j, x, y, cell) + Widget w; + int i; + int j; + Position x,y; + XawTableCell cell; +{ + XawTableWidget tw = (XawTableWidget) w; + XRectangle rectangle[1]; + Position label_x; + Position label_y; + unsigned int width = (unsigned int) COLUMN_WIDTH(tw,j); + unsigned int height = (unsigned int) tw->table.row_height; + + x += tw->table.label_shadow_thickness; + y += tw->table.label_shadow_thickness; + + if (CELL(special_colour) || CELL(highlight)) + { + GC gc; + + if (CELL(special_colour)) + gc = CELL(highlight) ? CELL(normal) : CELL(reverse); + else + gc = tw->table.normal ; + + /* Fill background for cell with a special colour */ + XFillRectangle(XtDisplay(w), XtWindow(w), gc, + (int)x, (int)y, width, height); + } + else + { + XClearArea (XtDisplay(w), XtWindow(w), (int)x, (int)y, + width, height, FALSE); + } + + if (CELL(label_len) > 0) + { + GC gc; + register XFontStruct *fs = tw->table.font; + + if (CELL(special_colour)) + gc = CELL(highlight) ? CELL(reverse) : CELL(normal); + else + gc = CELL(highlight) ? tw->table.reverse : tw->table.normal; + + /* Set clip rectangle for label in cell */ + rectangle[0].x = (short)x; + rectangle[0].y = (short)y; + rectangle[0].width = (unsigned short)COLUMN_WIDTH(tw,j); + rectangle[0].height = (unsigned short)tw->table.row_height; + + XSetClipRectangles(XtDisplay(w), gc, 0, 0, rectangle, 1, YSorted); + + /* Drawing label */ + label_x = x + CELL(label_x); + label_y = y + + (tw->table.row_height-(fs->max_bounds.ascent+fs->max_bounds.descent))/2 + /* tw->table.internal_height */ + + fs->max_bounds.ascent; + + if (tw->table.encoding) + XDrawString16(XtDisplay(w), XtWindow(w), gc, + label_x, label_y, (TXT16*)CELL(label), + (int)CELL(label_len)/2); + else + XDrawString(XtDisplay(w), XtWindow(w), gc, + label_x, label_y, CELL(label), (int)CELL(label_len)); + + XSetClipMask(XtDisplay(w), gc, (Pixmap)None); + + } +} + +/* ARGSUSED */ +static Boolean PaintCell(p, i, j, call_data, client_data) + XtPointer p; + int i; + int j; + XtPointer call_data; + XtPointer client_data; /* unused */ +{ + Widget w = (Widget) p; + XawTableWidget tw = (XawTableWidget) w; + XawTableCell cell = (XawTableCell) call_data; + Position x; + Position y; + + x = GetX(tw,j); + y = GetY(tw,i); + + PaintLabel (w, i, j, x, y, cell); + PaintShadow (w, i, j, x, y, cell); + + XFlush(XtDisplay(w)); + return False; +} + +static void WhatCellsToBeDraw(tw, rect, b_row, e_row, b_column , e_column) + XawTableWidget tw; + XRectangle rect; + register int *b_row, *e_row, *b_column , *e_column; +{ + Position x1 = (Position)rect.x, + y1 = (Position)rect.y, + x2 = (Position)(rect.x + rect.width - 1), + y2 = (Position)(rect.y + rect.height - 1); + + for ((*b_column) = 0; (*b_column) < COLUMNS(tw); (*b_column)++) + { + if (x1 < (GetX(tw,(*b_column) + 1) - tw->table.col_margin)) { + /* Added to fix scrolling bug in Viewport parent. MJF 9/6/02 + */ + *b_column = MAX (0, *b_column-1); + break; + } + } + + for ((*e_column) = (*b_column); (*e_column) < COLUMNS(tw); (*e_column)++) + { + if (x2 < (GetX(tw,(*e_column) + 1) - tw->table.col_margin)) + break; + } + + + for ((*b_row) = 0; (*b_row) < ROWS(tw); (*b_row)++) + { + if (y1 < (GetY(tw,(*b_row) + 1) - tw->table.row_margin)) { + /* Added to fix scrolling bug in Viewport parent. MJF 9/6/02 + */ + *b_row = MAX (0, *b_row-1); + break; + } + } + + for ((*e_row) = (*b_row); (*e_row) < ROWS(tw); (*e_row)++) + { + if (y2 < (GetY(tw,(*e_row) + 1) - tw->table.row_margin)) + break; + } +} + + +static void Redisplay(w, event, region) + Widget w; + XEvent *event; + Region region; +{ + XawTableWidget tw = (XawTableWidget) w; + XRectangle rect; + int b_row, e_row, b_column , e_column ; + + + if (!XtIsRealized(w) || !w->core.visible || tw->table.no_redraw) + return; + + if (tw->container.shadow_thickness > 0) + (*SuperClass->core_class.expose) (w, event, region); + + if (region != NULL) + { + XClipBox(region, (XRectangle*)&rect); + + WhatCellsToBeDraw(tw, rect, &b_row, &e_row, &b_column , &e_column); + } + else if (event != (XEvent*)NULL) + { + rect.x = (short) event->xexpose.x; + rect.y = (short) event->xexpose.y; + rect.width = (unsigned short) event->xexpose.width; + rect.height = (unsigned short) event->xexpose.height; + + WhatCellsToBeDraw(tw, rect, &b_row, &e_row, &b_column , &e_column); + + /* The following is necessary so the table gets redrawn properly + * when being managed by e.g. a Viewport widget. MJF 9/6/02 + */ + XawTableDoLayout (w, TRUE); + } + else if (tw->table.v_scroll || tw->table.h_scroll) + { + rect.x = (short) 0; + rect.y = (short) 0; + rect.width = (unsigned short) tw->core.width; + rect.height = (unsigned short) tw->core.height; + + if (tw->table.v_scroll && XtIsManaged(tw->table.v_scroll)) + { + float top; + float shown; + + XtVaGetValues (tw->table.v_scroll, + XtNtopOfThumb, &top, + XtNshown, &shown, + NULL); + + rect.y = (short) ((float)(tw->core.height) * top); + rect.height = (unsigned short) ((float)(tw->core.height) * (top+shown)); + } + + if (tw->table.h_scroll && XtIsManaged(tw->table.h_scroll)) + { + float top; + float shown; + + XtVaGetValues (tw->table.h_scroll, + XtNtopOfThumb, &top, + XtNshown, &shown, + NULL); + + rect.x = (short) ((float)(tw->core.width) * top); + rect.width = (unsigned short) ((float)(tw->core.width) * (top+shown)); + } + + + WhatCellsToBeDraw(tw, rect, &b_row, &e_row, &b_column , &e_column); + } + else + { + b_row = 0; + e_row = ROWS(tw) - 1; + b_column = 0; + e_column = COLUMNS(tw) - 1; + } + + DrawCage(tw, b_row, e_row, b_column, e_column); + + WalkForCells(w, (XawTableProc)PaintCell, b_row, e_row, b_column, e_column); + + XFlush(XtDisplay(w)); +} + +/* ARGSUSED */ +static Boolean SetValues(current, request, new, args, num_args) + Widget current; + Widget request; /* unused */ + Widget new; + ArgList args; /* unused */ + Cardinal *num_args; /* unused */ +{ + XawTableWidget curtw = (XawTableWidget) current; + XawTableWidget newtw = (XawTableWidget) new; + register int i; + int j; + Boolean resize = False; + Boolean redisplay = False; + +#define NE(field) (curtw->table.field != newtw->table.field) + + if (NE(mask_number)) + XtWarning("Resource XtNmaskNumber in Table widget can not changed"); + + newtw->table.mask_number = curtw->table.mask_number; + newtw->table.literal = curtw->table.literal; + + if (NE(font->fid)) + XtVaSetValues (EDIT(newtw), XtNfont, curtw->table.font, NULL); + + if (NE(foreground) || + NE(row_fore) || + NE(column_fore) || + NE(row_oriented) || + NE(font->fid) || + NE(justify) || + NE(tab_margin) || + NE(row_margin) || + NE(col_margin) || + NE(internal_width) || + NE(internal_height) || + NE(label_shadow_thickness) || + NE(encoding)) + redisplay = True; + + if (NE(font->fid) || + NE(columns) || + NE(rows) || + NE(tab_margin) || + NE(row_margin) || + NE(col_margin) || + NE(internal_width) || + NE(internal_height) || + NE(row_height) || + NE(label_shadow_thickness)) + resize = True; + + if (NE(columns) || NE(rows)) + if (REJECT == SetTableSize(new, ROWS(newtw), COLUMNS(newtw))) { + newtw->table.columns = curtw->table.columns; + newtw->table.rows = curtw->table.rows; + } + + if(NE(row_height)) + { + XawTableCallbackStruct callback_str; + callback_str.reason = XawTABLE_CHANGED_ROW_HEIGHT; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = (XawTableCell)NULL; + callback_str.new_cell = (XawTableCell)NULL; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK(new, XtNchangedRowHeight, callback_str); + } + + if(NE(font->fid)) + { + for(i = 0; i < ROWS(newtw); i++) + for(j = 0; j < COLUMNS(newtw); j++) + SetLabelWidth(newtw, i, j); + + SetLabelHeight(newtw); + } + + if(NE(font->fid) || NE(encoding)) + { + SetLiteralWidth(newtw); + + for(i = 0; i < ROWS(newtw); i++) + for(j = 0; j < COLUMNS(newtw); j++) + Reposition(newtw, NULL, i, j); + } + else if(NE(internal_width) || NE(label_shadow_thickness)) { + for(i = 0; i < ROWS(newtw); i++) + for(j = 0; j < COLUMNS(newtw); j++) + Reposition(newtw, NULL, i, j); + } + + + if (NE(internal_height) || NE(label_shadow_thickness)) + { + SetLabelHeight(newtw); + } + + if (resize) + CalculatePreferredSize(new, &newtw->core.width, &newtw->core.height); + + if (NE(foreground) || NE(font->fid) || + curtw->core.background_pixel != newtw->core.background_pixel) + { + MultipleChangeGC(new, + (Pixel*)&newtw->table.foreground, + (Pixel*)&newtw->core.background_pixel, + (Font*)&newtw->table.font->fid, + (GC*)&newtw->table.normal, + (GC*)&newtw->table.reverse); + + } + + if (NE(row_fore)) + { + XtReleaseGC(new, curtw->table.row_gc); + GetGCByForeground(new,(GC*)&newtw->table.row_gc, newtw->table.row_fore); + } + + if (NE(column_fore)) + { + XtReleaseGC(new, curtw->table.column_gc); + GetGCByForeground(new, &newtw->table.column_gc,newtw->table.column_fore); + } + + if (resize) + CalculatePreferredSize(new, &(new->core.width), &(new->core.height)); + + return redisplay; +} + + +static void Destroy(w) + Widget w; +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCallbackStruct callback_str; + + if (STUFF(tw) != (XawTableCell)NULL) + { + callback_str.reason = XawTABLE_DELETE_TABLE; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = (XawTableCell)NULL; + callback_str.new_cell = (XawTableCell)NULL; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNdeleteTable, callback_str); + } + + if (tw->table.row_gc != (GC)NULL) { + XtReleaseGC(w, tw->table.row_gc); + tw->table.row_gc = (GC)NULL; + } + if (tw->table.column_gc != (GC)NULL) { + XtReleaseGC(w, tw->table.column_gc); + tw->table.column_gc = (GC)NULL; + } + if (tw->table.normal != (GC)NULL) { + XFreeGC(XtDisplay(w), tw->table.normal); + tw->table.normal = (GC)NULL; + } + + if (tw->table.reverse != (GC)NULL) { + XFreeGC(XtDisplay(w), tw->table.reverse); + tw->table.reverse = (GC)NULL; + } + + WalkForCells(w, (XawTableProc)DeleteCell, 0, ROWS(tw)-1, 0, COLUMNS(tw)-1); + + XtFree((XtPointer)tw->table.normal_hash_table); + XtFree((XtPointer)tw->table.shadow_hash_table); + + delete_table(tw->table.table_stuff); + STUFF(tw) = (XawTableCell)NULL; + + if (tw->table.column_data != NULL) + XtFree((XtPointer)tw->table.column_data); + + if (EDIT(w) != WNULL && !EDIT(w)->core.being_destroyed) + XtDestroyWidget(EDIT(w)); +} + + +static void Resize(w) + Widget w; +{ + XawTableWidget tw = (XawTableWidget)w; + + /* If widget is realized, just redisplay it w/o clearing */ + if (XtIsRealized(w) && tw->table.no_redraw == 0) + { + /* XClearWindow(XtDisplay(w), XtWindow(w)); */ + (*tableClassRec.core_class.expose) (w, (XEvent*)NULL,(Region)NULL); + } + + tw->table.was_resized = True; +} + + +static XtGeometryResult QueryGeometry(w, intended, preferred) + Widget w; + XtWidgetGeometry *intended, *preferred; +{ + preferred->request_mode = CWWidth | CWHeight; + + CalculatePreferredSize(w, &preferred->width, &preferred->height); + +#define Set(bit) (intended->request_mode & bit) + + if (Set(CWWidth) && intended->width == preferred->width && + Set(CWHeight) && intended->height == preferred->height) { + return XtGeometryYes; + } + + if (preferred->width == w->core.width && + preferred->height == w->core.height) { + return XtGeometryNo; + } + + return XtGeometryAlmost; + +#undef Set +} + +/* ARGSUSED */ +static XtGeometryResult GeometryManager(w, desired, allowed) + Widget w; + XtWidgetGeometry *desired; + XtWidgetGeometry *allowed; +{ + return XtGeometryYes; +} + + + +static void ExtractPosition(event, x, y , t) + XEvent *event; + Position *x, *y; /* RETURN */ + Time *t; /* RETURN */ +{ + if (event == NULL) + return; + + switch(event->type) { + case MotionNotify: + *x = event->xmotion.x; + *y = event->xmotion.y; + *t = event->xmotion.time; + break; + case ButtonPress: + case ButtonRelease: + *x = event->xbutton.x; + *y = event->xbutton.y; + *t = event->xbutton.time; + break; + case KeyPress: + case KeyRelease: + *x = event->xkey.x; + *y = event->xkey.y; + *t = event->xkey.time; + break; + case EnterNotify: + case LeaveNotify: + *x = event->xcrossing.x; + *y = event->xcrossing.y; + *t = event->xcrossing.time; + break; + default: + *x = 0; + *y = 0; + *t = XtLastTimestampProcessed(event->xany.display); + } +} + +/* ARGSUSED */ +static Boolean ExtractCell(tw, px, py, row, column) + XawTableWidget tw; + Position px,py; + int *row, *column; /* RETURN */ +{ + Position x; + Position y; +#define SH (tw->table.label_shadow_thickness) + for(*row = 0; *row < ROWS(tw); (*row)++) { + for(*column = 0; *column < COLUMNS(tw); (*column)++) + if ((x=GetX(tw,*column)+SH) <= px) + if ((y=GetY(tw,*row)+SH) <= py) + if ((x+COLUMN_WIDTH(tw,*column)) >= px) + if ((y+tw->table.row_height) >= py) + return False; + } +#undef SH + + return True; +} + + +/* ARGSUSED */ +static void WalkForCells(w, proc, b_r, e_r, b_c, e_c) + Widget w; + XawTableProc proc; + int b_r, e_r, b_c, e_c; +{ + XawTableWidget tw = (XawTableWidget)w; + int i,j; + + (void)go_table((XtPointer)w, proc, STUFF(tw), + b_r, e_r, b_c, e_c, + XawTABLE_RIGHT_DOWN, + &i, &j, (XtPointer)NULL); +} + +static char* DummyString() +{ + return XtNewString(""); +} + +static char* CopyOnlyPrintable(raw) + char* raw; +{ + char* clear; + char *s,*h; + int lenght; + + for(s = raw, lenght = 0; (*s) != '\0';) + { + if (isprint(*s++)) + lenght++; + } + + clear = CALLOC(++lenght, char); + + for(s = raw, h = clear; (*s) != '\0';) + { + if (isprint(*s)) + (*h++) = (*s++); + } + + (*h) = '\0'; + + return clear; +} + +#ifdef EBUG_XRAW_MALLOC +/* ARGSUSED */ +static Boolean CheckLabel(p, i, j, call_data, client_data) + XtPointer p; + int i; + int j; + XtPointer call_data; + XtPointer client_data; /* unused */ +{ + Widget w = (Widget) p; + XawTableWidget tw = (XawTableWidget) p; + XawTableCell cell = (XawTableCell)call_data; + char* label = CELL(label); + + for (label = CELL(label); *label != '\0'; label++) + if (!isprint(*label)) + { + char message[80]; + char *p = NULL; + sprintf(message, "wrong label '%s' in cell (%4d,%4d) in Table widget '%s'", + CELL(label), i, j, w->core.name); + XtWarning(message); + *p = '\0'; + break; + } + + return False; +} +#endif + +#ifdef EBUG_XRAW_MALLOC +static void CheckAllLabels(tw) + XawTableWidget tw; +{ + WalkForCells((Widget)tw, (XawTableProc)CheckLabel, + 0, ROWS(tw)-1, 0, COLUMNS(tw)-1); +} +#endif + +static void MoveEditCell (tw, row, column) + XawTableWidget tw; + int row; + int column; +{ + Position x,y; + + x = GetX(tw,column); + y = GetY(tw,row); + + XtConfigureWidget(EDIT(tw), + (Position)(x + tw->table.label_shadow_thickness), + (Position)(y + tw->table.label_shadow_thickness), + (Dimension) COLUMN_WIDTH(tw, column), + (Dimension) tw->table.row_height, + (Dimension)0); + XawDrawFrame((Widget)tw, + x, + y, + (Dimension)(COLUMN_WIDTH(tw, column) + + 2 * tw->table.label_shadow_thickness), + (Dimension)(tw->table.row_height + + 2 * tw->table.label_shadow_thickness), + XawSUNKEN, + tw->table.label_shadow_thickness, + tw->table.edit_top, + tw->table.edit_bottom); + +} + +/* ARGSUSED */ +static Boolean CompareCells(p, i, j, call_data, client_data) + XtPointer p; + int i; /* unused */ + int j; /* unused */ + XtPointer call_data; + XtPointer client_data; /* unused */ +{ + XawTableCell cell = (XawTableCell)call_data; + XawTableCell test_cell = (XawTableCell)client_data; + + return(cell == test_cell); +} + +/****************************************************************** + * + * CONVENIENCE FUNCTIONS + * + ******************************************************************/ + + +void +#ifdef Xraw_NEED_PROTO +XawTableGetSize (Widget w, + int *rows, + int *columns) +#else +XawTableGetSize (w, rows, columns) + Widget w; + int *rows; + int *columns; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + + *rows = ROWS(tw); + *columns = COLUMNS(tw); +} + +void +#ifdef Xraw_NEED_PROTO +XawTableDoLayout (Widget w, + Boolean do_layout) +#else +XawTableDoLayout (w, do_layout) + Widget w; + Boolean do_layout; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + + if (do_layout) + tw->table.no_redraw--; + else + tw->table.no_redraw++; + + tw->table.no_redraw = MAX (tw->table.no_redraw, 0); + + if (tw->table.no_redraw == 0) + Redisplay (w, (XEvent *)NULL, (Region)NULL); +} + +int +#ifdef Xraw_NEED_PROTO +XawTableSetNewSize (Widget w, + int rows, + int columns) +#else +XawTableSetNewSize (w, rows, columns) + Widget w; + int rows; + int columns; +#endif +{ + if (REJECT == SetTableSize(w, rows, columns)) + return REJECT; + + UpdateTable((XawTableWidget)w); + return ACCEPT; +} + +char * +#ifdef Xraw_NEED_PROTO +XawTableGetLabelByCell (XawTableCell cell) +#else +XawTableGetLabelByCell (cell) + XawTableCell cell; +#endif +{ + return GET_CELL_LABEL; +} + +void +#ifdef Xraw_NEED_PROTO +XawTableGetEditPosition (Widget w, int *row, int *column) +#else +XawTableGetEditPosition(w, row, column) + Widget w; + int *row; + int *column; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + + *row = tw->table.edit_row; + *column = tw->table.edit_column; +} + +Boolean +#ifdef Xraw_NEED_PROTO +XawTableWalk ( + Widget w, + XawTableProc proc, + int b_row, + int e_row, + int b_column, + int e_column, + int direction, + int *i, /* returned */ + int *j, /* returned */ + XtPointer client_data) +#else +XawTableWalk(w, proc, b_row, e_row, b_column, e_column, + direction, i, j, client_data) + Widget w; + XawTableProc proc; + int b_row, e_row, b_column, e_column; + int direction; + int *i; /* returned */ + int *j; /* returned */ + XtPointer client_data; +#endif +{ + return go_table((XtPointer)w, proc, STUFF(w), + b_row, e_row, b_column, e_column, + direction, + i, j, client_data); +} + +Boolean +#ifdef Xraw_NEED_PROTO +XawTableSearchLabel (Widget w, char *name, int *row, int *column) +#else +XawTableSearchLabel (w, name, row, column) + Widget w; + char *name; + int *row, *column; +#endif +{ + int row_start = *row; + int column_start = *column; + XrmQuark templ = XrmStringToQuark (name); + + if (XawTableWalk(w, (XawTableProc)MatchLabel, + row_start, row_start, column_start, COLUMNS(w)-1, + XawTABLE_RIGHT_DOWN, + row, column, (XtPointer)&templ)) { + return (True); + } + if (XawTableWalk(w, (XawTableProc)MatchLabel, + row_start+1, ROWS(w)-1, 0, COLUMNS(w)-1, + XawTABLE_RIGHT_DOWN, + row, column, (XtPointer)&templ)) { + return (True); + } + if (XawTableWalk(w, (XawTableProc)MatchLabel, + 0, row_start-1, 0, COLUMNS(w)-1, + XawTABLE_RIGHT_DOWN, + row, column, (XtPointer)&templ)) { + return (True); + } + if (XawTableWalk(w, (XawTableProc)MatchLabel, + row_start, row_start, 0, column_start, + XawTABLE_RIGHT_DOWN, + row, column, (XtPointer)&templ)) { + return (True); + } + return (False); + +} + +/************************************************************** + * + * + * + * ROW routines + * + * + * + **************************************************************/ + +int +#ifdef Xraw_NEED_PROTO +XawTablePrependRow (Widget w) +#else +XawTablePrependRow(w) + Widget w; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCell cell; + XawTableCallbackStruct callback_str; + + if (STUFF(tw) == NULL) { + String subs[1]; + Cardinal num_subs = 1; + subs[0] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "prependRow", "XawTablePrependRow","XawToolkitError", + "An attempt to add a row in empty table in TableWidget '%s'", + subs, &num_subs); + return REJECT; + } + + + /* request for allowance */ + + cell = STUFF(tw); + + callback_str.reason = XawTABLE_ALLOW_ADD_ROW; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNallowAddRow, callback_str); + + if (callback_str.do_it != True) + return REJECT; + + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + row_insert_before(STUFF(tw), sizeof(XawTableCellRec)); + ROWS(tw)++; + + STUFF(tw) = (XawTableCell)get_table(STUFF(tw)); + + WalkForCells(w, (XawTableProc)InitCell, 0, 0, 0, COLUMNS(tw)-1); + + if (XawTableIsEditManaged(w)) + MoveEditCell (tw, ++(tw->table.edit_row), tw->table.edit_column); + + UpdateTable(tw); + + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + if (XtCallbackHasSome == XtHasCallbacks(w, XtNaddRow)) + { + cell = STUFF(tw); + + callback_str.reason = XawTABLE_ADD_ROW; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + XtCallCallbacks (w, XtNaddRow, (XtPointer)&callback_str); + } + + return ACCEPT; +} + +int +#ifdef Xraw_NEED_PROTO +XawTableAppendRow (Widget w) +#else +XawTableAppendRow (w) + Widget w; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCell cell; + XawTableCallbackStruct callback_str; + + if (STUFF(tw) == NULL) + { + String subs[1]; + Cardinal num_subs = 1; + subs[0] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "appendRow", "XawTableAppendRow","XawToolkitError", + "An attempt to add a row in empty table in TableWidget '%s'", + subs, &num_subs); + return REJECT; + } + + + /* request for allowance */ + + cell = (XawTableCell)get_cell(STUFF(tw), ROWS(tw)-1, 0); + + callback_str.reason = XawTABLE_ALLOW_ADD_ROW; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNallowAddRow, callback_str); + + if (callback_str.do_it != True) + return REJECT; + + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + row_insert_after(get_cell(STUFF(tw), ROWS(tw) - 1, 0), + sizeof(XawTableCellRec)); + + ROWS(tw)++; + + WalkForCells(w, (XawTableProc)InitCell, + ROWS(tw)-1, ROWS(tw)-1, 0, COLUMNS(tw)-1); + + UpdateTable(tw); + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + if (XtCallbackHasSome == XtHasCallbacks(w, XtNaddRow)) + { + cell = (XawTableCell)get_cell(STUFF(tw), ROWS(tw)-1, 0); + + callback_str.reason = XawTABLE_ADD_ROW; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = ROWS(tw)-1; + callback_str.column = 0; + callback_str.do_it = True; + + XtCallCallbacks (w, XtNaddRow, (XtPointer)&callback_str); + } + + return ACCEPT; +} + +int +#ifdef Xraw_NEED_PROTO +XawTableInsertRow (Widget w, int row) +#else +XawTableInsertRow (w, row) + Widget w; + int row; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCell cell; + XawTableCallbackStruct callback_str; + + if (STUFF(tw) == NULL) { + String subs[1]; + Cardinal num_subs = 1; + subs[0] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "insertRow", "XawTableInsertRow","XawToolkitError", + "An attempt to add a row in empty table in TableWidget '%s'", + subs, &num_subs); + return REJECT; + } + + if (row != InRange(row, 0, ROWS(tw)-1)) { + String subs[1]; + Cardinal num_subs = 1; + subs[0] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "insertRow", "XawTableInsertRow","XawToolkitError", + "Incorrect attempt to insert a row in TableWidget '%s'", + subs, &num_subs); + return REJECT; + } + + /* request for allowance */ + + cell = (XawTableCell)get_cell(STUFF(tw), row, 0); + + callback_str.reason = XawTABLE_ALLOW_ADD_ROW; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNallowAddRow, callback_str); + + if (callback_str.do_it != True) + return REJECT; + + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + row_insert_before(get_cell((XtPointer)STUFF(tw), row, 0), + sizeof(XawTableCellRec)); + + ROWS(tw)++; + + if (row == 0) + STUFF(tw) = (XawTableCell)get_table(STUFF(tw)); + + WalkForCells(w, (XawTableProc)InitCell, row, row, 0, COLUMNS(tw)-1); + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + if (XawTableIsEditManaged(w) && row <= tw->table.edit_row){ + tw->table.no_redraw++; + MoveEditCell (tw, ++(tw->table.edit_row), tw->table.edit_column); + tw->table.no_redraw--; + } + + UpdateTable(tw); + + if (XtCallbackHasSome == XtHasCallbacks(w, XtNaddRow)) + { + cell = (XawTableCell)get_cell(STUFF(tw), row, 0); + + callback_str.reason = XawTABLE_ADD_ROW; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = row; + callback_str.column = 0; + callback_str.do_it = True; + + XtCallCallbacks (w, XtNaddRow, (XtPointer)&callback_str); + } + + return ACCEPT; +} + +int +#ifdef Xraw_NEED_PROTO +XawTableDeleteRow (Widget w, int row) +#else +XawTableDeleteRow (w, row) + Widget w; + int row; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCell cell; + XawTableCallbackStruct callback_str; + + if (STUFF(tw) == NULL) { + String subs[1]; + Cardinal num_subs = 1; + subs[0] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "deleteRow", "XawTableDeleteRow","XawToolkitError", + "An attempt to delete a row in empty table in TableWidget '%s'", + subs, &num_subs); + return REJECT; + } + + if (row != InRange(row, 0, ROWS(tw)-1)) { + String subs[3]; + Cardinal num_subs = 3; + sprintf(subs[0], "%5d", row); + sprintf(subs[1], "%5d", ROWS(tw)-1); + subs[2] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "deleteRow", "XawTableDeleteRow","XawToolkitError", + "Incorrect value of row (%s, max is %s) in TableWidget '%s'", + subs, &num_subs); + return REJECT; + } + + + /* request for allowance */ + + cell = (XawTableCell)get_cell(STUFF(tw), row, 0); + + callback_str.reason = XawTABLE_ALLOW_DELETE_ROW; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNallowDeleteRow, callback_str); + + if (callback_str.do_it != True) + return REJECT; + + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + + if (XtCallbackHasSome == XtHasCallbacks(w, XtNdeleteRow)) + { + cell = (XawTableCell)get_cell(STUFF(tw), row, 0); + + callback_str.reason = XawTABLE_DELETE_ROW; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = row; + callback_str.column = 0; + callback_str.do_it = True; + + XtCallCallbacks (w, XtNdeleteRow, (XtPointer)&callback_str); + } + + /* if selections owner locates here, then disown selections */ + + if (tw->table.cell_own != (XawTableCell)NULL) + { + Boolean have_find; + int i, j; + + have_find = go_table((XtPointer)w, CompareCells, STUFF(tw), + row, row, 0, COLUMNS(tw)-1, + XawTABLE_RIGHT_DOWN, &i, &j, + (XtPointer)tw->table.cell_own); + if (have_find) { + for (; 0 < tw->table.num_selections;) + XtDisownSelection (w, + tw->table.selections[--(tw->table.num_selections)], + XtLastTimestampProcessed(XtDisplay(w))); + + tw->table.cell_own = (XawTableCell)NULL; + } + } + + if (row == 0) + STUFF(tw) = (XawTableCell)get_cell(STUFF(tw), 1, 0); + + if (--ROWS(tw) == 0) + STUFF(tw) = (XawTableCell)NULL; + + WalkForCells(w, (XawTableProc)DeleteCell, row, row, 0, COLUMNS(tw)-1); + + row_delete(cell); + + if (XawTableIsEditManaged(w)) + { + tw->table.no_redraw++; + if (row < tw->table.edit_row){ + MoveEditCell (tw, --(tw->table.edit_row), tw->table.edit_column); + } + else if (row == tw->table.edit_row){ + UNMANAGE_EDIT(tw); + tw->table.edit_row = InRange (tw->table.edit_row, 0, ROWS(tw)-1); + XawTableSetEdit (w, tw->table.edit_row, tw->table.edit_column); + } + tw->table.no_redraw--; + } + + UpdateTable(tw); + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + return ACCEPT; +} + + + +/************************************************************** + * + * + * + * COLUMN routines + * + * + * + **************************************************************/ + +int +#ifdef Xraw_NEED_PROTO +XawTablePrependColumn (Widget w, int width) +#else +XawTablePrependColumn (w, width) + Widget w; + int width; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + int j; + XawTableCell cell; + XawTableCallbackStruct callback_str; + + if (STUFF(tw) == NULL) { + String subs[1]; + Cardinal num_subs = 1; + subs[0] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "prependColumn", "XawTablePrependColumn","XawToolkitError", + "An attempt to add a column in empty table in TableWidget '%s'", + subs, &num_subs); + return REJECT; + } + + /* request for allowance */ + + cell = STUFF(tw); + + callback_str.reason = XawTABLE_ALLOW_ADD_COLUMN; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNallowAddColumn, callback_str); + + if (callback_str.do_it != True) + return REJECT; + + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + column_insert_before(STUFF(tw), sizeof(XawTableCellRec)); + COLUMNS(tw)++; + + STUFF(tw) = (XawTableCell)get_table(STUFF(tw)); + + WalkForCells(w, (XawTableProc)InitCell, 0, ROWS(tw)-1, 0, 0); + + /* + * insert new item in `column_data' list + */ + + if (tw->table.column_data) + { + tw->table.column_data = (XawTableColumn) + XtRealloc((XtPointer)tw->table.column_data, + (Cardinal)(COLUMNS(tw) * sizeof(XawTableColumnRec))); + } + else + { + tw->table.column_data = CALLOC(COLUMNS(tw), XawTableColumnRec); + for(j = 0; j < COLUMNS(tw); j++) + COLUMN_DATA(tw)[j].flag = 0; + } + + for(j = COLUMNS(tw)-2; j >= 0; j--) + (void)memcpy((char*)&(COLUMN_DATA(tw)[j+1]), (char*)&(COLUMN_DATA(tw)[j]), + sizeof(XawTableColumnRec)); + + COLUMN_DATA(tw)[0].flag |= _CL_width; + COLUMN_DATA(tw)[0].width = width; + + + if (XawTableIsEditManaged(w)) + MoveEditCell (tw, tw->table.edit_row, ++(tw->table.edit_column)); + + /* Let's look the table which we have made now */ + UpdateTable(tw); + + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + if (XtCallbackHasSome == XtHasCallbacks(w, XtNaddColumn)) + { + cell = STUFF(tw); + + callback_str.reason = XawTABLE_ADD_COLUMN; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + XtCallCallbacks (w, XtNaddColumn, (XtPointer)&callback_str); + } + + return ACCEPT; +} + +int +#ifdef Xraw_NEED_PROTO +XawTableAppendColumn (Widget w, int width) +#else +XawTableAppendColumn (w, width) + Widget w; + int width; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + int j; + XawTableCell cell; + XawTableCallbackStruct callback_str; + + if (STUFF(tw) == NULL) { + String subs[1]; + Cardinal num_subs = 1; + subs[0] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "addingColumn", "XawTableAppendColumn","XawToolkitError", + "An attempt to add a column in empty table in TableWidget '%s'", + subs, &num_subs); + return REJECT; + } + + /* request for allowance */ + + cell = (XawTableCell)get_cell(STUFF(tw), 0, COLUMNS(tw)-1); + + callback_str.reason = XawTABLE_ALLOW_ADD_COLUMN; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNallowAddColumn, callback_str); + + if (callback_str.do_it != True) + return REJECT; + + + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + column_insert_after(get_cell(STUFF(tw), 0, COLUMNS(tw)-1), + sizeof(XawTableCellRec)); + + COLUMNS(tw)++; + + WalkForCells(w, (XawTableProc)InitCell, + 0, ROWS(tw)-1, COLUMNS(tw)-1, COLUMNS(tw)-1); + + + + + /* + * insert new item in `column_data' list + */ + + if (tw->table.column_data) + { + tw->table.column_data = (XawTableColumn) + XtRealloc((XtPointer)tw->table.column_data, + (Cardinal)(COLUMNS(tw) * sizeof(XawTableColumnRec))); + } + else + { + tw->table.column_data = CALLOC(COLUMNS(tw), XawTableColumnRec); + for(j = 0; j < COLUMNS(tw); j++) + COLUMN_DATA(tw)[j].flag = 0; + } + + COLUMN_DATA(tw)[COLUMNS(tw)-1].flag |= _CL_width; + COLUMN_DATA(tw)[COLUMNS(tw)-1].width = width; + + + /* Let's look the table which we have made now */ + UpdateTable(tw); + + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + if (XtCallbackHasSome == XtHasCallbacks(w, XtNaddColumn)) + { + cell = (XawTableCell)get_cell(STUFF(tw), 0, COLUMNS(tw)-1); + + callback_str.reason = XawTABLE_ADD_COLUMN; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = COLUMNS(tw)-1; + callback_str.do_it = True; + + XtCallCallbacks (w, XtNaddColumn, (XtPointer)&callback_str); + } + + return ACCEPT; +} + +int +#ifdef Xraw_NEED_PROTO +XawTableInsertColumn (Widget w, int column, int width) +#else +XawTableInsertColumn(w, column, width) + Widget w; + int column; + int width; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCell cell; + int j; + XawTableCallbackStruct callback_str; + + if (STUFF(tw) == NULL) { + String subs[1]; + Cardinal num_subs = 1; + subs[0] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "insertColumn", "XawTableInsertColumn","XawToolkitError", + "An attempt to add a column in empty table in TableWidget '%s'", + subs, &num_subs); + return REJECT; + } + + if (column != InRange(column, 0, COLUMNS(tw)-1)) { + String subs[1]; + Cardinal num_subs = 1; + subs[0] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "insertColumn", "XawTableInsertColumn","XawToolkitError", + "It detected incorrect value of column in TableWidget '%s'", + subs, &num_subs); + return REJECT; + } + + /* request for allowance */ + + cell = (XawTableCell)get_cell(STUFF(tw), 0, column); + + callback_str.reason = XawTABLE_ALLOW_ADD_COLUMN; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNallowAddColumn, callback_str); + + if (callback_str.do_it != True) + return REJECT; + + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + column_insert_before (get_cell ((XtPointer)STUFF(tw), 0, column), + sizeof(XawTableCellRec)); + COLUMNS(tw)++; + + if (column == 0) + STUFF(tw) = (XawTableCell) get_table (STUFF(tw)); + + WalkForCells(w, (XawTableProc)InitCell, 0, ROWS(tw)-1, column, column); + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + /* + * insert new item in `column_data' list + */ + + if (tw->table.column_data) + { + tw->table.column_data = (XawTableColumn) + XtRealloc((XtPointer)tw->table.column_data, + (Cardinal)(COLUMNS(tw) * sizeof(XawTableColumnRec))); + } + else + { + tw->table.column_data = CALLOC(COLUMNS(tw), XawTableColumnRec); + for(j = 0; j < COLUMNS(tw); j++) + COLUMN_DATA(tw)[j].flag = 0; + } + + for(j = COLUMNS(tw)-2; j >= column; j--) + (void)memcpy((char*)&(COLUMN_DATA(tw)[j+1]), (char*)&(COLUMN_DATA(tw)[j]), + sizeof(XawTableColumnRec)); + + COLUMN_DATA(tw)[column].flag |= _CL_width; + COLUMN_DATA(tw)[column].width = width; + + /* + * move the edit cell + */ + + if (XawTableIsEditManaged(w) && column <= tw->table.edit_column){ + tw->table.no_redraw++; + MoveEditCell (tw, tw->table.edit_row, ++(tw->table.edit_column)); + tw->table.no_redraw--; + } + + /* Let's look the table which we have made now */ + UpdateTable(tw); + + if (XtCallbackHasSome == XtHasCallbacks(w, XtNaddColumn)) + { + cell = (XawTableCell)get_cell(STUFF(tw), 0, column); + + callback_str.reason = XawTABLE_ADD_COLUMN; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = column; + callback_str.do_it = True; + + XtCallCallbacks (w, XtNaddColumn, (XtPointer)&callback_str); + } + + return ACCEPT; +} + +int +#ifdef Xraw_NEED_PROTO +XawTableDeleteColumn (Widget w, int column) +#else +XawTableDeleteColumn(w, column) + Widget w; + int column; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCell cell; + int j; + XawTableCallbackStruct callback_str; + + + if (STUFF(tw) == NULL) { + String subs[1]; + Cardinal num_subs = 1; + subs[0] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "deleteColumn", "XawTableDeleteColumn","XawToolkitError", + "An attempt to delete a column in empty table in TableWidget '%s'", + subs, &num_subs); + return REJECT; + } + + if (column != InRange(column, 0, COLUMNS(tw)-1)) { + String subs[1]; + Cardinal num_subs = 1; + subs[0] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "deleteColumn", "XawTableDeleteColumn","XawToolkitError", + "It detected incorrect value of column in TableWidget '%s'", + subs, &num_subs); + return REJECT; + } + + /* request for allowance */ + + cell = (XawTableCell)get_cell(STUFF(tw), 0, column); + + callback_str.reason = XawTABLE_ALLOW_DELETE_COLUMN; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = 0; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNallowDeleteColumn, callback_str); + + if (callback_str.do_it != True) + return REJECT; + + + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + if (XtCallbackHasSome == XtHasCallbacks(w, XtNdeleteColumn)) + { + cell = (XawTableCell)get_cell(STUFF(tw), 0, column); + + callback_str.reason = XawTABLE_DELETE_COLUMN; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = 0; + callback_str.column = column; + callback_str.do_it = True; + + XtCallCallbacks (w, XtNdeleteColumn, (XtPointer)&callback_str); + } + + /* if selections owner locates here, then disown selections */ + + if (tw->table.cell_own != (XawTableCell)NULL) + { + Boolean have_find; + int i, j; + + have_find = go_table((XtPointer)w, CompareCells, STUFF(tw), + 0, ROWS(tw)-1, column, column, + XawTABLE_RIGHT_DOWN, &i, &j, + (XtPointer)tw->table.cell_own); + if (have_find) { + for (; 0 < tw->table.num_selections;) + XtDisownSelection (w, + tw->table.selections[--(tw->table.num_selections)], + XtLastTimestampProcessed(XtDisplay(w))); + + tw->table.cell_own = (XawTableCell)NULL; + } + } + + if (column == 0) + STUFF(tw) = (XawTableCell)get_cell(STUFF(tw), 0, 1); + + if (--COLUMNS(tw) == 0) + STUFF(tw) = (XawTableCell)NULL; + + + WalkForCells(w, (XawTableProc)DeleteCell, 0, ROWS(tw)-1, column, column); + + column_delete(cell); + + /* + * shrink column data list + */ + + if (COLUMNS(tw) == 0) { + XtFree((XtPointer)tw->table.column_data); + tw->table.column_data = NULL; + } + else + { + for(j = column; j < COLUMNS(tw); j++) + (void)memcpy((char*)&(COLUMN_DATA(tw)[j]),(char*)&(COLUMN_DATA(tw)[j+1]), + sizeof(XawTableColumnRec)); + + tw->table.column_data = (XawTableColumn) + XtRealloc((XtPointer)tw->table.column_data, + (Cardinal)(COLUMNS(tw) * sizeof(XawTableColumnRec))); + } + + + /* + * shift the edit cell + */ + + if (XawTableIsEditManaged(w)) + { + tw->table.no_redraw++; + if (column < tw->table.edit_column){ + MoveEditCell (tw, tw->table.edit_row, --(tw->table.edit_column)); + } + else if (column == tw->table.edit_column){ + UNMANAGE_EDIT(tw); + tw->table.edit_column = InRange (tw->table.edit_column,0,COLUMNS(tw)-1); + XawTableSetEdit (w, tw->table.edit_row, tw->table.edit_column); + } + tw->table.no_redraw--; + } + + /* Let's look the table which we have made now */ + UpdateTable(tw); + +#ifdef EBUG_XRAW_MALLOC + CHECK_TABLE(tw); +#endif + + return ACCEPT; +} + + +Boolean +#ifdef Xraw_NEED_PROTO +XawTableIsEditManaged (Widget w) +#else +XawTableIsEditManaged (w) + Widget w; +#endif +{ + return XtIsManaged(((XawTableWidget)w)->table.edit); +} + + + +int +#ifdef Xraw_NEED_PROTO +XawTableSetLabel (Widget w, int row, int column, char *raw_label) +#else +XawTableSetLabel(w, row, column, raw_label) + Widget w; + int row; + int column; + char *raw_label; +#endif +{ + register XawTableWidget tw = (XawTableWidget)w; + XawTableCallbackStruct callback_str; + XawTableCell cell; + char* label = NULL; + XawTableCellRec new; + + if ((ROWS(tw) < 1) || (COLUMNS(tw) < 1) || + (row != InRange(row, 0, ROWS(tw)-1)) || + (column != InRange(column, 0, COLUMNS(tw)-1))) + { + String subs[3]; + Cardinal num_subs = 3; + sprintf(subs[0], "%5d", row); + sprintf(subs[1], "%5d", column); + subs[2] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "SetLabel", "XawTableSetLabel","XawToolkitError", +"XawTableSetLabel\nIncorrect value of rows or columns (%s,%s) in TableWidget '%s' ", + subs, &num_subs); + return REJECT; + } + + cell = (XawTableCell)get_cell(STUFF(tw), row, column); + + if (raw_label == (char*)NULL) + label = DummyString(); + else + label = CopyOnlyPrintable(raw_label); + + if (streq(label,CELL(label))) { + XtFree(label); /* XtMalloc in CopyOnlyPrintable */ + return ACCEPT; + } + + (void)memcpy((char*)&new, (char*)cell, sizeof(XawTableCellRec)); + new.label = label; + + callback_str.reason = XawTABLE_CHANGED_CELL; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = &new; + callback_str.row = row; + callback_str.column = column; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNchangedCell, callback_str); + + if (callback_str.do_it != True) { + XtFree(label); + return REJECT; + } + + + if (CELL(label)) + XtFree(CELL(label)); + + (void)memcpy((char*)cell, (char*)&new, sizeof(XawTableCellRec)); + + SetLabelWidth (tw, row, column); + Reposition (tw, cell, row, column); + + if (IsEditInRowColumn (tw, row, column)) + { + XtVaSetValues (EDIT(w), "string", CELL(label), NULL); + } + else if (XtIsRealized (w) && w->core.visible && !tw->table.no_redraw) + { + int x = GetX(tw,column); + int y = GetY(tw,row); + unsigned int width = (unsigned int) COLUMN_WIDTH(tw,column); + unsigned int height = (unsigned int) tw->table.row_height; + + XClearArea (XtDisplay(w), XtWindow(w), x, y, width, height, FALSE); + (void) PaintCell (w, row, column, (XtPointer)cell, (XtPointer)NULL); + } + return ACCEPT; +} + + + + +int +#ifdef Xraw_NEED_PROTO +XawTableSetCellColours (Widget w, int row, int column, + Pixel fore, Pixel back) +#else +XawTableSetCellColours (w, row, column, fore, back) + Widget w; + int row; + int column; + Pixel fore; + Pixel back; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCallbackStruct callback_str; + XawTableCell cell; + XawTableCellRec new; + NormalReverseGC* normal; + ShadowGC* shadow; + + + + if ((ROWS(tw) < 1) || (COLUMNS(tw) < 1) || + (row != InRange (row, 0, ROWS(tw)-1)) || + (column != InRange (column, 0, COLUMNS(tw)-1))) + { + String subs[3]; + Cardinal num_subs = 3; + sprintf(subs[0], "%5d", row); + sprintf(subs[1], "%5d", column); + subs[2] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "SetCellColours", "XawTableSetCellColours","XawToolkitError", +"XawTableSetCellColours\nIncorrect value of rows or columns (%s,%s) in TableWidget '%s' ", + subs, &num_subs); + return REJECT; + } + cell = (XawTableCell)get_cell(STUFF(tw), row, column); + + if (CELL(special_colour) && fore == CELL(fore) && back == CELL(back)) + return ACCEPT; + + /* + * prepare new cell stuff from old one + */ + (void)memcpy((char*)&new, (char*)cell, sizeof(XawTableCellRec)); + new.special_colour = True; + new.back = back; + new.fore = fore; + + /* normal and reverse GC's */ + normal = GetNormalGC(w, fore, back, tw->table.font->fid); + + new.normal = normal->normal; + new.reverse = normal->reverse; + + + /* shadow GC's */ + shadow = GetShadowGC(w, back); + + new.top = shadow->top; + new.bottom = shadow->bottom; + + + callback_str.reason = XawTABLE_CHANGED_CELL; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = &new; + callback_str.row = row; + callback_str.column = column; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNchangedCell, callback_str); + + if (callback_str.do_it) + { + int x = GetX(tw,column); + int y = GetY(tw,row); + unsigned int width = (unsigned int) COLUMN_WIDTH(tw,column); + unsigned int height = (unsigned int) tw->table.row_height; + + if (XtIsRealized(w) && w->core.visible && + !tw->table.no_redraw && !tw->table.no_refigure) { + XClearArea (XtDisplay(w), XtWindow(w), + x + tw->table.label_shadow_thickness, + y + tw->table.label_shadow_thickness, + width, height, FALSE); + PaintLabel (w, row, column, x, y, &new); + PaintShadow (w, row, column, x, y, &new); + XFlush(XtDisplay(w)); + } + + if (CELL(special_colour)) { + ReleaseNormalGC(w, CELL(fore), CELL(back)); + ReleaseShadowGC(w, CELL(back)); + } + (void)memcpy((char*)cell, (char*)&new, sizeof(XawTableCellRec)); + + return ACCEPT; + } + else + { + ReleaseNormalGC(w, fore, back); + ReleaseShadowGC(w, back); + return REJECT; + } +} + + +int +#ifdef Xraw_NEED_PROTO +XawTableSetCellDefaultColours (Widget w, int row, int column) +#else +XawTableSetCellDefaultColours (w, row, column) + Widget w; + int row; + int column; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCallbackStruct callback_str; + XawTableCell cell; + XawTableCellRec new; + + if ((ROWS(tw) < 1) || (COLUMNS(tw) < 1) || + (row != InRange (row, 0, ROWS(tw)-1)) || + (column != InRange (column, 0, COLUMNS(tw)-1))) + { + String subs[3]; + Cardinal num_subs = 3; + sprintf(subs[0], "%5d", row); + sprintf(subs[1], "%5d", column); + subs[2] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "SetCellColours", "XawTableSetCellDefaultColours","XawToolkitError", +"XawTableSetCellDefaultColours\n\ +Incorrect value of row or column (%s,%s) in Table widget '%s'", + subs, &num_subs); + return REJECT; + } + + cell = (XawTableCell)get_cell(STUFF(tw), row, column); + + if (!CELL(special_colour)) + return ACCEPT; + + /* + * prepare new cell stuff from old one + */ + (void)memcpy((char*)&new, (char*)cell, sizeof(XawTableCellRec)); + new.special_colour = False; + new.fore = tw->table.foreground; + new.back = tw->core.background_pixel; + + callback_str.reason = XawTABLE_CHANGED_CELL; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = &new; + callback_str.row = row; + callback_str.column = column; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNchangedCell, callback_str); + + if (callback_str.do_it) + { + int x = GetX(tw,column); + int y = GetY(tw,row); + unsigned int width = (unsigned int) COLUMN_WIDTH(tw,column); + unsigned int height = (unsigned int) tw->table.row_height; + + if (XtIsRealized(w) && w->core.visible && !tw->table.no_redraw) { + XClearArea (XtDisplay(w), XtWindow(w), + x + tw->table.label_shadow_thickness, + y + tw->table.label_shadow_thickness, + width, height, FALSE); + PaintLabel (w, row, column, x, y, &new); + PaintShadow (w, row, column, x, y, &new); + XFlush(XtDisplay(w)); + } + + if (CELL(special_colour)) { + ReleaseNormalGC(w, CELL(fore), CELL(back)); + ReleaseShadowGC(w, CELL(back)); + } + (void)memcpy((char*)cell, (char*)&new, sizeof(XawTableCellRec)); + + return ACCEPT; + } + else + { + return REJECT; + } +} + +int +#ifdef Xraw_NEED_PROTO +XawTableSetCellBackground (Widget w, int row, int column, Pixel back) +#else +XawTableSetCellBackground (w, row, column, back) + Widget w; + int row; + int column; + Pixel back; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCallbackStruct callback_str; + XawTableCell cell; + XawTableCellRec new; + NormalReverseGC* normal; + ShadowGC* shadow; + + if ((ROWS(tw) < 1) || (COLUMNS(tw) < 1) || + (row != InRange (row, 0, ROWS(tw)-1)) || + (column != InRange (column, 0, COLUMNS(tw)-1))) + { + String subs[3]; + Cardinal num_subs = 3; + sprintf(subs[0], "%5d", row); + sprintf(subs[1], "%5d", column); + subs[2] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "SetCellColours", "XawTableSetCellBackground","XawToolkitError", +"XawTableSetCellBackground\n\ +Incorrect value of row or column (%s,%s) in Table widget '%s'", + subs, &num_subs); + return REJECT; + } + + cell = (XawTableCell)get_cell(STUFF(tw), row, column); + + if (CELL(special_colour) && back == CELL(back)) + return ACCEPT; + + /* + * prepare new cell stuff from old one + */ + (void)memcpy((char*)&new, (char*)cell, sizeof(XawTableCellRec)); + new.special_colour = True; + new.back = back; + + if (!CELL(special_colour)) + new.fore = tw->table.foreground; + + /* normal and reverse GC's */ + normal = GetNormalGC(w, new.fore, back, tw->table.font->fid); + + new.normal = normal->normal; + new.reverse = normal->reverse; + + + /* shadow GC's */ + shadow = GetShadowGC(w, back); + + new.top = shadow->top; + new.bottom = shadow->bottom; + + + callback_str.reason = XawTABLE_CHANGED_CELL; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = &new; + callback_str.row = row; + callback_str.column = column; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNchangedCell, callback_str); + + if (callback_str.do_it) + { + int x = GetX(tw,column); + int y = GetY(tw,row); + unsigned int width = (unsigned int) COLUMN_WIDTH(tw,column); + unsigned int height = (unsigned int) tw->table.row_height; + + if (XtIsRealized(w) && w->core.visible && !tw->table.no_redraw) { + XClearArea (XtDisplay(w), XtWindow(w), + x + tw->table.label_shadow_thickness, + y + tw->table.label_shadow_thickness, + width, height, FALSE); + PaintLabel (w, row, column, x, y, &new); + PaintShadow (w, row, column, x, y, &new); + XFlush(XtDisplay(w)); + } + + if (CELL(special_colour)) { + ReleaseNormalGC(w, CELL(fore), CELL(back)); + ReleaseShadowGC(w, CELL(back)); + } + (void)memcpy((char*)cell, (char*)&new, sizeof(XawTableCellRec)); + + return ACCEPT; + } + else + { + ReleaseNormalGC(w, new.fore, back); + ReleaseShadowGC(w, back); + return REJECT; + } + +} + +int +#ifdef Xraw_NEED_PROTO +XawTableSetCellForeground (Widget w, int row, int column, Pixel fore) +#else +XawTableSetCellForeground (w, row, column, fore) + Widget w; + int row; + int column; + Pixel fore; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCallbackStruct callback_str; + XawTableCell cell; + XawTableCellRec new; + NormalReverseGC* normal; + ShadowGC* shadow; + + if ((ROWS(tw) < 1) || (COLUMNS(tw) < 1) || + (row != InRange (row, 0, ROWS(tw)-1)) || + (column != InRange (column, 0, COLUMNS(tw)-1))) + { + String subs[3]; + Cardinal num_subs = 3; + sprintf(subs[0], "%5d", row); + sprintf(subs[1], "%5d", column); + subs[2] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "SetCellColours", "XawTableSetCellBackground","XawToolkitError", +"XawTableSetCellBackground\n\ +Incorrect value of row or column (%s,%s) in Table widget '%s'", + subs, &num_subs); + return REJECT; + } + + cell = (XawTableCell)get_cell(STUFF(tw), row, column); + + if (CELL(special_colour) && fore == CELL(fore)) + return ACCEPT; + + /* + * prepare new cell stuff from old one + */ + (void)memcpy((char*)&new, (char*)cell, sizeof(XawTableCellRec)); + new.special_colour = True; + new.fore = fore; + + if (!CELL(special_colour)) + new.back = tw->core.background_pixel; + + /* normal and reverse GC's */ + normal = GetNormalGC(w, fore, new.back, tw->table.font->fid); + + new.normal = normal->normal; + new.reverse = normal->reverse; + + + /* shadow GC's */ + shadow = GetShadowGC(w, new.back); + + new.top = shadow->top; + new.bottom = shadow->bottom; + + + callback_str.reason = XawTABLE_CHANGED_CELL; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = cell; + callback_str.new_cell = &new; + callback_str.row = row; + callback_str.column = column; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNchangedCell, callback_str); + + if (callback_str.do_it) + { + int x = GetX(tw,column); + int y = GetY(tw,row); + unsigned int width = (unsigned int) COLUMN_WIDTH(tw,column); + unsigned int height = (unsigned int) tw->table.row_height; + + if (XtIsRealized(w) && w->core.visible && !tw->table.no_redraw) { + XClearArea (XtDisplay(w), XtWindow(w), + x + tw->table.label_shadow_thickness, + y + tw->table.label_shadow_thickness, + width, height, FALSE); + PaintLabel (w, row, column, x, y, &new); + PaintShadow (w, row, column, x, y, &new); + XFlush(XtDisplay(w)); + } + + if (CELL(special_colour)) { + ReleaseNormalGC(w, CELL(fore), CELL(back)); + ReleaseShadowGC(w, CELL(back)); + } + (void)memcpy((char*)cell, (char*)&new, sizeof(XawTableCellRec)); + + return ACCEPT; + } + else + { + ReleaseNormalGC(w, fore, new.back); + ReleaseShadowGC(w, new.back); + return REJECT; + } +} + +void +#ifdef Xraw_NEED_PROTO +XawTableGetCellColours (Widget w, int row, int column, + Pixel *fore, Pixel *back) +#else +XawTableGetCellColours (w, row, column, fore, back) + Widget w; + int row; + int column; + Pixel *fore; + Pixel *back; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCell cell = (XawTableCell)get_cell(STUFF(tw), row, column); + + + if (cell && cell->special_colour) { + *fore = cell->fore; + *back = cell->back; + } + else { + *fore = tw->table.foreground; + *back = tw->core.background_pixel; + } +} + +void +#ifdef Xraw_NEED_PROTO +XawTableGetCellColoursByCell (Widget w, XawTableCell cell, + Pixel *fore, Pixel *back) +#else +XawTableGetCellColoursByCell (w, cell, fore, back) + Widget w; + XawTableCell cell; + Pixel *fore; + Pixel *back; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + + if (cell && cell->special_colour) { + *fore = cell->fore; + *back = cell->back; + } + else { + *fore = tw->table.foreground; + *back = tw->core.background_pixel; + } +} + +/*#########################################################################*/ +/*# #*/ +/*# Column Defaults #*/ +/*# #*/ +/*#########################################################################*/ + +#ifdef notdef +/* ARGSUSED */ +static Boolean PaintCellWithClear(p, i, j, call_data, client_data) + XtPointer p; + int i; + int j; + XtPointer call_data; + XtPointer client_data; /* unused */ +{ + Widget w = (Widget) p; + XawTableWidget tw = (XawTableWidget) w; + XawTableCell cell = (XawTableCell) call_data; + unsigned int width = (unsigned int) COLUMN_WIDTH(tw,j); + unsigned int height = (unsigned int) tw->table.row_height; + Position x; + Position y; + + + x = GetX(tw,j); + y = GetY(tw,i); + + XClearArea (XtDisplay(w), XtWindow(w), + x + tw->table.label_shadow_thickness, + y + tw->table.label_shadow_thickness, + width, height, FALSE); + + PaintLabel (w, i, j, x, y, cell); + PaintShadow (w, i, j, x, y, cell); + + XFlush(XtDisplay(w)); + return False; +} +#endif + +void +#ifdef Xraw_NEED_PROTO +XawTableSetColumnJustify (Widget w, int column, XtJustify justify) +#else +XawTableSetColumnJustify (w, column, justify) + Widget w; + int column; + XtJustify justify; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + int i, j; + + if (column != InRange (column, 0, COLUMNS(tw)-1)) + return; + + COLUMN_DATA(tw)[column].flag |= _CL_justify; + COLUMN_DATA(tw)[column].justify = justify; + + for(i = 0; i < ROWS(tw); i++) + Reposition(tw, NULL, i, column); + + if (XtIsRealized(w) && w->core.visible && + !tw->table.no_redraw && !tw->table.no_refigure) + { + (void)go_table((XtPointer)w, PaintCell, STUFF(tw), + 0, ROWS(tw)-1, column, column, + XawTABLE_DOWN_RIGHT, + &i, &j, (XtPointer)NULL); + XFlush(XtDisplay(w)); + } +} + + +XtJustify +#ifdef Xraw_NEED_PROTO +XawTableGetColumnJustify (Widget w, int column) +#else +XawTableGetColumnJustify (w, column) + Widget w; + int column; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + + if (column != InRange (column, 0, COLUMNS(tw)-1)) + return XtJustifyCenter; + + if (COLUMN_DATA(tw)[column].flag & _CL_justify) + return COLUMN_DATA(tw)[column].justify; + + return XtJustifyCenter; +} + + +void +#ifdef Xraw_NEED_PROTO +XawTableSetColumnWidth (Widget w, int column, int width) +#else +XawTableSetColumnWidth(w, column, width) + Widget w; + int column; + int width; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCallbackStruct callback_str; + register int row; + + if (column != InRange (column, 0, COLUMNS(tw)-1)) + return; + + if ((COLUMN_DATA(tw)[column].flag & _CL_width) && + COLUMN_DATA(tw)[column].width == width) + return; + + COLUMN_DATA(tw)[column].flag |= _CL_width; + COLUMN_DATA(tw)[column].width = width; + + for(row = 0; row < ROWS(tw); row++) + Reposition(tw, NULL, row, column); + + UpdateTable(tw); + + callback_str.reason = XawTABLE_CHANGED_COLUMN_WIDTH; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = (XawTableCell)NULL; + callback_str.new_cell = (XawTableCell)NULL; + callback_str.row = 0; + callback_str.column = column; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNchangedColumnWidth, callback_str); +} + + +void +#ifdef Xraw_NEED_PROTO +XawTableSetMultiColumnWidths (Widget w, int *columns, int *widths, int ncols) +#else +XawTableSetMultiColumnWidths (w, columns, widths, ncols) + Widget w; + int *columns; + int *widths; + int ncols; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCallbackStruct callback_str; + register int i, row, col, width; + + for (i=0; i < ncols; i++ ) { + if (columns[i] != InRange (columns[i], 0, COLUMNS(tw)-1)) + return; + } + + for (i=0; i < ncols; i++ ) { + if ((COLUMN_DATA(tw)[columns[i]].flag & _CL_width) && + COLUMN_DATA(tw)[columns[i]].width == widths[i]) + return; + + COLUMN_DATA(tw)[columns[i]].flag |= _CL_width; + COLUMN_DATA(tw)[columns[i]].width = widths[i]; + + for(row = 0; row < ROWS(tw); row++) + Reposition(tw, NULL, row, columns[i]); + } + + UpdateTable(tw); + +/* + callback_str.reason = XawTABLE_CHANGED_COLUMN_WIDTH; + callback_str.event = (XEvent*)NULL; + callback_str.old_cell = (XawTableCell)NULL; + callback_str.new_cell = (XawTableCell)NULL; + callback_str.row = 0; + callback_str.column = column; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNchangedColumnWidth, callback_str); +*/ +} + + + +int +#ifdef Xraw_NEED_PROTO +XawTableGetColumnWidth (Widget w, int column) +#else +XawTableGetColumnWidth(w, column) + Widget w; + int column; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + + if (column != InRange (column, 0, COLUMNS(tw)-1)) + return tw->table.column_default_width; + + if ((COLUMN_DATA(tw)[column].flag & _CL_width)) + return COLUMN_DATA(tw)[column].width; + + return tw->table.column_default_width; +} + +int +#ifdef Xraw_NEED_PROTO +XawTableGetColumnPixelWidth (Widget w, int column) +#else +XawTableGetColumnPixelWidth(w, column) + Widget w; + int column; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + int width; + + if (column != InRange (column, 0, COLUMNS(tw)-1)) + width = tw->table.column_default_width; + else if ((COLUMN_DATA(tw)[column].flag & _CL_width)) + width = COLUMN_DATA(tw)[column].width; + else + width = tw->table.column_default_width; + + if (tw->table.literal) { + width = width * tw->table.literal_width + 2 * tw->table.internal_width; + } + + return width; +} + +char * +#ifdef Xraw_NEED_PROTO +XawTableGetLabelByPosition (Widget w, int i, int j) +#else + XawTableGetLabelByPosition(w,i,j) + Widget w; + int i,j; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCell cell; + + + if ((ROWS(tw) < 1) || (COLUMNS(tw) < 1) || + (i != InRange(i, 0, ROWS(tw)-1)) || + (j != InRange(j, 0, COLUMNS(tw)-1))) + { + String subs[3]; + Cardinal num_subs = 3; + sprintf(subs[0], "%5d", i); + sprintf(subs[1], "%5d", j); + subs[2] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "GetLabelByPosition", "XawTableGetLabelByPosition","XawToolkitError", +"XawTableGetLabelByPosition\nIncorrect value of rows or columns (%s,%s) in TableWidget '%s' ", + subs, &num_subs); + return NULL; + } + + cell = (XawTableCell)get_cell(STUFF(tw), i, j); + return GET_CELL_LABEL; +} + +void +#ifdef Xraw_NEED_PROTO +XawTableUnsetEdit (Widget w) +#else + XawTableUnsetEdit(w) + Widget w; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + char* label; + XawTableCell cell; + + if (XawTableIsEditManaged(w)) + { + tw->table.no_redraw++; + UNMANAGE_EDIT(tw); + tw->table.no_redraw--; + + XtVaGetValues(EDIT(w), "string", &label, NULL); + + label = CopyOnlyPrintable(label); + + cell = (XawTableCell) + get_cell(STUFF(tw),tw->table.edit_row, tw->table.edit_column); + + if (!streq(label,CELL(label))) + XawTableSetLabel(w, tw->table.edit_row, tw->table.edit_column, label); + + XtFree(label); /* XtMalloc in CopyOnlyPrintable */ + } +} + +void +#ifdef Xraw_NEED_PROTO +XawTableSetEdit (Widget w, int row, int column) +#else + XawTableSetEdit(w, row, column) + Widget w; + int row; + int column; +#endif +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCell cell; + + if (IsEditInRowColumn(tw, row, column) || STUFF(tw) == NULL) + return; + + if ((ROWS(tw) < 1) || (COLUMNS(tw) < 1) || + (row != InRange(row, 0, ROWS(tw)-1)) || + (column != InRange(column, 0, COLUMNS(tw)-1))) + { + String subs[3]; + Cardinal num_subs = 3; + sprintf(subs[0], "%5d", row); + sprintf(subs[1], "%5d", column); + subs[2] = w->core.name; + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "SetEdit", "XawTableSetEdit","XawToolkitError", +"XawTableSetEdit\nIncorrect value of rows or columns (%s,%s) in TableWidget '%s' ", + subs, &num_subs); + return; + } + + XawTableUnsetEdit(w); + + cell = (XawTableCell)get_cell(STUFF(tw), row, column); + + if (CELL(label) == NULL) + XtVaSetValues(EDIT(tw), "string", Dummy, NULL); + else + XtVaSetValues(EDIT(tw), "string", CELL(label), NULL); + + tw->table.edit_row = row; + tw->table.edit_column = column; + + MoveEditCell (tw, tw->table.edit_row, tw->table.edit_column); + + MANAGE_EDIT(tw); +} + +/****************************************************************** + * + * Actions + * + ******************************************************************/ + +static void HighlightCell(w,event,params,num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCell cell; + int row, column; + Position x,y; + Time tm; + + if (!tw->table.editable) + return; + + if (*num_params == 2) + { + row = atoi(params[0]); + column = atoi(params[1]); + } + else if (event != (XEvent*)NULL) + { + ExtractPosition(event, &x, &y , &tm); + if (ExtractCell(tw, x, y, &row, &column)) + return ; + } + else + { + return; + } + + cell = (XawTableCell) get_cell (STUFF(tw), row, column); + + if (CELL(highlight)) + return ; + + CELL(highlight) = True; + + x = GetX(tw,column); + y = GetY(tw,row); + + PaintLabel(w, row, column, x, y, cell); + XFlush(XtDisplay(w)); +} + +/* ARGSUSED */ +static void UnhighlightCell(w,event,params,num_params) + Widget w; + XEvent *event; + String *params; /* unused */ + Cardinal *num_params; +{ + XawTableWidget tw = (XawTableWidget)w; + XawTableCell cell; + int row, column; + Position x,y; + Time tm; + unsigned int width; + unsigned int height; + + if (!tw->table.editable) + return; + + if (*num_params == 2) + { + row = atoi(params[0]); + column = atoi(params[1]); + } + else if (event != (XEvent*)NULL) + { + ExtractPosition(event, &x, &y , &tm); + if (ExtractCell(tw, x, y, &row, &column)) + return ; + } + else + { + return; + } + + cell = (XawTableCell)get_cell(STUFF(tw), row, column); + + if (!CELL(highlight)) + return ; + + CELL(highlight) = False; + + width = (unsigned int) COLUMN_WIDTH(tw, column) + + 2 * tw->table.label_shadow_thickness; + height = (unsigned int) tw->table.row_height + + 2 * tw->table.label_shadow_thickness; + + XClearArea(XtDisplay(w), XtWindow(w), + (int)GetX(tw,column), + (int)GetY(tw,row), + width, height, FALSE); + + PaintLabel(w, row, column, x, y, cell); + + XFlush(XtDisplay(w)); + +} + +/* ARGSUSED */ +static void WhatCell(w,event,params,num_params) + Widget w; + XEvent *event; + String *params; /* unused */ + Cardinal *num_params; +{ + XawTableWidget tw = (XawTableWidget)w; + Position x,y; + int row, column; + XawTableCallbackStruct callback_str; + XawTableCell cell; + Time tm; + + if (event->type != ButtonPress && event->type != ButtonRelease) + return; + + ExtractPosition(event, &x, &y , &tm); + + if (ExtractCell(tw, x, y, &row, &column)) + return ; + + cell = (XawTableCell) get_cell (STUFF(tw), row, column); + + callback_str.reason = XawTABLE_WHAT_CELL; + callback_str.event = event; + callback_str.old_cell = cell; + callback_str.new_cell = cell; + callback_str.row = row; + callback_str.column = column; + callback_str.do_it = True; + + DO_CALLBACK(w, XtNwhatCell, callback_str); +} + +/* ARGSUSED */ +static void KeyReturn(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; /* unused */ + Cardinal *num_params; /* unused */ +{ + Widget tw; + KeySym ksSymbol; + + ksSymbol = XtGetActionKeysym(event, (Modifiers*)NULL); + + if (ksSymbol == XK_Return || ksSymbol == XK_Linefeed) + { + XtVaGetValues(w, XtNuserData, &tw, NULL); + XawTableUnsetEdit(tw); + } + +} + +static Atom FetchAtom(w, name) + Widget w; + String name; +{ + Atom a; + XrmValue source, dest; + + source.size = strlen(name)+1; + source.addr = name; + dest.size = sizeof(Atom); + dest.addr = (XtPointer) &a; + + (void) XtConvertAndStore(w, XtRString, &source, XtRAtom, &dest); + return a; +} + +/* ARGSUSED */ +static Boolean DeliverSelection(w, selection, target, + type, value, length, format) + Widget w; + Atom *selection, *target, *type; + XtPointer *value; + unsigned long *length; + int *format; +{ + XawTableWidget tw = (XawTableWidget) w; + static Atom targets = 0; + + if (targets == 0) { + targets = FetchAtom(w, "TARGETS"); + } + + if (*target == targets) { + *type = XA_ATOM; + *value = (XtPointer) CALLOC(1, Atom); + *(Atom *) *value = XA_STRING; + *length = 1; + *format = 32; + return TRUE; + } + + if (*target == XA_STRING) { + *type = XA_STRING; + *value = (XtPointer) XtNewString(tw->table.cell_own->label); + *length = tw->table.cell_own->label_len; + *format = 8; + return TRUE; + } + + return FALSE; +} + +/* ARGSUSED */ +static void LoseSelection(w, selection) + Widget w; + Atom *selection; +{ + XawTableWidget tw = (XawTableWidget) w; + XawTableCell cell; + int row, column; + int x,y; + unsigned int width, height; + + cell = tw->table.cell_own; + tw->table.cell_own = (XawTableCell)NULL; + + if (!CELL(highlight)) + return ; + + get_cell_positions(cell, &row, &column); + + CELL(highlight) = False; + + x = GetX(tw,column) + tw->table.label_shadow_thickness; + y = GetY(tw,row) + tw->table.label_shadow_thickness; + width = (unsigned int) COLUMN_WIDTH(tw, column); + height = (unsigned int) tw->table.row_height; + + XClearArea(XtDisplay(w), XtWindow(w), x, y, width, height, FALSE); + (void)PaintCell(w, row, column, (XtPointer)cell, (XtPointer)NULL); + + XFlush(XtDisplay(w)); +} + +static int GetCutBufferNumber(); + +static void StoreBuffer(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; /* selections in precedence order */ + Cardinal *num_params; +{ + XawTableWidget tw = (XawTableWidget)w; + Position x, y; + int row, column; + int i, buffer; + Time tm; + Atom selection; + + if (!tw->table.editable) + return; + + if (event->type != ButtonPress && event->type != ButtonRelease) + return; + + ExtractPosition(event, &x, &y ,&tm); + + if (ExtractCell(tw, x, y, &row, &column)) + return ; + + if (tw->table.cell_own != (XawTableCell)NULL) + LoseSelection(w, (Atom*)NULL); + + tw->table.cell_own = (XawTableCell)get_cell(STUFF(tw), row, column); + + for(i=0; i<(int)*num_params; i++) { + selection = FetchAtom(w, *(String *)(params+i)); + + buffer = GetCutBufferNumber(selection); + + if (buffer >= 0) { + if (buffer == 0) { + +#define Create(buffer) \ + XChangeProperty(XtDisplay(w), DefaultRootWindow(XtDisplay(w)),\ + buffer,XA_STRING, 8,PropModeAppend, NULL, 0) + + Create(XA_CUT_BUFFER0); + Create(XA_CUT_BUFFER1); + Create(XA_CUT_BUFFER2); + Create(XA_CUT_BUFFER3); + Create(XA_CUT_BUFFER4); + Create(XA_CUT_BUFFER5); + Create(XA_CUT_BUFFER6); + Create(XA_CUT_BUFFER7); +#undef Create + + XRotateBuffers(XtDisplay(w), 1); + } + + XStoreBuffer(XtDisplay(w), tw->table.cell_own->label, + (int)MIN(tw->table.cell_own->label_len, MAXCUT), buffer); + + } else { + tw->table.selections[tw->table.num_selections++] = selection; + + XtOwnSelection (w, selection, tm, + DeliverSelection, LoseSelection, + (XtSelectionDoneProc) NULL); + } + } +} + + +/* ARGSUSED */ +static void CallEdit(w,event,params,num_params) + Widget w; + XEvent *event; + String *params; /* unused */ + Cardinal *num_params; +{ + XawTableWidget tw = (XawTableWidget)w; + Position x,y; + int row, column; + Time tm; + + if (!tw->table.editable) + return; + + ExtractPosition(event, &x, &y , &tm); + + if (ExtractCell(tw, x, y, &row, &column)) + return ; + + XawTableSetEdit(w, row, column); +} + + + +typedef struct { + Widget w; + Atom *selections; + Time time; + int row; + int column; + int count; + int num; +}RowColumn; + +static void GetProc(); + +static void GetSelection (rc) + RowColumn *rc; +{ + Atom selection; + int buffer; + int nbytes; + char *label; + + selection = *(rc->selections + rc->num); + + if (rc->num < rc->count){ + + buffer = GetCutBufferNumber(selection); + + if (buffer >= 0) { + label = XFetchBuffer(XtDisplay(rc->w), &nbytes, buffer); + XawTableSetLabel(rc->w, rc->row, rc->column, label); + XtFree((XtPointer)rc->selections); + XtFree((XtPointer)rc); + }else { + XtGetSelectionValue(rc->w, selection, XA_STRING, GetProc, + (XtPointer)rc, rc->time); + rc->num++; + } + } +} + +/* ARGSUSED */ +static void GetProc(w, client_data, selection, + type, value, length, format) + Widget w; + XtPointer client_data; + Atom *selection; + Atom *type; + XtPointer value; + unsigned long *length; + int *format; +{ + RowColumn *rc = (RowColumn*)client_data; + + if ((*type == XA_STRING) && (value != NULL)) { + XawTableSetLabel(w, rc->row, rc->column, (char*)value); + XtFree((XtPointer)value); + XtFree((XtPointer)client_data); + }else { + GetSelection(rc); + } + +} + +static void InsertSelection(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; /* selections in precedence order */ + Cardinal *num_params; +{ + XawTableWidget tw = (XawTableWidget)w; + Position x,y; + int row, column; + RowColumn *rc; + Time tm; + + if (!tw->table.editable) + return; + + if (event->type != ButtonPress && event->type != ButtonRelease) + return; + + ExtractPosition(event, &x, &y ,&tm); + + if (ExtractCell(tw, x, y, &row, &column)) + return ; + + if (*num_params > 0) { + + rc = XtNew(RowColumn); + + rc->time = tm; + rc->w = w; + rc->row = row; + rc->column = column; + rc->count = (int)*num_params; + rc->num = 0; + + if (*num_params > (Cardinal)0) { + rc->selections = CALLOC(*num_params, Atom); + XmuInternStrings(XtDisplay(w), params, *num_params, rc->selections); + } else { + rc->selections = XtNew(Atom); + *rc->selections = FetchAtom(w, "PRIMARY"); + } + GetSelection(rc); + } +} + + +static int GetCutBufferNumber(atom) + register Atom atom; +{ + if (atom == XA_CUT_BUFFER0) return(0); + if (atom == XA_CUT_BUFFER1) return(1); + if (atom == XA_CUT_BUFFER2) return(2); + if (atom == XA_CUT_BUFFER3) return(3); + if (atom == XA_CUT_BUFFER4) return(4); + if (atom == XA_CUT_BUFFER5) return(5); + if (atom == XA_CUT_BUFFER6) return(6); + if (atom == XA_CUT_BUFFER7) return(7); + return(-1); +} + + +/* ARGSUSED */ +static void DoingNothing(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + /* doing nothing */ +} + -- cgit