1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  *
3  * ***** BEGIN LICENSE BLOCK *****
4  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5  *
6  * The contents of this file are subject to the Mozilla Public License Version
7  * 1.1 (the "License"); you may not use this file except in compliance with
8  * the License. You may obtain a copy of the License at
9  * http://www.mozilla.org/MPL/
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is the Microline Widget Library, originally made available under the NPL by Neuron Data <http://www.neurondata.com>.
17  *
18  * The Initial Developer of the Original Code is
19  * Netscape Communications Corporation.
20  * Portions created by the Initial Developer are Copyright (C) 1998
21  * the Initial Developer. All Rights Reserved.
22  *
23  * Contributor(s):
24  *
25  * Alternatively, the contents of this file may be used under the terms of
26  * either the GNU General Public License Version 2 or later (the "GPL"), or
27  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28  * in which case the provisions of the GPL or the LGPL are applicable instead
29  * of those above. If you wish to allow use of your version of this file only
30  * under the terms of either the GPL or the LGPL, and not to allow others to
31  * use your version of this file under the terms of the MPL, indicate your
32  * decision by deleting the provisions above and replace them with the notice
33  * and other provisions required by the GPL or the LGPL. If you do not delete
34  * the provisions above, a recipient may use your version of this file under
35  * the terms of any one of the MPL, the GPL or the LGPL.
36  *
37  * In addition, as a special exception to the GNU GPL, the copyright holders
38  * give permission to link the code of this program with the Motif and Open
39  * Motif libraries (or with modified versions of these that use the same
40  * license), and distribute linked combinations including the two. You
41  * must obey the GNU General Public License in all respects for all of
42  * the code used other than linking with Motif/Open Motif. If you modify
43  * this file, you may extend this exception to your version of the file,
44  * but you are not obligated to do so. If you do not wish to do so,
45  * delete this exception statement from your version.
46  *
47  * ***** END LICENSE BLOCK ***** */
48 
49 #include "GridP.h"
50 
51 #include <Xm/ScrollBar.h>
52 #include <Xm/Text.h>
53 #include <Xm/DrawnB.h>
54 #include <Xm/CutPaste.h>
55 #ifndef MOTIF11
56 #include <Xm/DropSMgr.h>
57 #endif
58 #include <X11/StringDefs.h>
59 #include <X11/cursorfont.h>
60 #include <stdio.h>
61 #include <stdlib.h>
62 
63 #ifdef SUNOS4
64 int fprintf(FILE *, char *, ...);
65 int fseek(FILE *, long, int);
66 int fread(char *, int, int, FILE *);
67 #endif
68 
69 /* Create and Destroy */
70 static void ClassInitialize(void);
71 static void ClassPartInitialize(WidgetClass wc);
72 static void Initialize(Widget req, Widget newW, ArgList args, Cardinal *nargs);
73 static void Destroy(Widget w);
74 
75 /* Geometry, Drawing, Entry and Picking */
76 static void Realize(Widget w, XtValueMask *valueMask,
77 	XSetWindowAttributes *attr);
78 static void Redisplay(Widget w, XExposeEvent *event, Region region);
79 static void DrawResizeLine(XmLGridWidget g, int xy, int erase);
80 static void DrawXORRect(XmLGridWidget g, int xy, int size,
81 	int isVert, int erase);
82 static void DefineCursor(XmLGridWidget g, char defineCursor);
83 static void DrawArea(XmLGridWidget g, int type, int row, int col);
84 static void ExtendSelectRange(XmLGridWidget g, int *type,
85 	int *fr, int *lr, int *fc, int *lc);
86 static void ExtendSelect(XmLGridWidget g, XEvent *event, Boolean set,
87 	int row, int col);
88 static void SelectTypeArea(XmLGridWidget g, int type, XEvent *event,
89 	int row, int col, Boolean select, Boolean notify);
90 static int GetSelectedArea(XmLGridWidget g, int type, int *rowPos,
91 	int *colPos, int count);
92 static void ChangeManaged(Widget w);
93 static void Resize(Widget w);
94 static void PlaceScrollbars(XmLGridWidget w);
95 static void VertLayout(XmLGridWidget g, int resizeIfNeeded);
96 static void HorizLayout(XmLGridWidget g, int resizeIfNeeded);
97 static void ApplyVisibleRows(XmLGridWidget g);
98 static void ApplyVisibleCols(XmLGridWidget g);
99 static void VisPosChanged(XmLGridWidget g, int isVert);
100 static void RecalcVisPos(XmLGridWidget g, int isVert);
101 static int PosToVisPos(XmLGridWidget g, int pos, int isVert);
102 static int VisPosToPos(XmLGridWidget g, int visPos, int isVert);
103 static unsigned char ColPosToType(XmLGridWidget g, int pos);
104 static int ColPosToTypePos(XmLGridWidget g, unsigned char type, int pos);
105 static unsigned char RowPosToType(XmLGridWidget g, int pos);
106 static int RowPosToTypePos(XmLGridWidget g, unsigned char type, int pos);
107 static int ColTypePosToPos(XmLGridWidget g, unsigned char type,
108 	int pos, int allowNeg);
109 static int RowTypePosToPos(XmLGridWidget g, unsigned char type,
110 	int pos, int allowNeg);
111 static int ScrollRowBottomPos(XmLGridWidget g, int row);
112 static int ScrollColRightPos(XmLGridWidget g, int col);
113 static int PosIsResize(XmLGridWidget g, int x, int y,
114 	int *row, int *col, int *isVert);
115 static int XYToRowCol(XmLGridWidget g, int x, int y, int *row, int *col);
116 static int RowColToXY(XmLGridWidget g, int row, int col,
117 	Boolean clipped, XRectangle *rect);
118 static int RowColFirstSpan(XmLGridWidget g, int row, int col,
119 	int *spanRow, int *spanCol, XRectangle *rect, Boolean lookLeft,
120 	Boolean lookUp);
121 static void RowColSpanRect(XmLGridWidget g, int row, int col, XRectangle *rect);
122 static XmLGridCell GetCell(XmLGridWidget g, int row, int col);
123 static int GetColWidth(XmLGridWidget g, int col);
124 static int GetRowHeight(XmLGridWidget g, int row);
125 static int ColIsVisible(XmLGridWidget g, int col);
126 static int RowIsVisible(XmLGridWidget g, int row);
127 static XtGeometryResult GeometryManager(Widget w, XtWidgetGeometry *request,
128 	XtWidgetGeometry *);
129 static void ScrollCB(Widget w, XtPointer, XtPointer);
130 static int FindNextFocus(XmLGridWidget g, int row, int col,
131 	int rowDir, int colDir, int *nextRow, int *nextCol);
132 static int SetFocus(XmLGridWidget g, int row, int col, int rowDir, int colDir);
133 static void ChangeFocus(XmLGridWidget g, int row, int col);
134 static void MakeColVisible(XmLGridWidget g, int col);
135 static void MakeRowVisible(XmLGridWidget g, int row);
136 static void TextAction(XmLGridWidget g, int action);
137 
138 /* Getting and Setting Values */
139 static void GetSubValues(Widget w, ArgList args, Cardinal *nargs);
140 static void SetSubValues(Widget w, ArgList args, Cardinal *nargs);
141 static Boolean SetValues(Widget curW, Widget, Widget newW,
142 	ArgList args, Cardinal *nargs);
143 static void CopyFontList(XmLGridWidget g);
144 static Boolean CvtStringToSizePolicy(Display *dpy, XrmValuePtr args,
145 	Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
146 	XtPointer *data);
147 static Boolean CvtStringToSelectionPolicy(Display *dpy, XrmValuePtr args,
148 	Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
149 	XtPointer *data);
150 static Boolean CvtStringToRowColType(Display *dpy, XrmValuePtr args,
151 	Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
152 	XtPointer *data);
153 static Boolean CvtStringToCellAlignment(Display *dpy, XrmValuePtr args,
154 	Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
155 	XtPointer *data);
156 static Boolean CvtStringToCellType(Display *dpy, XrmValuePtr args,
157 	Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
158 	XtPointer *data);
159 static Boolean CvtStringToCellBorderType(Display *dpy, XrmValuePtr args,
160 	Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
161 	XtPointer *data);
162 static void SetSimpleHeadings(XmLGridWidget g, char *data);
163 static void SetSimpleWidths(XmLGridWidget g, char *data);
164 
165 /* Getting and Setting Row Values */
166 static void GetRowValueMask(XmLGridWidget g, char *s, long *mask);
167 static void _GetRowValueMask(XmLGridWidget g, char *s, long *mask);
168 static void GetRowValue(XmLGridWidget g, XmLGridRow row,
169 	XtArgVal value, long mask);
170 static void _GetRowValue(XmLGridWidget g, XmLGridRow row,
171 	XtArgVal value, long mask);
172 static int SetRowValues(XmLGridWidget g, XmLGridRow row, long mask);
173 static int _SetRowValues(XmLGridWidget g, XmLGridRow row, long mask);
174 
175 /* Getting and Setting Column Values */
176 static void GetColumnValueMask(XmLGridWidget g, char *s, long *mask);
177 static void _GetColumnValueMask(XmLGridWidget g, char *s, long *mask);
178 static void GetColumnValue(XmLGridWidget g, XmLGridColumn col,
179 	XtArgVal value, long mask);
180 static void _GetColumnValue(XmLGridWidget g, XmLGridColumn col,
181 	XtArgVal value, long mask);
182 static int SetColumnValues(XmLGridWidget g, XmLGridColumn col, long mask);
183 static int _SetColumnValues(XmLGridWidget g, XmLGridColumn col, long mask);
184 
185 /* Getting and Setting Cell Values */
186 static void CellValueGetMask(char *s, long *mask);
187 static void GetCellValue(XmLGridCell cell, XtArgVal value, long mask);
188 static XmLGridCellRefValues *CellRefValuesCreate(XmLGridWidget g,
189 	XmLGridCellRefValues *copy);
190 static void SetCellValuesPreprocess(XmLGridWidget g, long mask);
191 static int SetCellHasRefValues(long mask);
192 static int SetCellValuesResize(XmLGridWidget g, XmLGridRow row,
193 	XmLGridColumn col, XmLGridCell cell, long mask);
194 static int _SetCellValuesResize(XmLGridWidget g, XmLGridRow row,
195 	XmLGridColumn col, XmLGridCell cell, long mask);
196 static void SetCellValues(XmLGridWidget g, XmLGridCell cell, long mask);
197 static void SetCellRefValues(XmLGridWidget g, XmLGridCellRefValues *values,
198 	long mask);
199 static int SetCellRefValuesCompare(void *, void **, void **);
200 static void SetCellRefValuesPreprocess(XmLGridWidget g, int row, int col,
201 	XmLGridCell cell, long mask);
202 
203 /* Read, Write, Copy, Paste */
204 static int Read(XmLGridWidget g, int format, char delimiter,
205 	int row, int col, char *data);
206 static void Write(XmLGridWidget g, FILE *file, int format, char delimiter,
207 	Boolean skipHidden, int row, int col, int nrow, int ncol);
208 static char *CopyDataCreate(XmLGridWidget g, int selected, int row, int col,
209 	int nrow, int ncol);
210 static Boolean Copy(XmLGridWidget g, Time time, int selected,
211 	int row, int col, int nrow, int ncol);
212 static Boolean Paste(XmLGridWidget g, int row, int col);
213 
214 /* Utility */
215 static void GetCoreBackground(Widget w, int, XrmValue *value);
216 static void GetManagerForeground(Widget w, int, XrmValue *value);
217 static void ClipRectToReg(XmLGridWidget g, XRectangle *rect, GridReg *reg);
218 static char *FileToString(FILE *file);
219 static char *CvtXmStringToStr(XmString str);
220 static XmLGridWidget WidgetToGrid(Widget w, char *funcname);
221 
222 /* Actions, Callbacks and Handlers */
223 static void ButtonMotion(Widget w, XEvent *event, String *, Cardinal *);
224 static void DragTimer(XtPointer, XtIntervalId *);
225 static void CursorMotion(Widget w, XEvent *event, String *, Cardinal *);
226 static void Edit(Widget w, XEvent *event, String *, Cardinal *);
227 static void EditCancel(Widget w, XEvent *event, String *, Cardinal *);
228 static void EditComplete(Widget w, XEvent *event, String *, Cardinal *);
229 static void DragStart(Widget w, XEvent *event, String *, Cardinal *);
230 static Boolean DragConvert(Widget w, Atom *selection, Atom *target,
231 	Atom *type, XtPointer *value, unsigned long *length, int *format);
232 static void DragFinish(Widget w, XtPointer clientData, XtPointer callData);
233 static void DropRegister(XmLGridWidget g, Boolean set);
234 static void DropStart(Widget w, XtPointer clientData, XtPointer callData);
235 static void DropTransfer(Widget w, XtPointer clientData, Atom *selType,
236 	Atom *type, XtPointer value, unsigned long *length, int *format);
237 static void Select(Widget w, XEvent *event, String *, Cardinal *);
238 static void PopupSelect(Widget w, XEvent *event, String *, Cardinal *);
239 static void TextActivate(Widget w, XtPointer clientData, XtPointer callData);
240 static void TextFocus(Widget w, XtPointer clientData, XtPointer callData);
241 static void TextMapped(Widget w, XtPointer closure, XEvent *event,
242 	Boolean *ctd);
243 static void TextModifyVerify(Widget w, XtPointer clientData,
244 	XtPointer callData);
245 static void Traverse(Widget w, XEvent *event, String *, Cardinal *);
246 
247 /* XFE Additions */
248 static void EditTimer(XtPointer, XtIntervalId *);
249 static void CreateHideUnhideButtons(XmLGridWidget g);
250 static void HideAction(Widget w, XEvent *event, String *, Cardinal *);
251 static void UnhideAction(Widget w, XEvent *event, String *, Cardinal *);
252 static void setHideUnhideSensitivity(Widget w);
253 static void MenuArm(Widget w, XEvent *event, String *, Cardinal *);
254 static void MenuDisarm(Widget w, XEvent *event, String *, Cardinal *);
255 static void ResizeColumnToFit(XmLGridWidget g, int x);
256 static int  SizeColumnsToFit(XmLGridWidget g, int start_at);
257 static void GridCrossingEH(Widget w, XtPointer closure, XEvent *event,
258 						   Boolean *ctd);
259 static void	GridInvokeCellCrossingCallbacks(Widget w,XtCallbackList list,
260 											int reason,XEvent * event,
261 											int row,int col);
262 static void GridCrossingEH(Widget w,XtPointer closure,XEvent * event,
263 						   Boolean * ctd);
264 
265 /* XmLGridRow */
266 
267 static XmLGridRow XmLGridRowNew(Widget grid);
268 static void XmLGridRowFree(Widget grid, XmLGridRow row);
269 static XmLGridRow _GridRowNew(Widget grid);
270 static void _GridRowFree(XmLGridRow row);
271 static XmLArray XmLGridRowCells(XmLGridRow row);
272 static int XmLGridRowGetPos(XmLGridRow row);
273 static int XmLGridRowGetVisPos(XmLGridRow row);
274 static Boolean XmLGridRowIsHidden(XmLGridRow row);
275 static Boolean XmLGridRowIsSelected(XmLGridRow row);
276 static void XmLGridRowSetSelected(XmLGridRow row, Boolean selected);
277 static void XmLGridRowSetVisPos(XmLGridRow row, int visPos);
278 static int XmLGridRowHeightInPixels(XmLGridRow row);
279 static void XmLGridRowHeightChanged(XmLGridRow row);
280 
281 /* XmLGridColumn */
282 
283 static XmLGridColumn XmLGridColumnNew(Widget grid);
284 static void XmLGridColumnFree(Widget grid, XmLGridColumn column);
285 static XmLGridColumn _GridColumnNew(Widget grid);
286 static void _GridColumnFree(XmLGridColumn column);
287 static int XmLGridColumnGetPos(XmLGridColumn column);
288 static int XmLGridColumnGetVisPos(XmLGridColumn column);
289 static Boolean XmLGridColumnIsHidden(XmLGridColumn column);
290 static Boolean XmLGridColumnIsSelected(XmLGridColumn column);
291 static void XmLGridColumnSetSelected(XmLGridColumn column, Boolean selected);
292 static void XmLGridColumnSetVisPos(XmLGridColumn column, int visPos);
293 static int XmLGridColumnWidthInPixels(XmLGridColumn column);
294 static void XmLGridColumnWidthChanged(XmLGridColumn column);
295 
296 /* XmLGridCell */
297 
298 static XmLGridCell XmLGridCellNew();
299 static void XmLGridCellFree(Widget grid, XmLGridCell cell);
300 static int XmLGridCellAction(XmLGridCell cell, Widget w,
301 	XmLGridCallbackStruct *cbs);
302 static int _GridCellAction(XmLGridCell cell, Widget w,
303 	XmLGridCallbackStruct *cbs);
304 static XmLGridCellRefValues *XmLGridCellGetRefValues(XmLGridCell cell);
305 static void XmLGridCellSetRefValues(XmLGridCell cell,
306 	XmLGridCellRefValues *values);
307 static void XmLGridCellDerefValues(XmLGridCellRefValues *values);
308 static Boolean XmLGridCellInRowSpan(XmLGridCell cell);
309 static Boolean XmLGridCellInColumnSpan(XmLGridCell cell);
310 static Boolean XmLGridCellIsSelected(XmLGridCell cell);
311 static Boolean XmLGridCellIsValueSet(XmLGridCell cell);
312 static void XmLGridCellSetValueSet(XmLGridCell cell, Boolean set);
313 static void XmLGridCellSetInRowSpan(XmLGridCell cell, Boolean set);
314 static void XmLGridCellSetInColumnSpan(XmLGridCell cell, Boolean set);
315 static void XmLGridCellSetSelected(XmLGridCell cell, Boolean selected);
316 static void XmLGridCellAllocIcon(XmLGridCell cell);
317 static void XmLGridCellAllocPixmap(XmLGridCell cell);
318 static void XmLGridCellSetString(XmLGridCell cell, XmString string,
319 	Boolean copy);
320 static XmString XmLGridCellGetString(XmLGridCell cell);
321 static void XmLGridCellSetToggle(XmLGridCell cell, Boolean state);
322 static Boolean XmLGridCellGetToggle(XmLGridCell cell);
323 static void XmLGridCellSetPixmap(XmLGridCell cell, Pixmap pixmap,
324 	Dimension width, Dimension height);
325 static void XmLGridCellSetPixmask(XmLGridCell cell, Pixmap pixmask);
326 static XmLGridCellPixmap *XmLGridCellGetPixmap(XmLGridCell cell);
327 /* static void XmLGridCellClearTextString(XmLGridCell cell, Widget w); */
328 static int _XmLGridCellConfigureText(XmLGridCell cell, Widget w,
329 	XRectangle *rect);
330 static int _XmLGridCellBeginTextEdit(XmLGridCell cell, Widget w,
331 	XRectangle *clipRect);
332 static void _XmLGridCellCompleteTextEdit(XmLGridCell cell, Widget w);
333 static void _XmLGridCellInsertText(XmLGridCell cell, Widget w);
334 static int _XmLGridCellGetHeight(XmLGridCell cell, Widget w,XmLGridRow row);
335 static int _XmLGridCellGetWidth(XmLGridCell cell, Widget w,XmLGridColumn col);
336 static void _XmLGridCellFreeValue(XmLGridCell cell);
337 
338 /*Xfe Additions*/
339 static Boolean XmLGridCellDrawSort(XmLGridCell cell);
340 static Boolean XmLGridCellSortAscending(XmLGridCell cell);
341 static void XmLGridCellSetDrawSort(XmLGridCell cell, Boolean drawSort);
342 static void XmLGridCellSetSortAscending(XmLGridCell cell, Boolean ascending);
343 
344 static XtActionsRec actions[] =
345 	{
346 	{ "XmLGridEditComplete", EditComplete },
347 	{ "XmLGridButtonMotion", ButtonMotion },
348 	{ "XmLGridCursorMotion", CursorMotion },
349 	{ "XmLGridEditCancel",   EditCancel   },
350 	{ "XmLGridEdit",         Edit         },
351 	{ "XmLGridSelect",       Select       },
352 	{ "XmLGridPopupSelect",  PopupSelect  },
353 	{ "XmLGridDragStart",    DragStart    },
354 	{ "XmLGridTraverse",     Traverse     },
355 	/* XFE Additions */
356 	{ "XmLGridHideColumn",   HideAction   },
357 	{ "XmLGridUnhideColumn", UnhideAction },
358 	{ "MenuArm", MenuArm },
359 	{ "MenuDisarm", MenuDisarm },
360 	};
361 
362 #define TEXT_HIDE           1
363 #define TEXT_SHOW           2
364 #define TEXT_EDIT           3
365 #define TEXT_EDIT_CANCEL    4
366 #define TEXT_EDIT_COMPLETE  5
367 #define TEXT_EDIT_INSERT    6
368 
369 /* future defines */
370 #define XmTOGGLE_CELL  240
371 
372 /* backwards compatibility defines */
373 #define XmTEXT_CELL    250
374 #define XmLABEL_CELL   251
375 
376 /* Cursors */
377 
378 #define horizp_width 19
379 #define horizp_height 13
380 static unsigned char horizp_bits[] = {
381  0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0xff, 0x07, 0x00, 0x00, 0x06, 0x00,
382  0x00, 0x06, 0x00, 0x20, 0x46, 0x00, 0x30, 0xc6, 0x00, 0x38, 0xc6, 0x01,
383  0xfc, 0xff, 0x03, 0x38, 0xc6, 0x01, 0x30, 0xc6, 0x00, 0x20, 0x46, 0x00,
384  0x00, 0x06, 0x00 };
385 
386 #define horizm_width 19
387 #define horizm_height 13
388 static unsigned char horizm_bits[] = {
389  0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00,
390  0x60, 0x6f, 0x00, 0x70, 0xef, 0x00, 0x78, 0xef, 0x01, 0xfc, 0xff, 0x03,
391  0xfe, 0xff, 0x07, 0xfc, 0xff, 0x03, 0x78, 0xef, 0x01, 0x70, 0xef, 0x00,
392  0x60, 0x6f, 0x00 };
393 
394 #define vertp_width 13
395 #define vertp_height 19
396 static unsigned char vertp_bits[] = {
397    0x06, 0x00, 0x06, 0x00, 0x06, 0x01, 0x86, 0x03, 0xc6, 0x07, 0xe6, 0x0f,
398    0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0xfe, 0x1f, 0xfe, 0x1f, 0x00, 0x01,
399    0x00, 0x01, 0x00, 0x01, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03, 0x00, 0x01,
400    0x00, 0x00};
401 
402 #define vertm_width 13
403 #define vertm_height 19
404 static unsigned char vertm_bits[] = {
405    0x0f, 0x00, 0x0f, 0x01, 0x8f, 0x03, 0xcf, 0x07, 0xef, 0x0f, 0xff, 0x1f,
406    0xff, 0x1f, 0x8f, 0x03, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f,
407    0x80, 0x03, 0xf0, 0x1f, 0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03,
408    0x00, 0x01};
409 
410 /* Grid Translations */
411 
412 static char translations[] =
413 "<Btn1Motion>:           XmLGridButtonMotion()\n\
414 <MotionNotify>:          XmLGridCursorMotion()\n\
415 ~Ctrl ~Shift <Btn1Down>: XmLGridSelect(BEGIN)\n\
416 ~Ctrl Shift <Btn1Down>:  XmLGridSelect(EXTEND)\n\
417 Ctrl ~Shift <Btn1Down>:  XmLGridSelect(TOGGLE)\n\
418 <Btn1Up>:                XmLGridSelect(END)\n\
419 <Btn2Down>:              XmLGridDragStart()\n\
420 ~Ctrl ~Shift <Btn3Down>: XmLGridPopupSelect(BEGIN)\n\
421 ~Ctrl Shift <Btn3Down>:  XmLGridPopupSelect(EXTEND)\n\
422 Ctrl ~Shift <Btn3Down>:  XmLGridPopupSelect(TOGGLE)\n\
423 <EnterWindow>:           ManagerEnter()\n\
424 <LeaveWindow>:           ManagerLeave()\n\
425 <FocusOut>:              ManagerFocusOut()\n\
426 <FocusIn>:               ManagerFocusIn()";
427 
428 /* Text Translations */
429 
430 static char traverseTranslations[] =
431 "~Ctrl ~Shift <Key>osfUp:         XmLGridTraverse(UP)\n\
432 ~Ctrl Shift <Key>osfUp:           XmLGridTraverse(EXTEND_UP)\n\
433 Ctrl ~Shift <Key>osfUp:           XmLGridTraverse(PAGE_UP)\n\
434 ~Ctrl ~Shift <Key>osfDown:        XmLGridTraverse(DOWN)\n\
435 ~Ctrl Shift <Key>osfDown:         XmLGridTraverse(EXTEND_DOWN)\n\
436 Ctrl ~Shift <Key>osfDown:         XmLGridTraverse(PAGE_DOWN)\n\
437 ~Ctrl ~Shift <Key>osfLeft:        XmLGridTraverse(LEFT)\n\
438 ~Ctrl Shift <Key>osfLeft:         XmLGridTraverse(EXTEND_LEFT)\n\
439 Ctrl ~Shift <Key>osfLeft:         XmLGridTraverse(PAGE_LEFT)\n\
440 ~Ctrl ~Shift <Key>osfRight:       XmLGridTraverse(RIGHT)\n\
441 ~Ctrl Shift <Key>osfRight:        XmLGridTraverse(EXTEND_RIGHT)\n\
442 Ctrl ~Shift <Key>osfRight:        XmLGridTraverse(PAGE_RIGHT)\n\
443 ~Ctrl ~Shift <Key>osfPageUp:      XmLGridTraverse(PAGE_UP)\n\
444 ~Ctrl Shift <Key>osfPageUp:       XmLGridTraverse(EXTEND_PAGE_UP)\n\
445 Ctrl ~Shift <Key>osfPageUp:       XmLGridTraverse(PAGE_LEFT)\n\
446 Ctrl Shift <Key>osfPageUp:        XmLGridTraverse(EXTEND_PAGE_LEFT)\n\
447 ~Ctrl Shift <Key>osfPageDown:     XmLGridTraverse(EXTEND_PAGE_DOWN)\n\
448 Ctrl ~Shift <Key>osfPageDown:     XmLGridTraverse(PAGE_RIGHT)\n\
449 ~Ctrl ~Shift <Key>osfPageDown:    XmLGridTraverse(PAGE_DOWN)\n\
450 Ctrl Shift <Key>osfPageDown:      XmLGridTraverse(EXTEND_PAGE_RIGHT)\n\
451 ~Ctrl ~Shift <Key>Tab:            XmLGridTraverse(RIGHT)\n\
452 ~Ctrl Shift <Key>Tab:             XmLGridTraverse(LEFT)\n\
453 ~Ctrl ~Shift <Key>Home:           XmLGridTraverse(TO_TOP)\n\
454 ~Ctrl ~Shift <Key>osfBeginLine:   XmLGridTraverse(TO_TOP)\n\
455 Ctrl ~Shift <Key>Home:            XmLGridTraverse(TO_TOP_LEFT)\n\
456 ~Ctrl ~Shift <Key>End:            XmLGridTraverse(TO_BOTTOM)\n\
457 ~Ctrl ~Shift <Key>osfEndLine:     XmLGridTraverse(TO_BOTTOM)\n\
458 Ctrl ~Shift <Key>End:             XmLGridTraverse(TO_BOTTOM_RIGHT)\n\
459 <Key>osfInsert:                   XmLGridEdit()\n\
460 <Key>F2:                          XmLGridEdit()\n\
461 ~Ctrl ~Shift <KeyDown>space:      XmLGridSelect(BEGIN)\n\
462 ~Ctrl Shift <KeyDown>space:       XmLGridSelect(EXTEND)\n\
463 Ctrl ~Shift <KeyDown>space:       XmLGridSelect(TOGGLE)\n\
464 <KeyUp>space:                     XmLGridSelect(END)";
465 
466 /* You can't put multiple actions for any translation
467    where one translation changes the translation table
468    XmLGridComplete() and XmLGridCancel() do this and these
469    actions can't be combined with others */
470 static char editTranslations[] =
471 "~Ctrl ~Shift <Key>osfDown:     XmLGridEditComplete(DOWN)\n\
472 ~Ctrl Shift <Key>Tab:	        XmLGridEditComplete(LEFT)\n\
473 ~Ctrl ~Shift <Key>Tab:	        XmLGridEditComplete(RIGHT)\n\
474 ~Ctrl ~Shift <Key>osfUp:        XmLGridEditComplete(UP)\n\
475 <Key>osfCancel:                 XmLGridEditCancel()\n\
476 <Key>Escape:                    XmLGridEditCancel()";
477 
478 #if 0
479 static char hideButtonTranslations[] =
480 "<BtnDown>,<BtnUp>:                      XmLGridHideColumn()";
481 
482 static char unhideButtonTranslations[] =
483 "<BtnDown>,<BtnUp>:                      XmLGridUnhideColumn()";
484 #endif /*0*/
485 
486 static XtResource resources[] =
487 	{
488 		/* Grid Resources */
489 		{
490 		XmNactivateCallback, XmCCallback,
491 		XmRCallback, sizeof(XtCallbackList),
492 		XtOffset(XmLGridWidget, grid.activateCallback),
493 		XmRImmediate, (XtPointer)0,
494 		},
495 		{
496 		XmNaddCallback, XmCCallback,
497 		XmRCallback, sizeof(XtCallbackList),
498 		XtOffset(XmLGridWidget, grid.addCallback),
499 		XmRImmediate, (XtPointer)0,
500 		},
501 		{
502 		XmNallowColumnHide, XmCAllowColumnHide,
503 		XmRBoolean, sizeof(Boolean),
504 		XtOffset(XmLGridWidget, grid.allowColHide),
505 		XmRImmediate, (XtPointer)False,
506 		},
507 		{
508 		XmNallowColumnResize, XmCAllowColumnResize,
509 		XmRBoolean, sizeof(Boolean),
510 		XtOffset(XmLGridWidget, grid.allowColResize),
511 		XmRImmediate, (XtPointer)False,
512 		},
513 		{
514 		XmNallowDragSelected, XmCAllowDragSelected,
515 		XmRBoolean, sizeof(Boolean),
516 		XtOffset(XmLGridWidget, grid.allowDrag),
517 		XmRImmediate, (XtPointer)False,
518 		},
519 		{
520 		XmNallowDrop, XmCAllowDrop,
521 		XmRBoolean, sizeof(Boolean),
522 		XtOffset(XmLGridWidget, grid.allowDrop),
523 		XmRImmediate, (XtPointer)False,
524 		},
525 		{
526 		XmNallowRowHide, XmCAllowRowHide,
527 		XmRBoolean, sizeof(Boolean),
528 		XtOffset(XmLGridWidget, grid.allowRowHide),
529 		XmRImmediate, (XtPointer)False,
530 		},
531 		{
532 		XmNallowRowResize, XmCAllowRowResize,
533 		XmRBoolean, sizeof(Boolean),
534 		XtOffset(XmLGridWidget, grid.allowRowResize),
535 		XmRImmediate, (XtPointer)False,
536 		},
537 		{
538 		XmNautoSelect, XmCAutoSelect,
539 		XmRBoolean, sizeof(Boolean),
540 		XtOffset(XmLGridWidget, grid.autoSelect),
541 		XmRImmediate, (XtPointer)True,
542 		},
543 		{
544 		XmNblankBackground, XmCBlankBackground,
545 		XmRPixel, sizeof(Pixel),
546 		XtOffset(XmLGridWidget, grid.blankBg),
547 		XmRCallProc, (XtPointer)GetCoreBackground,
548 		},
549 		{
550 		XmNbottomFixedCount, XmCBottomFixedCount,
551 		XmRInt, sizeof(int),
552 		XtOffset(XmLGridWidget, grid.bottomFixedCount),
553 		XmRImmediate, (XtPointer)0,
554 		},
555 		{
556 		XmNbottomFixedMargin, XmCBottomFixedMargin,
557 		XmRDimension, sizeof(Dimension),
558 		XtOffset(XmLGridWidget, grid.bottomFixedMargin),
559 		XmRImmediate, (XtPointer)0,
560 		},
561 		{
562 		XmNcellDefaults, XmCCellDefaults,
563 		XmRBoolean, sizeof(Boolean),
564 		XtOffset(XmLGridWidget, grid.cellDefaults),
565 		XmRImmediate, (XtPointer)False,
566 		},
567 		{
568 		XmNcellDrawCallback, XmCCallback,
569 		XmRCallback, sizeof(XtCallbackList),
570 		XtOffset(XmLGridWidget, grid.cellDrawCallback),
571 		XmRImmediate, (XtPointer)0,
572 		},
573 		{
574 		XmNcellDropCallback, XmCCallback,
575 		XmRCallback, sizeof(XtCallbackList),
576 		XtOffset(XmLGridWidget, grid.cellDropCallback),
577 		XmRImmediate, (XtPointer)0,
578 		},
579 		{
580 		XmNcellFocusCallback, XmCCallback,
581 		XmRCallback, sizeof(XtCallbackList),
582 		XtOffset(XmLGridWidget, grid.cellFocusCallback),
583 		XmRImmediate, (XtPointer)0,
584 		},
585 		{
586 		XmNcellPasteCallback, XmCCallback,
587 		XmRCallback, sizeof(XtCallbackList),
588 		XtOffset(XmLGridWidget, grid.cellPasteCallback),
589 		XmRImmediate, (XtPointer)0,
590 		},
591 		{
592 		XmNcolumns, XmCColumns,
593 		XmRInt, sizeof(int),
594 		XtOffset(XmLGridWidget, grid.colCount),
595 		XmRImmediate, (XtPointer)0,
596 		},
597 		{
598 		XmNdeleteCallback, XmCCallback,
599 		XmRCallback, sizeof(XtCallbackList),
600 		XtOffset(XmLGridWidget, grid.deleteCallback),
601 		XmRImmediate, (XtPointer)0,
602 		},
603 		{
604 		XmNdeselectCallback, XmCCallback,
605 		XmRCallback, sizeof(XtCallbackList),
606 		XtOffset(XmLGridWidget, grid.deselectCallback),
607 		XmRImmediate, (XtPointer)0,
608 		},
609 		{
610 		XmNdebugLevel, XmCDebugLevel,
611 		XmRInt, sizeof(int),
612 		XtOffset(XmLGridWidget, grid.debugLevel),
613 		XmRImmediate, (XtPointer)0,
614 		},
615 		{
616 		XmNeditCallback, XmCCallback,
617 		XmRCallback, sizeof(XtCallbackList),
618 		XtOffset(XmLGridWidget, grid.editCallback),
619 		XmRImmediate, (XtPointer)0,
620 		},
621 		{
622 		XmNeditTranslations, XmCTranslations,
623 		XmRTranslationTable, sizeof(XtTranslations),
624 		XtOffset(XmLGridWidget, grid.editTrans),
625 		XmRString, (XtPointer)editTranslations,
626 		},
627 		{
628 		XmNfontList, XmCFontList,
629 		XmRFontList, sizeof(XmFontList),
630 		XtOffset(XmLGridWidget, grid.fontList),
631 		XmRImmediate, (XtPointer)0
632 		},
633 		{
634 		XmNfooterColumns, XmCFooterColumns,
635 		XmRInt, sizeof(int),
636 		XtOffset(XmLGridWidget, grid.footerColCount),
637 		XmRImmediate, (XtPointer)0,
638 		},
639 		{
640 		XmNfooterRows, XmCFooterRows,
641 		XmRInt, sizeof(int),
642 		XtOffset(XmLGridWidget, grid.footerRowCount),
643 		XmRImmediate, (XtPointer)0,
644 		},
645 		{
646 		XmNglobalPixmapHeight, XmCGlobalPixmapHeight,
647 		XmRDimension, sizeof(Dimension),
648 		XtOffset(XmLGridWidget, grid.globalPixmapHeight),
649 		XmRImmediate, (XtPointer)0,
650 		},
651 		{
652 		XmNglobalPixmapWidth, XmCGlobalPixmapWidth,
653 		XmRDimension, sizeof(Dimension),
654 		XtOffset(XmLGridWidget, grid.globalPixmapWidth),
655 		XmRImmediate, (XtPointer)0,
656 		},
657 		{
658 		XmNheadingColumns, XmCHeadingColumns,
659 		XmRInt, sizeof(int),
660 		XtOffset(XmLGridWidget, grid.headingColCount),
661 		XmRImmediate, (XtPointer)0,
662 		},
663 		{
664 		XmNheadingRows, XmCHeadingRows,
665 		XmRInt, sizeof(int),
666 		XtOffset(XmLGridWidget, grid.headingRowCount),
667 		XmRImmediate, (XtPointer)0,
668 		},
669 		{
670 		XmNhiddenColumns, XmCHiddenColumns,
671 		XmRInt, sizeof(int),
672 		XtOffset(XmLGridWidget, grid.hiddenColCount),
673 		XmRImmediate, (XtPointer)0,
674 		},
675 		{
676 		XmNhiddenRows, XmCHiddenRows,
677 		XmRInt, sizeof(int),
678 		XtOffset(XmLGridWidget, grid.hiddenRowCount),
679 		XmRImmediate, (XtPointer)0,
680 		},
681 		{
682 		XmNhighlightRowMode, XmCHighlightRowMode,
683 		XmRBoolean, sizeof(Boolean),
684 		XtOffset(XmLGridWidget, grid.highlightRowMode),
685 		XmRImmediate, (XtPointer)False,
686 		},
687 		{
688 		XmNhighlightThickness, XmCHighlightThickness,
689 		XmRDimension, sizeof(Dimension),
690 		XtOffset(XmLGridWidget, grid.highlightThickness),
691 		XmRImmediate, (XtPointer)2,
692 		},
693 		{
694 		XmNhorizontalScrollBar, XmCHorizontalScrollBar,
695 		XmRWidget, sizeof(Widget),
696 		XtOffset(XmLGridWidget, grid.hsb),
697 		XmRImmediate, (XtPointer)0,
698 		},
699 		{
700 		XmNhorizontalSizePolicy, XmCHorizontalSizePolicy,
701 		XmRGridSizePolicy, sizeof(unsigned char),
702 		XtOffset(XmLGridWidget, grid.hsPolicy),
703 		XmRImmediate, (XtPointer)XmCONSTANT,
704 		},
705 		{
706 		XmNhsbDisplayPolicy, XmCHsbDisplayPolicy,
707 		XmRScrollBarDisplayPolicy, sizeof(unsigned char),
708 		XtOffset(XmLGridWidget, grid.hsbDisplayPolicy),
709 		XmRImmediate, (XtPointer)XmAS_NEEDED,
710 		},
711 		{
712 		XmNimmediateDraw, XmCImmediateDraw,
713 		XmRBoolean, sizeof(Boolean),
714 		XtOffset(XmLGridWidget, grid.immediateDraw),
715 		XmRImmediate, (XtPointer)False,
716 		},
717 		{
718 		XmNlayoutFrozen, XmCLayoutFrozen,
719 		XmRBoolean, sizeof(Boolean),
720 		XtOffset(XmLGridWidget, grid.layoutFrozen),
721 		XmRImmediate, (XtPointer)False,
722 		},
723 		{
724 		XmNleftFixedCount, XmCLeftFixedCount,
725 		XmRInt, sizeof(int),
726 		XtOffset(XmLGridWidget, grid.leftFixedCount),
727 		XmRImmediate, (XtPointer)0,
728 		},
729 		{
730 		XmNleftFixedMargin, XmCLeftFixedMargin,
731 		XmRDimension, sizeof(Dimension),
732 		XtOffset(XmLGridWidget, grid.leftFixedMargin),
733 		XmRImmediate, (XtPointer)0,
734 		},
735 		{
736 		XmNminColumnWidth, XmCMinColumnWidth,
737 		XmRDimension, sizeof(Dimension),
738 		XtOffset(XmLGridWidget, grid.minColWidth),
739 		XmRImmediate, (XtPointer)0,
740 		},
741 		{
742 		XmNrightFixedCount, XmCRightFixedCount,
743 		XmRInt, sizeof(int),
744 		XtOffset(XmLGridWidget, grid.rightFixedCount),
745 		XmRImmediate, (XtPointer)0,
746 		},
747 		{
748 		XmNrightFixedMargin, XmCRightFixedMargin,
749 		XmRDimension, sizeof(Dimension),
750 		XtOffset(XmLGridWidget, grid.rightFixedMargin),
751 		XmRImmediate, (XtPointer)0,
752 		},
753 		{
754 		XmNresizeCallback, XmCCallback,
755 		XmRCallback, sizeof(XtCallbackList),
756 		XtOffset(XmLGridWidget, grid.resizeCallback),
757 		XmRImmediate, (XtPointer)0,
758 		},
759 		{
760 		XmNrows, XmCRows,
761 		XmRInt, sizeof(int),
762 		XtOffset(XmLGridWidget, grid.rowCount),
763 		XmRImmediate, (XtPointer)0,
764 		},
765 		{
766 		XmNscrollBarMargin, XmCScrollBarMargin,
767 		XmRDimension, sizeof(Dimension),
768 		XtOffset(XmLGridWidget, grid.scrollBarMargin),
769 		XmRImmediate, (XtPointer)2,
770 		},
771 		{
772 		XmNscrollCallback, XmCCallback,
773 		XmRCallback, sizeof(XtCallbackList),
774 		XtOffset(XmLGridWidget, grid.scrollCallback),
775 		XmRImmediate, (XtPointer)0,
776 		},
777 		{
778 		XmNscrollColumn, XmCScrollColumn,
779 		XmRInt, sizeof(int),
780 		XtOffset(XmLGridWidget, grid.cScrollCol),
781 		XmRImmediate, (XtPointer)0,
782 		},
783 		{
784 		XmNscrollRow, XmCScrollRow,
785 		XmRInt, sizeof(int),
786 		XtOffset(XmLGridWidget, grid.cScrollRow),
787 		XmRImmediate, (XtPointer)0,
788 		},
789 		{
790 		XmNselectCallback, XmCCallback,
791 		XmRCallback, sizeof(XtCallbackList),
792 		XtOffset(XmLGridWidget, grid.selectCallback),
793 		XmRImmediate, (XtPointer)0,
794 		},
795 		{
796 		XmNselectionPolicy, XmCGridSelectionPolicy,
797 		XmRGridSelectionPolicy, sizeof(unsigned char),
798 		XtOffset(XmLGridWidget, grid.selectionPolicy),
799 		XmRImmediate, (XtPointer)XmSELECT_BROWSE_ROW,
800 		},
801 		{
802 		XmNselectBackground, XmCSelectBackground,
803 		XmRPixel, sizeof(Pixel),
804 		XtOffset(XmLGridWidget, grid.selectBg),
805 		XmRCallProc, (XtPointer)GetManagerForeground,
806 		},
807 		{
808 		XmNselectForeground, XmCSelectForeground,
809 		XmRPixel, sizeof(Pixel),
810 		XtOffset(XmLGridWidget, grid.selectFg),
811 		XmRCallProc, (XtPointer)GetCoreBackground,
812 		},
813 		{
814 		XmNshadowRegions, XmCShadowRegions,
815 		XmRInt, sizeof(int),
816 		XtOffset(XmLGridWidget, grid.shadowRegions),
817 		XmRImmediate, (XtPointer)511,
818 		},
819 		{
820 		XmNshadowType, XmCShadowType,
821 		XmRShadowType, sizeof(unsigned char),
822 		XtOffset(XmLGridWidget, grid.shadowType),
823 		XmRImmediate, (XtPointer)XmSHADOW_IN,
824 		},
825 		{
826 		XmNsimpleHeadings, XmCSimpleHeadings,
827 		XmRString, sizeof(char *),
828 		XtOffset(XmLGridWidget, grid.simpleHeadings),
829 		XmRImmediate, (XtPointer)0,
830 		},
831 		{
832 		XmNsimpleWidths, XmCSimpleWidths,
833 		XmRString, sizeof(char *),
834 		XtOffset(XmLGridWidget, grid.simpleWidths),
835 		XmRImmediate, (XtPointer)0,
836 		},
837 		{
838 		XmNtextWidget, XmCTextWidget,
839 		XmRWidget, sizeof(Widget),
840 		XtOffset(XmLGridWidget, grid.text),
841 		XmRImmediate, (XtPointer)0,
842 		},
843 		{
844 		XmNtoggleBottomColor, XmCToggleBottomColor,
845 		XmRPixel, sizeof(Pixel),
846 		XtOffset(XmLGridWidget, grid.toggleBotColor),
847 		XmRCallProc, (XtPointer)GetManagerForeground,
848 		},
849 		{
850 		XmNtoggleTopColor, XmCToggleTopColor,
851 		XmRPixel, sizeof(Pixel),
852 		XtOffset(XmLGridWidget, grid.toggleTopColor),
853 		XmRCallProc, (XtPointer)GetManagerForeground,
854 		},
855 		{
856 		XmNtoggleSize, XmCToggleSize,
857 		XmRDimension, sizeof(Dimension),
858 		XtOffset(XmLGridWidget, grid.toggleSize),
859 		XmRImmediate, (XtPointer)16,
860 		},
861 		{
862 		XmNtraverseTranslations, XmCTranslations,
863 		XmRTranslationTable, sizeof(XtTranslations),
864 		XtOffset(XmLGridWidget, grid.traverseTrans),
865 		XmRString, (XtPointer)traverseTranslations,
866 		},
867 		{
868 		XmNtopFixedCount, XmCTopFixedCount,
869 		XmRInt, sizeof(int),
870 		XtOffset(XmLGridWidget, grid.topFixedCount),
871 		XmRImmediate, (XtPointer)0,
872 		},
873 		{
874 		XmNtopFixedMargin, XmCTopFixedMargin,
875 		XmRDimension, sizeof(Dimension),
876 		XtOffset(XmLGridWidget, grid.topFixedMargin),
877 		XmRImmediate, (XtPointer)0,
878 		},
879 		{
880 		XmNuseAverageFontWidth, XmCUseAverageFontWidth,
881 		XmRBoolean, sizeof(Boolean),
882 		XtOffset(XmLGridWidget, grid.useAvgWidth),
883 		XmRImmediate, (XtPointer)True,
884 		},
885 		{
886 		XmNverticalScrollBar, XmCVerticalScrollBar,
887 		XmRWidget, sizeof(Widget),
888 		XtOffset(XmLGridWidget, grid.vsb),
889 		XmRImmediate, (XtPointer)0,
890 		},
891 		{
892 		XmNverticalSizePolicy, XmCVerticalSizePolicy,
893 		XmRGridSizePolicy, sizeof(unsigned char),
894 		XtOffset(XmLGridWidget, grid.vsPolicy),
895 		XmRImmediate, (XtPointer)XmCONSTANT,
896 		},
897 		{
898 		XmNvisibleColumns, XmCVisibleColumns,
899 		XmRInt, sizeof(int),
900 		XtOffset(XmLGridWidget, grid.visibleCols),
901 		XmRImmediate, (XtPointer)0,
902 		},
903 		{
904 		XmNvisibleRows, XmCVisibleRows,
905 		XmRInt, sizeof(int),
906 		XtOffset(XmLGridWidget, grid.visibleRows),
907 		XmRImmediate, (XtPointer)0,
908 		},
909 		{
910 		XmNvsbDisplayPolicy, XmCVsbDisplayPolicy,
911 		XmRScrollBarDisplayPolicy, sizeof(unsigned char),
912 		XtOffset(XmLGridWidget, grid.vsbDisplayPolicy),
913 		XmRImmediate, (XtPointer)XmAS_NEEDED,
914 		},
915         /* Xfe Additions*/
916 		{
917 		XmNpopupCallback, XmCCallback,
918 		XmRCallback, sizeof(XtCallbackList),
919 		XtOffset(XmLGridWidget, grid.popupCallback),
920 		XmRImmediate, (XtPointer)0,
921 		},
922 		{
923 			XmNenterCellCallback,
924 			XmCCallback,
925 			XmRCallback,
926 			sizeof(XtCallbackList),
927 			XtOffset(XmLGridWidget, grid . enterCellCallback),
928 			XmRImmediate,
929 			(XtPointer) NULL
930 		},
931 		{
932 			XmNleaveCellCallback,
933 			XmCCallback,
934 			XmRCallback,
935 			sizeof(XtCallbackList),
936 			XtOffset(XmLGridWidget, grid . leaveCellCallback),
937 			XmRImmediate,
938 			(XtPointer) NULL
939 		},
940 		{
941 			XmNenterGridCallback,
942 			XmCCallback,
943 			XmRCallback,
944 			sizeof(XtCallbackList),
945 			XtOffset(XmLGridWidget, grid . enterGridCallback),
946 			XmRImmediate,
947 			(XtPointer) NULL
948 		},
949 		{
950 			XmNleaveGridCallback,
951 			XmCCallback,
952 			XmRCallback,
953 			sizeof(XtCallbackList),
954 			XtOffset(XmLGridWidget, grid . leaveGridCallback),
955 			XmRImmediate,
956 			(XtPointer) NULL
957 		},
958 
959 		/* Row Resources */
960 		{
961 		XmNrow, XmCGridRow,
962 		XmRInt, sizeof(int),
963 		XtOffset(XmLGridWidget, grid.cellRow),
964 		XmRImmediate, (XtPointer)-1,
965 		},
966 		{
967 		XmNrowUserData, XmCUserData,
968 		XmRPointer, sizeof(XtPointer),
969 		XtOffset(XmLGridWidget, grid.rowUserData),
970 		XmRImmediate, (XtPointer)0,
971 		},
972 		{
973 		XmNrowHeight, XmCRowHeight,
974 		XmRDimension, sizeof(Dimension),
975 		XtOffset(XmLGridWidget, grid.rowHeight),
976 		XmRImmediate, (XtPointer)0,
977 		},
978 		{
979 		XmNrowRangeEnd, XmCRowRangeEnd,
980 		XmRInt, sizeof(int),
981 		XtOffset(XmLGridWidget, grid.cellRowRangeEnd),
982 		XmRImmediate, (XtPointer)-1,
983 		},
984 		{
985 		XmNrowRangeStart, XmCRowRangeStart,
986 		XmRInt, sizeof(int),
987 		XtOffset(XmLGridWidget, grid.cellRowRangeStart),
988 		XmRImmediate, (XtPointer)-1,
989 		},
990 		{
991 		XmNrowSizePolicy, XmCRowSizePolicy,
992 		XmRGridSizePolicy, sizeof(unsigned char),
993 		XtOffset(XmLGridWidget, grid.rowSizePolicy),
994 		XmRImmediate, (XtPointer)0,
995 		},
996 		{
997 		XmNrowStep, XmCRowStep,
998 		XmRInt, sizeof(int),
999 		XtOffset(XmLGridWidget, grid.rowStep),
1000 		XmRImmediate, (XtPointer)1,
1001 		},
1002 		{
1003 		XmNrowType, XmCRowType,
1004 		XmRRowType, sizeof(unsigned char),
1005 		XtOffset(XmLGridWidget, grid.rowType),
1006 		XmRImmediate, (XtPointer)XmINVALID_TYPE,
1007 		},
1008 		/* Column Resources */
1009 		{
1010 		XmNcolumn, XmCGridColumn,
1011 		XmRInt, sizeof(int),
1012 		XtOffset(XmLGridWidget, grid.cellCol),
1013 		XmRImmediate, (XtPointer)-1,
1014 		},
1015 		{
1016 		XmNcolumnUserData, XmCUserData,
1017 		XmRPointer, sizeof(XtPointer),
1018 		XtOffset(XmLGridWidget, grid.colUserData),
1019 		XmRImmediate, (XtPointer)0,
1020 		},
1021 		{
1022 		XmNcolumnResizable, XmCColumnResizable,
1023 		XmRBoolean, sizeof(Boolean),
1024 		XtOffset(XmLGridWidget, grid.colResizable),
1025 		XmRImmediate, (XtPointer)TRUE,
1026 		},
1027 		{
1028 		XmNcolumnWidth, XmCColumnWidth,
1029 		XmRDimension, sizeof(Dimension),
1030 		XtOffset(XmLGridWidget, grid.colWidth),
1031 		XmRImmediate, (XtPointer)0,
1032 		},
1033 		{
1034 		XmNcolumnRangeEnd, XmCColumnRangeEnd,
1035 		XmRInt, sizeof(int),
1036 		XtOffset(XmLGridWidget, grid.cellColRangeEnd),
1037 		XmRImmediate, (XtPointer)-1,
1038 		},
1039 		{
1040 		XmNcolumnRangeStart, XmCColumnRangeStart,
1041 		XmRInt, sizeof(int),
1042 		XtOffset(XmLGridWidget, grid.cellColRangeStart),
1043 		XmRImmediate, (XtPointer)-1,
1044 		},
1045 		{
1046 		XmNcolumnSizePolicy, XmCColumnSizePolicy,
1047 		XmRGridSizePolicy, sizeof(unsigned char),
1048 		XtOffset(XmLGridWidget, grid.colSizePolicy),
1049 		XmRImmediate, (XtPointer)0,
1050 		},
1051 		{
1052 		XmNcolumnStep, XmCColumnStep,
1053 		XmRInt, sizeof(int),
1054 		XtOffset(XmLGridWidget, grid.colStep),
1055 		XmRImmediate, (XtPointer)1,
1056 		},
1057 		{
1058 		XmNcolumnType, XmCColumnType,
1059 		XmRColumnType, sizeof(unsigned char),
1060 		XtOffset(XmLGridWidget, grid.colType),
1061 		XmRImmediate, (XtPointer)XmINVALID_TYPE,
1062 		},
1063         /* xfe Column Resource additions */
1064 		{
1065 		XmNcolumnHidden, XmCColumnHidden,
1066 		XmRBoolean, sizeof(Boolean),
1067 		XtOffset(XmLGridWidget, grid.colHidden),
1068 		XmRImmediate, (XtPointer)FALSE,
1069 		},
1070 		{
1071 		XmNcolumnSortType, XmCColumnSortType,
1072 		XmRColumnSortType, sizeof(unsigned char),
1073 		XtOffset(XmLGridWidget, grid.colSortType),
1074 		XmRImmediate, (XtPointer)XmSORT_NONE,
1075 		},
1076 		/* Cell Resources */
1077 		{
1078 		XmNcellAlignment, XmCCellAlignment,
1079 		XmRCellAlignment, sizeof(unsigned char),
1080 		XtOffset(XmLGridWidget, grid.cellValues.alignment),
1081 		XmRImmediate, (XtPointer)0,
1082 		},
1083 		{
1084 		XmNcellBackground, XmCCellBackground,
1085 		XmRPixel, sizeof(Pixel),
1086 		XtOffset(XmLGridWidget, grid.cellValues.background),
1087 		XmRImmediate, (XtPointer)0,
1088 		},
1089 		{
1090 		XmNcellBottomBorderColor, XmCCellBottomBorderColor,
1091 		XmRPixel, sizeof(Pixel),
1092 		XtOffset(XmLGridWidget, grid.cellValues.bottomBorderColor),
1093 		XmRImmediate, (XtPointer)0,
1094 		},
1095 		{
1096 		XmNcellBottomBorderType, XmCCellBottomBorderType,
1097 		XmRCellBorderType, sizeof(unsigned char),
1098 		XtOffset(XmLGridWidget, grid.cellValues.bottomBorderType),
1099 		XmRImmediate, (XtPointer)0,
1100 		},
1101 		{
1102 		XmNcellColumnSpan, XmCCellColumnSpan,
1103 		XmRInt, sizeof(int),
1104 		XtOffset(XmLGridWidget, grid.cellValues.columnSpan),
1105 		XmRImmediate, (XtPointer)0,
1106 		},
1107 		{
1108 		XmNcellEditable, XmCCellEditable,
1109 		XmRBoolean, sizeof(Boolean),
1110 		XtOffset(XmLGridWidget, grid.cellValues.editable),
1111 		XmRImmediate, (XtPointer)False,
1112 		},
1113 		{
1114 		XmNcellFontList, XmCCellFontList,
1115 		XmRFontList, sizeof(XmFontList),
1116 		XtOffset(XmLGridWidget, grid.cellValues.fontList),
1117 		XmRImmediate, (XtPointer)0,
1118 		},
1119 		{
1120 		XmNcellForeground, XmCCellForeground,
1121 		XmRPixel, sizeof(Pixel),
1122 		XtOffset(XmLGridWidget, grid.cellValues.foreground),
1123 		XmRImmediate, (XtPointer)0,
1124 		},
1125 		{
1126 		XmNcellLeftBorderColor, XmCCellLeftBorderColor,
1127 		XmRPixel, sizeof(Pixel),
1128 		XtOffset(XmLGridWidget, grid.cellValues.leftBorderColor),
1129 		XmRImmediate, (XtPointer)0,
1130 		},
1131 		{
1132 		XmNcellLeftBorderType, XmCCellLeftBorderType,
1133 		XmRCellBorderType, sizeof(unsigned char),
1134 		XtOffset(XmLGridWidget, grid.cellValues.leftBorderType),
1135 		XmRImmediate, (XtPointer)0,
1136 		},
1137 		{
1138 		XmNcellMarginBottom, XmCCellMarginBottom,
1139 		XmRDimension, sizeof(Dimension),
1140 		XtOffset(XmLGridWidget, grid.cellValues.bottomMargin),
1141 		XmRImmediate, (XtPointer)0,
1142 		},
1143 		{
1144 		XmNcellMarginLeft, XmCCellMarginLeft,
1145 		XmRDimension, sizeof(Dimension),
1146 		XtOffset(XmLGridWidget, grid.cellValues.leftMargin),
1147 		XmRImmediate, (XtPointer)0,
1148 		},
1149 		{
1150 		XmNcellMarginRight, XmCCellMarginRight,
1151 		XmRDimension, sizeof(Dimension),
1152 		XtOffset(XmLGridWidget, grid.cellValues.rightMargin),
1153 		XmRImmediate, (XtPointer)0,
1154 		},
1155 		{
1156 		XmNcellMarginTop, XmCCellMarginTop,
1157 		XmRDimension, sizeof(Dimension),
1158 		XtOffset(XmLGridWidget, grid.cellValues.topMargin),
1159 		XmRImmediate, (XtPointer)0,
1160 		},
1161 		{
1162 		XmNcellPixmap, XmCCellPixmap,
1163 		XmRManForegroundPixmap, sizeof(Pixmap),
1164 		XtOffset(XmLGridWidget, grid.cellPixmap),
1165 		XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
1166 		},
1167 		{
1168 		XmNcellPixmapMask, XmCCellPixmapMask,
1169 		XtRBitmap, sizeof(Pixmap),
1170 		XtOffset(XmLGridWidget, grid.cellPixmapMask),
1171 		XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
1172 		},
1173 		{
1174 		XmNcellRightBorderColor, XmCCellRightBorderColor,
1175 		XmRPixel, sizeof(Pixel),
1176 		XtOffset(XmLGridWidget, grid.cellValues.rightBorderColor),
1177 		XmRImmediate, (XtPointer)0,
1178 		},
1179 		{
1180 		XmNcellRightBorderType, XmCCellRightBorderType,
1181 		XmRCellBorderType, sizeof(unsigned char),
1182 		XtOffset(XmLGridWidget, grid.cellValues.rightBorderType),
1183 		XmRImmediate, (XtPointer)0,
1184 		},
1185 		{
1186 		XmNcellRowSpan, XmCCellRowSpan,
1187 		XmRInt, sizeof(int),
1188 		XtOffset(XmLGridWidget, grid.cellValues.rowSpan),
1189 		XmRImmediate, (XtPointer)0,
1190 		},
1191 		{
1192 		XmNcellString, XmCXmString,
1193 		XmRXmString, sizeof(XmString),
1194 		XtOffset(XmLGridWidget, grid.cellString),
1195 		XmRImmediate, (XtPointer)0,
1196 		},
1197 		{
1198 		XmNcellToggleSet, XmCCellToggleSet,
1199 		XmRBoolean, sizeof(Boolean),
1200 		XtOffset(XmLGridWidget, grid.cellToggleSet),
1201 		XmRImmediate, (XtPointer)False,
1202 		},
1203 		{
1204 		XmNcellTopBorderColor, XmCCellTopBorderColor,
1205 		XmRPixel, sizeof(Pixel),
1206 		XtOffset(XmLGridWidget, grid.cellValues.topBorderColor),
1207 		XmRImmediate, (XtPointer)0,
1208 		},
1209 		{
1210 		XmNcellTopBorderType, XmCCellTopBorderType,
1211 		XmRCellBorderType, sizeof(unsigned char),
1212 		XtOffset(XmLGridWidget, grid.cellValues.topBorderType),
1213 		XmRImmediate, (XtPointer)0,
1214 		},
1215 		{
1216 		XmNcellType, XmCCellType,
1217 		XmRCellType, sizeof(unsigned char),
1218 		XtOffset(XmLGridWidget, grid.cellValues.type),
1219 		XmRImmediate, (XtPointer)XmSTRING_CELL,
1220 		},
1221 		{
1222 		XmNcellUserData, XmCUserData,
1223 		XmRPointer, sizeof(XtPointer),
1224 		XtOffset(XmLGridWidget, grid.cellValues.userData),
1225 		XmRImmediate, (XtPointer)0,
1226 		},
1227 		/* Overridden inherited resources */
1228 		{
1229 		XmNshadowThickness, XmCShadowThickness,
1230 		XmRHorizontalDimension, sizeof(Dimension),
1231 		XtOffset(XmLGridWidget, manager.shadow_thickness),
1232 		XmRImmediate, (XtPointer)2,
1233 		},
1234         /* XFE Addition*/
1235 		{
1236 		XmNhideUnhideButtons, XmCHideUnhideButtons,
1237 		XmRBoolean, sizeof(Boolean),
1238 		XtOffset(XmLGridWidget, grid.hideUnhideButtons),
1239 		XmRImmediate, (XtPointer)False,
1240 		},
1241 		{
1242 		XmNsingleClickActivation, XmCSingleClickActivation,
1243 		XmRBoolean, sizeof(Boolean),
1244 		XtOffset(XmLGridWidget, grid.singleClickActivation),
1245 		XmRImmediate, (XtPointer)False,
1246 		},
1247 #if 0
1248 		{
1249 		XmNhideButtonTranslations, XmCTranslations,
1250 		XmRTranslationTable, sizeof(XtTranslations),
1251 		XtOffset(XmLGridWidget, grid.hideButtonTrans),
1252 		XmRString, (XtPointer)hideButtonTranslations,
1253 		},
1254 		{
1255 		XmNunhideButtonTranslations, XmCTranslations,
1256 		XmRTranslationTable, sizeof(XtTranslations),
1257 		XtOffset(XmLGridWidget, grid.unhideButtonTrans),
1258 		XmRString, (XtPointer)unhideButtonTranslations,
1259 		},
1260 #endif /*0*/
1261 		{
1262 		XmNuseTextWidget, XmCUseTextWidget,
1263 		XmRBoolean, sizeof(Boolean),
1264 		XtOffset(XmLGridWidget, grid.useTextWidget),
1265 		XmRImmediate, (XtPointer)True,
1266 		},
1267 		{
1268           XmNiconSpacing, XmCIconSpacing,
1269 		  XmRHorizontalDimension, sizeof(Dimension),
1270 		  XtOffset(XmLGridWidget, grid.iconSpacing),
1271 		  XmRImmediate, (XtPointer) 4,
1272 		},
1273     };
1274 
1275 XmLGridClassRec xmlGridClassRec =
1276 	{
1277 		{ /* core_class */
1278 		(WidgetClass)&xmManagerClassRec,          /* superclass         */
1279 		"XmLGrid",                                /* class_name         */
1280 		sizeof(XmLGridRec),                       /* widget_size        */
1281 		ClassInitialize,                          /* class_init         */
1282 		ClassPartInitialize,                      /* class_part_init    */
1283 		FALSE,                                    /* class_inited       */
1284 		(XtInitProc)Initialize,                   /* initialize         */
1285 		0,                                        /* initialize_hook    */
1286 		(XtRealizeProc)Realize,                   /* realize            */
1287 		(XtActionList)actions,                    /* actions            */
1288 		(Cardinal)XtNumber(actions),              /* num_actions        */
1289 		(XtResource *)resources,				  /* resources          */
1290 		XtNumber(resources),                      /* num_resources      */
1291 		NULLQUARK,                                /* xrm_class          */
1292 		TRUE,                                     /* compress_motion    */
1293 		XtExposeCompressMaximal,                  /* compress_exposure  */
1294 		TRUE,                                     /* compress_enterleav */
1295 		TRUE,                                     /* visible_interest   */
1296 		(XtWidgetProc)Destroy,                    /* destroy            */
1297 		(XtWidgetProc)Resize,                     /* resize             */
1298 		(XtExposeProc)Redisplay,                  /* expose             */
1299 		(XtSetValuesFunc)SetValues,               /* set_values         */
1300 		0,                                        /* set_values_hook    */
1301 		XtInheritSetValuesAlmost,                 /* set_values_almost  */
1302 		(XtArgsProc)GetSubValues,                 /* get_values_hook    */
1303 		0,                                        /* accept_focus       */
1304 		XtVersion,                                /* version            */
1305 		0,                                        /* callback_private   */
1306 		translations,                             /* tm_table           */
1307 		0,                                        /* query_geometry     */
1308 		0,                                        /* display_accelerato */
1309 		0,                                        /* extension          */
1310 		},
1311 		{ /* composite_class */
1312 		(XtGeometryHandler)GeometryManager,       /* geometry_manager   */
1313 		(XtWidgetProc)ChangeManaged,              /* change_managed     */
1314 		XtInheritInsertChild,                     /* insert_child       */
1315 		XtInheritDeleteChild,                     /* delete_child       */
1316 		0,                                        /* extension          */
1317 		},
1318 		{ /* constraint_class */
1319 		0,                                        /* subresources       */
1320 		0,                                        /* subresource_count  */
1321 		sizeof(XmLGridConstraintRec),             /* constraint_size    */
1322 		0,                                        /* initialize         */
1323 		0,                                        /* destroy            */
1324 		0,                                        /* set_values         */
1325 		0,                                        /* extension          */
1326 		},
1327 		{ /* manager_class */
1328 		XtInheritTranslations,                    /* translations       */
1329 		0,                                        /* syn resources      */
1330 		0,                                        /* num syn_resources  */
1331 		0,                                        /* get_cont_resources */
1332 		0,                                        /* num_get_cont_res   */
1333 		XmInheritParentProcess,                   /* parent_process     */
1334 		0,                                        /* extension          */
1335 		},
1336 		{ /* grid_class */
1337 		0,                                        /* initial rows       */
1338 		0,                                        /* initial columns    */
1339 		XmInheritGridPreLayout,                   /* pre layout         */
1340 		sizeof(struct _XmLGridRowRec),            /* row rec size       */
1341 		_GridRowNew,                              /* row new            */
1342 		_GridRowFree,                             /* row free           */
1343 		_GetRowValueMask,                         /* get row value mask */
1344 		_GetRowValue,                             /* get row value      */
1345 		_SetRowValues,                            /* set row values     */
1346 		sizeof(struct _XmLGridColumnRec),         /* column rec size    */
1347 		_GridColumnNew,                           /* column new         */
1348 		_GridColumnFree,                          /* column free        */
1349 		_GetColumnValueMask,                      /* get col value mask */
1350 		_GetColumnValue,                          /* get column value   */
1351 		_SetColumnValues,                         /* set column values  */
1352 		_SetCellValuesResize,                     /* set cell vl resize */
1353 		_GridCellAction,                          /* cell action        */
1354 		}
1355 	};
1356 
1357 WidgetClass xmlGridWidgetClass = (WidgetClass)&xmlGridClassRec;
1358 
1359 /*
1360    Create and Destroy
1361 */
1362 
1363 static void
ClassInitialize(void)1364 ClassInitialize(void)
1365 	{
1366 	int off1, off2;
1367 
1368 	XmLInitialize();
1369 
1370 	XtSetTypeConverter(XmRString, XmRGridSizePolicy,
1371 		CvtStringToSizePolicy, 0, 0, XtCacheNone, 0);
1372 	XtSetTypeConverter(XmRString, XmRColumnType,
1373 		CvtStringToRowColType, 0, 0, XtCacheNone, 0);
1374 	XtSetTypeConverter(XmRString, XmRRowType,
1375 		CvtStringToRowColType, 0, 0, XtCacheNone, 0);
1376 	XtSetTypeConverter(XmRString, XmRGridSelectionPolicy,
1377 		CvtStringToSelectionPolicy, 0, 0, XtCacheNone, 0);
1378 	XtSetTypeConverter(XmRString, XmRCellAlignment,
1379 		CvtStringToCellAlignment, 0, 0, XtCacheNone, 0);
1380 	XtSetTypeConverter(XmRString, XmRCellType,
1381 		CvtStringToCellType, 0, 0, XtCacheNone, 0);
1382 	XtSetTypeConverter(XmRString, XmRCellBorderType,
1383 		CvtStringToCellBorderType, 0, 0, XtCacheNone, 0);
1384 	/* long must be > 2 bytes for cell mask to work */
1385 	if (sizeof(long) < 3)
1386 		fprintf(stderr, "xmlGridClass: fatal error: long < 3 bytes\n");
1387 	/* compiler sanity check - make sure array pos lines up */
1388 	off1 = XtOffset(XmLArrayItem *, pos);
1389 	off2 = XtOffset(XmLGridColumn, grid.pos);
1390 	if (off1 != off2)
1391 		fprintf(stderr, "xmlGridClass: fatal error: column pos offset bad\n");
1392 	off2 = XtOffset(XmLGridRow, grid.pos);
1393 	if (off1 != off2)
1394 		fprintf(stderr, "xmlGridClass: fatal error: row pos offset bad\n");
1395 	}
1396 
1397 static void
ClassPartInitialize(WidgetClass wc)1398 ClassPartInitialize(WidgetClass wc)
1399 	{
1400 	XmLGridWidgetClass c, sc;
1401 
1402 	c = (XmLGridWidgetClass)wc;
1403 	sc = (XmLGridWidgetClass)c->core_class.superclass;
1404 
1405 #define INHERIT_PROC(proc, inherit) \
1406 	if (c->grid_class.proc == inherit) \
1407 		c->grid_class.proc = sc->grid_class.proc;
1408 
1409 	INHERIT_PROC(rowNewProc, XmInheritGridRowNew)
1410 	INHERIT_PROC(rowFreeProc, XmInheritGridRowFree)
1411 	INHERIT_PROC(getRowValueMaskProc, XmInheritGridGetRowValueMask)
1412 	INHERIT_PROC(getRowValueProc, XmInheritGridGetRowValue)
1413 	INHERIT_PROC(setRowValuesProc, XmInheritGridSetRowValues)
1414 
1415 	INHERIT_PROC(columnNewProc, XmInheritGridColumnNew)
1416 	INHERIT_PROC(columnFreeProc, XmInheritGridColumnFree)
1417 	INHERIT_PROC(getColumnValueMaskProc, XmInheritGridGetColumnValueMask)
1418 	INHERIT_PROC(getColumnValueProc, XmInheritGridGetColumnValue)
1419 	INHERIT_PROC(setColumnValuesProc, XmInheritGridSetColumnValues)
1420 
1421 	INHERIT_PROC(setCellValuesResizeProc, XmInheritGridSetCellValuesResize)
1422 	INHERIT_PROC(cellActionProc, XmInheritGridCellAction)
1423 
1424 #undef INHERIT_PROC
1425 	}
1426 
1427 static void
Initialize(Widget reqW,Widget newW,ArgList args,Cardinal * narg)1428 Initialize(Widget reqW,
1429 	   Widget newW,
1430 	   ArgList args,
1431 	   Cardinal *narg)
1432 	{
1433 	XmLGridWidget g, request;
1434 	Display *dpy;
1435 	Pixmap pix, pixMask;
1436 	Pixel white, black;
1437 	XColor fg, bg;
1438 	GridReg *reg;
1439 	int i, valid, hc, c, fc, hr, r, fr;
1440 	Boolean layoutFrozen;
1441 #ifdef POINTER_FOCUS_CHECK
1442 	unsigned char kfp;
1443 	Widget shell;
1444 #endif
1445 
1446 	g = (XmLGridWidget)newW;
1447 	dpy = XtDisplay((Widget)g);
1448 	request = (XmLGridWidget)reqW;
1449 
1450 #ifdef POINTER_FOCUS_CHECK
1451 	shell = XmLShellOfWidget(newW);
1452 	if (shell && XmIsVendorShell(shell))
1453 		{
1454 		XtVaGetValues(shell,
1455 			XmNkeyboardFocusPolicy, &kfp,
1456 			NULL);
1457 		if (kfp == XmPOINTER)
1458 			XmLWarning(newW, "keyboardFocusPolicy of XmPOINTER not supported");
1459 		}
1460 #endif
1461 
1462 	black = BlackPixelOfScreen(XtScreen((Widget)g));
1463 	white = WhitePixelOfScreen(XtScreen((Widget)g));
1464 
1465 	g->grid.rowArray = XmLArrayNew(1, 1);
1466 	g->grid.colArray = XmLArrayNew(1, 1);
1467 
1468 	if (g->core.width <= 0)
1469 		g->core.width = 100;
1470 	if (g->core.height <= 0)
1471 		g->core.height = 100;
1472 
1473 	CopyFontList(g);
1474 
1475 	if (g->grid.useTextWidget) {
1476 	  g->grid.text = XtVaCreateManagedWidget("text", xmTextWidgetClass, (Widget)g,
1477 						 XmNmarginHeight, 0,
1478 						 XmNmarginWidth, 3,
1479 						 XmNshadowThickness, 0,
1480 						 XmNhighlightThickness, 0,
1481 						 XmNx, 0,
1482 						 XmNy, 0,
1483 						 XmNwidth, 40,
1484 						 XmNheight, 40,
1485 						 XmNbackground, g->core.background_pixel,
1486 						 XmNforeground, g->manager.foreground,
1487 						 NULL);
1488 	  XtOverrideTranslations(g->grid.text, g->grid.traverseTrans);
1489 	  XtAddEventHandler(g->grid.text, StructureNotifyMask,
1490 			    True, (XtEventHandler)TextMapped, (XtPointer)0);
1491 	  XtAddCallback(g->grid.text, XmNactivateCallback, TextActivate, 0);
1492 	  XtAddCallback(g->grid.text, XmNfocusCallback, TextFocus, 0);
1493 	  XtAddCallback(g->grid.text, XmNlosingFocusCallback, TextFocus, 0);
1494 	  XtAddCallback(g->grid.text, XmNmodifyVerifyCallback, TextModifyVerify, 0);
1495 	}
1496 
1497 	g->grid.hsb = XtVaCreateWidget(
1498 		"hsb", xmScrollBarWidgetClass, (Widget)g,
1499 		XmNincrement, 1,
1500 		XmNorientation, XmHORIZONTAL,
1501 		XmNtraversalOn, False,
1502 		XmNbackground, g->core.background_pixel,
1503 /* Don't force foreground on IRIX - it screws up the thumb color in sgiMode */
1504 #ifndef IRIX
1505 		XmNforeground, g->manager.foreground,
1506 #endif
1507 		XmNtopShadowColor, g->manager.top_shadow_color,
1508 		XmNbottomShadowColor, g->manager.bottom_shadow_color,
1509 		NULL);
1510 	XtAddCallback(g->grid.hsb, XmNdragCallback, ScrollCB, 0);
1511 	XtAddCallback(g->grid.hsb, XmNvalueChangedCallback, ScrollCB, 0);
1512 	g->grid.vsb = XtVaCreateWidget(
1513 		"vsb", xmScrollBarWidgetClass, (Widget)g,
1514 		XmNorientation, XmVERTICAL,
1515 		XmNincrement, 1,
1516 		XmNtraversalOn, False,
1517 		XmNbackground, g->core.background_pixel,
1518 /* Don't force foreground on IRIX - it screws up the thumb color in sgiMode */
1519 #ifndef IRIX
1520 		XmNforeground, g->manager.foreground,
1521 #endif
1522 		XmNtopShadowColor, g->manager.top_shadow_color,
1523 		XmNbottomShadowColor, g->manager.bottom_shadow_color,
1524 		NULL);
1525 	XtAddCallback(g->grid.vsb, XmNdragCallback, ScrollCB, 0);
1526 	XtAddCallback(g->grid.vsb, XmNvalueChangedCallback, ScrollCB, 0);
1527 
1528     if (g->grid.hideUnhideButtons)
1529         {
1530         CreateHideUnhideButtons(g);
1531         }
1532     else
1533         {
1534         g->grid.hideButton = 0;
1535         g->grid.unhideButton = 0;
1536         }
1537 
1538 	g->grid.inResize = False;
1539 
1540 	/* Cursors */
1541 	fg.red = ~0;
1542 	fg.green = ~0;
1543 	fg.blue = ~0;
1544 	fg.pixel = white;
1545 	fg.flags = DoRed | DoGreen | DoBlue;
1546 	bg.red = 0;
1547 	bg.green = 0;
1548 	bg.blue = 0;
1549 	bg.pixel = black;
1550 	bg.flags = DoRed | DoGreen | DoBlue;
1551     pix = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
1552 		(char *)horizp_bits, horizp_width, horizp_height, 0, 1, 1);
1553     pixMask = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
1554 		(char *)horizm_bits, horizm_width, horizm_height, 1, 0, 1);
1555 	g->grid.hResizeCursor = XCreatePixmapCursor(dpy, pix, pixMask,
1556 		&fg, &bg, 9, 9);
1557 	XFreePixmap(dpy, pix);
1558 	XFreePixmap(dpy, pixMask);
1559     pix = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
1560 		(char *)vertp_bits, vertp_width, vertp_height, 0, 1, 1);
1561     pixMask = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
1562 		(char *)vertm_bits, vertm_width, vertm_height, 1, 0, 1);
1563 	g->grid.vResizeCursor = XCreatePixmapCursor(dpy, pix, pixMask,
1564 		&fg, &bg, 9, 9);
1565 	XFreePixmap(dpy, pix);
1566 	XFreePixmap(dpy, pixMask);
1567 
1568 	g->grid.cursorDefined = CursorNormal;
1569 	g->grid.focusIn = 0;
1570 	g->grid.focusRow = -1;
1571 	g->grid.focusCol = -1;
1572 	g->grid.mayHaveRowSpans = 0;
1573 	g->grid.scrollCol = 0;
1574 	g->grid.scrollRow = 0;
1575 	g->grid.textHidden = 1;
1576 	g->grid.inMode = InNormal;
1577 	g->grid.inEdit = 0;
1578 	g->grid.singleColScrollMode = 0;
1579 	g->grid.layoutStack = 0;
1580 	g->grid.needsHorizLayout = 0;
1581 	g->grid.needsVertLayout = 0;
1582 	g->grid.recalcHorizVisPos = 0;
1583 	g->grid.recalcVertVisPos = 0;
1584 	g->grid.vertVisChangedHint = 0;
1585 	g->grid.defCellValues = CellRefValuesCreate(g, 0);
1586 	g->grid.defCellValues->refCount = 1;
1587 	g->grid.ignoreModifyVerify = 0;
1588 	g->grid.extendRow = -1;
1589 	g->grid.extendCol = -1;
1590 	g->grid.extendToRow = -1;
1591 	g->grid.extendToCol = -1;
1592 	g->grid.extendSelect = True;
1593 	g->grid.lastSelectRow = -1;
1594 	g->grid.lastSelectCol = -1;
1595 	g->grid.lastSelectTime = 0;
1596 	g->grid.dragTimerSet = 0;
1597 	g->grid.editTimerSet = 0;
1598 	g->grid.gc = 0;
1599 
1600 	/*
1601 	 * Support for:
1602 	 *
1603 	 * XmNenterCellCallback
1604 	 * XmNenterCellCallback
1605 	 * XmNenterCallback
1606 	 * XmNleaveCallback
1607 	 */
1608 	g->grid.lastCursorMotionRow = -1;
1609 	g->grid.lastCursorMotionCol = -1;
1610 
1611 	XtAddEventHandler(newW,
1612 					  EnterWindowMask | LeaveWindowMask,
1613 					  True,
1614 					  (XtEventHandler) GridCrossingEH,
1615 					  (XtPointer) NULL);
1616 
1617 	reg = g->grid.reg;
1618 	for (i = 0; i < 9; i++)
1619 			{
1620 			reg[i].x = 0;
1621 			reg[i].y = 0;
1622 			reg[i].width = 0;
1623 			reg[i].height = 0;
1624 			reg[i].row = 0;
1625 			reg[i].col = 0;
1626 			reg[i].nrow = 0;
1627 			reg[i].ncol = 0;
1628 			}
1629 
1630 	layoutFrozen = g->grid.layoutFrozen;
1631 	g->grid.layoutFrozen = True;
1632 
1633 	if (g->grid.hiddenColCount || g->grid.hiddenRowCount)
1634 		{
1635 		XmLWarning(newW, "Initialize() - can't set hidden rows or columns");
1636 		g->grid.hiddenColCount = 0;
1637 		g->grid.hiddenRowCount = 0;
1638 		}
1639 	hc = g->grid.headingColCount;
1640 	c = XmLGridClassPartOfWidget(g).initialCols;
1641 	if (c < g->grid.colCount)
1642 		c = g->grid.colCount;
1643 	fc = g->grid.footerColCount;
1644 	hr = g->grid.headingRowCount;
1645 	r = XmLGridClassPartOfWidget(g).initialRows;
1646 	if (r < g->grid.rowCount)
1647 		r = g->grid.rowCount ;
1648 	fr = g->grid.footerRowCount;
1649 	g->grid.headingColCount = 0;
1650 	g->grid.colCount = 0;
1651 	g->grid.footerColCount = 0;
1652 	g->grid.headingRowCount = 0;
1653 	g->grid.rowCount = 0;
1654 	g->grid.footerRowCount = 0;
1655 	XmLGridAddColumns(newW, XmHEADING, -1, hc);
1656 	XmLGridAddColumns(newW, XmCONTENT, -1, c);
1657 	XmLGridAddColumns(newW, XmFOOTER, -1, fc);
1658 	XmLGridAddRows(newW, XmHEADING, -1, hr);
1659 	XmLGridAddRows(newW, XmCONTENT, -1, r);
1660 	XmLGridAddRows(newW, XmFOOTER, -1, fr);
1661 	if (g->grid.simpleHeadings)
1662 		{
1663 		g->grid.simpleHeadings = (char *)strdup(g->grid.simpleHeadings);
1664 		SetSimpleHeadings(g, g->grid.simpleHeadings);
1665 		}
1666 	if (g->grid.simpleWidths)
1667 		{
1668 		g->grid.simpleWidths = (char *)strdup(g->grid.simpleWidths);
1669 		SetSimpleWidths(g, g->grid.simpleWidths);
1670 		}
1671 	if (g->grid.visibleRows)
1672 		ApplyVisibleRows(g);
1673 	if (g->grid.visibleCols && g->grid.hsPolicy == XmCONSTANT)
1674         ApplyVisibleCols(g);
1675 
1676 	g->grid.layoutFrozen = layoutFrozen;
1677 	VertLayout(g, 1);
1678 	HorizLayout(g, 1);
1679 	PlaceScrollbars(g);
1680 
1681 	valid = 1;
1682 	for (i = 0; i < *narg; i++)
1683 		{
1684 		if (!args[i].name)
1685 			continue;
1686 		if (!strcmp(args[i].name, XmNrows) ||
1687 			!strcmp(args[i].name, XmNcolumns))
1688 			continue;
1689 		if (!strncmp(args[i].name, "row", 3) ||
1690 			!strncmp(args[i].name, "column", 6) ||
1691 			!strncmp(args[i].name, "cell", 4))
1692 			valid = 0;
1693 		}
1694 	if (!valid)
1695 		XmLWarning(newW,
1696 			"Initialize() - can't set row,column or cell values in init");
1697 
1698 	DropRegister(g, g->grid.allowDrop);
1699 	}
1700 
1701 static void
Destroy(Widget w)1702 Destroy(Widget w)
1703 	{
1704 	XmLGridWidget g;
1705 	Display *dpy;
1706 	int i, count;
1707 
1708 	g = (XmLGridWidget)w;
1709 	dpy = XtDisplay(w);
1710 	if (g->grid.dragTimerSet)
1711 		XtRemoveTimeOut(g->grid.dragTimerId);
1712 	if (g->grid.editTimerSet)
1713 		XtRemoveTimeOut(g->grid.editTimerId);
1714 	DefineCursor(g, CursorNormal);
1715 	XFreeCursor(dpy, g->grid.hResizeCursor);
1716 	XFreeCursor(dpy, g->grid.vResizeCursor);
1717 	if (g->grid.gc)
1718 		{
1719 		XFreeGC(dpy, g->grid.gc);
1720 		XFreeFont(dpy, g->grid.fallbackFont);
1721 		}
1722 	XmFontListFree(g->grid.fontList);
1723 	XmLGridCellDerefValues(g->grid.defCellValues);
1724 	ExtendSelect(g, (XEvent *)0, False, -1, -1);
1725 	count = XmLArrayGetCount(g->grid.rowArray);
1726 	for (i = 0; i < count; i++)
1727 		XmLGridRowFree(w, (XmLGridRow)XmLArrayGet(g->grid.rowArray, i));
1728 	XmLArrayFree(g->grid.rowArray);
1729 	count = XmLArrayGetCount(g->grid.colArray);
1730 	for (i = 0; i < count; i++)
1731 		XmLGridColumnFree(w, (XmLGridColumn)XmLArrayGet(g->grid.colArray, i));
1732 	XmLArrayFree(g->grid.colArray);
1733 	if (g->grid.simpleHeadings)
1734 		free((char *)g->grid.simpleHeadings);
1735 	if (g->grid.simpleWidths)
1736 		free((char *)g->grid.simpleWidths);
1737 	}
1738 
1739 /*
1740    Geometry, Drawing, Entry and Picking
1741 */
1742 
1743 static void
Realize(Widget w,XtValueMask * valueMask,XSetWindowAttributes * attr)1744 Realize(Widget w,
1745 	XtValueMask *valueMask,
1746 	XSetWindowAttributes *attr)
1747 	{
1748 	XmLGridWidget g;
1749 	Display *dpy;
1750 	WidgetClass superClass;
1751 	XtRealizeProc realize;
1752 	XGCValues values;
1753 	XtGCMask mask;
1754 	static char dashes[2] = { 1, 1 };
1755 
1756 	g = (XmLGridWidget)w;
1757 	dpy = XtDisplay(g);
1758 	superClass = xmlGridWidgetClass->core_class.superclass;
1759 	realize = superClass->core_class.realize;
1760 	(*realize)(w, valueMask, attr);
1761 
1762 	if (!g->grid.gc)
1763 		{
1764 		g->grid.fallbackFont = XLoadQueryFont(dpy, "fixed");
1765 		values.foreground = g->manager.foreground;
1766 		values.font = g->grid.fallbackFont->fid;
1767 		mask = GCForeground | GCFont;
1768 		g->grid.gc = XCreateGC(dpy, XtWindow(g), mask, &values);
1769 		XSetDashes(dpy, g->grid.gc, 0, dashes, 2);
1770 		if (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW &&
1771 			g->grid.autoSelect == True &&
1772 			g->grid.rowCount)
1773 			XmLGridSelectRow(w, 0, False);
1774 		}
1775 	}
1776 
1777 static void
Redisplay(Widget w,XExposeEvent * event,Region region)1778 Redisplay(Widget w,
1779 	  XExposeEvent *event,
1780 	  Region region)
1781 	{
1782 	XmLGridWidget g;
1783 	Display *dpy;
1784 	Window win;
1785 	XmLGridCell cell;
1786 	XmLGridRow row;
1787 	XmLGridColumn col;
1788 	XmLGridCellRefValues *cellValues;
1789 	XmLGridDrawStruct ds;
1790 	XmLGridCallbackStruct cbs;
1791 	GridReg *reg;
1792 	XRectangle eRect, rRect, clipRect, rect[6];
1793 	int i, n, st, c, r, sc, sr, width, height, rowHeight;
1794 	int lastVisPos, visPos, hasDrawCB;
1795 	Boolean spanUp, spanLeft;
1796 
1797 	g = (XmLGridWidget)w;
1798 	if (!XtIsRealized((Widget)g))
1799 		return;
1800 	if (!g->core.visible)
1801 		return;
1802 	if (g->grid.layoutFrozen == True)
1803 		XmLWarning(w, "Redisplay() - layout frozen is True during redraw");
1804 	dpy = XtDisplay(g);
1805 	win = XtWindow(g);
1806 	st = g->manager.shadow_thickness;
1807 	reg = g->grid.reg;
1808 	if (event)
1809 		{
1810 		eRect.x = event->x;
1811 		eRect.y = event->y;
1812 		eRect.width = event->width;
1813 		eRect.height = event->height;
1814 		if (g->grid.debugLevel > 1)
1815 			fprintf(stderr, "XmLGrid: Redisplay x %d y %d w %d h %d\n",
1816 				event->x, event->y, event->width, event->height);
1817 		}
1818 	else
1819 		{
1820 		eRect.x = 0;
1821 		eRect.y = 0;
1822 		eRect.width = g->core.width;
1823 		eRect.height = g->core.height;
1824 		}
1825 	if (!eRect.width || !eRect.height)
1826 		return;
1827 	/* Hide any XORed graphics */
1828 	DrawResizeLine(g, 0, 1);
1829 	hasDrawCB = 0;
1830 	if (XtHasCallbacks(w, XmNcellDrawCallback) == XtCallbackHasSome)
1831 			hasDrawCB = 1;
1832 
1833     /* Add extra shadow around the whole widget
1834      * if 512 is set for shadow regions
1835      */
1836     if (g->grid.shadowRegions == 512
1837         && g->manager.shadow_thickness
1838 		&& XmLRectIntersect(&eRect, &rRect) != XmLRectInside)
1839     {
1840 #ifdef MOTIF11
1841 				_XmDrawShadow(dpy, win,
1842 					g->manager.bottom_shadow_GC,
1843 					g->manager.top_shadow_GC,
1844 					g->manager.shadow_thickness,
1845                     0,0,
1846                     g->core.width, g->core.height);
1847 #else
1848 				_XmDrawShadows(dpy, win,
1849 					g->manager.top_shadow_GC,
1850 					g->manager.bottom_shadow_GC,
1851                     0,0,
1852                     g->core.width, g->core.height,
1853 					g->manager.shadow_thickness,
1854 					g->grid.shadowType);
1855 #endif
1856     }
1857 /* end of extra shadow */
1858 	for (i = 0; i < 9; i++)
1859 		{
1860 		if (!reg[i].width || !reg[i].height)
1861 			continue;
1862 		rRect.x = reg[i].x;
1863 		rRect.y = reg[i].y;
1864 		rRect.width = reg[i].width;
1865 		rRect.height = reg[i].height;
1866 		if (XmLRectIntersect(&eRect, &rRect) == XmLRectOutside)
1867 			continue;
1868 		if (g->grid.debugLevel > 2)
1869 			fprintf(stderr, "XmLGrid: Redisplay region %d shadows\n", i);
1870 		rRect.x += st;
1871 		rRect.width -= st * 2;
1872 		rRect.y += st;
1873 		rRect.height -= st * 2;
1874 		if (XmLRectIntersect(&eRect, &rRect) != XmLRectInside
1875             && g->manager.shadow_thickness
1876             && g->grid.shadowRegions != 512)
1877 			{
1878 			if (g->grid.shadowRegions & (1 << i))
1879 #ifdef MOTIF11
1880 				_XmDrawShadow(dpy, win,
1881 					g->manager.bottom_shadow_GC,
1882 					g->manager.top_shadow_GC,
1883 					g->manager.shadow_thickness,
1884 					reg[i].x, reg[i].y,
1885 					reg[i].width, reg[i].height);
1886 #else
1887 				_XmDrawShadows(dpy, win,
1888 					g->manager.top_shadow_GC,
1889 					g->manager.bottom_shadow_GC,
1890 					reg[i].x, reg[i].y,
1891 					reg[i].width, reg[i].height,
1892 					g->manager.shadow_thickness,
1893 					g->grid.shadowType);
1894 #endif
1895 			else
1896 #ifdef MOTIF11
1897 				_XmEraseShadow(dpy, win,
1898 					g->manager.shadow_thickness,
1899 					reg[i].x, reg[i].y,
1900 					reg[i].width, reg[i].height);
1901 #else
1902 				_XmClearBorder(dpy, win,
1903 					reg[i].x, reg[i].y,
1904 					reg[i].width, reg[i].height,
1905 					g->manager.shadow_thickness);
1906 #endif
1907 			}
1908 		rRect.x += st;
1909 		height = 0;
1910 		if (g->grid.debugLevel > 2)
1911 			fprintf(stderr, "XmLGrid: Redisplay region %d content\n", i);
1912 		for (r = reg[i].row; r < reg[i].row + reg[i].nrow; r++)
1913 			{
1914 			rowHeight = GetRowHeight(g, r);
1915 			if (!rowHeight && !g->grid.mayHaveRowSpans)
1916 				continue;
1917 			width = 0;
1918 			for (c = reg[i].col; c < reg[i].col + reg[i].ncol; c++)
1919 				{
1920 				rRect.x = reg[i].x + st + width;
1921 				rRect.y = reg[i].y + st + height;
1922 				if (g->grid.singleColScrollMode)
1923 					rRect.x -= g->grid.singleColScrollPos;
1924 				rRect.width = GetColWidth(g, c);
1925 #if 0
1926                 if (i == 1 && r == reg[1].row && c == reg[1].col - 1)
1927                     {
1928                         rRect.width -= 10;
1929                     }
1930 #endif /*0 slamm */
1931 				rRect.height = rowHeight;
1932 				width += rRect.width;
1933 				cell = GetCell(g, r, c);
1934 				if (!cell)
1935 					continue;
1936 				cellValues = XmLGridCellGetRefValues(cell);
1937 
1938 				spanUp = False;
1939 				spanLeft = False;
1940 				if (XmLGridCellInRowSpan(cell))
1941 					{
1942 					if (r == reg[i].row)
1943 						{
1944 						spanUp = True;
1945 						if (c == reg[i].col)
1946 							spanLeft = True;
1947 						}
1948 					else
1949 						continue;
1950 					}
1951 				if (XmLGridCellInColumnSpan(cell))
1952 					{
1953 					if (c == reg[i].col)
1954 						spanLeft = True;
1955 					else
1956 						continue;
1957 					}
1958 				sr = r;
1959 				sc = c;
1960 				if (spanUp == True || spanLeft == True ||
1961 					cellValues->rowSpan || cellValues->columnSpan)
1962 					{
1963 					if (RowColFirstSpan(g, r, c, &sr, &sc, &rRect,
1964 						spanLeft, spanUp) == -1)
1965 						continue;
1966 					RowColSpanRect(g, sr, sc, &rRect);
1967 					}
1968 				if (!rRect.width || !rRect.height)
1969 					continue;
1970 				clipRect = rRect;
1971 				ClipRectToReg(g, &clipRect, &reg[i]);
1972 				if (!clipRect.width || !clipRect.height)
1973 					continue;
1974 				if (event && XRectInRegion(region, clipRect.x, clipRect.y,
1975 						clipRect.width, clipRect.height) == RectangleOut)
1976 					continue;
1977 				cell = GetCell(g, sr, sc);
1978 				if (!cell)
1979 					continue;
1980 				cellValues = XmLGridCellGetRefValues(cell);
1981 				cbs.reason = XmCR_CELL_DRAW;
1982 				cbs.event = (XEvent *)event;
1983 				cbs.rowType = RowPosToType(g, sr);
1984 				cbs.row = RowPosToTypePos(g, cbs.rowType, sr);
1985 				cbs.columnType = ColPosToType(g, sc);
1986 				cbs.column = ColPosToTypePos(g, cbs.columnType, sc);
1987 				cbs.clipRect = &clipRect;
1988 				cbs.drawInfo = &ds;
1989 				ds.gc = g->grid.gc;
1990 				ds.cellRect = &rRect;
1991 				ds.topMargin = cellValues->topMargin;
1992 				ds.bottomMargin = cellValues->bottomMargin;
1993 				ds.leftMargin = cellValues->leftMargin;
1994 				ds.rightMargin = cellValues->rightMargin;
1995 				ds.background = cellValues->background;
1996 				ds.foreground = cellValues->foreground;
1997 				ds.fontList = cellValues->fontList;
1998 				ds.alignment = cellValues->alignment;
1999 				ds.selectBackground = g->grid.selectBg;
2000 				ds.selectForeground = g->grid.selectFg;
2001 				row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, sr);
2002 				col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, sc);
2003 				ds.drawFocusType = XmDRAW_FOCUS_NONE;
2004 				if (g->grid.focusRow == sr &&
2005 					g->grid.highlightRowMode == True &&
2006 					g->grid.focusIn)
2007 					{
2008 					RecalcVisPos(g, 0);
2009 					visPos = XmLGridColumnGetVisPos(col);
2010 					lastVisPos = XmLArrayGetCount(g->grid.colArray) -
2011 						g->grid.hiddenColCount - 1;
2012 					if (visPos == 0 && visPos == lastVisPos)
2013 						ds.drawFocusType = XmDRAW_FOCUS_CELL;
2014 					else if (visPos == 0)
2015 						ds.drawFocusType = XmDRAW_FOCUS_LEFT;
2016 					else if (visPos == lastVisPos)
2017 						ds.drawFocusType = XmDRAW_FOCUS_RIGHT;
2018 					else
2019 						ds.drawFocusType = XmDRAW_FOCUS_MID;
2020 					}
2021 				if (g->grid.focusRow == sr &&
2022 					g->grid.focusCol == sc &&
2023 					g->grid.highlightRowMode == False &&
2024 					g->grid.focusIn)
2025 					ds.drawFocusType = XmDRAW_FOCUS_CELL;
2026 				if (XmLGridRowIsSelected(row) == True ||
2027 					XmLGridColumnIsSelected(col) == True ||
2028 					XmLGridCellIsSelected(cell) == True)
2029 					ds.drawSelected = True;
2030 				else
2031 					ds.drawSelected = False;
2032 				if (g->grid.selectionPolicy == XmSELECT_CELL &&
2033 					g->grid.focusIn && g->grid.focusRow == sr &&
2034 					g->grid.focusCol == sc)
2035 					ds.drawSelected = False;
2036 				ds.stringDirection = g->manager.string_direction;
2037 				XmLGridCellAction(cell, (Widget)g, &cbs);
2038 				if (hasDrawCB)
2039 					XtCallCallbackList(w, g->grid.cellDrawCallback,
2040 						(XtPointer)&cbs);
2041 				}
2042 			height += rowHeight;
2043 			}
2044 		}
2045 	if (g->grid.debugLevel > 1)
2046 		fprintf(stderr, "XmLGrid: Redisplay non-cell areas\n");
2047 	n = 0;
2048 	if (reg[0].width && g->grid.leftFixedMargin)
2049 		{
2050 		rect[n].x = reg[0].width;
2051 		rect[n].y = 0;
2052 		rect[n].width = g->grid.leftFixedMargin;
2053 		rect[n].height = g->core.height;
2054 		n++;
2055 		}
2056 	if (reg[2].width && g->grid.rightFixedMargin)
2057 		{
2058 		width = 0;
2059 		if (reg[0].ncol)
2060 			width += reg[0].width + g->grid.leftFixedMargin;
2061 		if (reg[1].ncol)
2062 			width += reg[1].width;
2063 		rect[n].x = width;
2064 		rect[n].y = 0;
2065 		rect[n].width = g->grid.rightFixedMargin;
2066 		rect[n].height = g->core.height;
2067 		n++;
2068 		}
2069 	if (reg[0].height && g->grid.topFixedMargin)
2070 		{
2071 		rect[n].x = 0;
2072 		rect[n].y = reg[0].height;
2073 		rect[n].width = g->core.width;
2074 		rect[n].height = g->grid.topFixedMargin;
2075 		n++;
2076 		}
2077 	if (reg[6].height && g->grid.bottomFixedMargin)
2078 		{
2079 		rect[n].x = 0;
2080 		height = 0;
2081 		if (reg[0].nrow)
2082 			height += reg[0].height + g->grid.topFixedMargin;
2083 		if (reg[3].nrow)
2084 			height += reg[3].height;
2085 		rect[n].y = height;
2086 		rect[n].width = g->core.width;
2087 		rect[n].height = g->grid.bottomFixedMargin;
2088 		n++;
2089 		}
2090 	width = reg[1].width;
2091 	if (reg[0].ncol)
2092 		width += reg[0].width + g->grid.leftFixedMargin;
2093 	if (reg[2].ncol)
2094 		width += g->grid.rightFixedMargin + reg[2].width;
2095 	if (width < (int)g->core.width)
2096 		{
2097 		rect[n].x = width;
2098 		rect[n].y = 0;
2099 		rect[n].width = g->core.width - width;
2100 		rect[n].height = g->core.height;
2101 		n++;
2102 		}
2103 	height = reg[3].height;
2104 	if (reg[0].nrow)
2105 		height += reg[0].height + g->grid.topFixedMargin;
2106 	if (reg[6].nrow)
2107 		height += g->grid.bottomFixedMargin + reg[6].height;
2108 	if (height < (int)g->core.height)
2109 		{
2110 		rect[n].x = 0;
2111 		rect[n].y = height;
2112 		rect[n].width = g->core.width;
2113 		rect[n].height = g->core.height - height;
2114 		n++;
2115 		}
2116 	for (i = 0; i < n; i++)
2117 		{
2118 		if (XmLRectIntersect(&eRect, &rect[i]) == XmLRectOutside)
2119 			continue;
2120 		XClearArea(dpy, win, rect[i].x, rect[i].y, rect[i].width,
2121 			rect[i].height, False);
2122 		}
2123 	n = 0;
2124 	if (reg[1].width)
2125 		{
2126 		width = 0;
2127 		for (c = reg[1].col; c < reg[1].col + reg[1].ncol; c++)
2128 			width += GetColWidth(g, c);
2129 		for (i = 1; i < 9; i += 3)
2130 			if (reg[i].height && width < reg[i].width - st * 2)
2131 				{
2132 				rect[n].x = reg[i].x + st + width;
2133 				rect[n].y = reg[i].y + st;
2134 				rect[n].width = reg[i].x + reg[i].width -
2135 					rect[n].x - st;
2136 				rect[n].height = reg[i].height - st * 2;
2137 				n++;
2138 				}
2139 		}
2140 	if (reg[3].height)
2141 		{
2142 		height = 0;
2143 		for (r = reg[3].row; r < reg[3].row + reg[3].nrow; r++)
2144 			height += GetRowHeight(g, r);
2145 		for (i = 3; i < 6; i++)
2146 			if (reg[i].width && height < reg[i].height - st * 2)
2147 				{
2148 				rect[n].x = reg[i].x + st;
2149 				rect[n].y = reg[i].y + st + height;
2150 				rect[n].width = reg[i].width - st * 2;
2151 				rect[n].height = reg[i].y + reg[i].height -
2152 					rect[n].y - st;
2153 				n++;
2154 				}
2155 		}
2156 	XSetForeground(dpy, g->grid.gc, g->grid.blankBg);
2157 	for (i = 0; i < n; i++)
2158 		{
2159 		if (XmLRectIntersect(&eRect, &rect[i]) == XmLRectOutside)
2160 			continue;
2161 		XFillRectangle(dpy, win, g->grid.gc, rect[i].x, rect[i].y,
2162 			rect[i].width, rect[i].height);
2163 		}
2164 	/* Show any XORed graphics */
2165 	DrawResizeLine(g, 0, 1);
2166 	}
2167 
2168 static void
DrawResizeLine(XmLGridWidget g,int xy,int erase)2169 DrawResizeLine(XmLGridWidget g,
2170 	       int xy,
2171 	       int erase)
2172 	{
2173 	if (g->grid.inMode != InResize)
2174 		return;
2175     if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE && !g->grid.resizeIsVert)
2176         return;
2177 	DrawXORRect(g, xy, 2, g->grid.resizeIsVert, erase);
2178 	}
2179 
2180 static void
DrawXORRect(XmLGridWidget g,int xy,int size,int isVert,int erase)2181 DrawXORRect(XmLGridWidget g,
2182 	    int xy,
2183 	    int size,
2184 	    int isVert,
2185 	    int erase)
2186 	{
2187 	Display *dpy;
2188 	Window win;
2189 	GC gc;
2190 	Pixel black, white;
2191 	int oldXY, maxX, maxY;
2192 
2193 	if (!XtIsRealized((Widget)g))
2194 		return;
2195 	/* erase is (0 == none) (1 == hide/show) (2 == permenent erase) */
2196 	dpy = XtDisplay(g);
2197 	win = XtWindow(g);
2198 	gc = g->grid.gc;
2199 	XSetFunction(dpy, gc, GXinvert);
2200 	black = BlackPixelOfScreen(XtScreen((Widget)g));
2201 	white = WhitePixelOfScreen(XtScreen((Widget)g));
2202 	XSetForeground(dpy, gc, black ^ white);
2203 	maxX = g->core.width;
2204 	if (XtIsManaged(g->grid.vsb))
2205 		maxX -= g->grid.vsb->core.width + g->grid.scrollBarMargin;
2206 	maxY = g->core.height;
2207 	if (XtIsManaged(g->grid.hsb))
2208 		maxY -= g->grid.hsb->core.height + g->grid.scrollBarMargin;
2209 	oldXY = g->grid.resizeLineXY;
2210 	if (isVert)
2211 		{
2212 		if (oldXY != -1)
2213 			XFillRectangle(dpy, win, gc, 0, oldXY, maxX, size);
2214 		}
2215 	else
2216 		{
2217 		if (oldXY != -1)
2218 			XFillRectangle(dpy, win, gc, oldXY, 0, size, maxY);
2219 		}
2220 	if (!erase)
2221 		{
2222 		if (isVert)
2223 			{
2224 			if (xy > maxY)
2225 				xy = maxY - 2;
2226 			if (xy < 0)
2227 				xy = 0;
2228 			XFillRectangle(dpy, win, gc, 0, xy, maxX, size);
2229 			}
2230 		else
2231 			{
2232 			if (xy > maxX)
2233 				xy = maxX - 2;
2234 			if (xy < 0)
2235 				xy = 0;
2236 			XFillRectangle(dpy, win, gc, xy, 0, size, maxY);
2237 			}
2238 		g->grid.resizeLineXY = xy;
2239 		}
2240 	else if (erase == 2)
2241 		g->grid.resizeLineXY = -1;
2242 	XSetFunction(dpy, gc, GXcopy);
2243 	}
2244 
2245 static void
DefineCursor(XmLGridWidget g,char defineCursor)2246 DefineCursor(XmLGridWidget g,
2247 	     char defineCursor)
2248 	{
2249 	Display *dpy;
2250 	Window win;
2251 
2252 	if (!XtIsRealized((Widget)g))
2253 		return;
2254 	dpy = XtDisplay(g);
2255 	win = XtWindow(g);
2256 	if (defineCursor != g->grid.cursorDefined)
2257 		XUndefineCursor(dpy, win);
2258 	if (defineCursor == CursorVResize)
2259 		XDefineCursor(dpy, win, g->grid.vResizeCursor);
2260 	else if (defineCursor == CursorHResize)
2261 		XDefineCursor(dpy, win, g->grid.hResizeCursor);
2262 	g->grid.cursorDefined = defineCursor;
2263 	}
2264 
2265 static void
DrawArea(XmLGridWidget g,int type,int row,int col)2266 DrawArea(XmLGridWidget g,
2267 	 int type,
2268 	 int row,
2269 	 int col)
2270 	{
2271 	GridReg *reg;
2272 	Display *dpy;
2273 	Window win;
2274 	XExposeEvent event;
2275 	XRectangle rect[3];
2276 	Region region;
2277 	int i, j, n;
2278 	Dimension width, height, st;
2279 
2280 	if (g->grid.layoutFrozen == True)
2281 		return;
2282 	if (!XtIsRealized((Widget)g))
2283 		return;
2284 	if (!g->core.visible)
2285 		return;
2286 	dpy = XtDisplay(g);
2287 	win = XtWindow(g);
2288 	reg = g->grid.reg;
2289 	st = g->manager.shadow_thickness;
2290 	if (g->grid.debugLevel > 1)
2291 		fprintf(stderr, "XmLGrid: DrawArea %d %d %d\n", type, row, col);
2292 
2293 	n = 0;
2294 	switch (type)
2295 	{
2296 	case DrawAll:
2297 		{
2298 		rect[n].x = 0;
2299 		rect[n].y = 0;
2300 		rect[n].width = g->core.width;
2301 		rect[n].height = g->core.height;
2302 		n++;
2303 		break;
2304 		}
2305 	case DrawHScroll:
2306 		{
2307 		for (i = 1; i < 9; i += 3)
2308 			{
2309 			if (!reg[i].width || !reg[i].height)
2310 				continue;
2311 			rect[n].x = reg[i].x + st;
2312 			rect[n].y = reg[i].y + st;
2313 			rect[n].width = reg[i].width - st * 2;
2314 			rect[n].height = reg[i].height - st * 2;
2315 			n++;
2316 			}
2317 		break;
2318 		}
2319 	case DrawVScroll:
2320 		{
2321 		for (i = 3; i < 6; i++)
2322 
2323 			{
2324 			if (!reg[i].width || !reg[i].height)
2325 				continue;
2326 			rect[n].x = reg[i].x + st;
2327 			rect[n].y = reg[i].y + st;
2328 			rect[n].width = reg[i].width - st * 2;
2329 			rect[n].height = reg[i].height - st * 2;
2330 			n++;
2331 			}
2332 		break;
2333 		}
2334 	case DrawRow:
2335 		{
2336 		for (i = 0; i < 9; i++)
2337 			{
2338 			if (!reg[i].width || !reg[i].height)
2339 				continue;
2340 			if (!(row >= reg[i].row &&
2341 				row < reg[i].row + reg[i].nrow))
2342 				continue;
2343 			height = 0;
2344 			for (j = reg[i].row; j < row; j++)
2345 				height += GetRowHeight(g, j);
2346 			rect[n].x = reg[i].x + st;
2347 			rect[n].y = reg[i].y + st + height;
2348 			rect[n].width = reg[i].width - st * 2;
2349 			rect[n].height = GetRowHeight(g, row);
2350 			ClipRectToReg(g, &rect[n], &reg[i]);
2351 			n++;
2352 			}
2353 		break;
2354 		}
2355 	case DrawCol:
2356 		{
2357 		for (i = 0; i < 9; i++)
2358 			{
2359 			if (!reg[i].width || !reg[i].height)
2360 				continue;
2361 			if (!(col >= reg[i].col &&
2362 				col < reg[i].col + reg[i].ncol))
2363 				continue;
2364 			width = 0;
2365 			for (j = reg[i].col; j < col; j++)
2366 				width += GetColWidth(g, j);
2367 			rect[n].x = reg[i].x + st + width;
2368 			rect[n].y = reg[i].y + st;
2369 			rect[n].width = GetColWidth(g, col);
2370 			rect[n].height = reg[i].height - st * 2;
2371 			ClipRectToReg(g, &rect[n], &reg[i]);
2372 			n++;
2373 			}
2374 		break;
2375 		}
2376 	case DrawCell:
2377 		{
2378 		if (!RowColToXY(g, row, col, True, &rect[n]))
2379 			n++;
2380 		break;
2381 		}
2382 	}
2383 	for (i = 0; i < n; i++)
2384 		{
2385 		if (!rect[i].width || !rect[i].height)
2386 			continue;
2387 		event.type = Expose;
2388 		event.window = win;
2389 		event.display = dpy;
2390 		event.x = rect[i].x;
2391 		event.y = rect[i].y;
2392 		event.width = rect[i].width;
2393 		event.height = rect[i].height;
2394 		event.send_event = True;
2395 		event.count = 0;
2396 		if (g->grid.immediateDraw)
2397 			{
2398 			region = XCreateRegion();
2399 			XUnionRectWithRegion(&rect[i], region, region);
2400 			Redisplay((Widget)g, &event, region);
2401 			XDestroyRegion(region);
2402 			}
2403 		else
2404 			XSendEvent(dpy, win, False, ExposureMask, (XEvent *)&event);
2405 		if (g->grid.debugLevel > 1)
2406 			fprintf(stderr, "XmLGrid: DrawArea expose x %d y %d w %d h %d\n",
2407 				event.x, event.y, event.width, event.height);
2408 		}
2409 	}
2410 
2411 static void
ExtendSelectRange(XmLGridWidget g,int * type,int * fr,int * lr,int * fc,int * lc)2412 ExtendSelectRange(XmLGridWidget g,
2413 		  int *type,
2414 		  int *fr,
2415 		  int *lr,
2416 		  int *fc,
2417 		  int *lc)
2418 	{
2419 	int r, c;
2420 
2421 	if ((g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW) ||
2422 		(ColPosToType(g, g->grid.extendCol) != XmCONTENT))
2423 		*type = SelectRow;
2424 	else if (RowPosToType(g, g->grid.extendRow) != XmCONTENT)
2425 		*type = SelectCol;
2426 	else
2427 		*type = SelectCell;
2428 
2429 	r = g->grid.extendToRow;
2430 	if (r < g->grid.headingRowCount)
2431 		r = g->grid.headingRowCount;
2432 	if (r >= g->grid.headingRowCount + g->grid.rowCount)
2433 		r = g->grid.headingRowCount + g->grid.rowCount - 1;
2434 	if (*type == SelectCol)
2435 		{
2436 		*fr = 0;
2437 		*lr = 1;
2438 		}
2439 	else if (g->grid.extendRow < r)
2440 		{
2441 		*fr = g->grid.extendRow;
2442 		*lr = r;
2443 		}
2444 	else
2445 		{
2446 		*fr = r;
2447 		*lr = g->grid.extendRow;
2448 		}
2449 	c = g->grid.extendToCol;
2450 	if (c < g->grid.headingColCount)
2451 		c = g->grid.headingColCount;
2452 	if (c >= g->grid.headingColCount + g->grid.colCount)
2453 		c = g->grid.headingColCount + g->grid.colCount - 1;
2454 	if (*type == SelectRow)
2455 		{
2456 		*fc = 0;
2457 		*lc = 1;
2458 		}
2459 	else if (g->grid.extendCol < c)
2460 		{
2461 		*fc = g->grid.extendCol;
2462 		*lc = c;
2463 		}
2464 	else
2465 		{
2466 		*fc = c;
2467 		*lc = g->grid.extendCol;
2468 		}
2469 	}
2470 
2471 static void
ExtendSelect(XmLGridWidget g,XEvent * event,Boolean set,int row,int col)2472 ExtendSelect(XmLGridWidget g,
2473 	     XEvent *event,
2474 	     Boolean set,
2475 	     int row,
2476 	     int col)
2477 	{
2478 	int type;
2479 	int r, fr, lr;
2480 	int c, fc, lc;
2481 
2482 	if (row == -1 || col == -1)
2483 		{
2484 		g->grid.extendRow = -1;
2485 		g->grid.extendCol = -1;
2486 		g->grid.extendToRow = -1;
2487 		g->grid.extendToCol = -1;
2488 		g->grid.extendSelect = True;
2489 		return;
2490 		}
2491 	if (RowPosToType(g, row) == XmFOOTER || ColPosToType(g, col) == XmFOOTER)
2492 		return;
2493 	if ((g->grid.extendToRow == row && g->grid.extendToCol == col) ||
2494 		(g->grid.extendRow == -1 && row == g->grid.focusRow &&
2495 		g->grid.extendCol == -1 && col == g->grid.focusCol))
2496 		return;
2497 	if (g->grid.extendRow != -1 && g->grid.extendCol != -1)
2498 		{
2499 		/* clear previous extend */
2500 		ExtendSelectRange(g, &type, &fr, &lr, &fc, &lc);
2501 		for (r = fr; r <= lr; r += 1)
2502 			for (c = fc; c <= lc; c += 1)
2503 				SelectTypeArea(g, type, event,
2504 					RowPosToTypePos(g, XmCONTENT, r),
2505 					ColPosToTypePos(g, XmCONTENT, c), False, True);
2506 		}
2507 	else
2508 		{
2509 		g->grid.extendRow = g->grid.focusRow;
2510 		g->grid.extendCol = g->grid.focusCol;
2511 		}
2512 	if (set == True)
2513 		{
2514 		g->grid.extendRow = row;
2515 		g->grid.extendCol = col;
2516 		}
2517 	if (g->grid.extendRow < 0 || g->grid.extendCol < 0)
2518 		return;
2519 	g->grid.extendToRow = row;
2520 	g->grid.extendToCol = col;
2521 
2522 	/* set new extend */
2523 	ExtendSelectRange(g, &type, &fr, &lr, &fc, &lc);
2524 	for (r = fr; r <= lr; r += 1)
2525 		for (c = fc; c <= lc; c += 1)
2526 			SelectTypeArea(g, type, event,
2527 				RowPosToTypePos(g, XmCONTENT, r),
2528 				ColPosToTypePos(g, XmCONTENT, c),
2529 				g->grid.extendSelect, True);
2530 	}
2531 
2532 static void
SelectTypeArea(XmLGridWidget g,int type,XEvent * event,int row,int col,Boolean select,Boolean notify)2533 SelectTypeArea(XmLGridWidget g,
2534 	       int type,
2535 	       XEvent *event,
2536 	       int row,
2537 	       int col,
2538 	       Boolean select,
2539 	       Boolean notify)
2540 	{
2541 	Widget w;
2542 	XmLGridRow rowp;
2543 	XmLGridColumn colp;
2544 	XmLGridCell cellp;
2545 	int r, fr, lr, hrc;
2546 	int c, fc, lc, hcc;
2547 	int badPos, hasCB;
2548 	XmLGridCallbackStruct cbs;
2549 
2550 	w = (Widget)g;
2551 	hrc = g->grid.headingRowCount;
2552 	hcc = g->grid.headingColCount;
2553 	cbs.event = event;
2554 	cbs.rowType = XmCONTENT;
2555 	cbs.columnType = XmCONTENT;
2556 	hasCB = 0;
2557 	if (select == True)
2558 		{
2559 		if (type == SelectRow)
2560 			cbs.reason = XmCR_SELECT_ROW;
2561 		else if (type == SelectCol)
2562 			cbs.reason = XmCR_SELECT_COLUMN;
2563 		else if (type == SelectCell)
2564 			cbs.reason = XmCR_SELECT_CELL;
2565 		if (XtHasCallbacks(w, XmNselectCallback) == XtCallbackHasSome)
2566 			hasCB = 1;
2567 		}
2568 	else
2569 		{
2570 		if (type == SelectRow)
2571 			cbs.reason = XmCR_DESELECT_ROW;
2572 		else if (type == SelectCol)
2573 			cbs.reason = XmCR_DESELECT_COLUMN;
2574 		else if (type == SelectCell)
2575 			cbs.reason = XmCR_DESELECT_CELL;
2576 		if (XtHasCallbacks(w, XmNdeselectCallback) == XtCallbackHasSome)
2577 			hasCB = 1;
2578 		}
2579 	if (row != -1)
2580 		{
2581 		fr = hrc + row;
2582 		lr = fr + 1;
2583 		}
2584 	else
2585 		{
2586 		fr = hrc;
2587 		lr = XmLArrayGetCount(g->grid.rowArray) - g->grid.footerRowCount;
2588 		}
2589 	if (col != -1)
2590 		{
2591 		fc = hcc + col;
2592 		lc = fc + 1;
2593 		}
2594 	else
2595 		{
2596 		fc = hcc;
2597 		lc = XmLArrayGetCount(g->grid.colArray) - g->grid.footerColCount;
2598 		}
2599 	badPos = 0;
2600 	for (r = fr; r < lr; r++)
2601 		for (c = fc; c < lc; c++)
2602 			{
2603 			if (type == SelectRow)
2604 				{
2605 				rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
2606 				if (!rowp)
2607 					{
2608 					badPos = 1;
2609 					continue;
2610 					}
2611 				if (XmLGridRowIsSelected(rowp) == select)
2612 					continue;
2613 				if (select == True &&
2614 					(g->grid.selectionPolicy == XmSELECT_BROWSE_ROW ||
2615 					g->grid.selectionPolicy == XmSELECT_SINGLE_ROW))
2616 					SelectTypeArea(g, SelectRow, event, -1, 0, False, notify);
2617 				XmLGridRowSetSelected(rowp, select);
2618 				if (RowIsVisible(g, r))
2619 					DrawArea(g, DrawRow, r, 0);
2620 				if (notify && hasCB)
2621 					{
2622 					cbs.row = r - hrc;
2623 					if (select == True)
2624 						XtCallCallbackList(w, g->grid.selectCallback,
2625 							(XtPointer)&cbs);
2626 					else
2627 						XtCallCallbackList(w, g->grid.deselectCallback,
2628 							(XtPointer)&cbs);
2629 					}
2630 				}
2631 			else if (type == SelectCol)
2632 				{
2633 				colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
2634 				if (!colp)
2635 					{
2636 					badPos = 1;
2637 					continue;
2638 					}
2639 				if (XmLGridColumnIsSelected(colp) == select)
2640 					continue;
2641 				XmLGridColumnSetSelected(colp, select);
2642 				if (ColIsVisible(g, c))
2643 					DrawArea(g, DrawCol, 0, c);
2644 				if (notify && hasCB)
2645 					{
2646 					cbs.column = c - hcc;
2647 					if (select == True)
2648 						XtCallCallbackList(w, g->grid.selectCallback,
2649 							(XtPointer)&cbs);
2650 					else
2651 						XtCallCallbackList(w, g->grid.deselectCallback,
2652 							(XtPointer)&cbs);
2653 					}
2654 				}
2655 			else if (type == SelectCell)
2656 				{
2657 				cellp = GetCell(g, r, c);
2658 				if (!cellp)
2659 					{
2660 					badPos = 1;
2661 					continue;
2662 					}
2663 				if (XmLGridCellIsSelected(cellp) == select)
2664 					continue;
2665 				XmLGridCellSetSelected(cellp, select);
2666 				DrawArea(g, DrawCell, r, c);
2667 				if (notify && hasCB)
2668 					{
2669 					cbs.column = c - hcc;
2670 					cbs.row = r - hrc;
2671 					if (select == True)
2672 						XtCallCallbackList(w, g->grid.selectCallback,
2673 							(XtPointer)&cbs);
2674 					else
2675 						XtCallCallbackList(w, g->grid.deselectCallback,
2676 							(XtPointer)&cbs);
2677 					}
2678 				}
2679 			}
2680 	if (badPos)
2681 		XmLWarning((Widget)g, "SelectTypeArea() - bad position");
2682 	}
2683 
2684 static int
GetSelectedArea(XmLGridWidget g,int type,int * rowPos,int * colPos,int count)2685 GetSelectedArea(XmLGridWidget g,
2686 		int type,
2687 		int *rowPos,
2688 		int *colPos,
2689 		int count)
2690 	{
2691 	XmLGridRow row;
2692 	XmLGridColumn col;
2693 	XmLGridCell cell;
2694 	int r, fr, lr;
2695 	int c, fc, lc;
2696 	int n;
2697 
2698 	if (type == SelectCol)
2699 		{
2700 		fr = 0;
2701 		lr = 1;
2702 		}
2703 	else
2704 		{
2705 		fr = g->grid.headingRowCount;
2706 		lr = XmLArrayGetCount(g->grid.rowArray) - g->grid.footerRowCount;
2707 		}
2708 	if (type == SelectRow)
2709 		{
2710 		fc = 0;
2711 		lc = 1;
2712 		}
2713 	else
2714 		{
2715 		fc = g->grid.headingColCount;
2716 		lc = XmLArrayGetCount(g->grid.colArray) - g->grid.footerColCount;
2717 		}
2718 	n = 0;
2719 	for (r = fr; r < lr; r++)
2720 		for (c = fc; c < lc; c++)
2721 			{
2722 			if (type == SelectRow)
2723 				{
2724 				row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
2725 				if (row && XmLGridRowIsSelected(row) == True)
2726 					{
2727 					if (rowPos && n < count)
2728 						rowPos[n] = r - fr;
2729 					n++;
2730 					}
2731 				}
2732 			else if (type == SelectCol)
2733 				{
2734 				col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
2735 				if (col && XmLGridColumnIsSelected(col) == True)
2736 					{
2737 					if (colPos && n < count)
2738 						colPos[n] = c - fc;
2739 					n++;
2740 					}
2741 				}
2742 			else if (type == SelectCell)
2743 				{
2744 				cell = GetCell(g, r, c);
2745 				if (cell && XmLGridCellIsSelected(cell) == True)
2746 					{
2747 					if (rowPos && colPos && n < count)
2748 						{
2749 						rowPos[n] = r - fr;
2750 						colPos[n] = c - fc;
2751 						}
2752 					n++;
2753 					}
2754 				}
2755 			}
2756 	return n;
2757 	}
2758 
2759 static void
ChangeManaged(Widget w)2760 ChangeManaged(Widget w)
2761 	{
2762 	_XmNavigChangeManaged(w);
2763 	}
2764 
2765 static void
Resize(Widget w)2766 Resize(Widget w)
2767 	{
2768 	XmLGridWidget g;
2769 	XmLGridCallbackStruct cbs;
2770 
2771 	g = (XmLGridWidget)w;
2772 
2773 	if (!g->grid.inResize)
2774 	  {
2775 	    cbs.reason = XmCR_RESIZE_GRID;
2776 
2777 	    g->grid.inResize = True;
2778 	    XtCallCallbackList((Widget)g, g->grid.resizeCallback,
2779 			       (XtPointer)&cbs);
2780 	    g->grid.inResize = False;
2781 	  }
2782 
2783 	VertLayout(g, 0);
2784 	HorizLayout(g, 0);
2785 	PlaceScrollbars(g);
2786 	DrawArea(g, DrawAll, 0, 0);
2787 	}
2788 
2789 static void
PlaceScrollbars(XmLGridWidget g)2790 PlaceScrollbars(XmLGridWidget g)
2791 	{
2792 	int x, y;
2793 	int width, height;
2794 	Widget vsb, hsb;
2795 	Dimension st, headingRowHeight = 0;
2796 
2797 	st = g->manager.shadow_thickness;
2798 	vsb = g->grid.vsb;
2799 	hsb = g->grid.hsb;
2800 	width = g->core.width;
2801 	if (XtIsManaged(vsb))
2802 		width -= vsb->core.width;
2803 	if (width <= 0)
2804 		width = 1;
2805 	y = g->core.height - hsb->core.height;
2806 	XtConfigureWidget(hsb, 0, y, width, hsb->core.height, 0);
2807 
2808 	height = g->core.height;
2809 	if (XtIsManaged(hsb))
2810 		height -= hsb->core.height;
2811 
2812 	y = 0;
2813 
2814 	if (g->grid.headingRowCount > 0)
2815 	  {
2816 	    XmLGridRow rowp;
2817 
2818 	    rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, 0);
2819 
2820 	    headingRowHeight = XmLGridRowHeightInPixels(rowp) + st;
2821 	  }
2822 
2823     if (g->grid.hideUnhideButtons
2824         && g->grid.hideButton && g->grid.unhideButton)
2825 	    {
2826           int buttonWidth = vsb->core.width - 4;
2827 
2828 	      if (headingRowHeight == 0)
2829               headingRowHeight = 20;
2830 
2831 	      /* if there is at least heading row, we make the
2832 		   height of the button the height of the first
2833 		   heading row.
2834 
2835 		   This is pretty braindead... */
2836 
2837 		XtConfigureWidget(g->grid.unhideButton,
2838 				  g->core.width - buttonWidth*2 - st,
2839 				  y + st,
2840 				  buttonWidth,
2841 				  headingRowHeight - st, 0);
2842 		XtConfigureWidget(g->grid.hideButton,
2843 				  g->core.width - buttonWidth - st,
2844 				  y + st,
2845 				  buttonWidth,
2846 				  headingRowHeight - st, 0);
2847 
2848         setHideUnhideSensitivity((Widget)g);
2849 
2850 		/* once we've positioned it, make sure it's managed.
2851 		   Doing it in this order (position, then manage) reduces
2852 		   screen flickering -- the button doesn't flash on in the
2853 		   upper left corner for an instant. */
2854 		if (!XtIsManaged(g->grid.hideButton))
2855 		    XtManageChild(g->grid.hideButton);
2856 		if (!XtIsManaged(g->grid.unhideButton))
2857 		    XtManageChild(g->grid.unhideButton);
2858 	    }
2859 
2860 	if (height <= 0)
2861 		width = 1;
2862 	x = g->core.width - vsb->core.width;
2863 	XtConfigureWidget(vsb,
2864 			  x, y + headingRowHeight + g->manager.shadow_thickness,
2865 			  vsb->core.width, height - headingRowHeight - g->manager.shadow_thickness,
2866 			  0);
2867 	}
2868 
2869 void
_XmLGridLayout(XmLGridWidget g)2870 _XmLGridLayout(XmLGridWidget g)
2871 	{
2872 	VertLayout(g, 1);
2873 	HorizLayout(g, 1);
2874 	}
2875 
2876 static void
VertLayout(XmLGridWidget g,int resizeIfNeeded)2877 VertLayout(XmLGridWidget g,
2878 	   int resizeIfNeeded)
2879 	{
2880 	GridReg *reg;
2881 	int i, j, st2, height, rowCount;
2882 	int topNRow, topHeight;
2883 	int midRow, midY, midNRow, midHeight;
2884 	int botRow, botY, botNRow, botHeight;
2885 	int scrollChanged, needsSB, needsResize, cRow;
2886 	int maxRow, maxPos, maxHeight, newHeight, sliderSize;
2887 	int horizSizeChanged;
2888 	XtWidgetGeometry req;
2889 	XmLGridCallbackStruct cbs;
2890 	XmLGridPreLayoutProc preLayoutProc;
2891 
2892 	if (g->grid.layoutFrozen == True)
2893 		{
2894 		g->grid.needsVertLayout = 1;
2895 		return;
2896 		}
2897 
2898 	maxRow = maxPos = maxHeight = newHeight = horizSizeChanged = 0;
2899 	preLayoutProc = XmLGridClassPartOfWidget(g).preLayoutProc;
2900 	if (g->grid.layoutStack < 2 && preLayoutProc != XmInheritGridPreLayout)
2901 		horizSizeChanged = preLayoutProc(g, 1);
2902 
2903 	scrollChanged = 0;
2904 	needsResize = 0;
2905 	needsSB = 0;
2906 	rowCount = XmLArrayGetCount(g->grid.rowArray);
2907 	reg = g->grid.reg;
2908 	st2 = g->manager.shadow_thickness * 2;
2909 	TextAction(g, TEXT_HIDE);
2910 
2911 	topHeight = 0;
2912 	topNRow = g->grid.topFixedCount;
2913 	if (topNRow > g->grid.rowCount + g->grid.headingRowCount)
2914 		topNRow = g->grid.rowCount + g->grid.headingRowCount;
2915 	if (topNRow)
2916 		{
2917 		topHeight += st2;
2918 		for (i = 0; i < topNRow; i++)
2919 			topHeight += GetRowHeight(g, i);
2920 		}
2921 	botHeight = 0;
2922 	botNRow = g->grid.bottomFixedCount;
2923 	if (topNRow + botNRow > rowCount)
2924 		botNRow = rowCount - topNRow;
2925 	botRow = rowCount - botNRow;
2926 	if (botNRow)
2927 		{
2928 		botHeight += st2;
2929 		for (i = botRow; i < rowCount; i++)
2930 			botHeight += GetRowHeight(g, i);
2931 		}
2932 	height = 0;
2933 	if (topNRow)
2934 		height += topHeight + g->grid.topFixedMargin;
2935 	midY = height;
2936 	if (botNRow)
2937 		height += botHeight + g->grid.bottomFixedMargin;
2938 	if (XtIsManaged(g->grid.hsb))
2939 		{
2940 		height += g->grid.hsb->core.height;
2941 		height += g->grid.scrollBarMargin;
2942 		}
2943 	maxHeight = g->core.height - height;
2944 	if (g->grid.vsPolicy != XmCONSTANT)
2945 		{
2946 		if (rowCount == topNRow + botNRow)
2947 			midHeight = 0;
2948 		else
2949 			midHeight = st2;
2950 		for (i = topNRow; i < rowCount - botNRow; i++)
2951 			midHeight += GetRowHeight(g, i);
2952 		midRow = topNRow;
2953 		midNRow = rowCount - topNRow - botNRow;
2954 		needsResize = 1;
2955 		newHeight = midHeight + height;
2956 		if (g->grid.debugLevel)
2957 			fprintf(stderr, "XmLGrid: VertLayout VARIABLE height\n");
2958 		}
2959 	else
2960 		{
2961 		if (maxHeight < st2)
2962 			maxHeight = 0;
2963 		height = st2;
2964 		j = rowCount - botNRow - 1;
2965 		for (i = j; i >= topNRow; i--)
2966 			{
2967 			height += GetRowHeight(g, i);
2968 			if (height > maxHeight)
2969 				break;
2970 			}
2971 		i++;
2972 		if (i > j)
2973 			i = j;
2974 		maxRow = i;
2975 		if (maxRow < topNRow)
2976 			maxRow = topNRow;
2977 		if (g->grid.debugLevel)
2978 			fprintf(stderr, "XmLGrid: VertLayout max scroll row %d\n", i);
2979 		if (maxRow == topNRow)
2980 			{
2981 			if (g->grid.scrollRow != topNRow)
2982 				{
2983 				scrollChanged = 1;
2984 				g->grid.scrollRow = topNRow;
2985 				}
2986 			midRow = topNRow;
2987 			midHeight = maxHeight;
2988 			midNRow = rowCount - topNRow - botNRow;
2989 			if (g->grid.debugLevel)
2990 				fprintf(stderr, "XmLGrid: VertLayout everything fits\n");
2991 			}
2992 		else
2993 			{
2994 			if (g->grid.scrollRow < topNRow)
2995 				{
2996 				scrollChanged = 1;
2997 				g->grid.scrollRow = topNRow;
2998 				if (g->grid.debugLevel)
2999 					fprintf(stderr, "XmLGrid: VertLayout scrolled < topRow\n");
3000 				}
3001 			if (g->grid.scrollRow > maxRow)
3002 				{
3003 				if (g->grid.debugLevel)
3004 					fprintf(stderr, "XmLGrid: VertLayout scrolled > maxRow\n");
3005 				scrollChanged = 1;
3006 				g->grid.scrollRow = maxRow;
3007 				}
3008 			height = st2;
3009 			midNRow = 0;
3010 			for (i = g->grid.scrollRow; i < rowCount - botNRow; i++)
3011 				{
3012 				midNRow++;
3013 				height += GetRowHeight(g, i);
3014 				if (height >= maxHeight)
3015 					break;
3016 				}
3017 			needsSB = 1;
3018 			midRow = g->grid.scrollRow;
3019 			midHeight = maxHeight;
3020 			}
3021 		}
3022 	botY = midY + midHeight;
3023 	if (botNRow)
3024 		botY += g->grid.bottomFixedMargin;
3025 	for (i = 0; i < 3; i++)
3026 		{
3027 		reg[i].y = 0;
3028 		reg[i].height = topHeight;
3029 		reg[i].row = 0;
3030 		reg[i].nrow = topNRow;
3031 		}
3032 	for (i = 3; i < 6; i++)
3033 		{
3034 		reg[i].y = midY;
3035 		reg[i].height = midHeight;
3036 		reg[i].row = midRow;
3037 		reg[i].nrow = midNRow;
3038 		}
3039 	for (i = 6; i < 9; i++)
3040 		{
3041 		reg[i].y = botY;
3042 		reg[i].height = botHeight;
3043 		reg[i].row = botRow;
3044 		reg[i].nrow = botNRow;
3045 		}
3046 	if (g->grid.debugLevel)
3047 			{
3048 			fprintf(stderr, "XmLGrid: VertLayout TOP %3dy %3dh %3dr %3dnr\n",
3049 				reg[0].y, reg[0].height, reg[0].row, reg[0].nrow);
3050 			fprintf(stderr, "XmLGrid: VertLayout MID %3dy %3dh %3dr %3dnr\n",
3051 				reg[3].y, reg[3].height, reg[3].row, reg[3].nrow);
3052 			fprintf(stderr, "XmLGrid: VertLayout BOT %3dy %3dh %3dr %3dnr\n",
3053 				reg[6].y, reg[6].height, reg[6].row, reg[6].nrow);
3054 			}
3055 	if (needsSB)
3056 		{
3057 		if (!XtIsManaged(g->grid.vsb))
3058 			{
3059 			XtManageChild(g->grid.vsb);
3060 			horizSizeChanged = 1;
3061 			}
3062 		if (g->grid.debugLevel)
3063 			fprintf(stderr, "XmLGrid: VertLayout set sb values\n");
3064 		maxPos = PosToVisPos(g, maxRow, 1);
3065 		sliderSize = PosToVisPos(g, rowCount - botNRow - 1, 1) - maxPos + 1;
3066 		XtVaSetValues(g->grid.vsb,
3067 			XmNminimum, PosToVisPos(g, topNRow, 1),
3068 			XmNmaximum, maxPos + sliderSize,
3069 			XmNsliderSize, sliderSize,
3070 			XmNpageIncrement, sliderSize,
3071 			XmNvalue, PosToVisPos(g, g->grid.scrollRow, 1),
3072 			NULL);
3073 		}
3074 	else if (g->grid.vsPolicy == XmCONSTANT &&
3075 		g->grid.vsbDisplayPolicy == XmSTATIC)
3076 		{
3077 		if (!XtIsManaged(g->grid.vsb))
3078 			{
3079 			XtManageChild(g->grid.vsb);
3080 			horizSizeChanged = 1;
3081 			}
3082 		if (g->grid.debugLevel)
3083 			fprintf(stderr, "XmLGrid: VertLayout vsb not needed but static\n");
3084 		XtVaSetValues(g->grid.vsb,
3085 			XmNminimum, 0,
3086 			XmNmaximum, 1,
3087 			XmNsliderSize, 1,
3088 			XmNpageIncrement, 1,
3089 			XmNvalue, 0,
3090 			NULL);
3091 		}
3092 	else
3093 		{
3094 		if (XtIsManaged(g->grid.vsb))
3095 			{
3096 			XtUnmanageChild(g->grid.vsb);
3097 			horizSizeChanged = 1;
3098 			}
3099 		}
3100 	if (needsResize && resizeIfNeeded)
3101 		{
3102 		if (newHeight < 1)
3103 			newHeight = 1;
3104 		req.request_mode = CWHeight;
3105 		req.height = newHeight;
3106 		if (g->grid.debugLevel)
3107 			fprintf(stderr, "XmLGrid: VertLayout Req h %d\n", (int)newHeight);
3108 		XtMakeGeometryRequest((Widget)g, &req, NULL);
3109 		PlaceScrollbars(g);
3110 		}
3111 	if (scrollChanged)
3112 		DrawArea(g, DrawVScroll, 0, 0);
3113 	TextAction(g, TEXT_SHOW);
3114 	cRow = g->grid.scrollRow - g->grid.headingRowCount;
3115 	if (cRow != g->grid.cScrollRow)
3116 		{
3117 		g->grid.cScrollRow = cRow;
3118 		cbs.reason = XmCR_SCROLL_ROW;
3119 		cbs.rowType = XmCONTENT;
3120 		cbs.row = cRow;
3121 		XtCallCallbackList((Widget)g, g->grid.scrollCallback, (XtPointer)&cbs);
3122 		}
3123 	if (horizSizeChanged)
3124 		{
3125 		if (g->grid.layoutStack > 2)
3126 			XmLWarning((Widget)g, "VertLayout() - recursion error");
3127 		else
3128 			{
3129 			g->grid.layoutStack++;
3130 			HorizLayout(g, resizeIfNeeded);
3131 			g->grid.layoutStack--;
3132 			}
3133 		PlaceScrollbars(g);
3134 		}
3135 	}
3136 
3137 static void
HorizLayout(XmLGridWidget g,int resizeIfNeeded)3138 HorizLayout(XmLGridWidget g,
3139 	    int resizeIfNeeded)
3140 	{
3141 	GridReg *reg;
3142 	int i, j, st2, width, colCount;
3143 	int leftNCol, leftWidth;
3144 	int midCol, midX, midNCol, midWidth;
3145 	int rightCol, rightX, rightNCol, rightWidth;
3146 	int scrollChanged, needsSB, needsResize, cCol;
3147 	int maxCol, maxPos, maxWidth, newWidth, sliderSize;
3148 	int vertSizeChanged;
3149 	XtWidgetGeometry req;
3150 	XmLGridCallbackStruct cbs;
3151 	XmLGridPreLayoutProc preLayoutProc;
3152 
3153 	if (g->grid.layoutFrozen == True)
3154 		{
3155 		g->grid.needsHorizLayout = 1;
3156 		return;
3157 		}
3158 
3159 	maxCol = maxPos = newWidth = vertSizeChanged = 0;
3160 	preLayoutProc = XmLGridClassPartOfWidget(g).preLayoutProc;
3161 	if (g->grid.layoutStack < 2 && preLayoutProc != XmInheritGridPreLayout)
3162 		vertSizeChanged = preLayoutProc(g, 0);
3163 
3164 	scrollChanged = 0;
3165 	needsResize = 0;
3166 	needsSB = 0;
3167 
3168     if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE && g->grid.visibleCols)
3169         colCount = g->grid.visibleCols;
3170     else
3171         colCount = g->grid.colCount + g->grid.headingColCount
3172             + g->grid.footerColCount;
3173 
3174     if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
3175         {
3176         SizeColumnsToFit(g, 0);
3177         }
3178 
3179 	reg = g->grid.reg;
3180 	st2 = g->manager.shadow_thickness * 2;
3181 	TextAction(g, TEXT_HIDE);
3182 
3183 	leftWidth = 0;
3184 	leftNCol = g->grid.leftFixedCount;
3185 	if (leftNCol > g->grid.colCount + g->grid.headingColCount)
3186 		leftNCol = g->grid.colCount + g->grid.headingColCount;
3187 	if (leftNCol)
3188 		{
3189 		leftWidth += st2;
3190 		for (i = 0; i < leftNCol; i++)
3191 			leftWidth += GetColWidth(g, i);
3192 		}
3193 	rightWidth = 0;
3194 	rightNCol = g->grid.rightFixedCount;
3195 	if (rightNCol + leftNCol > colCount)
3196 		rightNCol = colCount - leftNCol;
3197 	rightCol = colCount - rightNCol;
3198 	if (rightNCol)
3199 		{
3200 		rightWidth += st2;
3201 		for (i = rightCol; i < colCount; i++)
3202 			rightWidth += GetColWidth(g, i);
3203 		}
3204 	width = 0;
3205 	if (leftNCol)
3206 		width += leftWidth + g->grid.leftFixedMargin;
3207 	midX = width;
3208 	if (rightNCol)
3209 		width += rightWidth + g->grid.rightFixedMargin;
3210 	if (XtIsManaged(g->grid.vsb))
3211 		{
3212 		width += g->grid.vsb->core.width;
3213 		width += g->grid.scrollBarMargin;
3214 		}
3215 	maxWidth = g->core.width - width;
3216 	if (g->grid.hsPolicy == XmVARIABLE ||
3217         g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
3218 		{
3219 		if (colCount == leftNCol + rightNCol)
3220 			midWidth = 0;
3221 		else
3222 			midWidth = st2;
3223 
3224         /* This assumes the show/hide buttons will be wider
3225            than the vertical scrollbar
3226          */
3227         if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
3228             {
3229             if (g->grid.hideUnhideButtons)
3230                 midWidth += XtWidth(g->grid.hideButton) * 2;
3231             else if (XtIsManaged(g->grid.vsb))
3232                 midWidth += XtWidth(g->grid.vsb);
3233             }
3234 
3235 
3236 		for (i = leftNCol; i < colCount - rightNCol; i++)
3237 			midWidth += GetColWidth(g, i);
3238 		midCol = leftNCol;
3239 		midNCol = colCount - leftNCol - rightNCol;
3240 		needsResize = 1;
3241 		newWidth = midWidth + width;
3242 		if (g->grid.debugLevel)
3243             {
3244             if (g->grid.hsPolicy == XmVARIABLE)
3245                 fprintf(stderr, "XmLGrid: HorizLayout VARIABLE width\n");
3246             else
3247                 fprintf(stderr, "XmLGrid: HorizLayout REZISE_IF_POSSIBLE\n");
3248             }
3249 		}
3250 	else
3251 		{
3252 		if (maxWidth < st2)
3253 			maxWidth = 0;
3254 		width = st2;
3255 		j = colCount - rightNCol - 1;
3256 		for (i = j; i >= leftNCol; i--)
3257 			{
3258 			width += GetColWidth(g, i);
3259 			if (width > maxWidth)
3260 				break;
3261 			}
3262 		i++;
3263 		if (i > j)
3264 			i = j;
3265 		maxCol = i;
3266 		if (maxCol < leftNCol)
3267 			maxCol = leftNCol;
3268 		if (g->grid.debugLevel)
3269 			fprintf(stderr, "XmLGrid: HorizLayout max scroll col %d\n", i);
3270 		if (maxCol == leftNCol)
3271 			{
3272 			if (g->grid.scrollCol != leftNCol)
3273 				{
3274 				scrollChanged = 1;
3275 				g->grid.scrollCol = leftNCol;
3276 				}
3277 			midCol = leftNCol;
3278 			midWidth = maxWidth;
3279 			midNCol = colCount - leftNCol - rightNCol;
3280 			if (g->grid.debugLevel)
3281 				fprintf(stderr, "XmLGrid: HorizLayout everything fits\n");
3282 			}
3283 		else
3284 			{
3285 			if (g->grid.scrollCol < leftNCol)
3286 				{
3287 				scrollChanged = 1;
3288 				g->grid.scrollCol = leftNCol;
3289 				if (g->grid.debugLevel)
3290 					fprintf(stderr, "XmLGrid: HorizLayout scroll < leftCol\n");
3291 				}
3292 			if (g->grid.scrollCol > maxCol)
3293 				{
3294 				if (g->grid.debugLevel)
3295 					fprintf(stderr, "XmLGrid: HorizLayout scroll > maxCol\n");
3296 				scrollChanged = 1;
3297 				g->grid.scrollCol = maxCol;
3298 				}
3299 			width = st2;
3300 			midNCol = 0;
3301 			for (i = g->grid.scrollCol; i < colCount - rightNCol; i++)
3302 				{
3303 				midNCol++;
3304 				width += GetColWidth(g, i);
3305 				if (width >= maxWidth)
3306 					break;
3307 				}
3308 			needsSB = 1;
3309 			midCol = g->grid.scrollCol;
3310 			midWidth = maxWidth;
3311 			}
3312 		}
3313 	rightX = midX + midWidth;
3314 	if (rightNCol)
3315 		rightX += g->grid.rightFixedMargin;
3316 	for (i = 0; i < 9; i += 3)
3317 		{
3318 		reg[i].x = 0;
3319 		reg[i].width = leftWidth;
3320 		reg[i].col = 0;
3321 		reg[i].ncol = leftNCol;
3322 		}
3323 	for (i = 1; i < 9; i += 3)
3324 		{
3325 		reg[i].x = midX;
3326 		reg[i].width = midWidth;
3327 		reg[i].col = midCol;
3328 		reg[i].ncol = midNCol;
3329 		}
3330 	for (i = 2; i < 9; i += 3)
3331 		{
3332 		reg[i].x = rightX;
3333 		reg[i].width = rightWidth;
3334 		reg[i].col = rightCol;
3335 		reg[i].ncol = rightNCol;
3336 		}
3337 
3338 	if (g->grid.debugLevel)
3339 		{
3340 		fprintf(stderr, "XmLGrid: HorizLayout LFT %3dx %3dw %3dc %3dnc\n",
3341 			reg[0].x, reg[0].width, reg[0].col, reg[0].ncol);
3342 		fprintf(stderr, "XmLGrid: HorizLayout MID %3dx %3dw %3dc %3dnc\n",
3343 			reg[1].x, reg[1].width, reg[1].col, reg[1].ncol);
3344 		fprintf(stderr, "XmLGrid: HorizLayout RHT %3dx %3dw %3dc %3dnc\n",
3345 			reg[2].x, reg[2].width, reg[2].col, reg[2].ncol);
3346 		}
3347 	if (g->grid.hsPolicy == XmCONSTANT && colCount == 1 &&
3348 		g->grid.colCount == 1 && width > maxWidth)
3349 		{
3350 		/* Single Column Pixel Scroll Mode */
3351 		if (g->grid.singleColScrollMode)
3352 			{
3353 			i = g->grid.singleColScrollPos;
3354 			if (i < 0)
3355 				i = 0;
3356 			else if (i > width - maxWidth)
3357 				i = width - maxWidth;
3358 			}
3359 		else
3360 			i = 0;
3361 		XtVaSetValues(g->grid.hsb,
3362 			XmNminimum, 0,
3363 			XmNmaximum, width - maxWidth + 1,
3364 			XmNsliderSize, 1,
3365 			XmNpageIncrement, ((width - maxWidth) / 4) + 1,
3366 			XmNvalue, i,
3367 			NULL);
3368 		if (!XtIsManaged(g->grid.hsb))
3369 			{
3370 			XtManageChild(g->grid.hsb);
3371 			vertSizeChanged = 1;
3372 			}
3373 		g->grid.singleColScrollMode = 1;
3374 		g->grid.singleColScrollPos = i;
3375 		}
3376 	else
3377 		g->grid.singleColScrollMode = 0;
3378 	if (g->grid.singleColScrollMode)
3379 		;
3380 	else if (needsSB)
3381 		{
3382 		if (g->grid.debugLevel)
3383 			fprintf(stderr, "XmLGrid: HorizLayout set sb values\n");
3384 		if (!XtIsManaged(g->grid.hsb))
3385 			{
3386 			XtManageChild(g->grid.hsb);
3387 			vertSizeChanged = 1;
3388 			}
3389 		maxPos = PosToVisPos(g, maxCol, 0);
3390 		sliderSize = PosToVisPos(g, colCount - rightNCol - 1, 0) - maxPos + 1;
3391 		XtVaSetValues(g->grid.hsb,
3392 			XmNminimum, PosToVisPos(g, leftNCol, 0),
3393 			XmNmaximum, maxPos + sliderSize,
3394 			XmNsliderSize, sliderSize,
3395 			XmNpageIncrement, sliderSize,
3396 			XmNvalue, PosToVisPos(g, g->grid.scrollCol, 0),
3397 			NULL);
3398 		}
3399 	else if (g->grid.hsPolicy == XmCONSTANT &&
3400 		g->grid.hsbDisplayPolicy == XmSTATIC)
3401 		{
3402 		if (!XtIsManaged(g->grid.hsb))
3403 			{
3404 			XtManageChild(g->grid.hsb);
3405 			vertSizeChanged = 1;
3406 			}
3407 		if (g->grid.debugLevel)
3408 			fprintf(stderr, "XmLGrid: HorizLayout hsb not needed - static\n");
3409 		XtVaSetValues(g->grid.hsb,
3410 			XmNminimum, 0,
3411 			XmNmaximum, 1,
3412 			XmNsliderSize, 1,
3413 			XmNpageIncrement, 1,
3414 			XmNvalue, 0,
3415 			NULL);
3416 		}
3417 	else
3418 		{
3419 		if (XtIsManaged(g->grid.hsb))
3420 			{
3421 			XtUnmanageChild(g->grid.hsb);
3422 			vertSizeChanged = 1;
3423 			}
3424 		}
3425 	if (needsResize && resizeIfNeeded)
3426 		{
3427 		if (newWidth < 1)
3428 			newWidth = 1;
3429 		req.request_mode = CWWidth;
3430 		req.width = newWidth;
3431 		if (g->grid.debugLevel)
3432 			fprintf(stderr, "XmLGrid: HorizLayout Req w %d\n", (int)newWidth);
3433 		XtMakeGeometryRequest((Widget)g, &req, NULL);
3434 		PlaceScrollbars(g);
3435 		}
3436 	if (scrollChanged)
3437 		DrawArea(g, DrawHScroll, 0, 0);
3438 	TextAction(g, TEXT_SHOW);
3439 	cCol = g->grid.scrollCol - g->grid.headingColCount;
3440 	if (cCol != g->grid.cScrollCol)
3441 		{
3442 		g->grid.cScrollCol = cCol;
3443 		cbs.reason = XmCR_SCROLL_COLUMN;
3444 		cbs.columnType = XmCONTENT;
3445 		cbs.column = cCol;
3446 		XtCallCallbackList((Widget)g, g->grid.scrollCallback, (XtPointer)&cbs);
3447 		}
3448 	if (vertSizeChanged)
3449 		{
3450 		if (g->grid.layoutStack > 2)
3451 			XmLWarning((Widget)g, "HorizLayout() - recursion error");
3452 		else
3453 			{
3454 			g->grid.layoutStack++;
3455 			VertLayout(g, resizeIfNeeded);
3456 			g->grid.layoutStack--;
3457 			}
3458 		PlaceScrollbars(g);
3459 		}
3460 	}
3461 
3462 static void
ApplyVisibleRows(XmLGridWidget g)3463 ApplyVisibleRows(XmLGridWidget g)
3464 	{
3465 	XtWidgetGeometry req;
3466 	XmLGridCellRefValues *cellValues;
3467 
3468 	if (g->grid.vsPolicy != XmCONSTANT)
3469 		{
3470 		XmLWarning((Widget)g,
3471 			"verticalSizePolicy must be XmCONSTANT to set visibleRows");
3472 		return;
3473 		}
3474 	cellValues = g->grid.defCellValues;
3475 	req.request_mode = CWHeight;
3476 	req.height = g->manager.shadow_thickness * 2 + g->grid.visibleRows *
3477 		(4 + cellValues->fontHeight + cellValues->topMargin +
3478 		cellValues->bottomMargin);
3479 	if (g->grid.hsPolicy == XmCONSTANT &&
3480 		g->grid.hsbDisplayPolicy == XmSTATIC)
3481 		req.height += g->grid.scrollBarMargin + XtHeight(g->grid.hsb);
3482 	XtMakeGeometryRequest((Widget)g, &req, NULL);
3483 	}
3484 
3485 static void
ApplyVisibleCols(XmLGridWidget g)3486 ApplyVisibleCols(XmLGridWidget g)
3487 	{
3488 	XtWidgetGeometry req;
3489 	XmLGridCellRefValues *cellValues;
3490 
3491 	if (g->grid.hsPolicy != XmCONSTANT)
3492 		{
3493 		XmLWarning((Widget)g,
3494 			"horizontalSizePolicy must be XmCONSTANT to set visibleColumns");
3495 		return;
3496 		}
3497 	cellValues = g->grid.defCellValues;
3498 	req.request_mode = CWWidth;
3499 	req.width = g->manager.shadow_thickness * 2 + g->grid.visibleCols *
3500 		(4 + 8 * cellValues->fontWidth + cellValues->leftMargin +
3501 		cellValues->rightMargin);
3502 	if (g->grid.vsPolicy == XmCONSTANT &&
3503 		g->grid.vsbDisplayPolicy == XmSTATIC)
3504 		req.width += g->grid.scrollBarMargin + XtWidth(g->grid.vsb);
3505 	XtMakeGeometryRequest((Widget)g, &req, NULL);
3506 	}
3507 
3508 static void
VisPosChanged(XmLGridWidget g,int isVert)3509 VisPosChanged(XmLGridWidget g,
3510 	      int isVert)
3511 	{
3512 	if (isVert)
3513 		{
3514 		g->grid.recalcVertVisPos = 1;
3515 		g->grid.vertVisChangedHint = 1;
3516 		}
3517 	else
3518 		g->grid.recalcHorizVisPos = 1;
3519 	}
3520 
3521 static void
RecalcVisPos(XmLGridWidget g,int isVert)3522 RecalcVisPos(XmLGridWidget g,
3523 	     int isVert)
3524 	{
3525 	XmLGridRow row;
3526 	XmLGridColumn col;
3527 	int i, count, visPos;
3528 
3529 	if (g->grid.layoutFrozen == True)
3530 			XmLWarning((Widget)g, "RecalcVisPos() - layout is frozen");
3531 	visPos = 0;
3532 	if (isVert)
3533 		{
3534 		if (!g->grid.recalcVertVisPos)
3535 			return;
3536 		count = XmLArrayGetCount(g->grid.rowArray);
3537 		for (i = 0; i < count; i++)
3538 			{
3539 			row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
3540 			XmLGridRowSetVisPos(row, visPos);
3541 			if (!XmLGridRowIsHidden(row))
3542 				visPos++;
3543 			}
3544 		g->grid.recalcVertVisPos = 0;
3545 		}
3546 	else
3547 		{
3548 		if (!g->grid.recalcHorizVisPos)
3549 			return;
3550 		count = XmLArrayGetCount(g->grid.colArray);
3551 		for (i = 0; i < count; i++)
3552 			{
3553 			col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
3554 			XmLGridColumnSetVisPos(col, visPos);
3555 			if (!XmLGridColumnIsHidden(col))
3556 				visPos++;
3557 			}
3558 		g->grid.recalcHorizVisPos = 0;
3559 		}
3560 	}
3561 
3562 static int
PosToVisPos(XmLGridWidget g,int pos,int isVert)3563 PosToVisPos(XmLGridWidget g,
3564 	    int pos,
3565 	    int isVert)
3566 	{
3567 	int visPos;
3568 	XmLGridRow row;
3569 	XmLGridColumn col;
3570 
3571 	if (isVert)
3572 		{
3573 		if (!g->grid.hiddenRowCount)
3574 			visPos = pos;
3575 		else
3576 			{
3577 			RecalcVisPos(g, isVert);
3578 			row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, pos);
3579 			if (row)
3580 				visPos = XmLGridRowGetVisPos(row);
3581 			else
3582 				visPos = -1;
3583 			}
3584 		}
3585 	else
3586 		{
3587 		if (!g->grid.hiddenColCount)
3588 			visPos = pos;
3589 		else
3590 			{
3591 			RecalcVisPos(g, isVert);
3592 			col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, pos);
3593 			if (col)
3594 				visPos = XmLGridColumnGetVisPos(col);
3595 			else
3596 				visPos = -1;
3597 			}
3598 		}
3599 	if (visPos == -1)
3600 		XmLWarning((Widget)g, "PosToVisPos() - invalid pos");
3601 	return visPos;
3602 	}
3603 
3604 static int
VisPosToPos(XmLGridWidget g,int visPos,int isVert)3605 VisPosToPos(XmLGridWidget g,
3606 	    int visPos,
3607 	    int isVert)
3608 	{
3609 	XmLGridRow row;
3610 	XmLGridColumn col;
3611 	int i1, i2, vp1, vp2, ic, mid, val, count;
3612 
3613 	if (isVert)
3614 		{
3615 		if (!g->grid.hiddenRowCount)
3616 			return visPos;
3617 		count = XmLArrayGetCount(g->grid.rowArray);
3618 		if (!count)
3619 			{
3620 			XmLWarning((Widget)g, "VisPosToPos() - called when no rows exist");
3621 			return -1;
3622 			}
3623 		RecalcVisPos(g, isVert);
3624 		row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, 0);
3625 		vp1 = XmLGridRowGetVisPos(row);
3626 		row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, count - 1);
3627 		vp2 = XmLGridRowGetVisPos(row);
3628 		if (visPos < vp1 || visPos > vp2)
3629 			{
3630 			XmLWarning((Widget)g, "VisPosToPos() - invalid Vert visPos");
3631 			return -1;
3632 			}
3633 		}
3634 	else
3635 		{
3636 		if (!g->grid.hiddenColCount)
3637 			return visPos;
3638 		count = XmLArrayGetCount(g->grid.colArray);
3639 		if (!count)
3640 			{
3641 			XmLWarning((Widget)g, "VisPosToPos() - called when no cols exist");
3642 			return -1;
3643 			}
3644 		RecalcVisPos(g, isVert);
3645 		col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, 0);
3646 		vp1 = XmLGridColumnGetVisPos(col);
3647 		col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, count - 1);
3648 		vp2 = XmLGridColumnGetVisPos(col);
3649 		if (visPos < vp1 || visPos > vp2)
3650 			{
3651 			XmLWarning((Widget)g, "VisPosToPos() - invalid Horiz visPos");
3652 			return -1;
3653 			}
3654 		}
3655 	i1 = 0;
3656 	i2 = count;
3657 	ic = 0;
3658 	while (1)
3659 		{
3660 		mid = i1 + (i2 - i1) / 2;
3661 		if (isVert)
3662 			{
3663 			row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, mid);
3664 			val = XmLGridRowGetVisPos(row);
3665 			}
3666 		else
3667 			{
3668 			col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, mid);
3669 			val = XmLGridColumnGetVisPos(col);
3670 			}
3671 		if (visPos > val)
3672 			i1 = mid;
3673 		else if (visPos < val)
3674 			i2 = mid;
3675 		else
3676 			break;
3677 		if (++ic > 1000)
3678 				return -1; /* inf loop */
3679 		}
3680 	return mid;
3681 	}
3682 
3683 static unsigned char
ColPosToType(XmLGridWidget g,int pos)3684 ColPosToType(XmLGridWidget g,
3685 	     int pos)
3686 	{
3687 	unsigned char type;
3688 
3689 	if (pos < g->grid.headingColCount)
3690 		type = XmHEADING;
3691 	else if (pos < g->grid.headingColCount + g->grid.colCount)
3692 		type = XmCONTENT;
3693 	else
3694 		type = XmFOOTER;
3695 	return type;
3696 	}
3697 
3698 static int
ColPosToTypePos(XmLGridWidget g,unsigned char type,int pos)3699 ColPosToTypePos(XmLGridWidget g,
3700 		unsigned char type,
3701 		int pos)
3702 {
3703 	int c;
3704 
3705 	if (type == XmHEADING)
3706 		c = pos;
3707 	else if (type == XmCONTENT)
3708 		c = pos - g->grid.headingColCount;
3709 	else
3710 		c = pos - g->grid.headingColCount - g->grid.colCount;
3711 	return c;
3712 	}
3713 
3714 static unsigned char
RowPosToType(XmLGridWidget g,int pos)3715 RowPosToType(XmLGridWidget g,
3716 	     int pos)
3717 	{
3718 	unsigned char type;
3719 
3720 	if (pos < g->grid.headingRowCount)
3721 		type = XmHEADING;
3722 	else if (pos < g->grid.headingRowCount + g->grid.rowCount)
3723 		type = XmCONTENT;
3724 	else
3725 		type = XmFOOTER;
3726 	return type;
3727 	}
3728 
3729 static int
RowPosToTypePos(XmLGridWidget g,unsigned char type,int pos)3730 RowPosToTypePos(XmLGridWidget g,
3731 		unsigned char type,
3732 		int pos)
3733 	{
3734 	int r;
3735 
3736 	if (type == XmHEADING)
3737 		r = pos;
3738 	else if (type == XmCONTENT)
3739 		r = pos - g->grid.headingRowCount;
3740 	else
3741 		r = pos - g->grid.headingRowCount - g->grid.rowCount;
3742 	return r;
3743 	}
3744 
3745 static int
ColTypePosToPos(XmLGridWidget g,unsigned char type,int pos,int allowNeg)3746 ColTypePosToPos(XmLGridWidget g,
3747 		unsigned char type,
3748 		int pos,
3749 		int allowNeg)
3750 	{
3751 	if (pos < 0)
3752 		{
3753 		if (!allowNeg)
3754 			return -1;
3755 		if (type == XmHEADING)
3756 			pos = g->grid.headingColCount;
3757 		else if (type == XmFOOTER || type == XmALL_TYPES)
3758 			pos = g->grid.headingColCount + g->grid.colCount +
3759 				g->grid.footerColCount;
3760 		else /* XmCONTENT */
3761 			pos = g->grid.headingColCount + g->grid.colCount;
3762 		}
3763 	else
3764 		{
3765 		if (type == XmALL_TYPES)
3766 			;
3767 		else if (type == XmHEADING)
3768 			{
3769 			if (pos >= g->grid.headingColCount)
3770 				return -1;
3771 			}
3772 		else if (type == XmFOOTER)
3773 			{
3774 			if (pos >= g->grid.footerColCount)
3775 				return -1;
3776 			pos += g->grid.headingColCount + g->grid.colCount;
3777 			}
3778 		else /* XmCONTENT */
3779 			{
3780 			if (pos >= g->grid.colCount)
3781 				return -1;
3782 			pos += g->grid.headingColCount;
3783 			}
3784 		}
3785 	return pos;
3786 	}
3787 
3788 static int
RowTypePosToPos(XmLGridWidget g,unsigned char type,int pos,int allowNeg)3789 RowTypePosToPos(XmLGridWidget g,
3790 		unsigned char type,
3791 		int pos,
3792 		int allowNeg)
3793 	{
3794 	if (pos < 0)
3795 		{
3796 		if (!allowNeg)
3797 			return -1;
3798 		if (type == XmHEADING)
3799 			pos = g->grid.headingRowCount;
3800 		else if (type == XmFOOTER || type == XmALL_TYPES)
3801 			pos = g->grid.headingRowCount + g->grid.rowCount +
3802 					g->grid.footerRowCount;
3803 		else /* XmCONTENT */
3804 			pos = g->grid.headingRowCount + g->grid.rowCount;
3805 		}
3806 	else
3807 		{
3808 		if (type == XmALL_TYPES)
3809 			;
3810 		else if (type == XmHEADING)
3811 			{
3812 			if (pos >= g->grid.headingRowCount)
3813 				return -1;
3814 			}
3815 		else if (type == XmFOOTER)
3816 			{
3817 			if (pos >= g->grid.footerRowCount)
3818 				return -1;
3819 			pos += g->grid.headingRowCount + g->grid.rowCount;
3820 			}
3821 		else /* XmCONTENT */
3822 			{
3823 			if (pos >= g->grid.rowCount)
3824 				return -1;
3825 			pos += g->grid.headingRowCount;
3826 			}
3827 		}
3828 	return pos;
3829 	}
3830 
3831 static int
ScrollRowBottomPos(XmLGridWidget g,int row)3832 ScrollRowBottomPos(XmLGridWidget g,
3833 		   int row)
3834 	{
3835 	int r, h, height;
3836 
3837 	if (g->grid.vsPolicy == XmVARIABLE)
3838 		return -1;
3839 	height = g->grid.reg[4].height;
3840 	h = 0;
3841 	r = row;
3842 	while (r >= 0)
3843 		{
3844 		h += GetRowHeight(g, r);
3845 		if (h > height)
3846 			break;
3847 		r--;
3848 		}
3849 	if (r != row)
3850 		r++;
3851 	return r;
3852 	}
3853 
3854 static int
ScrollColRightPos(XmLGridWidget g,int col)3855 ScrollColRightPos(XmLGridWidget g,
3856 		  int col)
3857 	{
3858 	int c, w, width;
3859 
3860 	if (g->grid.hsPolicy == XmVARIABLE)
3861 		return -1;
3862 	width = g->grid.reg[4].width;
3863 	w = 0;
3864 	c = col;
3865 	while (c >= 0)
3866 		{
3867 		w += GetColWidth(g, c);
3868 		if (w >= width)
3869 			break;
3870 		c--;
3871 		}
3872 	if (c != col)
3873 		c++;
3874 	return c;
3875 	}
3876 
3877 static int
PosIsResize(XmLGridWidget g,int x,int y,int * row,int * col,int * isVert)3878 PosIsResize(XmLGridWidget g,
3879 			int x,
3880 			int y,
3881 			int *row,
3882 			int *col,
3883 			int *isVert)
3884 {
3885 	XRectangle rect;
3886 	int i, nx, ny, margin;
3887 
3888 	/* check for bottom resize */
3889 	if (g->grid.allowRowResize == True)
3890 		for (i = 0; i < 2; i++)
3891 			{
3892 				nx = x;
3893 				ny = y - (4 * i);
3894 
3895 				if (XYToRowCol(g, nx, ny, row, col) != -1
3896                     && RowColToXY(g, *row, *col, False, &rect) != -1
3897                     && ColPosToType(g, *col) == XmHEADING)
3898                     {
3899                         margin = ny - (rect.y + rect.height);
3900                         if (margin > -5 && margin < 5)
3901                             {
3902                                 *isVert = 1;
3903                                 return 1;
3904                             }
3905                     }
3906 			}
3907 	/* check for right resize */
3908 	if (g->grid.allowColResize == True)
3909       for (i = 0; i < 2; i++)
3910         {
3911           XmLGridColumn colp;
3912           int c;
3913 
3914           nx = x - (4 * i);
3915           ny = y;
3916 
3917           if (XYToRowCol(g, nx, ny, row, col) != -1
3918               && RowColToXY(g, *row, *col, False, &rect) != -1
3919               && RowPosToType(g, *row) == XmHEADING
3920               && *col != XmLArrayGetCount(g->grid.colArray) - 1)
3921             {
3922               Boolean foundResizable = 0;
3923 
3924               colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, *col);
3925 
3926               if (!colp->grid.resizable)
3927                 continue;
3928 
3929               for (c = *col + 1;
3930                    c < XmLArrayGetCount(g->grid.colArray);
3931                    c ++)
3932                 {
3933                   colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
3934 
3935                   if (colp->grid.resizable
3936                       && (g->grid.hsPolicy != XmRESIZE_IF_POSSIBLE
3937                           || (g->grid.visibleCols == 0
3938                               || c < g->grid.visibleCols))
3939                      )
3940                     {
3941                       foundResizable = True;
3942                       break;
3943                     }
3944                 }
3945               if (!foundResizable) return 0;
3946 
3947               margin = nx - (rect.x + rect.width);
3948               if (margin > -5 && margin < 5)
3949                 {
3950                   *isVert = 0;
3951                   return 1;
3952                 }
3953 			}
3954         }
3955 	return 0;
3956 }
3957 
3958 int
XmLGridPosIsResize(Widget g,int x,int y)3959 XmLGridPosIsResize(Widget g,
3960 		   int x,
3961 		   int y)
3962 {
3963   int row, col;
3964   int isVert;
3965   return PosIsResize((XmLGridWidget) g, x, y, &row, &col, &isVert);
3966 }
3967 
3968 static int
XYToRowCol(XmLGridWidget g,int x,int y,int * row,int * col)3969 XYToRowCol(XmLGridWidget g,
3970 	   int x,
3971 	   int y,
3972 	   int *row,
3973 	   int *col)
3974 	{
3975 	XRectangle xyRect, rect;
3976 	GridReg *reg;
3977 	int i, r, c;
3978 	int width, height;
3979 	int st;
3980 
3981 	reg = g->grid.reg;
3982 	st = g->manager.shadow_thickness;
3983 	xyRect.x = x;
3984 	xyRect.y = y;
3985 	xyRect.width = 1;
3986 	xyRect.height = 1;
3987 	for (i = 0; i < 9; i++)
3988 		{
3989 		if (!reg[i].width || !reg[i].height)
3990 			continue;
3991 		rect.x = reg[i].x + st;
3992 		rect.y = reg[i].y + st;
3993 		rect.width = reg[i].width - st * 2;
3994 		rect.height = reg[i].height - st * 2;
3995 		if (XmLRectIntersect(&xyRect, &rect) == XmLRectOutside)
3996 			continue;
3997 		height = 0;
3998 		for (r = reg[i].row; r < reg[i].row + reg[i].nrow; r++)
3999 			{
4000 			width = 0;
4001 			for (c = reg[i].col; c < reg[i].col + reg[i].ncol; c++)
4002 				{
4003 				rect.x = reg[i].x + st + width;
4004 				rect.y = reg[i].y + st + height;
4005 				rect.width = GetColWidth(g, c);
4006 				rect.height = GetRowHeight(g, r);
4007 				if (g->grid.singleColScrollMode)
4008 					rect.x -= g->grid.singleColScrollPos;
4009 				ClipRectToReg(g, &rect, &reg[i]);
4010 				if (XmLRectIntersect(&xyRect, &rect) != XmLRectOutside)
4011 					{
4012 					if (!RowColFirstSpan(g, r, c, row, col, 0, True, True))
4013 						return 0; /* SUCCESS */
4014 					else
4015 						return -1;
4016 					}
4017 				width += GetColWidth(g, c);
4018 				}
4019 			height += GetRowHeight(g, r);
4020 			}
4021 		}
4022 	return -1;
4023 	}
4024 
4025 static int
RowColToXY(XmLGridWidget g,int row,int col,Boolean clipped,XRectangle * rect)4026 RowColToXY(XmLGridWidget g,
4027 	   int row,
4028 	   int col,
4029 	   Boolean clipped,
4030 	   XRectangle *rect)
4031 	{
4032 	XmLGridCell cell;
4033 	XmLGridCellRefValues *cellValues;
4034 	GridReg *reg;
4035 	Dimension st;
4036 	int i, r, c, off;
4037 
4038 	reg = g->grid.reg;
4039 	st = g->manager.shadow_thickness;
4040 	cell = GetCell(g, row, col);
4041 	if (!cell)
4042 		return -1;
4043 	cellValues = XmLGridCellGetRefValues(cell);
4044 
4045 	if (!cellValues) return -1;
4046 
4047 	for (i = 0; i < 9; i++)
4048 		{
4049 		if (!reg[i].width || !reg[i].height)
4050 			continue;
4051 		if (!(col >= reg[i].col &&
4052 			col < reg[i].col + reg[i].ncol &&
4053 			row >= reg[i].row &&
4054 			row < reg[i].row + reg[i].nrow))
4055 			continue;
4056 		off = 0;
4057 		for (r = reg[i].row; r < row; r++)
4058 			off += GetRowHeight(g, r);
4059 		rect->y = reg[i].y + st + off;
4060 		rect->height = GetRowHeight(g, row);
4061 		if (cellValues->rowSpan)
4062 			for (r = row + 1; r <= row + cellValues->rowSpan; r++)
4063 				rect->height += GetRowHeight(g, r);
4064 		off = 0;
4065 		for (c = reg[i].col; c < col; c++)
4066 			off += GetColWidth(g, c);
4067 		rect->x = reg[i].x + st + off;
4068 		rect->width = GetColWidth(g, col);
4069 		if (cellValues->columnSpan)
4070 			for (c = col + 1; c <= col + cellValues->columnSpan; c++)
4071 				rect->width += GetColWidth(g, c);
4072 		if (g->grid.singleColScrollMode)
4073 			rect->x -= g->grid.singleColScrollPos;
4074 		if (clipped == True)
4075 			ClipRectToReg(g, rect, &reg[i]);
4076 		return 0;
4077 		}
4078 	return -1;
4079 	}
4080 
4081 static int
RowColFirstSpan(XmLGridWidget g,int row,int col,int * firstRow,int * firstCol,XRectangle * rect,Boolean lookLeft,Boolean lookUp)4082 RowColFirstSpan(XmLGridWidget g,
4083 		int row,
4084 		int col,
4085 		int *firstRow,
4086 		int *firstCol,
4087 		XRectangle *rect,
4088 		Boolean lookLeft,
4089 		Boolean lookUp)
4090 	{
4091 	XmLGridCell cell;
4092 	int done;
4093 
4094 	done = 0;
4095 	while (!done)
4096 		{
4097 		cell = GetCell(g, row, col);
4098 		if (!cell)
4099 			return -1;
4100 		if (XmLGridCellInRowSpan(cell) == True)
4101 			{
4102 			if (lookUp == True)
4103 				{
4104 				row--;
4105 				if (rect)
4106 					rect->y -= GetRowHeight(g, row);
4107 				}
4108 			else
4109 				row = -1;
4110 			if (row < 0)
4111 				done = 1;
4112 			}
4113 		else if (XmLGridCellInColumnSpan(cell) == True)
4114 			{
4115 			if (lookLeft == True)
4116 				{
4117 				col--;
4118 				if (rect)
4119 					rect->x -= GetColWidth(g, col);
4120 				}
4121 			else
4122 				col = -1;
4123 			if (col < 0)
4124 				done = 1;
4125 			}
4126 		else
4127 			done = 1;
4128 		}
4129 	if (row < 0 || col < 0)
4130 		return -1;
4131 	*firstRow = row;
4132 	*firstCol = col;
4133 	return 0;
4134 	}
4135 
4136 static void
RowColSpanRect(XmLGridWidget g,int row,int col,XRectangle * rect)4137 RowColSpanRect(XmLGridWidget g,
4138 	       int row,
4139 	       int col,
4140 	       XRectangle *rect)
4141 	{
4142 	XmLGridCell cell;
4143 	XmLGridCellRefValues *cellValues;
4144 	int r, c;
4145 
4146 	cell = GetCell(g, row, col);
4147 	cellValues = XmLGridCellGetRefValues(cell);
4148 	rect->width = 0;
4149 	rect->height = 0;
4150 	for (r = row; r <= row + cellValues->rowSpan; r++)
4151 		rect->height += GetRowHeight(g, r);
4152 	for (c = col; c <= col + cellValues->columnSpan; c++)
4153 		rect->width += GetColWidth(g, c);
4154 	}
4155 
4156 static XmLGridCell
GetCell(XmLGridWidget g,int row,int col)4157 GetCell(XmLGridWidget g,
4158 	int row,
4159 	int col)
4160 	{
4161 	XmLGridRow rowp;
4162 
4163 	rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
4164 	if (!rowp)
4165 		return 0;
4166 	return (XmLGridCell)XmLArrayGet(XmLGridRowCells(rowp), col);
4167 	}
4168 
4169 static int
GetColWidth(XmLGridWidget g,int col)4170 GetColWidth(XmLGridWidget g,
4171 	    int col)
4172 	{
4173 	XmLGridColumn colp;
4174 
4175 	colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
4176 	if (!colp)
4177 		return 0;
4178 	return XmLGridColumnWidthInPixels(colp);
4179 	}
4180 
4181 static int
GetRowHeight(XmLGridWidget g,int row)4182 GetRowHeight(XmLGridWidget g,
4183 	     int row)
4184 	{
4185 	XmLGridRow rowp;
4186 
4187 	rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
4188 	if (!rowp)
4189 		return 0;
4190 	return XmLGridRowHeightInPixels(rowp);
4191 	}
4192 
4193 static int
ColIsVisible(XmLGridWidget g,int col)4194 ColIsVisible(XmLGridWidget g,
4195 	     int col)
4196 	{
4197 	XmLGridColumn c;
4198 	int i, c1, c2;
4199 
4200 	c = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
4201 	if (!c)
4202 		{
4203 		XmLWarning((Widget)g, "ColumnIsVisible() - invalid column");
4204 		return -1;
4205 		}
4206 	if (XmLGridColumnIsHidden(c) == True)
4207 		return 0;
4208 	if (g->grid.hsPolicy != XmCONSTANT)
4209 		return 1;
4210 	for (i = 0; i < 3; i ++)
4211 		{
4212 		c1 = g->grid.reg[i].col;
4213 		c2 = c1 + g->grid.reg[i].ncol;
4214 		if (col >= c1 && col < c2)
4215 			return 1;
4216 		}
4217 	return 0;
4218 	}
4219 
4220 static int
RowIsVisible(XmLGridWidget g,int row)4221 RowIsVisible(XmLGridWidget g,
4222 	     int row)
4223 	{
4224 	XmLGridRow r;
4225 	int i, r1, r2;
4226 
4227 	r = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
4228 	if (!r)
4229 		{
4230 		XmLWarning((Widget)g, "RowIsVisible() - invalid row");
4231 		return -1;
4232 		}
4233 	if (XmLGridRowIsHidden(r) == True)
4234 		return 0;
4235 	if (g->grid.vsPolicy != XmCONSTANT)
4236 		return 1;
4237 	for (i = 0; i < 9; i += 3)
4238 		{
4239 		r1 = g->grid.reg[i].row;
4240 		r2 = r1 + g->grid.reg[i].nrow;
4241 		if (row >= r1 && row < r2)
4242 			return 1;
4243 		}
4244 	return 0;
4245 	}
4246 
4247 static XtGeometryResult
GeometryManager(Widget w,XtWidgetGeometry * request,XtWidgetGeometry * allow)4248 GeometryManager(Widget w,
4249 		XtWidgetGeometry *request,
4250 		XtWidgetGeometry *allow)
4251 	{
4252 	if (request->request_mode & CWWidth)
4253 		w->core.width = request->width;
4254 	if (request->request_mode & CWHeight)
4255 		w->core.height = request->height;
4256 	if (request->request_mode & CWX)
4257 		w->core.x = request->x;
4258 	if (request->request_mode & CWY)
4259 		w->core.y = request->y;
4260 	if (request->request_mode & CWBorderWidth)
4261 		w->core.border_width = request->border_width;
4262 	return XtGeometryYes;
4263 	}
4264 
4265 static void
ScrollCB(Widget w,XtPointer clientData,XtPointer callData)4266 ScrollCB(Widget w,
4267 	 XtPointer clientData,
4268 	 XtPointer callData)
4269 {
4270 	XmLGridWidget g;
4271 	XmScrollBarCallbackStruct *cbs;
4272 	unsigned char orientation;
4273 	int visPos;
4274 
4275 	g = (XmLGridWidget)(XtParent(w));
4276 	cbs = (XmScrollBarCallbackStruct *)callData;
4277 	visPos = cbs->value;
4278 	XtVaGetValues(w, XmNorientation, &orientation, NULL);
4279 	if (orientation == XmHORIZONTAL && g->grid.singleColScrollMode)
4280 		{
4281 		g->grid.singleColScrollPos = visPos;
4282 		DrawArea(g, DrawHScroll, 0, 0);
4283 		}
4284 	else if (orientation == XmVERTICAL)
4285 		{
4286 		if (visPos == PosToVisPos(g, g->grid.scrollRow, 1))
4287 			return;
4288 		g->grid.scrollRow = VisPosToPos(g, visPos, 1);
4289 		VertLayout(g, 0);
4290 		DrawArea(g, DrawVScroll, 0, 0);
4291 		}
4292 	else
4293 		{
4294 		if (visPos == PosToVisPos(g, g->grid.scrollCol, 0))
4295 			return;
4296 		g->grid.scrollCol = VisPosToPos(g, visPos, 0);
4297 		HorizLayout(g, 0);
4298 		DrawArea(g, DrawHScroll, 0, 0);
4299 		}
4300 	}
4301 
4302 static int
FindNextFocus(XmLGridWidget g,int row,int col,int rowDir,int colDir,int * nextRow,int * nextCol)4303 FindNextFocus(XmLGridWidget g,
4304 	      int row,
4305 	      int col,
4306 	      int rowDir,
4307 	      int colDir,
4308 	      int *nextRow,
4309 	      int *nextCol)
4310 	{
4311 	int traverse;
4312 	int hrc, hcc, rc, cc;
4313 	XmLGridColumn colp;
4314 	XmLGridRow rowp;
4315 	XmLGridCell cell;
4316 
4317 	hcc = g->grid.headingColCount;
4318 	cc = g->grid.colCount;
4319 	hrc = g->grid.headingRowCount;
4320 	rc = g->grid.rowCount;
4321 	if (!rc || !cc)
4322 		return -1;
4323 	if (col < hcc)
4324 		col = hcc;
4325 	else if (col >= hcc + cc)
4326 		col = hcc + cc - 1;
4327 	if (row < hrc)
4328 		row = hrc;
4329 	else if (row >= hrc + rc)
4330 		row = hrc + rc - 1;
4331 	traverse = 0;
4332 	while (1)
4333 		{
4334 		if (row < hrc || row >= hrc + rc)
4335 			break;
4336 		if (col < hcc || col >= hcc + cc)
4337 			break;
4338 		rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
4339 		colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
4340 		cell = GetCell(g, row, col);
4341 		if (cell &&
4342 			RowPosToType(g, row) == XmCONTENT &&
4343 			ColPosToType(g, col) == XmCONTENT &&
4344 			XmLGridCellInRowSpan(cell) == False &&
4345 			XmLGridCellInColumnSpan(cell) == False &&
4346 			XmLGridRowIsHidden(rowp) == False &&
4347 			XmLGridColumnIsHidden(colp) == False)
4348 			{
4349 			traverse = 1;
4350 			break;
4351 			}
4352 		if (!rowDir && !colDir)
4353 			break;
4354 		row += rowDir;
4355 		col += colDir;
4356 		}
4357 	if (!traverse)
4358 		return -1;
4359 	*nextRow = row;
4360 	*nextCol = col;
4361 	return 0;
4362 	}
4363 
4364 static int
SetFocus(XmLGridWidget g,int row,int col,int rowDir,int colDir)4365 SetFocus(XmLGridWidget g,
4366 	 int row,
4367 	 int col,
4368 	 int rowDir,
4369 	 int colDir)
4370 	{
4371 	if (FindNextFocus(g, row, col, rowDir, colDir, &row, &col) == -1)
4372 		return -1;
4373 	ChangeFocus(g, row, col);
4374 	return 0;
4375 	}
4376 
4377 static void
ChangeFocus(XmLGridWidget g,int row,int col)4378 ChangeFocus(XmLGridWidget g,
4379 	    int row,
4380 	    int col)
4381 	{
4382 	XmLGridCell cell;
4383 	XmLGridCallbackStruct cbs;
4384 	int focusRow, focusCol;
4385 
4386 	focusRow = g->grid.focusRow;
4387 	focusCol = g->grid.focusCol;
4388 	g->grid.focusRow = row;
4389 	g->grid.focusCol = col;
4390 	if (focusRow != -1 && focusCol != -1)
4391 		{
4392 		cell = GetCell(g, focusRow, focusCol);
4393 		if (cell)
4394 			{
4395 			if (g->grid.highlightRowMode == True)
4396 				DrawArea(g, DrawRow, focusRow, 0);
4397 			else
4398 				DrawArea(g, DrawCell, focusRow, focusCol);
4399 			cbs.reason = XmCR_CELL_FOCUS_OUT;
4400 			cbs.columnType = ColPosToType(g, focusCol);
4401 			cbs.column = ColPosToTypePos(g, cbs.columnType, focusCol);
4402 			cbs.rowType = RowPosToType(g, focusRow);
4403 			cbs.row = RowPosToTypePos(g, cbs.rowType, focusRow);
4404 			XmLGridCellAction(cell, (Widget)g, &cbs);
4405 			XtCallCallbackList((Widget)g, g->grid.cellFocusCallback,
4406 				(XtPointer)&cbs);
4407 			}
4408 		}
4409 	if (row != -1 && col != -1)
4410 		{
4411 		cell = GetCell(g, row, col);
4412 		if (cell)
4413 			{
4414 			if (g->grid.highlightRowMode == True)
4415 				DrawArea(g, DrawRow, row, 0);
4416 			else
4417 				DrawArea(g, DrawCell, row, col);
4418 			cbs.reason = XmCR_CELL_FOCUS_IN;
4419 			cbs.columnType = ColPosToType(g, col);
4420 			cbs.column = ColPosToTypePos(g, cbs.columnType, col);
4421 			cbs.rowType = RowPosToType(g, row);
4422 			cbs.row = RowPosToTypePos(g, cbs.rowType, row);
4423 			XmLGridCellAction(cell, (Widget)g, &cbs);
4424 			XtCallCallbackList((Widget)g, g->grid.cellFocusCallback,
4425 				(XtPointer)&cbs);
4426 			}
4427 		else
4428 			{
4429 			if (!XmLArrayGet(g->grid.rowArray, row))
4430 				g->grid.focusRow = -1;
4431 			if (!XmLArrayGet(g->grid.colArray, col))
4432 				g->grid.focusCol = -1;
4433 			}
4434 		}
4435 	}
4436 
4437 static void
MakeColVisible(XmLGridWidget g,int col)4438 MakeColVisible(XmLGridWidget g,
4439 	       int col)
4440 	{
4441 	int st, width, scrollWidth, scrollCol, prevScrollCol;
4442 
4443 	if (g->grid.hsPolicy != XmCONSTANT)
4444 		return;
4445 	if (col < g->grid.leftFixedCount ||
4446 		col >= XmLArrayGetCount(g->grid.colArray) - g->grid.rightFixedCount)
4447 		return;
4448 	st = g->manager.shadow_thickness;
4449 	scrollCol = col;
4450 	if (col > g->grid.scrollCol)
4451 		{
4452 		scrollWidth = g->grid.reg[4].width - st * 2;
4453 		width = 0;
4454 		while (1)
4455 			{
4456 			width += GetColWidth(g, scrollCol);
4457 			if (width > scrollWidth)
4458 				break;
4459 			if (scrollCol < g->grid.leftFixedCount)
4460 				break;
4461 			scrollCol--;
4462 			}
4463 		scrollCol++;
4464 		if (scrollCol > col)
4465 			scrollCol = col;
4466 		/* only scroll if needed */
4467 		if (scrollCol < g->grid.scrollCol)
4468 			scrollCol = g->grid.scrollCol;
4469 		}
4470 	if (scrollCol == g->grid.scrollCol)
4471 		return;
4472 	prevScrollCol = g->grid.scrollCol;
4473 	g->grid.scrollCol = scrollCol;
4474 	HorizLayout(g, 0);
4475 	if (g->grid.scrollCol != prevScrollCol)
4476 		DrawArea(g, DrawHScroll, 0, 0);
4477 	}
4478 
4479 static void
MakeRowVisible(XmLGridWidget g,int row)4480 MakeRowVisible(XmLGridWidget g,
4481 	       int row)
4482 	{
4483 	int st, height, scrollHeight, scrollRow, prevScrollRow;
4484 
4485 	if (g->grid.vsPolicy != XmCONSTANT)
4486 		return;
4487 	if (row < g->grid.topFixedCount ||
4488 		row >= XmLArrayGetCount(g->grid.rowArray) - g->grid.bottomFixedCount)
4489 		return;
4490 	st = g->manager.shadow_thickness;
4491 	scrollRow = row;
4492 	if (row > g->grid.scrollRow)
4493 		{
4494 		scrollHeight = g->grid.reg[4].height - st * 2;
4495 		height = 0;
4496 		while (1)
4497 			{
4498 			height += GetRowHeight(g, scrollRow);
4499 			if (height > scrollHeight)
4500 				break;
4501 			if (scrollRow < g->grid.topFixedCount)
4502 				break;
4503 			scrollRow--;
4504 			}
4505 		scrollRow++;
4506 		if (scrollRow > row)
4507 			scrollRow = row;
4508 		/* only scroll if needed */
4509 		if (scrollRow < g->grid.scrollRow)
4510 			scrollRow = g->grid.scrollRow;
4511 		}
4512 	if (scrollRow == g->grid.scrollRow)
4513 		return;
4514 	prevScrollRow = g->grid.scrollRow;
4515 	g->grid.scrollRow = scrollRow;
4516 	VertLayout(g, 0);
4517 	if (g->grid.scrollRow != prevScrollRow)
4518 		DrawArea(g, DrawVScroll, 0, 0);
4519 	}
4520 
4521 static void
TextAction(XmLGridWidget g,int action)4522 TextAction(XmLGridWidget g,
4523 	   int action)
4524 	{
4525 	int row, col, reason, ret, isVisible;
4526 	XRectangle rect;
4527 	XtTranslations trans;
4528 	WidgetClass wc;
4529 	XmLGridCell cellp;
4530 	XmLGridCallbackStruct cbs;
4531 
4532 	if (!g->grid.text || !XtIsRealized(g->grid.text))
4533 		return;
4534 	row = g->grid.focusRow;
4535 	col = g->grid.focusCol;
4536 	if (row == -1 || col == -1)
4537 		return;
4538 	isVisible = 0;
4539 	if (RowColToXY(g, row, col, True, &rect) != -1)
4540 		isVisible = 1;
4541 	cellp = GetCell(g, row, col);
4542 	if (!cellp)
4543 		return;
4544 	cbs.rowType = XmCONTENT;
4545 	cbs.row = RowPosToTypePos(g, XmCONTENT, row);
4546 	cbs.columnType = XmCONTENT;
4547 	cbs.column = ColPosToTypePos(g, XmCONTENT, col);
4548 	cbs.clipRect = &rect;
4549 	switch (action)
4550 		{
4551 		case TEXT_EDIT:
4552 		case TEXT_EDIT_INSERT:
4553 			{
4554 			if (g->grid.inEdit || !isVisible)
4555 				return;
4556 			g->grid.inEdit = 1;
4557 			if (action == TEXT_EDIT)
4558 				cbs.reason = XmCR_EDIT_BEGIN;
4559 			else
4560 				cbs.reason = XmCR_EDIT_INSERT;
4561 			ret = XmLGridCellAction(cellp, (Widget)g, &cbs);
4562 			if (ret)
4563 				{
4564 				reason = cbs.reason;
4565 				cbs.reason = XmCR_CONF_TEXT;
4566 				XmLGridCellAction(cellp, (Widget)g, &cbs);
4567 				cbs.reason = reason;
4568 				wc = g->grid.text->core.widget_class;
4569 				trans = (XtTranslations)wc->core_class.tm_table;
4570 				XtVaSetValues(g->grid.text, XmNtranslations, trans, NULL);
4571 				XtOverrideTranslations(g->grid.text, g->grid.editTrans);
4572 				XtMapWidget(g->grid.text);
4573 				g->grid.textHidden = 0;
4574 				XtCallCallbackList((Widget)g, g->grid.editCallback,
4575 					(XtPointer)&cbs);
4576 				}
4577 			else
4578 				g->grid.inEdit = 0;
4579 			break;
4580 			}
4581 		case TEXT_EDIT_CANCEL:
4582 		case TEXT_EDIT_COMPLETE:
4583 			{
4584 			if (!g->grid.inEdit)
4585 				return;
4586 			if (action == TEXT_EDIT_COMPLETE)
4587 				cbs.reason = XmCR_EDIT_COMPLETE;
4588 			else
4589 				cbs.reason = XmCR_EDIT_CANCEL;
4590 			XmLGridCellAction(cellp, (Widget)g, &cbs);
4591 			wc = g->grid.text->core.widget_class;
4592 			trans = (XtTranslations)wc->core_class.tm_table;
4593 			XtVaSetValues(g->grid.text, XmNtranslations, trans, NULL);
4594 			XtOverrideTranslations(g->grid.text, g->grid.traverseTrans);
4595 			XtCallCallbackList((Widget)g, g->grid.editCallback,
4596 				(XtPointer)&cbs);
4597 			XmTextSetString(g->grid.text, "");
4598 			XmTextSetInsertionPosition(g->grid.text, 0);
4599 			g->grid.inEdit = 0;
4600 			XtUnmapWidget(g->grid.text);
4601 			g->grid.textHidden = 1;
4602 			XtConfigureWidget(g->grid.text, 0, 0, 30, 10, 0);
4603 			break;
4604 			}
4605 		case TEXT_HIDE:
4606 			{
4607 			if (g->grid.textHidden || !isVisible)
4608 				return;
4609 			XtUnmapWidget(g->grid.text);
4610 			g->grid.textHidden = 1;
4611 			break;
4612 			}
4613 		case TEXT_SHOW:
4614 			{
4615 			if (!g->grid.textHidden || !g->grid.inEdit || !isVisible)
4616 				return;
4617 			if (rect.width == 0 || rect.height == 0)
4618 				TextAction(g, TEXT_EDIT_CANCEL);
4619 			else
4620 				{
4621 				cbs.reason = XmCR_CONF_TEXT;
4622 				XmLGridCellAction(cellp, (Widget)g, &cbs);
4623 				XtMapWidget(g->grid.text);
4624 				g->grid.textHidden = 0;
4625 				}
4626 			break;
4627 			}
4628 		}
4629 	}
4630 
4631 /*
4632    Getting and Setting Values
4633 */
4634 
4635 static void
GetSubValues(Widget w,ArgList args,Cardinal * nargs)4636 GetSubValues(Widget w,
4637 	     ArgList args,
4638 	     Cardinal *nargs)
4639 	{
4640 	XmLGridWidget g;
4641 	int i, c;
4642 	long mask;
4643 	XmLGridRow row;
4644 	XmLGridColumn col;
4645 	XmLGridCell cell;
4646 
4647 	g = (XmLGridWidget)w;
4648 	row = 0;
4649 	col = 0;
4650 	for (i = 0; i < *nargs; i++)
4651 		{
4652 		if (!args[i].name)
4653 			continue;
4654 		if (!strncmp(args[i].name, "row", 3))
4655 			{
4656 			if (!strcmp(args[i].name, XmNrowPtr))
4657 				{
4658 				row = (XmLGridRow)args[i].value;
4659 				continue;
4660 				}
4661 			mask = 0;
4662 			GetRowValueMask(g, args[i].name, &mask);
4663 			if (!mask)
4664 				continue;
4665 			if (!row)
4666 				{
4667 				XmLWarning(w, "GetValues() - invalid row");
4668 				continue;
4669 				}
4670 			GetRowValue(g, row, args[i].value, mask);
4671 			}
4672 		else if (!strncmp(args[i].name, "column", 6))
4673 			{
4674 			if (!strcmp(args[i].name, XmNcolumnPtr))
4675 				{
4676 				col = (XmLGridColumn)args[i].value;
4677 				continue;
4678 				}
4679 			mask = 0;
4680 			GetColumnValueMask(g, args[i].name, &mask);
4681 			if (!mask)
4682 				continue;
4683 			if (!col)
4684 				{
4685 				XmLWarning(w, "GetValues() - invalid column");
4686 				continue;
4687 				}
4688 			GetColumnValue(g, col, args[i].value, mask);
4689 			}
4690 		else if (!strncmp(args[i].name, "cell", 4))
4691 			{
4692 			mask = 0;
4693 			CellValueGetMask(args[i].name, &mask);
4694 			if (!mask)
4695 				continue;
4696 			if (!row || !col)
4697 				{
4698 				XmLWarning(w, "GetValues() - invalid cell");
4699 				continue;
4700 				}
4701 			c = XmLGridColumnGetPos(col);
4702 			cell = (XmLGridCell)XmLArrayGet(XmLGridRowCells(row), c);
4703 			GetCellValue(cell, args[i].value, mask);
4704 			}
4705 		}
4706 	}
4707 
4708 static void
SetSubValues(Widget w,ArgList args,Cardinal * nargs)4709 SetSubValues(Widget w,
4710 	     ArgList args,
4711 	     Cardinal *nargs)
4712 	{
4713 	XmLGridWidget g;
4714 	XmLGridRow row;
4715 	XmLGridColumn col;
4716 	XmLGridCell cell;
4717 	XmLGridCellRefValues *values, *newValues, *prevValues;
4718 	XmLArray cellArray;
4719 	int r, r1, r2, rowsValid;
4720 	int c, c1, c2, cd1, cd2, colsValid;
4721 	unsigned char rowType, colType;
4722 	long rowMask, colMask, cellMask;
4723 	int i, nRefValues, allCols;
4724 	int needsHorizResize, needsVertResize;
4725 	char buf[256];
4726 
4727 	newValues = (XmLGridCellRefValues *)NULL;
4728 	g = (XmLGridWidget)w;
4729 	needsHorizResize = 0;
4730 	needsVertResize = 0;
4731 	rowMask = 0;
4732 	colMask = 0;
4733 	cellMask = 0;
4734 	for (i = 0; i < *nargs; i++)
4735 		{
4736 		if (!args[i].name)
4737 			continue;
4738 		if (!strncmp(args[i].name, "row", 3))
4739 			{
4740 			if (!strcmp(args[i].name, XmNrowPtr))
4741 				XmLWarning(w, "SetValues() - can't use XmNrowPtr");
4742 			GetRowValueMask(g, args[i].name, &rowMask);
4743 			}
4744 		else if (!strncmp(args[i].name, "column", 6))
4745 			{
4746 			if (!strcmp(args[i].name, XmNcolumnPtr))
4747 				XmLWarning(w, "SetValues() - can't use XmNcolumnPtr");
4748 			GetColumnValueMask(g, args[i].name, &colMask);
4749 			}
4750 		else if (!strncmp(args[i].name, "cell", 4))
4751 			CellValueGetMask(args[i].name, &cellMask);
4752 		else if (rowMask || colMask || cellMask)
4753 			{
4754 			sprintf(buf, "SetValues() - %s is not a row/column/cell resource",
4755 				args[i].name);
4756 			XmLWarning(w, buf);
4757 			}
4758 		}
4759 	if (rowMask || colMask || cellMask)
4760 		{
4761 		if (g->grid.rowType == XmINVALID_TYPE)
4762 			rowType = XmCONTENT;
4763 		else
4764 			rowType = g->grid.rowType;
4765 		rowsValid = 1;
4766 		if (g->grid.cellRowRangeStart != -1 && g->grid.cellRowRangeEnd != -1)
4767 			{
4768 			r1 = RowTypePosToPos(g, rowType, g->grid.cellRowRangeStart, 0);
4769 			r2 = RowTypePosToPos(g, rowType, g->grid.cellRowRangeEnd, 0);
4770 			if (r1 < 0 || r2 < 0 || r1 > r2)
4771 				rowsValid = 0;
4772 			r2++;
4773 			}
4774 		else if (g->grid.cellRow != -1)
4775 			{
4776 			r1 = RowTypePosToPos(g, rowType, g->grid.cellRow, 0);
4777 			if (r1 == -1)
4778 				rowsValid = 0;
4779 			r2 = r1 + 1;
4780 			}
4781 		else
4782 			{
4783 			r1 = RowTypePosToPos(g, rowType, 0, 0);
4784 			if (r1 == -1)
4785 				r1 = 0;
4786 			r2 = RowTypePosToPos(g, rowType, -1, 1);
4787 			}
4788 		if (!rowsValid)
4789 			{
4790 			XmLWarning(w, "SetValues() - invalid row(s) specified");
4791 			r1 = 0;
4792 			r2 = 0;
4793 			}
4794 		if (g->grid.colType == XmINVALID_TYPE)
4795 			colType = XmCONTENT;
4796 		else
4797 			colType = g->grid.colType;
4798 		colsValid = 1;
4799 		if (g->grid.cellColRangeStart != -1 && g->grid.cellColRangeEnd != -1)
4800 			{
4801 			c1 = ColTypePosToPos(g, colType, g->grid.cellColRangeStart, 0);
4802 			c2 = ColTypePosToPos(g, colType, g->grid.cellColRangeEnd, 0);
4803 			if (c1 < 0 || c2 < 0 || c1 > c2)
4804 				colsValid = 0;
4805 			c2++;
4806 			}
4807 		else if (g->grid.cellCol != -1)
4808 			{
4809 			c1 = ColTypePosToPos(g, colType, g->grid.cellCol, 0);
4810 			if (c1 == -1)
4811 				colsValid = 0;
4812 			c2 = c1 + 1;
4813 			}
4814 		else
4815 			{
4816 			c1 = ColTypePosToPos(g, colType, 0, 0);
4817 			if (c1 == -1)
4818 				c1 = 0;
4819 			c2 = ColTypePosToPos(g, colType, -1, 1);
4820 			}
4821 		if (!colsValid)
4822 			{
4823 			XmLWarning(w, "SetValues() - invalid column(s) specified");
4824 			c1 = 0;
4825 			c2 = 0;
4826 			}
4827 		if (g->grid.debugLevel)
4828 			{
4829 			fprintf(stderr, "XmLGrid: SetValues for rows %d to %d\n", r1, r2);
4830 			fprintf(stderr, "XmLGrid: & columns %d to %d\n", c1, c2);
4831 			}
4832 		if (rowMask)
4833 			for (r = r1; r < r2; r += g->grid.rowStep)
4834 				{
4835 				row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
4836 				if (!row)
4837 					continue;
4838 				if (SetRowValues(g, row, rowMask))
4839 					needsVertResize = 1;
4840 				DrawArea(g, DrawRow, r, 0);
4841 				}
4842 		if (colMask)
4843 			for (c = c1; c < c2; c += g->grid.colStep)
4844 				{
4845 				col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
4846 				if (!col)
4847 					continue;
4848 				if (SetColumnValues(g, col, colMask))
4849 					needsHorizResize = 1;
4850 				DrawArea(g, DrawCol, 0, c);
4851 				}
4852 		if (cellMask)
4853 			SetCellValuesPreprocess(g, cellMask);
4854 		if (cellMask && g->grid.cellDefaults == True)
4855 			{
4856 			allCols = 0;
4857 			if (g->grid.colType == XmINVALID_TYPE &&
4858 				g->grid.cellCol == -1 &&
4859 				g->grid.cellColRangeStart == -1 &&
4860 				g->grid.cellColRangeEnd == -1 &&
4861 				g->grid.colStep == 1)
4862 				allCols = 1;
4863 
4864 			if (allCols)
4865 				{
4866 				/* set cell default values */
4867 				newValues = CellRefValuesCreate(g, g->grid.defCellValues);
4868 				newValues->refCount = 1;
4869 				SetCellRefValues(g, newValues, cellMask);
4870 				if (newValues->rowSpan || newValues->columnSpan)
4871 					{
4872 					newValues->rowSpan = 0;
4873 					newValues->columnSpan = 0;
4874 					XmLWarning((Widget)g,
4875 						"SetValues() - can't set default cell spans");
4876 					}
4877 				XmLGridCellDerefValues(g->grid.defCellValues);
4878 				g->grid.defCellValues = newValues;
4879 				cd1 = 0;
4880 				cd2 = XmLArrayGetCount(g->grid.colArray);
4881 				}
4882 			else
4883 				{
4884 				cd1 = c1;
4885 				cd2 = c2;
4886 				}
4887 			/* set column cell default values */
4888 			for (c = cd1; c < cd2; c += g->grid.colStep)
4889 				{
4890 				col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
4891 				if (!col)
4892 					continue;
4893 				if (allCols && !col->grid.defCellValues)
4894 					continue;
4895 				if (col->grid.defCellValues)
4896 					newValues = CellRefValuesCreate(g, col->grid.defCellValues);
4897 				else
4898 					newValues = CellRefValuesCreate(g, g->grid.defCellValues);
4899 				newValues->refCount = 1;
4900 				SetCellRefValues(g, newValues, cellMask);
4901 				if (newValues->rowSpan || newValues->columnSpan)
4902 					{
4903 					newValues->rowSpan = 0;
4904 					newValues->columnSpan = 0;
4905 					XmLWarning((Widget)g,
4906 						"SetValues() - can't set default cell spans");
4907 					}
4908 				if (col->grid.defCellValues)
4909 					XmLGridCellDerefValues(col->grid.defCellValues);
4910 				col->grid.defCellValues = newValues;
4911 				}
4912 			}
4913 		else if (cellMask)
4914 			{
4915 			/* set cell values */
4916 			if (SetCellHasRefValues(cellMask))
4917 				{
4918 				cellArray = XmLArrayNew(0, 0);
4919 				XmLArrayAdd(cellArray, -1, (r2 - r1) * (c2 - c1));
4920 				nRefValues = 0;
4921 				for (r = r1; r < r2; r += g->grid.rowStep)
4922 					for (c = c1; c < c2; c += g->grid.colStep)
4923 						{
4924 						cell = GetCell(g, r, c);
4925 						if (!cell)
4926 							continue;
4927 						SetCellRefValuesPreprocess(g, r, c, cell, cellMask);
4928 						XmLArraySet(cellArray, nRefValues, cell);
4929 						nRefValues++;
4930 						}
4931 				XmLArraySort(cellArray, SetCellRefValuesCompare,
4932 					(void *)&cellMask, 0, nRefValues);
4933 				prevValues = 0;
4934 				for (i = 0; i < nRefValues; i++)
4935 					{
4936 					cell = (XmLGridCell)XmLArrayGet(cellArray, i);
4937 					values = XmLGridCellGetRefValues(cell);
4938 					if (values != prevValues)
4939 						{
4940 						newValues = CellRefValuesCreate(g, values);
4941 						SetCellRefValues(g, newValues, cellMask);
4942 						}
4943 					XmLGridCellSetRefValues(cell, newValues);
4944 					prevValues = values;
4945 					}
4946 				XmLArrayFree(cellArray);
4947 				}
4948 			for (r = r1; r < r2; r += g->grid.rowStep)
4949 				for (c = c1; c < c2; c += g->grid.colStep)
4950 					{
4951 					row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
4952 					col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
4953 					cell = GetCell(g, r, c);
4954 					if (!row || !col || !cell)
4955 						continue;
4956 					if (SetCellValuesResize(g, row, col, cell, cellMask))
4957 						{
4958 						needsHorizResize = 1;
4959 						needsVertResize = 1;
4960 						}
4961 					SetCellValues(g, cell, cellMask);
4962 					if (!needsHorizResize && !needsVertResize)
4963 						DrawArea(g, DrawCell, r, c);
4964 					}
4965 			}
4966 		}
4967 	if (needsHorizResize)
4968 		HorizLayout(g, 1);
4969 	if (needsVertResize)
4970 		VertLayout(g, 1);
4971 	if (needsHorizResize || needsVertResize)
4972 		DrawArea(g, DrawAll, 0, 0);
4973 	g->grid.rowType = XmINVALID_TYPE;
4974 	g->grid.colType = XmINVALID_TYPE;
4975 	g->grid.rowStep = 1;
4976 	g->grid.colStep = 1;
4977 	g->grid.cellRow = -1;
4978 	g->grid.cellRowRangeStart = -1;
4979 	g->grid.cellRowRangeEnd = -1;
4980 	g->grid.cellCol = -1;
4981 	g->grid.cellColRangeStart = -1;
4982 	g->grid.cellColRangeEnd = -1;
4983 	g->grid.cellDefaults = False;
4984 	}
4985 
4986 static Boolean
SetValues(Widget curW,Widget reqW,Widget newW,ArgList args,Cardinal * nargs)4987 SetValues(Widget curW,
4988 	  Widget reqW,
4989 	  Widget newW,
4990 	  ArgList args,
4991 	  Cardinal *nargs)
4992 	{
4993 	XmLGridWidget g, cur;
4994 	int hc, c, fc, hr, r, fr;
4995 	int tfc, bfc, lfc, rfc;
4996 	int needsVertLayout, needsHorizLayout, needsRedraw;
4997 	XmLGridCellRefValues *cellValues;
4998 
4999 	g = (XmLGridWidget)newW;
5000 	cur = (XmLGridWidget)curW;
5001 	needsRedraw = 0;
5002 	needsVertLayout = 0;
5003 	needsHorizLayout = 0;
5004 
5005 #define NE(value) (g->value != cur->value)
5006 	if (NE(grid.cScrollCol))
5007 		{
5008 		g->grid.scrollCol = g->grid.cScrollCol + g->grid.headingColCount;
5009 		needsHorizLayout = 1;
5010 		needsRedraw = 1;
5011 		}
5012 	if (NE(grid.cScrollRow))
5013 		{
5014 		g->grid.scrollRow = g->grid.cScrollRow + g->grid.headingRowCount;
5015 		needsVertLayout = 1;
5016 		needsRedraw = 1;
5017 		}
5018 	if (NE(grid.bottomFixedCount) ||
5019 		NE(grid.bottomFixedMargin) ||
5020 		NE(grid.topFixedCount) ||
5021 		NE(grid.topFixedMargin) ||
5022 		NE(grid.vsbDisplayPolicy))
5023 		{
5024 		needsVertLayout = 1;
5025 		needsRedraw = 1;
5026 		}
5027 	if (NE(grid.leftFixedCount) ||
5028 		NE(grid.leftFixedMargin) ||
5029 		NE(grid.rightFixedCount) ||
5030 		NE(grid.rightFixedMargin) ||
5031 		NE(grid.hsbDisplayPolicy))
5032 		{
5033 		needsHorizLayout = 1;
5034 		needsRedraw = 1;
5035 		}
5036 	if (NE(grid.layoutFrozen))
5037 		{
5038 		if (g->grid.layoutFrozen == False)
5039 			{
5040 			if (g->grid.needsVertLayout == True)
5041 				{
5042 				needsVertLayout = 1;
5043 				g->grid.needsVertLayout = False;
5044 				}
5045 			if (g->grid.needsHorizLayout == True)
5046 				{
5047 				needsHorizLayout = 1;
5048 				g->grid.needsHorizLayout = False;
5049 				}
5050 			needsRedraw = 1;
5051 			}
5052 		}
5053 	if (NE(grid.scrollBarMargin) ||
5054 		NE(manager.shadow_thickness) ||
5055 		NE(core.border_width) ||
5056 		NE(grid.vsPolicy) ||
5057 		NE(grid.hsPolicy))
5058 		{
5059 		needsVertLayout = 1;
5060 		needsHorizLayout = 1;
5061 		needsRedraw = 1;
5062 		}
5063 	if (NE(grid.blankBg) ||
5064 		NE(grid.highlightThickness) ||
5065 		NE(grid.selectBg) ||
5066 		NE(grid.selectFg) ||
5067 		NE(grid.toggleTopColor) ||
5068 		NE(grid.toggleBotColor) ||
5069 		NE(grid.shadowRegions) ||
5070 		NE(grid.shadowType))
5071 		needsRedraw = 1;
5072 	if (NE(grid.fontList))
5073 		{
5074 		XmFontListFree(cur->grid.fontList);
5075 		CopyFontList(g);
5076 		cellValues = CellRefValuesCreate(g, g->grid.defCellValues);
5077 		cellValues->refCount = 1;
5078 		XmFontListFree(cellValues->fontList);
5079 		cellValues->fontList = XmFontListCopy(g->grid.fontList);
5080 		XmLFontListGetDimensions(cellValues->fontList,
5081 			&cellValues->fontWidth, &cellValues->fontHeight,
5082 			g->grid.useAvgWidth);
5083 		XmLGridCellDerefValues(g->grid.defCellValues);
5084 		g->grid.defCellValues = cellValues;
5085 		}
5086 	if (NE(grid.allowDrop))
5087 		DropRegister(g, g->grid.allowDrop);
5088 	if (g->grid.rowStep < 1)
5089 		{
5090 		XmLWarning(newW, "SetValues() - rowStep can't be < 1");
5091 		g->grid.rowStep = 1;
5092 		}
5093 	if (g->grid.colStep < 1)
5094 		{
5095 		XmLWarning(newW, "SetValues() - colStep can't be < 1");
5096 		g->grid.colStep = 1;
5097 		}
5098 	if (NE(grid.hsb) ||
5099 		NE(grid.vsb) ||
5100 		NE(grid.text))
5101 		{
5102 		XmLWarning(newW, "SetValues() - child Widgets are read-only");
5103 		g->grid.hsb = cur->grid.hsb;
5104 		g->grid.vsb = cur->grid.vsb;
5105 		g->grid.text = cur->grid.text;
5106 		}
5107 	if (NE(grid.useTextWidget))
5108 		{
5109 		XmLWarning(newW, "SetValues() - can't set use of text widget");
5110 		g->grid.useTextWidget = cur->grid.useTextWidget;
5111 		}
5112 	if (NE(grid.hiddenColCount) ||
5113 		NE(grid.hiddenRowCount))
5114 		{
5115 		XmLWarning(newW, "SetValues() - can't set hidden rows or columns");
5116 		g->grid.hiddenColCount = cur->grid.hiddenColCount;
5117 		g->grid.hiddenRowCount = cur->grid.hiddenRowCount;
5118 		}
5119 
5120 	/* store fixed counts, add/removing rows/columns can change these */
5121 	tfc = -1;
5122 	bfc = -1;
5123 	lfc = -1;
5124 	rfc = -1;
5125 	if (NE(grid.topFixedCount))
5126 		tfc = g->grid.topFixedCount;
5127 	if (NE(grid.bottomFixedCount))
5128 		bfc = g->grid.bottomFixedCount;
5129 	if (NE(grid.leftFixedCount))
5130 		lfc = g->grid.leftFixedCount;
5131 	if (NE(grid.rightFixedCount))
5132 		rfc = g->grid.rightFixedCount;
5133 	g->grid.topFixedCount = cur->grid.topFixedCount;
5134 	g->grid.bottomFixedCount = cur->grid.bottomFixedCount;
5135 	g->grid.leftFixedCount = cur->grid.leftFixedCount;
5136 	g->grid.rightFixedCount = cur->grid.rightFixedCount;
5137 
5138 	hc = g->grid.headingColCount - cur->grid.headingColCount;
5139 	c = g->grid.colCount - cur->grid.colCount;
5140 	fc = g->grid.footerColCount - cur->grid.footerColCount;
5141 	hr = g->grid.headingRowCount - cur->grid.headingRowCount;
5142 	r = g->grid.rowCount - cur->grid.rowCount;
5143 	fr = g->grid.footerRowCount - cur->grid.footerRowCount;
5144 	g->grid.headingColCount = cur->grid.headingColCount;
5145 	g->grid.colCount = cur->grid.colCount;
5146 	g->grid.footerColCount = cur->grid.footerColCount;
5147 	g->grid.headingRowCount = cur->grid.headingRowCount;
5148 	g->grid.rowCount = cur->grid.rowCount;
5149 	g->grid.footerRowCount = cur->grid.footerRowCount;
5150 	if (hc > 0)
5151 		XmLGridAddColumns((Widget)g, XmHEADING, -1, hc);
5152 	if (hc < 0)
5153 		XmLGridDeleteColumns((Widget)g, XmHEADING,
5154 			g->grid.headingColCount + hc, -(hc));
5155 	if (c > 0)
5156 		XmLGridAddColumns((Widget)g, XmCONTENT, -1, c);
5157 	if (c < 0)
5158 		XmLGridDeleteColumns((Widget)g, XmCONTENT,
5159 			g->grid.colCount + c, -(c));
5160 	if (fc > 0)
5161 		XmLGridAddColumns((Widget)g, XmFOOTER, -1, fc);
5162 	if (fc < 0)
5163 		XmLGridDeleteColumns((Widget)g, XmFOOTER,
5164 			g->grid.footerColCount + fc, -(fc));
5165 	if (hr > 0)
5166 		XmLGridAddRows((Widget)g, XmHEADING, -1, hr);
5167 	if (hr < 0)
5168 		XmLGridDeleteRows((Widget)g, XmHEADING,
5169 			g->grid.headingRowCount + hr, -(hr));
5170 	if (r > 0)
5171 		XmLGridAddRows((Widget)g, XmCONTENT, -1, r);
5172 	if (r < 0)
5173 		XmLGridDeleteRows((Widget)g, XmCONTENT,
5174 			g->grid.rowCount + r, -(r));
5175 	if (fr > 0)
5176 		XmLGridAddRows((Widget)g, XmFOOTER, -1, fr);
5177 	if (fr < 0)
5178 		XmLGridDeleteRows((Widget)g, XmFOOTER,
5179 			g->grid.footerRowCount + fr, -(fr));
5180 
5181 	/* restore fixed counts if user specified */
5182 	if (tfc != -1)
5183 		g->grid.topFixedCount = tfc;
5184 	if (bfc != -1)
5185 		g->grid.bottomFixedCount = bfc;
5186 	if (lfc != -1)
5187 		g->grid.leftFixedCount = lfc;
5188 	if (rfc != -1)
5189 		g->grid.rightFixedCount = rfc;
5190 
5191 	if (g->grid.topFixedCount < g->grid.headingRowCount)
5192 		{
5193 		XmLWarning(newW,
5194 			"SetValues() - can't set topFixedCount < headingRowCount");
5195 		g->grid.topFixedCount = cur->grid.topFixedCount;
5196 		}
5197 	if (g->grid.bottomFixedCount < g->grid.footerRowCount)
5198 		{
5199 		XmLWarning(newW,
5200 			"SetValues() - can't set bottomFixedCount < footerRowCount");
5201 		g->grid.bottomFixedCount = cur->grid.bottomFixedCount;
5202 		}
5203 	if (g->grid.leftFixedCount < g->grid.headingColCount)
5204 		{
5205 		XmLWarning(newW,
5206 			"SetValues() - can't set leftFixedCount < headingColumnCount");
5207 		g->grid.leftFixedCount = cur->grid.leftFixedCount;
5208 		}
5209 	if (g->grid.rightFixedCount < g->grid.footerColCount)
5210 		{
5211 		XmLWarning(newW,
5212 			"SetValues() - can't set rightFixedCount < footerColumnCount");
5213 		g->grid.rightFixedCount = cur->grid.rightFixedCount;
5214 		}
5215 
5216 	if (NE(grid.simpleHeadings))
5217 		{
5218 		if (cur->grid.simpleHeadings)
5219 			free((char *)cur->grid.simpleHeadings);
5220 		if (g->grid.simpleHeadings)
5221 			{
5222 			g->grid.simpleHeadings = (char *)strdup(g->grid.simpleHeadings);
5223 			SetSimpleHeadings(g, g->grid.simpleHeadings);
5224 			}
5225 		}
5226 	if (NE(grid.simpleWidths))
5227 		{
5228 		if (cur->grid.simpleWidths)
5229 			free((char *)cur->grid.simpleWidths);
5230 		if (g->grid.simpleWidths)
5231 			{
5232 			g->grid.simpleWidths = (char *)strdup(g->grid.simpleWidths);
5233 			SetSimpleWidths(g, g->grid.simpleWidths);
5234 			}
5235 		}
5236 	if (NE(grid.visibleRows))
5237 		{
5238 		ApplyVisibleRows(g);
5239 		needsVertLayout = 1;
5240 		needsRedraw = 1;
5241 		}
5242 	if (NE(grid.visibleCols))
5243 		{
5244         if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
5245             XmLGridSetVisibleColumnCount((Widget)g, g->grid.visibleCols);
5246         else
5247             ApplyVisibleCols(g);
5248 		needsHorizLayout = 1;
5249 		needsRedraw = 1;
5250 		}
5251 
5252 	/* for the hidden columns stuff */
5253 	if (NE(grid.hideUnhideButtons))
5254 	    {
5255 		if (g->grid.hideUnhideButtons)
5256 		    {
5257                 CreateHideUnhideButtons(g);
5258 		    }
5259 		else
5260 		    {
5261 			XtDestroyWidget(g->grid.hideButton);
5262 			XtDestroyWidget(g->grid.unhideButton);
5263             g->grid.hideButton = 0;
5264             g->grid.unhideButton = 0;
5265 		    }
5266 
5267 		needsVertLayout = 1;
5268 		needsHorizLayout = 1;
5269 		needsRedraw = 1;
5270 	    }
5271 #undef NE
5272 
5273 	SetSubValues(newW, args, nargs);
5274 
5275 	if (needsVertLayout)
5276 		VertLayout(g, 1);
5277 	if (needsHorizLayout)
5278 		HorizLayout(g, 1);
5279 	if (needsRedraw)
5280 		DrawArea(g, DrawAll, 0, 0);
5281 	return (False);
5282 	}
5283 
5284 static void
CopyFontList(XmLGridWidget g)5285 CopyFontList(XmLGridWidget g)
5286 	{
5287 	if (!g->grid.fontList)
5288 		g->grid.fontList = XmLFontListCopyDefault((Widget)g);
5289 	else
5290 		g->grid.fontList = XmFontListCopy(g->grid.fontList);
5291 	if (!g->grid.fontList)
5292 		XmLWarning((Widget)g, "- fatal error - font list NULL");
5293 	}
5294 
5295 static Boolean
CvtStringToSizePolicy(Display * dpy,XrmValuePtr args,Cardinal * narg,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * data)5296 CvtStringToSizePolicy(Display *dpy,
5297 		      XrmValuePtr args,
5298 		      Cardinal *narg,
5299 		      XrmValuePtr fromVal,
5300 		      XrmValuePtr toVal,
5301 		      XtPointer *data)
5302 	{
5303 	static XmLStringToUCharMap map[] =
5304 		{
5305 		{ "CONSTANT", XmCONSTANT },
5306 		{ "VARIABLE", XmVARIABLE },
5307         { "RESIZE_IF_POSSIBLE", XmRESIZE_IF_POSSIBLE },
5308 		{ 0, 0 },
5309 		};
5310 
5311 	return XmLCvtStringToUChar(dpy, "XmRGridSizePolicy", map, fromVal, toVal);
5312 	}
5313 
5314 static Boolean
CvtStringToRowColType(Display * dpy,XrmValuePtr args,Cardinal * narg,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * data)5315 CvtStringToRowColType(Display *dpy,
5316 		      XrmValuePtr args,
5317 		      Cardinal *narg,
5318 		      XrmValuePtr fromVal,
5319 		      XrmValuePtr toVal,
5320 		      XtPointer *data)
5321 	{
5322 	static XmLStringToUCharMap map[] =
5323 		{
5324 		{ "HEADING",    XmHEADING },
5325 		{ "CONTENT",    XmCONTENT },
5326 		{ "FOOTER",     XmFOOTER },
5327 		{ "ALL_TYPES",  XmALL_TYPES },
5328 		{ 0, 0 },
5329 		};
5330 
5331 	return XmLCvtStringToUChar(dpy, "XmRRowColType", map, fromVal, toVal);
5332 	}
5333 
5334 static Boolean
CvtStringToSelectionPolicy(Display * dpy,XrmValuePtr args,Cardinal * narg,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * data)5335 CvtStringToSelectionPolicy(Display *dpy,
5336 			   XrmValuePtr args,
5337 			   Cardinal *narg,
5338 			   XrmValuePtr fromVal,
5339 			   XrmValuePtr toVal,
5340 			   XtPointer *data)
5341 	{
5342 	static XmLStringToUCharMap map[] =
5343 		{
5344 		{ "SELECT_NONE", XmSELECT_NONE },
5345 		{ "SELECT_SINGLE_ROW", XmSELECT_SINGLE_ROW },
5346 		{ "SELECT_BROWSE_ROW", XmSELECT_BROWSE_ROW },
5347 		{ "SELECT_MULTIPLE_ROW", XmSELECT_MULTIPLE_ROW },
5348 		{ "SELECT_CELL", XmSELECT_CELL },
5349 		{ 0, 0 },
5350 		};
5351 
5352 	return XmLCvtStringToUChar(dpy, "XmRGridSelectionPolicy", map,
5353 		fromVal, toVal);
5354 	}
5355 
5356 static Boolean
CvtStringToCellAlignment(Display * dpy,XrmValuePtr args,Cardinal * narg,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * data)5357 CvtStringToCellAlignment(Display *dpy,
5358 			 XrmValuePtr args,
5359 			 Cardinal *narg,
5360 			 XrmValuePtr fromVal,
5361 			 XrmValuePtr toVal,
5362 			 XtPointer *data)
5363 	{
5364 	static XmLStringToUCharMap map[] =
5365 		{
5366 		{ "ALIGNMENT_LEFT", XmALIGNMENT_LEFT },
5367 		{ "ALIGNMENT_CENTER", XmALIGNMENT_CENTER },
5368 		{ "ALIGNMENT_RIGHT", XmALIGNMENT_RIGHT },
5369 		{ "ALIGNMENT_TOP_LEFT", XmALIGNMENT_TOP_LEFT },
5370 		{ "ALIGNMENT_TOP", XmALIGNMENT_TOP },
5371 		{ "ALIGNMENT_TOP_RIGHT", XmALIGNMENT_TOP_RIGHT },
5372 		{ "ALIGNMENT_BOTTOM_LEFT", XmALIGNMENT_BOTTOM_LEFT },
5373 		{ "ALIGNMENT_BOTTOM", XmALIGNMENT_BOTTOM },
5374 		{ "ALIGNMENT_BOTTOM_RIGHT", XmALIGNMENT_BOTTOM_RIGHT },
5375 		{ 0, 0 },
5376 		};
5377 
5378 	return XmLCvtStringToUChar(dpy, "XmRGridCellAlignment", map,
5379 		fromVal, toVal);
5380 	}
5381 
5382 static Boolean
CvtStringToCellBorderType(Display * dpy,XrmValuePtr args,Cardinal * narg,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * data)5383 CvtStringToCellBorderType(Display *dpy,
5384 			  XrmValuePtr args,
5385 			  Cardinal *narg,
5386 			  XrmValuePtr fromVal,
5387 			  XrmValuePtr toVal,
5388 			  XtPointer *data)
5389 	{
5390 	static XmLStringToUCharMap map[] =
5391 		{
5392 		{ "BORDER_NONE", XmBORDER_NONE },
5393 		{ "BORDER_LINE", XmBORDER_LINE },
5394 		{ "BORDER_DASH", XmBORDER_DASH },
5395 		{ 0, 0 },
5396 		};
5397 
5398 	return XmLCvtStringToUChar(dpy, "XmRGridCellBorderType", map,
5399 		fromVal, toVal);
5400 	}
5401 
5402 static Boolean
CvtStringToCellType(Display * dpy,XrmValuePtr args,Cardinal * narg,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * data)5403 CvtStringToCellType(Display *dpy,
5404 		    XrmValuePtr args,
5405 		    Cardinal *narg,
5406 		    XrmValuePtr fromVal,
5407 		    XrmValuePtr toVal,
5408 		    XtPointer *data)
5409 	{
5410 	static XmLStringToUCharMap map[] =
5411 		{
5412 		{ "ICON_CELL",   XmICON_CELL },
5413 		{ "STRING_CELL", XmSTRING_CELL },
5414 		{ "PIXMAP_CELL", XmPIXMAP_CELL },
5415 		{ "TOGGLE_CELL", XmTOGGLE_CELL },
5416 		{ 0, 0 },
5417 		};
5418 
5419 	return XmLCvtStringToUChar(dpy, "XmRGridCellType", map, fromVal, toVal);
5420 	}
5421 
5422 static void
SetSimpleHeadings(XmLGridWidget g,char * data)5423 SetSimpleHeadings(XmLGridWidget g,
5424 		  char *data)
5425 	{
5426 	char *c;
5427 	int n, count;
5428 
5429 	if (!data || !*data)
5430 		return;
5431 	c = data;
5432 	n = 1;
5433 	while (*c)
5434 		{
5435 		if (*c == '|')
5436 			n++;
5437 		c++;
5438 		}
5439 	count = XmLArrayGetCount(g->grid.colArray);
5440 	if (n > count)
5441 		{
5442 		XmLWarning((Widget)g,
5443 			"SetSimpleHeadings() - headings given for non-existing columns");
5444 		return;
5445 		}
5446 	if (g->grid.headingRowCount < 1)
5447 		{
5448 		XmLWarning((Widget)g, "SetSimpleHeadings() - no heading row exists");
5449 		return;
5450 		}
5451 	XmLGridSetStrings((Widget)g, data);
5452 	}
5453 
5454 static void
SetSimpleWidths(XmLGridWidget g,char * data)5455 SetSimpleWidths(XmLGridWidget g,
5456 		char *data)
5457 	{
5458 	XmLGridColumn colp;
5459 	int i, n, colCount, valid;
5460 	Dimension prevWidth;
5461 	unsigned char prevSizePolicy;
5462 	long mask;
5463 	struct WidthRec
5464 		{
5465 		Dimension width;
5466 		unsigned char sizePolicy;
5467 		} *widths;
5468 
5469 	if (!data)
5470 		return;
5471 	i = ((int)strlen(data) / 2) + 1;
5472 	widths = (struct WidthRec *)malloc(i * sizeof(struct WidthRec));
5473 	valid = 1;
5474 	n = 0;
5475 	while (*data)
5476 		{
5477 		if (*data >= '0' && *data <= '9')
5478 			{
5479 			widths[n].width = atoi(data);
5480 			while (*data >= '0' && *data <= '9')
5481 				data++;
5482 			}
5483 		else
5484 			{
5485 			valid = 0;
5486 			break;
5487 			}
5488 		if (*data == 'c' || *data == 'C')
5489 			{
5490 			widths[n].sizePolicy = XmVARIABLE;
5491 			data++;
5492 			}
5493 		else if (*data == 'p' || *data == 'P')
5494 			{
5495 			widths[n].sizePolicy = XmCONSTANT;
5496 			data++;
5497 			}
5498 		else
5499 			{
5500 			valid = 0;
5501 			break;
5502 			}
5503 		while (*data == ' ')
5504 			data++;
5505 		n++;
5506 		}
5507 	if (!valid)
5508 		{
5509 		free((char *)widths);
5510 		XmLWarning((Widget)g, "SetSimpleWidths() - invalid widths string");
5511 		return;
5512 		}
5513 	colCount = XmLArrayGetCount(g->grid.colArray);
5514 	if (n > colCount)
5515 		{
5516 		free((char *)widths);
5517 		XmLWarning((Widget)g,
5518 			"SetSimpleWidths() - widths given for non-existing columns");
5519 		return;
5520 		}
5521 	prevWidth = g->grid.colWidth;
5522 	prevSizePolicy = g->grid.colSizePolicy;
5523 	for (i = 0; i < n; i++)
5524 		{
5525 		colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
5526 		if (!colp)
5527 			continue;
5528 		GetColumnValueMask(g, XmNcolumnWidth, &mask);
5529 		GetColumnValueMask(g, XmNcolumnSizePolicy, &mask);
5530 		g->grid.colWidth = widths[i].width;
5531 		g->grid.colSizePolicy = widths[i].sizePolicy;
5532 		SetColumnValues(g, colp, mask);
5533 		}
5534 	free((char *)widths);
5535 	g->grid.colWidth = prevWidth;
5536 	g->grid.colSizePolicy = prevSizePolicy;
5537 	HorizLayout(g, 1);
5538 	DrawArea(g, DrawAll, 0, 0);
5539 	}
5540 
5541 /*
5542    Getting and Setting Row Values
5543 */
5544 
5545 static void
GetRowValueMask(XmLGridWidget g,char * s,long * mask)5546 GetRowValueMask(XmLGridWidget g,
5547 		char *s,
5548 		long *mask)
5549 	{
5550 	XmLGridClassPartOfWidget(g).getRowValueMaskProc(g, s, mask);
5551 	}
5552 
5553 /* Only to be called through Grid class */
5554 static void
_GetRowValueMask(XmLGridWidget g,char * s,long * mask)5555 _GetRowValueMask(XmLGridWidget g,
5556 		 char *s,
5557 		 long *mask)
5558 	{
5559 	static XrmQuark qHeight, qSizePolicy, qUserData;
5560 	static int quarksValid = 0;
5561 	XrmQuark q;
5562 
5563 	if (!quarksValid)
5564 		{
5565 		qHeight = XrmStringToQuark(XmNrowHeight);
5566 		qSizePolicy = XrmStringToQuark(XmNrowSizePolicy);
5567 		qUserData = XrmStringToQuark(XmNrowUserData);
5568 		quarksValid = 1;
5569 		}
5570 	q = XrmStringToQuark(s);
5571 	if (q == qHeight)
5572 			*mask |= XmLGridRowHeight;
5573 	else if (q == qSizePolicy)
5574 			*mask |= XmLGridRowSizePolicy;
5575 	else if (q == qUserData)
5576 			*mask |= XmLGridRowUserData;
5577 	}
5578 
5579 static void
GetRowValue(XmLGridWidget g,XmLGridRow row,XtArgVal value,long mask)5580 GetRowValue(XmLGridWidget g,
5581 	    XmLGridRow row,
5582 	    XtArgVal value,
5583 	    long mask)
5584 	{
5585 	XmLGridClassPartOfWidget(g).getRowValueProc(g, row, value, mask);
5586 	}
5587 
5588 /* Only to be called through Grid class */
5589 static void
_GetRowValue(XmLGridWidget g,XmLGridRow row,XtArgVal value,long mask)5590 _GetRowValue(XmLGridWidget g,
5591 	     XmLGridRow row,
5592 	     XtArgVal value,
5593 	     long mask)
5594 	{
5595 	switch (mask)
5596 		{
5597 		case XmLGridRowHeight:
5598 			*((Dimension *)value) = row->grid.height;
5599 			break;
5600 		case XmLGridRowSizePolicy:
5601 			*((unsigned char *)value) = row->grid.sizePolicy;
5602 			break;
5603 		case XmLGridRowUserData:
5604 			*((XtPointer *)value) = (XtPointer)row->grid.userData;
5605 			break;
5606 		}
5607 	}
5608 
5609 static int
SetRowValues(XmLGridWidget g,XmLGridRow row,long mask)5610 SetRowValues(XmLGridWidget g,
5611 	     XmLGridRow row,
5612 	     long mask)
5613 	{
5614 	return XmLGridClassPartOfWidget(g).setRowValuesProc(g, row, mask);
5615 	}
5616 
5617 /* Only to be called through Grid class */
5618 static int
_SetRowValues(XmLGridWidget g,XmLGridRow row,long mask)5619 _SetRowValues(XmLGridWidget g, XmLGridRow row, long mask)
5620 	{
5621 	int needsResize = 0, visible = 0;
5622 	Boolean newIsHidden;
5623 
5624 	if (mask & XmLGridRowHeight || mask & XmLGridRowSizePolicy)
5625 		{
5626 		visible = RowIsVisible(g, XmLGridRowGetPos(row));
5627 		XmLGridRowHeightChanged(row);
5628 		}
5629 	if (mask & XmLGridRowHeight)
5630 		{
5631 		if (g->grid.rowHeight > 0)
5632 			newIsHidden = False;
5633 		else
5634 			newIsHidden = True;
5635 		if (XmLGridRowIsHidden(row) != newIsHidden)
5636 			{
5637 			if (newIsHidden == True)
5638 				g->grid.hiddenRowCount++;
5639 			else
5640 				g->grid.hiddenRowCount--;
5641 			VisPosChanged(g, 1);
5642 			needsResize = 1;
5643 			}
5644 		if (visible && !g->grid.inResize)
5645 			needsResize = 1;
5646 		row->grid.height = g->grid.rowHeight;
5647 		}
5648 	if (mask & XmLGridRowSizePolicy)
5649 		{
5650 		row->grid.sizePolicy = g->grid.rowSizePolicy;
5651 		if (visible && !g->grid.inResize)
5652 			needsResize = 1;
5653 		}
5654 	if (mask & XmLGridRowUserData)
5655 		row->grid.userData = g->grid.rowUserData;
5656 	return needsResize;
5657 	}
5658 
5659 /*
5660    Getting and Setting Column Values
5661 */
5662 
5663 static void
GetColumnValueMask(XmLGridWidget g,char * s,long * mask)5664 GetColumnValueMask(XmLGridWidget g,
5665 		   char *s,
5666 		   long *mask)
5667 	{
5668 	XmLGridClassPartOfWidget(g).getColumnValueMaskProc(g, s, mask);
5669 	}
5670 
5671 /* Only to be called through Grid class */
5672 static void
_GetColumnValueMask(XmLGridWidget g,char * s,long * mask)5673 _GetColumnValueMask(XmLGridWidget g,
5674 		    char *s,
5675 		    long *mask)
5676 	{
5677 	static XrmQuark qWidth, qSizePolicy, qUserData, qResizable;
5678     static XrmQuark qHidden, qSortType;
5679 	static int quarksValid = 0;
5680 	XrmQuark q;
5681 
5682 	if (!quarksValid)
5683 		{
5684 		qWidth = XrmStringToQuark(XmNcolumnWidth);
5685 		qSizePolicy = XrmStringToQuark(XmNcolumnSizePolicy);
5686 		qUserData = XrmStringToQuark(XmNcolumnUserData);
5687 		qResizable = XrmStringToQuark(XmNcolumnResizable);
5688 		qHidden = XrmStringToQuark(XmNcolumnHidden);
5689 		qSortType = XrmStringToQuark(XmNcolumnSortType);
5690 		quarksValid = 1;
5691 		}
5692 	q = XrmStringToQuark(s);
5693 	if (q == qWidth)
5694 			*mask |= XmLGridColumnWidth;
5695 	else if (q == qSizePolicy)
5696 			*mask |= XmLGridColumnSizePolicy;
5697 	else if (q == qUserData)
5698 			*mask |= XmLGridColumnUserData;
5699 	else if (q == qResizable)
5700 			*mask |= XmLGridColumnResizable;
5701 	else if (q == qHidden)
5702 			*mask |= XmLGridColumnHidden;
5703 	else if (q == qSortType)
5704 			*mask |= XmLGridColumnSortType;
5705 	}
5706 
5707 static void
GetColumnValue(XmLGridWidget g,XmLGridColumn col,XtArgVal value,long mask)5708 GetColumnValue(XmLGridWidget g,
5709 	       XmLGridColumn col,
5710 	       XtArgVal value,
5711 	       long mask)
5712 	{
5713 	XmLGridClassPartOfWidget(g).getColumnValueProc(g, col, value, mask);
5714 	}
5715 
5716 /* Only to be called through Grid class */
5717 static void
_GetColumnValue(XmLGridWidget g,XmLGridColumn col,XtArgVal value,long mask)5718 _GetColumnValue(XmLGridWidget g,
5719 		XmLGridColumn col,
5720 		XtArgVal value,
5721 		long mask)
5722 	{
5723 	switch (mask)
5724 		{
5725 		case XmLGridColumnWidth:
5726 			*((Dimension *)value) = col->grid.width;
5727 			break;
5728 		case XmLGridColumnSizePolicy:
5729 			*((unsigned char *)value) = col->grid.sizePolicy;
5730 			break;
5731 		case XmLGridColumnUserData:
5732 			*((XtPointer *)value) = col->grid.userData;
5733 			break;
5734 		case XmLGridColumnResizable:
5735 			*((Boolean *)value) = col->grid.resizable;
5736 			break;
5737 		case XmLGridColumnHidden:
5738 			*((Boolean *)value) = col->grid.hidden;
5739 			break;
5740 		case XmLGridColumnSortType:
5741 			*((unsigned char *)value) = col->grid.sort;
5742 			break;
5743 
5744 		}
5745 	}
5746 
5747 static int
SetColumnValues(XmLGridWidget g,XmLGridColumn col,long mask)5748 SetColumnValues(XmLGridWidget g,
5749 		XmLGridColumn col,
5750 		long mask)
5751 	{
5752 	return XmLGridClassPartOfWidget(g).setColumnValuesProc(g, col, mask);
5753 	}
5754 
5755 /* Only to be called through Grid class */
5756 static int
_SetColumnValues(XmLGridWidget g,XmLGridColumn col,long mask)5757 _SetColumnValues(XmLGridWidget g, XmLGridColumn col, long mask)
5758 	{
5759 	int needsResize = 0, visible = 0;
5760 	Boolean newIsHidden;
5761 
5762 	if (mask & XmLGridColumnWidth || mask & XmLGridColumnSizePolicy)
5763 		{
5764 		visible = ColIsVisible(g, XmLGridColumnGetPos(col));
5765 		XmLGridColumnWidthChanged(col);
5766 		}
5767 	if (mask & XmLGridColumnWidth)
5768 		{
5769 		if (g->grid.colWidth > 0)
5770 			newIsHidden = False;
5771 		else
5772 			newIsHidden = True;
5773 		if (XmLGridColumnIsHidden(col) != newIsHidden)
5774 			{
5775 			if (newIsHidden == True)
5776 				g->grid.hiddenColCount++;
5777 			else
5778 				g->grid.hiddenRowCount--;
5779 			VisPosChanged(g, 0);
5780 			needsResize = 1;
5781 			}
5782 		if (visible && !g->grid.inResize)
5783 			needsResize = 1;
5784 		col->grid.width = g->grid.colWidth;
5785 		}
5786 	if (mask & XmLGridColumnSizePolicy)
5787 		{
5788 		col->grid.sizePolicy = g->grid.colSizePolicy;
5789 		if (visible && !g->grid.inResize)
5790 			needsResize = 1;
5791         if (col->grid.sizePolicy != XmCONSTANT
5792             && g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
5793             {
5794                 XmLWarning((Widget)g, "XmNcolumnSizePolicy must equal XmCONSTANT");
5795             }
5796 		}
5797 	if (mask & XmLGridColumnUserData)
5798 		col->grid.userData = g->grid.colUserData;
5799 	if (mask & XmLGridColumnResizable)
5800 		col->grid.resizable = g->grid.colResizable;
5801 	if (mask & XmLGridColumnHidden)
5802 		col->grid.hidden = g->grid.colHidden;
5803 	if (mask & XmLGridColumnSortType)
5804         XmLGridSetSort((Widget)g, XmLGridColumnGetPos(col), g->grid.colSortType);
5805 	return needsResize;
5806 	}
5807 
5808 /*
5809    Getting and Setting Cell Values
5810 */
5811 
5812 static void
CellValueGetMask(char * s,long * mask)5813 CellValueGetMask(char *s,
5814 		 long *mask)
5815 	{
5816 	static XrmQuark qAlignment, qBackground, qBottomBorderColor;
5817 	static XrmQuark qBottomBorderType, qColumnSpan;
5818 	static XrmQuark qEditable, qFontList, qForeground;
5819 	static XrmQuark qLeftBorderColor, qLeftBorderType;
5820 	static XrmQuark qMarginBottom, qMarginLeft, qMarginRight;
5821 	static XrmQuark qMarginTop, qPixmap, qPixmapMask;
5822 	static XrmQuark qRightBorderColor, qRightBorderType;
5823 	static XrmQuark qRowSpan, qString, qToggleSet;
5824 	static XrmQuark qTopBorderColor, qTopBorderType, qType;
5825 	static XrmQuark qUserData;
5826 	static int quarksValid = 0;
5827 	XrmQuark q;
5828 
5829 	if (!quarksValid)
5830 		{
5831 		qAlignment = XrmStringToQuark(XmNcellAlignment);
5832 		qBackground = XrmStringToQuark(XmNcellBackground);
5833 		qBottomBorderColor = XrmStringToQuark(XmNcellBottomBorderColor);
5834 		qBottomBorderType = XrmStringToQuark(XmNcellBottomBorderType);
5835 		qColumnSpan = XrmStringToQuark(XmNcellColumnSpan);
5836 		qEditable = XrmStringToQuark(XmNcellEditable);
5837 		qFontList = XrmStringToQuark(XmNcellFontList);
5838 		qForeground = XrmStringToQuark(XmNcellForeground);
5839 		qLeftBorderColor = XrmStringToQuark(XmNcellLeftBorderColor);
5840 		qLeftBorderType = XrmStringToQuark(XmNcellLeftBorderType);
5841 		qMarginBottom = XrmStringToQuark(XmNcellMarginBottom);
5842 		qMarginLeft = XrmStringToQuark(XmNcellMarginLeft);
5843 		qMarginRight = XrmStringToQuark(XmNcellMarginRight);
5844 		qMarginTop= XrmStringToQuark(XmNcellMarginTop);
5845 		qPixmap = XrmStringToQuark(XmNcellPixmap);
5846 		qPixmapMask = XrmStringToQuark(XmNcellPixmapMask);
5847 		qRightBorderColor = XrmStringToQuark(XmNcellRightBorderColor);
5848 		qRightBorderType = XrmStringToQuark(XmNcellRightBorderType);
5849 		qRowSpan = XrmStringToQuark(XmNcellRowSpan);
5850 		qString = XrmStringToQuark(XmNcellString);
5851 		qToggleSet = XrmStringToQuark(XmNcellToggleSet);
5852 		qTopBorderColor = XrmStringToQuark(XmNcellTopBorderColor);
5853 		qTopBorderType = XrmStringToQuark(XmNcellTopBorderType);
5854 		qType = XrmStringToQuark(XmNcellType);
5855 		qUserData = XrmStringToQuark(XmNcellUserData);
5856 		quarksValid = 1;
5857 		}
5858 	q = XrmStringToQuark(s);
5859 	if (q == qAlignment)
5860 			*mask |= XmLGridCellAlignment;
5861 	else if (q == qBackground)
5862 			*mask |= XmLGridCellBackground;
5863 	else if (q == qBottomBorderColor)
5864 			*mask |= XmLGridCellBottomBorderColor;
5865 	else if (q == qBottomBorderType)
5866 			*mask |= XmLGridCellBottomBorderType;
5867 	else if (q == qColumnSpan)
5868 			*mask |= XmLGridCellColumnSpan;
5869 	else if (q == qEditable)
5870 			*mask |= XmLGridCellEditable;
5871 	else if (q == qFontList)
5872 			*mask |= XmLGridCellFontList;
5873 	else if (q == qForeground)
5874 			*mask |= XmLGridCellForeground;
5875 	else if (q == qLeftBorderColor)
5876 			*mask |= XmLGridCellLeftBorderColor;
5877 	else if (q == qLeftBorderType)
5878 			*mask |= XmLGridCellLeftBorderType;
5879 	else if (q == qMarginBottom)
5880 			*mask |= XmLGridCellMarginBottom;
5881 	else if (q == qMarginLeft)
5882 			*mask |= XmLGridCellMarginLeft;
5883 	else if (q == qMarginRight)
5884 			*mask |= XmLGridCellMarginRight;
5885 	else if (q == qMarginTop)
5886 			*mask |= XmLGridCellMarginTop;
5887 	else if (q == qPixmap)
5888 			*mask |= XmLGridCellPixmapF;
5889 	else if (q == qPixmapMask)
5890 			*mask |= XmLGridCellPixmapMask;
5891 	else if (q == qRightBorderColor)
5892 			*mask |= XmLGridCellRightBorderColor;
5893 	else if (q == qRightBorderType)
5894 			*mask |= XmLGridCellRightBorderType;
5895 	else if (q == qRowSpan)
5896 			*mask |= XmLGridCellRowSpan;
5897 	else if (q == qString)
5898 			*mask |= XmLGridCellString;
5899 	else if (q == qToggleSet)
5900 			*mask |= XmLGridCellToggleSet;
5901 	else if (q == qTopBorderColor)
5902 			*mask |= XmLGridCellTopBorderColor;
5903 	else if (q == qTopBorderType)
5904 			*mask |= XmLGridCellTopBorderType;
5905 	else if (q == qType)
5906 			*mask |= XmLGridCellType;
5907 	else if (q == qUserData)
5908 			*mask |= XmLGridCellUserData;
5909 	}
5910 
5911 static void
GetCellValue(XmLGridCell cell,XtArgVal value,long mask)5912 GetCellValue(XmLGridCell cell,
5913 	     XtArgVal value,
5914 	     long mask)
5915 	{
5916 	XmLGridCellRefValues *values;
5917 	XmLGridCellPixmap *pix;
5918 	XmString str;
5919 
5920 	values = XmLGridCellGetRefValues(cell);
5921 	switch (mask)
5922 		{
5923 		case XmLGridCellAlignment:
5924 			*((unsigned char *)value) = values->alignment;
5925 			break;
5926 		case XmLGridCellBackground:
5927 			*((Pixel *)value) = values->background;
5928 			break;
5929 		case XmLGridCellBottomBorderColor:
5930 			*((Pixel *)value) = values->bottomBorderColor;
5931 			break;
5932 		case XmLGridCellBottomBorderType:
5933 			*((unsigned char *)value) = values->bottomBorderType;
5934 			break;
5935 		case XmLGridCellColumnSpan:
5936 			*((int *)value) = values->columnSpan;
5937 			break;
5938 		case XmLGridCellEditable:
5939 			*((Boolean *)value) = values->editable;
5940 			break;
5941 		case XmLGridCellFontList:
5942 			*((XmFontList *)value) = values->fontList;
5943 			break;
5944 		case XmLGridCellForeground:
5945 			*((Pixel *)value) = values->foreground;
5946 			break;
5947 		case XmLGridCellLeftBorderColor:
5948 			*((Pixel *)value) = values->leftBorderColor;
5949 			break;
5950 		case XmLGridCellLeftBorderType:
5951 			*((unsigned char *)value) = values->leftBorderType;
5952 			break;
5953 		case XmLGridCellMarginBottom:
5954 			*((Dimension *)value) = values->bottomMargin;
5955 			break;
5956 		case XmLGridCellMarginLeft:
5957 			*((Dimension *)value) = values->leftMargin;
5958 			break;
5959 		case XmLGridCellMarginRight:
5960 			*((Dimension *)value) = values->rightMargin;
5961 			break;
5962 		case XmLGridCellMarginTop:
5963 			*((Dimension *)value) = values->topMargin;
5964 			break;
5965 		case XmLGridCellPixmapF:
5966 			pix = XmLGridCellGetPixmap(cell);
5967 			if (pix)
5968 				*((Pixmap *)value) = pix->pixmap;
5969 			else
5970 				*((Pixmap *)value) = (Pixmap)XmUNSPECIFIED_PIXMAP;
5971 			break;
5972 		case XmLGridCellPixmapMask:
5973 			pix = XmLGridCellGetPixmap(cell);
5974 			if (pix)
5975 				*((Pixmap *)value) = pix->pixmask;
5976 			else
5977 				*((Pixmap *)value) = (Pixmap)XmUNSPECIFIED_PIXMAP;
5978 			break;
5979 		case XmLGridCellRightBorderColor:
5980 			*((Pixel *)value) = values->rightBorderColor;
5981 			break;
5982 		case XmLGridCellRightBorderType:
5983 			*((unsigned char *)value) = values->rightBorderType;
5984 			break;
5985 		case XmLGridCellRowSpan:
5986 			*((int *)value) = values->rowSpan;
5987 			break;
5988 		case XmLGridCellString:
5989 			str = XmLGridCellGetString(cell);
5990 			if (str)
5991 				*((XmString *)value) = XmStringCopy(str);
5992 			else
5993 				*((XmString *)value) = 0;
5994 			break;
5995 		case XmLGridCellToggleSet:
5996 			*((Boolean *)value) = XmLGridCellGetToggle(cell);
5997 			break;
5998 		case XmLGridCellTopBorderColor:
5999 			*((Pixel *)value) = values->topBorderColor;
6000 			break;
6001 		case XmLGridCellTopBorderType:
6002 			*((unsigned char *)value) = values->topBorderType;
6003 			break;
6004 		case XmLGridCellType:
6005 			*((unsigned char *)value) = values->type;
6006 			break;
6007 		case XmLGridCellUserData:
6008 			*((XtPointer *)value) = (XtPointer)values->userData;
6009 			break;
6010 		}
6011 	}
6012 
6013 static XmLGridCellRefValues *
CellRefValuesCreate(XmLGridWidget g,XmLGridCellRefValues * copy)6014 CellRefValuesCreate(XmLGridWidget g,
6015 		    XmLGridCellRefValues *copy)
6016 	{
6017 	short width, height;
6018 	XmLGridCellRefValues *values;
6019 
6020 	values = (XmLGridCellRefValues *)malloc(sizeof(XmLGridCellRefValues));
6021 	if (!copy)
6022 		{
6023 		/* default values */
6024 		values->bottomBorderType = XmBORDER_LINE;
6025 		values->leftBorderType = XmBORDER_LINE;
6026 		values->rightBorderType = XmBORDER_LINE;
6027 		values->topBorderType = XmBORDER_LINE;
6028 		XmLFontListGetDimensions(g->grid.fontList, &width, &height,
6029 			g->grid.useAvgWidth);
6030 		values->alignment = XmALIGNMENT_CENTER;
6031 		values->background = g->core.background_pixel;
6032 		values->bottomBorderColor = g->manager.bottom_shadow_color;
6033 		values->bottomMargin = 0;
6034 		values->columnSpan = 0;
6035 		values->editable = False;
6036 		values->fontHeight = height;
6037 		values->fontList = XmFontListCopy(g->grid.fontList);
6038 		values->fontWidth = width;
6039 		values->foreground = g->manager.foreground;
6040 		values->leftBorderColor = g->manager.top_shadow_color;
6041 		values->leftMargin = 0;
6042 		values->refCount = 0;
6043 		values->rightBorderColor = g->manager.bottom_shadow_color;
6044 		values->rightMargin = 0;
6045 		values->rowSpan = 0;
6046 		values->topBorderColor = g->manager.top_shadow_color;
6047 		values->topMargin = 0;
6048 		values->type = XmSTRING_CELL;
6049 		values->userData = 0;
6050 		}
6051 	else
6052 		{
6053 		/* copy values */
6054 		*values = *copy;
6055 		values->fontList = XmFontListCopy(copy->fontList);
6056 		values->refCount = 0;
6057 		}
6058 	return values;
6059 	}
6060 
6061 static void
SetCellValuesPreprocess(XmLGridWidget g,long mask)6062 SetCellValuesPreprocess(XmLGridWidget g,
6063 			long mask)
6064 	{
6065 	XmLGridCellRefValues *newValues;
6066 	int x, y;
6067 	short width, height;
6068 	Display *dpy;
6069 	Window pixRoot;
6070 	unsigned int pixWidth, pixHeight;
6071 	unsigned int pixBW, pixDepth;
6072 
6073 	/* calculate font width and height if set */
6074 	newValues = &g->grid.cellValues;
6075 	if (mask & XmLGridCellFontList)
6076 		{
6077 		XmLFontListGetDimensions(newValues->fontList, &width, &height,
6078 			g->grid.useAvgWidth);
6079 		newValues->fontWidth = width;
6080 		newValues->fontHeight = height;
6081 		}
6082 	if (mask & XmLGridCellPixmapF)
6083 		{
6084 		if (g->grid.cellPixmap != XmUNSPECIFIED_PIXMAP &&
6085 			g->grid.globalPixmapWidth &&
6086 			g->grid.globalPixmapHeight)
6087 			{
6088 			g->grid.cellPixmapWidth = g->grid.globalPixmapWidth;
6089 			g->grid.cellPixmapHeight = g->grid.globalPixmapHeight;
6090 			}
6091 		else if (g->grid.cellPixmap != XmUNSPECIFIED_PIXMAP)
6092 			{
6093 			dpy = XtDisplay(g);
6094 			XGetGeometry(dpy, g->grid.cellPixmap, &pixRoot,
6095 				&x, &y, &pixWidth, &pixHeight, &pixBW, &pixDepth);
6096 			g->grid.cellPixmapWidth = (Dimension)pixWidth;
6097 			g->grid.cellPixmapHeight = (Dimension)pixHeight;
6098 			}
6099 		else
6100 			{
6101 			g->grid.cellPixmapWidth = 0;
6102 			g->grid.cellPixmapHeight = 0;
6103 			}
6104 		}
6105 	}
6106 
6107 static int
SetCellHasRefValues(long mask)6108 SetCellHasRefValues(long mask)
6109 	{
6110 	long unrefMask;
6111 
6112 	/* return 1 if mask contains any reference counted values */
6113 	unrefMask = XmLGridCellPixmapF | XmLGridCellPixmapMask |
6114 		XmLGridCellString | XmLGridCellToggleSet;
6115 	mask = mask | unrefMask;
6116 	mask = mask ^ unrefMask;
6117 	if (!mask)
6118 		return 0;
6119 	return 1;
6120 	}
6121 
6122 static int
SetCellValuesResize(XmLGridWidget g,XmLGridRow row,XmLGridColumn col,XmLGridCell cell,long mask)6123 SetCellValuesResize(XmLGridWidget g,
6124 		    XmLGridRow row,
6125 		    XmLGridColumn col,
6126 		    XmLGridCell cell,
6127 		    long mask)
6128 	{
6129 	return XmLGridClassPartOfWidget(g).setCellValuesResizeProc(g, row, col,
6130 		cell, mask);
6131 	}
6132 
6133 static int
_SetCellValuesResize(XmLGridWidget g,XmLGridRow row,XmLGridColumn col,XmLGridCell cell,long mask)6134 _SetCellValuesResize(XmLGridWidget g,
6135 		     XmLGridRow row,
6136 		     XmLGridColumn col,
6137 		     XmLGridCell cell,
6138 		     long mask)
6139 	{
6140 	XmLGridCellPixmap *cellPix;
6141 	int pixResize, needsResize, rowVisible, colVisible;
6142 
6143 	needsResize = 0;
6144 	pixResize = 0;
6145 	if (mask & XmLGridCellPixmapF)
6146 		{
6147 		pixResize = 1;
6148 		if (!(mask & XmLGridCellType))
6149 			{
6150 			/* no resize needed if we replace with an equal size pixmap */
6151 			cellPix = XmLGridCellGetPixmap(cell);
6152 			if (cellPix && cellPix->pixmap != XmUNSPECIFIED_PIXMAP &&
6153 				g->grid.cellPixmap != XmUNSPECIFIED_PIXMAP)
6154 				{
6155 				if (cellPix->width == g->grid.cellPixmapWidth &&
6156 					cellPix->height == g->grid.cellPixmapHeight)
6157 					pixResize = 0;
6158 				}
6159 			}
6160 		}
6161 	if (mask & XmLGridCellType || mask & XmLGridCellFontList || pixResize ||
6162 		mask & XmLGridCellRowSpan || mask & XmLGridCellColumnSpan ||
6163 		mask & XmLGridCellMarginLeft || mask & XmLGridCellMarginRight ||
6164 		mask & XmLGridCellMarginTop || mask & XmLGridCellMarginBottom)
6165 		{
6166 		XmLGridRowHeightChanged(row);
6167 		XmLGridColumnWidthChanged(col);
6168 		rowVisible = RowIsVisible(g, XmLGridRowGetPos(row));
6169 		colVisible = ColIsVisible(g, XmLGridColumnGetPos(col));
6170 		if (rowVisible | colVisible)
6171 			needsResize = 1;
6172 		}
6173 	return needsResize;
6174 	}
6175 
6176 static void
SetCellValues(XmLGridWidget g,XmLGridCell cell,long mask)6177 SetCellValues(XmLGridWidget g,
6178 	      XmLGridCell cell,
6179 	      long mask)
6180 	{
6181 	/* set non-reference counted cell values */
6182 	if (mask & XmLGridCellPixmapF)
6183 		XmLGridCellSetPixmap(cell, g->grid.cellPixmap,
6184 			g->grid.cellPixmapWidth, g->grid.cellPixmapHeight);
6185 	if (mask & XmLGridCellPixmapMask)
6186 		XmLGridCellSetPixmask(cell, g->grid.cellPixmapMask);
6187 	if (mask & XmLGridCellString)
6188 		XmLGridCellSetString(cell, g->grid.cellString, True);
6189 	if (mask & XmLGridCellToggleSet)
6190 		XmLGridCellSetToggle(cell, g->grid.cellToggleSet);
6191 	}
6192 
6193 static void
SetCellRefValues(XmLGridWidget g,XmLGridCellRefValues * values,long mask)6194 SetCellRefValues(XmLGridWidget g,
6195 		 XmLGridCellRefValues *values,
6196 		 long mask)
6197 	{
6198 	XmLGridCellRefValues *newValues;
6199 
6200 	/* set reference counted cell values */
6201 	newValues = &g->grid.cellValues;
6202 	if (mask & XmLGridCellAlignment)
6203 		values->alignment = newValues->alignment;
6204 	if (mask & XmLGridCellBackground)
6205 		values->background = newValues->background;
6206 	if (mask & XmLGridCellBottomBorderColor)
6207 		values->bottomBorderColor = newValues->bottomBorderColor;
6208 	if (mask & XmLGridCellBottomBorderType)
6209 		values->bottomBorderType = newValues->bottomBorderType;
6210 	if (mask & XmLGridCellColumnSpan)
6211 		values->columnSpan = newValues->columnSpan;
6212 	if (mask & XmLGridCellEditable)
6213 		values->editable = newValues->editable;
6214 	if (mask & XmLGridCellFontList)
6215 		{
6216 		XmFontListFree(values->fontList);
6217 		values->fontList = XmFontListCopy(newValues->fontList);
6218 		values->fontWidth = newValues->fontWidth;
6219 		values->fontHeight = newValues->fontHeight;
6220 		}
6221 	if (mask & XmLGridCellForeground)
6222 		values->foreground = newValues->foreground;
6223 	if (mask & XmLGridCellLeftBorderColor)
6224 		values->leftBorderColor = newValues->leftBorderColor;
6225 	if (mask & XmLGridCellLeftBorderType)
6226 		values->leftBorderType = newValues->leftBorderType;
6227 	if (mask & XmLGridCellRightBorderColor)
6228 		values->rightBorderColor = newValues->rightBorderColor;
6229 	if (mask & XmLGridCellRightBorderType)
6230 		values->rightBorderType = newValues->rightBorderType;
6231 	if (mask & XmLGridCellMarginBottom)
6232 		values->bottomMargin = newValues->bottomMargin;
6233 	if (mask & XmLGridCellMarginLeft)
6234 		values->leftMargin = newValues->leftMargin;
6235 	if (mask & XmLGridCellMarginRight)
6236 		values->rightMargin = newValues->rightMargin;
6237 	if (mask & XmLGridCellMarginTop)
6238 		values->topMargin = newValues->topMargin;
6239 	if (mask & XmLGridCellRowSpan)
6240 		values->rowSpan = newValues->rowSpan;
6241 	if (mask & XmLGridCellTopBorderColor)
6242 		values->topBorderColor = newValues->topBorderColor;
6243 	if (mask & XmLGridCellTopBorderType)
6244 		values->topBorderType = newValues->topBorderType;
6245 	if (mask & XmLGridCellType)
6246 		{
6247 		values->type = newValues->type;
6248 		/* backwards compatibility cell types */
6249 		if (values->type == XmLABEL_CELL)
6250 			{
6251 			values->type = XmSTRING_CELL;
6252 			values->editable = False;
6253 			}
6254 		else if (values->type == XmTEXT_CELL)
6255 			{
6256 			values->type = XmSTRING_CELL;
6257 			values->editable = True;
6258 			}
6259 		}
6260 	if (mask & XmLGridCellUserData)
6261 		values->userData = newValues->userData;
6262 	}
6263 
6264 static int
SetCellRefValuesCompare(void * userData,void ** item1,void ** item2)6265 SetCellRefValuesCompare(void *userData,
6266 			void **item1,
6267 			void **item2)
6268 	{
6269 	XmLGridCell cell1, cell2;
6270 	XmLGridCellRefValues *values1, *values2;
6271 	long mask;
6272 
6273 	mask = *((long *)userData);
6274 	cell1 = (XmLGridCell)*item1;
6275 	cell2 = (XmLGridCell)*item2;
6276 	values1 = XmLGridCellGetRefValues(cell1);
6277 	values2 = XmLGridCellGetRefValues(cell2);
6278 	if (values1 == values2)
6279 		return 0;
6280 
6281 #define RVCOMPARE(res, var) \
6282 	if (!(mask & res)) \
6283 		{ \
6284 		if (values1->var < values2->var) \
6285 			return -1; \
6286 		if (values1->var > values2->var) \
6287 			return 1; \
6288 		}
6289 	RVCOMPARE(XmLGridCellAlignment, alignment)
6290 	RVCOMPARE(XmLGridCellBackground, background)
6291 	RVCOMPARE(XmLGridCellBottomBorderColor, bottomBorderColor)
6292 	RVCOMPARE(XmLGridCellBottomBorderType, bottomBorderType)
6293 	RVCOMPARE(XmLGridCellColumnSpan, columnSpan)
6294 	RVCOMPARE(XmLGridCellEditable, editable)
6295 	RVCOMPARE(XmLGridCellFontList, fontList)
6296 	RVCOMPARE(XmLGridCellForeground, foreground)
6297 	RVCOMPARE(XmLGridCellLeftBorderColor, leftBorderColor)
6298 	RVCOMPARE(XmLGridCellLeftBorderType, leftBorderType)
6299 	RVCOMPARE(XmLGridCellMarginBottom, bottomMargin)
6300 	RVCOMPARE(XmLGridCellMarginLeft, leftMargin)
6301 	RVCOMPARE(XmLGridCellMarginRight, rightMargin)
6302 	RVCOMPARE(XmLGridCellMarginTop, topMargin)
6303 	RVCOMPARE(XmLGridCellRightBorderColor, rightBorderColor)
6304 	RVCOMPARE(XmLGridCellRightBorderType, rightBorderType)
6305 	RVCOMPARE(XmLGridCellRowSpan, rowSpan)
6306 	RVCOMPARE(XmLGridCellTopBorderColor, topBorderColor)
6307 	RVCOMPARE(XmLGridCellTopBorderType, topBorderType)
6308 	RVCOMPARE(XmLGridCellType, type)
6309 	RVCOMPARE(XmLGridCellUserData, userData)
6310 #undef RVCOMPARE
6311 
6312 	/* If the two cell values are equal, we merge them
6313 	   into one record here.  This speeds up the sort
6314   	   and will allow the merge to compare just the values
6315 	   pointers to test equality. Note that this will not
6316 	   merge every possible item that could be merged, we
6317 	   don't want to do that because of the performance impact */
6318 	if (values1 < values2)
6319 		XmLGridCellSetRefValues(cell1, values2);
6320 	else
6321 		XmLGridCellSetRefValues(cell2, values1);
6322 	return 0;
6323 	}
6324 
6325 static void
SetCellRefValuesPreprocess(XmLGridWidget g,int row,int col,XmLGridCell cell,long mask)6326 SetCellRefValuesPreprocess(XmLGridWidget g,
6327 			   int row,
6328 			   int col,
6329 			   XmLGridCell cell,
6330 			   long mask)
6331 	{
6332 	int r, c, rowSpan, colSpan;
6333 	XmLGridCell spanCell;
6334 	XmLGridCellRefValues *oldValues, *newValues;
6335 	unsigned char oldType, newType;
6336 	XmLGridCallbackStruct cbs;
6337 
6338 	if (mask & XmLGridCellType)
6339 		{
6340 		oldType = XmLGridCellGetRefValues(cell)->type;
6341 		newType = g->grid.cellValues.type;
6342 		if (oldType != newType)
6343 			{
6344 			cbs.reason = XmCR_FREE_VALUE;
6345 			XmLGridCellAction(cell, (Widget)g, &cbs);
6346 			}
6347 		}
6348 	if (mask & XmLGridCellRowSpan || mask & XmLGridCellColumnSpan)
6349 		{
6350 		/* expose old cell area in case the span area shrinks */
6351 		DrawArea(g, DrawCell, row, col);
6352 		oldValues = XmLGridCellGetRefValues(cell);
6353 		newValues = &g->grid.cellValues;
6354 		if (mask & XmLGridCellRowSpan)
6355 			{
6356 			g->grid.mayHaveRowSpans = 1;
6357 			if (newValues->rowSpan < 0)
6358 				{
6359 				XmLWarning((Widget)g,
6360 					"SetValues() - row span can't be < 0");
6361 				newValues->rowSpan = 0;
6362 				}
6363 			rowSpan = newValues->rowSpan;
6364 			}
6365 		else
6366 			rowSpan = oldValues->rowSpan;
6367 		if (mask & XmLGridCellColumnSpan)
6368 			{
6369 			if (newValues->columnSpan < 0)
6370 				{
6371 				XmLWarning((Widget)g,
6372 					"SetValues() - column span can't be < 0");
6373 				newValues->columnSpan = 0;
6374 				}
6375 			colSpan = newValues->columnSpan;
6376 			}
6377 		else
6378 			colSpan = oldValues->columnSpan;
6379 		/* clear old span */
6380 		for (c = col; c <= col + oldValues->columnSpan; c++)
6381 			for (r = row; r <= row + oldValues->rowSpan; r++)
6382 				{
6383 				/* skip the cell itself */
6384 				if (c == col && r == row)
6385 					continue;
6386 				spanCell = GetCell(g, r, c);
6387 				if (!spanCell)
6388 					continue;
6389 				XmLGridCellSetInRowSpan(spanCell, False);
6390 				XmLGridCellSetInColumnSpan(spanCell, False);
6391 				}
6392 		/* set new span */
6393 		for (c = col; c <= col + colSpan; c++)
6394 			for (r = row; r <= row + rowSpan; r++)
6395 				{
6396 				/* skip the cell itself */
6397 				if (c == col && r == row)
6398 					continue;
6399 				spanCell = GetCell(g, r, c);
6400 				if (!spanCell)
6401 					continue;
6402 				if (r == row)
6403 					XmLGridCellSetInColumnSpan(spanCell, True);
6404 				else
6405 					XmLGridCellSetInRowSpan(spanCell, True);
6406 				}
6407 		}
6408 	}
6409 
6410 /*
6411    Read, Write, Copy, Paste
6412 */
6413 
6414 static int
Read(XmLGridWidget g,int format,char delimiter,int row,int col,char * data)6415 Read(XmLGridWidget g,
6416      int format,
6417      char delimiter,
6418      int row,
6419      int col,
6420      char *data)
6421 	{
6422 	char *c1, *c2, buf[256], *bufp;
6423 	int r, c, i, j, len, n, needsResize, allowSet, done;
6424 	XmString str;
6425 	XmLGridCell cell;
6426 	XmLGridRow rowp;
6427 	XmLGridColumn colp;
6428 	XmLGridCellRefValues *cellValues;
6429 	XmLGridCallbackStruct cbs;
6430 
6431 	if (format == XmFORMAT_PAD)
6432 		{
6433 		XmLWarning((Widget)g, "Read() - FORMAT_PAD not supported");
6434 		return 0;
6435 		}
6436 	if (format == XmFORMAT_XL ||
6437 		format == XmFORMAT_DROP ||
6438 		format == XmFORMAT_PASTE)
6439 		delimiter = '\t';
6440 	c1 = data;
6441 	c2 = data;
6442 	r = row;
6443 	c = col;
6444 	needsResize = 0;
6445 	done = 0;
6446 	n = 0;
6447 	while (!done)
6448 		{
6449 		if (!(*c2) || *c2 == delimiter || *c2 == '\n')
6450 			{
6451 			len = c2 - c1;
6452 			if (len < 256)
6453 				bufp = buf;
6454 			else
6455 				bufp = (char *)malloc(len + 1);
6456 			if (format == XmFORMAT_XL)
6457 				{
6458 				/* strip leading and trailing double-quotes */
6459 				if (len && c1[0] == '"')
6460 					{
6461 					c1++;
6462 					len--;
6463 					}
6464 				if (len && c1[len - 1] == '"')
6465 					len--;
6466 				}
6467 			j = 0;
6468 			for (i = 0; i < len; i++)
6469 				{
6470 				if (c1[0] == '\\' && c1[1] == 'n')
6471 					{
6472 					bufp[j++] = '\n';
6473 					c1 += 2;
6474 					i++;
6475 					}
6476 				else
6477 					bufp[j++] = *c1++;
6478 				}
6479 			bufp[j] = 0;
6480 			j = 0;
6481 			str = XmStringCreateLtoR(bufp, XmSTRING_DEFAULT_CHARSET);
6482 			if (bufp != buf)
6483 				free((char *)bufp);
6484 			rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
6485 			colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
6486 			cell = GetCell(g, r, c);
6487 			allowSet = 1;
6488 			if (cell && (format == XmFORMAT_PASTE || format == XmFORMAT_DROP))
6489 				{
6490 				cellValues = XmLGridCellGetRefValues(cell);
6491 				if (cellValues->type != XmSTRING_CELL ||
6492 					cellValues->editable != True ||
6493 					RowPosToType(g, r) != XmCONTENT ||
6494 					ColPosToType(g, c) != XmCONTENT)
6495 					allowSet = 0;
6496 				}
6497 			if (cell && allowSet)
6498 				{
6499 				XmLGridCellSetString(cell, str, False);
6500 				if (SetCellValuesResize(g, rowp, colp, cell, XmLGridCellString))
6501 					needsResize = 1;
6502 				if (!needsResize)
6503 					DrawArea(g, DrawCell, r, c);
6504 				cbs.columnType = ColPosToType(g, c);
6505 				cbs.column = ColPosToTypePos(g, cbs.columnType, c);
6506 				cbs.rowType = RowPosToType(g, r);
6507 				cbs.row = RowPosToTypePos(g, cbs.rowType, r);
6508 				if (format == XmFORMAT_PASTE)
6509 					{
6510 					cbs.reason = XmCR_CELL_PASTE;
6511 					XtCallCallbackList((Widget)g, g->grid.cellPasteCallback,
6512 						(XtPointer)&cbs);
6513 					}
6514 				else if (format == XmFORMAT_DROP)
6515 					{
6516 					cbs.reason = XmCR_CELL_DROP;
6517 					XtCallCallbackList((Widget)g, g->grid.cellDropCallback,
6518 						(XtPointer)&cbs);
6519 					}
6520 				n++;
6521 				}
6522 			else
6523 				XmStringFree(str);
6524 			}
6525 		if (!(*c2))
6526 			done = 1;
6527 		else if (*c2 == delimiter)
6528 			{
6529 			c++;
6530 			c1 = c2 + 1;
6531 			}
6532 		else if (*c2 == '\n')
6533 			{
6534 			r++;
6535 			c = col;
6536 			c1 = c2 + 1;
6537 			}
6538 		c2++;
6539 		}
6540 	if (needsResize)
6541 		{
6542 		VertLayout(g, 1);
6543 		HorizLayout(g, 1);
6544 		DrawArea(g, DrawAll, 0, 0);
6545 		}
6546 	return n;
6547 	}
6548 
6549 static void
Write(XmLGridWidget g,FILE * file,int format,char delimiter,Boolean skipHidden,int row,int col,int nrow,int ncol)6550 Write(XmLGridWidget g,
6551       FILE *file,
6552       int format,
6553       char delimiter,
6554       Boolean skipHidden,
6555       int row,
6556       int col,
6557       int nrow,
6558       int ncol)
6559 	{
6560 	int r, c, i, first, last;
6561 	char *cs = NULL;
6562 	Boolean set;
6563 	XmString str;
6564 	XmLGridColumn colp;
6565 	XmLGridRow rowp;
6566 	XmLGridCell cell;
6567 
6568 	first = 1;
6569 	for (r = row; r < row + nrow; r++)
6570 		{
6571 		rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
6572 		if (!rowp)
6573 			continue;
6574 		if (skipHidden == True && XmLGridRowIsHidden(rowp) == True)
6575 			continue;
6576 		if (first)
6577 			first = 0;
6578 		else
6579 			fprintf(file, "\n");
6580 		for (c = col; c < col + ncol; c++)
6581 			{
6582 			colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
6583 			if (!colp)
6584 				continue;
6585 			if (skipHidden == True && XmLGridColumnIsHidden(colp) == True)
6586 				continue;
6587 			cell = GetCell(g, r, c);
6588 			if (!cell)
6589 				continue;
6590 			str = XmLGridCellGetString(cell);
6591 			set = False;
6592 			if (str)
6593 				{
6594 				cs = CvtXmStringToStr(str);
6595 				if (cs)
6596 					set = True;
6597 				}
6598 			if (set == False)
6599 				cs = "";
6600 			fprintf(file, "%s", cs);
6601 
6602 			last = 0;
6603 			if (c == col + ncol - 1)
6604 				last = 1;
6605 			if (!last && format == XmFORMAT_DELIMITED)
6606 				fprintf(file, "%c", delimiter);
6607 			else if (!last && format == XmFORMAT_XL)
6608 				fprintf(file, "\t");
6609 			else if (format == XmFORMAT_PAD)
6610 				{
6611 				if (colp->grid.sizePolicy == XmVARIABLE)
6612 					for (i = 0; i < (int)(colp->grid.width - strlen(cs)); i++)
6613 						fprintf(file, " ");
6614 				}
6615 
6616 			if (set == True)
6617 				free(cs);
6618 			}
6619 		}
6620 	}
6621 
6622 static char *
CopyDataCreate(XmLGridWidget g,int selected,int row,int col,int nrow,int ncol)6623 CopyDataCreate(XmLGridWidget g, int selected, int row, int col, int nrow, int ncol)
6624 	{
6625 	XmLGridColumn colp;
6626 	XmLGridRow rowp;
6627 	XmLGridCell cell;
6628 	char *buf, *cs = NULL;
6629 	XmString str;
6630 	Boolean set;
6631 	int r, c, wroteStr, bufsize, buflen, len;
6632 
6633 	if (selected)
6634 		{
6635 		row = 0;
6636 		nrow = XmLArrayGetCount(g->grid.rowArray);
6637 		col = 0;
6638 		ncol = XmLArrayGetCount(g->grid.colArray);
6639 		}
6640 	bufsize = 1024;
6641 	buflen = 0;
6642 	buf = (char *)malloc(bufsize);
6643 
6644 	for (r = row; r < row + nrow; r++)
6645 		{
6646 		wroteStr = 0;
6647 		rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
6648 		if (!rowp)
6649 			continue;
6650 		for (c = col; c < col + ncol; c++)
6651 			{
6652 			colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
6653 			if (!colp)
6654 				continue;
6655 			cell = GetCell(g, r, c);
6656 			if (!cell)
6657 				continue;
6658 			if (selected &&
6659 				XmLGridRowIsSelected(rowp) == False &&
6660 				XmLGridColumnIsSelected(colp) == False &&
6661 				XmLGridCellIsSelected(cell) == False)
6662 				continue;
6663 			str = XmLGridCellGetString(cell);
6664 			set = False;
6665 			if (str)
6666 				{
6667 				cs = CvtXmStringToStr(str);
6668 				if (cs)
6669 					set = True;
6670 				}
6671 			if (set == False)
6672 				cs = "";
6673 			if (wroteStr)
6674 				buf[buflen++] = '\t';
6675 
6676 			len = strlen(cs);
6677 			/* allocate if string plus tab plus new-line plus 0 if too large */
6678 			while (len + buflen + 3 > bufsize)
6679 				bufsize *= 2;
6680 			buf = (char *)realloc(buf, bufsize);
6681 			strcpy(&buf[buflen], cs);
6682 			buflen += len;
6683 			if (set == True)
6684 				free(cs);
6685 			wroteStr = 1;
6686 			}
6687 		if (wroteStr)
6688 			buf[buflen++] = '\n';
6689 		}
6690 	if (!buflen)
6691 		{
6692 		free((char *)buf);
6693 		return 0;
6694 		}
6695 	buf[buflen - 1] = 0;
6696 	return buf;
6697 	}
6698 
6699 static Boolean
Copy(XmLGridWidget g,Time time,int selected,int row,int col,int nrow,int ncol)6700 Copy(XmLGridWidget g,
6701      Time time,
6702      int selected,
6703      int row,
6704      int col,
6705      int nrow,
6706      int ncol)
6707 	{
6708 	int i;
6709 	long itemID;
6710 	Display *dpy;
6711 	Window win;
6712 	XmString clipStr;
6713 	char *buf;
6714 #ifdef MOTIF11
6715 	int dataID;
6716 #else
6717 	long ldataID;
6718 #endif
6719 
6720 	if (!XtIsRealized((Widget)g))
6721 		{
6722 		XmLWarning((Widget)g, "Copy() - widget not realized");
6723 		return False;
6724 		}
6725 	dpy = XtDisplay((Widget)g);
6726 	win = XtWindow((Widget)g);
6727 	buf = CopyDataCreate(g, selected, row, col, nrow, ncol);
6728 	if (!buf)
6729 		return False;
6730 	clipStr = XmStringCreateSimple("Grid Copy");
6731 	for (i = 0; i < 10000; i++)
6732 		if (XmClipboardStartCopy(dpy, win, clipStr, time, NULL,
6733 			NULL, &itemID) == ClipboardSuccess)
6734 			break;
6735 	XmStringFree(clipStr);
6736 	if (i == 10000)
6737 		{
6738 		XmLWarning((Widget)g, "Copy() - start clipboard copy failed");
6739 		return False;
6740 		}
6741 	for (i = 0; i < 10000; i++)
6742 #ifdef MOTIF11
6743 		if (XmClipboardCopy(dpy, win, itemID, "STRING", buf,
6744 			(long)strlen(buf) + 1, 0, &dataID) == ClipboardSuccess)
6745 #else
6746 		if (XmClipboardCopy(dpy, win, itemID, "STRING", buf,
6747 			(long)strlen(buf) + 1, 0, &ldataID) == ClipboardSuccess)
6748 #endif
6749 			break;
6750 	free((char *)buf);
6751 	if (i == 10000)
6752 		{
6753 		XmLWarning((Widget)g, "Copy() - clipboard copy transfer failed");
6754 		return False;
6755 		}
6756 	for (i = 0; i < 10000; i++)
6757 		if (XmClipboardEndCopy(dpy, win, itemID) == ClipboardSuccess)
6758 			break;
6759 	if (i == 10000)
6760 		{
6761 		XmLWarning((Widget)g, "Copy() - end clipboard copy failed");
6762 		return False;
6763 		}
6764 	return True;
6765 	}
6766 
6767 static Boolean
Paste(XmLGridWidget g,int row,int col)6768 Paste(XmLGridWidget g,
6769       int row,
6770       int col)
6771 	{
6772 	Display *dpy;
6773 	Window win;
6774 	int i, res, done;
6775 	unsigned long len, reclen;
6776 	char *buf;
6777 
6778 	if (!XtIsRealized((Widget)g))
6779 		{
6780 		XmLWarning((Widget)g, "Paste() - widget not realized");
6781 		return False;
6782 		}
6783 	dpy = XtDisplay((Widget)g);
6784 	win = XtWindow((Widget)g);
6785 	for (i = 0; i < 10000; i++)
6786 		if (XmClipboardInquireLength(dpy, win, "STRING", &len) ==
6787 			ClipboardSuccess)
6788 			break;
6789 	if (i == 10000)
6790 		{
6791 		XmLWarning((Widget)g, "Paste() - can't retrieve clipboard length");
6792 		return False;
6793 		}
6794 	if (!len)
6795 		return False;
6796 	buf = (char *)malloc((int)len);
6797 	done = 0;
6798 	while (!done)
6799 		{
6800 		res = XmClipboardRetrieve(dpy, win, "STRING", buf, len,
6801 			&reclen, NULL);
6802 		switch (res)
6803 			{
6804 			case ClipboardSuccess:
6805 				done = 2;
6806 				break;
6807 			case ClipboardTruncate:
6808 			case ClipboardNoData:
6809 				done = 1;
6810 				break;
6811 			case ClipboardLocked:
6812 				break;
6813 			}
6814 		}
6815 	if (done != 2 || reclen != len)
6816 		{
6817 		free((char *)buf);
6818 		XmLWarning((Widget)g, "Paste() - retrieve from clipboard failed");
6819 		return False;
6820 		}
6821 	Read(g, XmFORMAT_PASTE, 0, row, col, buf);
6822 	free((char *)buf);
6823 	return True;
6824 	}
6825 
6826 /*
6827    Utility
6828 */
6829 
6830 static void
GetCoreBackground(Widget w,int offset,XrmValue * value)6831 GetCoreBackground(Widget w,
6832 		  int offset,
6833 		  XrmValue *value)
6834 	{
6835 	value->addr = (caddr_t)&w->core.background_pixel;
6836 	}
6837 
6838 static void
GetManagerForeground(Widget w,int offset,XrmValue * value)6839 GetManagerForeground(Widget w,
6840 		     int offset,
6841 		     XrmValue *value)
6842 	{
6843 	XmLGridWidget g;
6844 
6845 	g = (XmLGridWidget)w;
6846 	value->addr = (caddr_t)&g->manager.foreground;
6847 	}
6848 
6849 static void
ClipRectToReg(XmLGridWidget g,XRectangle * rect,GridReg * reg)6850 ClipRectToReg(XmLGridWidget g,
6851 	      XRectangle *rect,
6852 	      GridReg *reg)
6853 	{
6854 	int i, st;
6855 	XRectangle regRect;
6856 
6857 	st = g->manager.shadow_thickness;
6858 	if (!reg->width || !reg->height)
6859 		i = XmLRectOutside;
6860 	else
6861 		{
6862 		regRect.x = reg->x + st;
6863 		regRect.y = reg->y + st;
6864 		regRect.width = reg->width - st * 2;
6865 		regRect.height = reg->height - st * 2;
6866 		i = XmLRectIntersect(rect, &regRect);
6867 		}
6868 	if (i == XmLRectInside)
6869 		return;
6870 	if (i == XmLRectOutside)
6871 		{
6872 		rect->width = 0;
6873 		rect->height = 0;
6874 		return;
6875 		}
6876 	if (rect->y + (int)rect->height - 1 >= reg->y + (int)reg->height - st)
6877 		rect->height = reg->y + reg->height - rect->y - st;
6878 	if (rect->x + (int)rect->width - 1 >= reg->x + (int)reg->width - st)
6879 		rect->width = reg->x + reg->width - rect->x - st;
6880 	if (rect->y < reg->y + st)
6881 		{
6882 		rect->height -= (reg->y + st) - rect->y;
6883 		rect->y = reg->y + st;
6884 		}
6885 	if (rect->x < reg->x + st)
6886 		{
6887 		rect->width -= (reg->x + st) - rect->x;
6888 		rect->x = reg->x + st;
6889 		}
6890 	}
6891 
6892 static char *
FileToString(FILE * file)6893 FileToString(FILE *file)
6894 	{
6895 	long len, n;
6896 	char *s;
6897 
6898 	if (!file)
6899 		return 0;
6900 	fseek(file, 0L, 2);
6901 	len = ftell(file);
6902 	s = (char *)malloc((int)len + 1);
6903 	if (!s)
6904 		return 0;
6905 	s[len] = 0;
6906 	fseek(file, 0L, 0);
6907 	n = fread(s, 1, (int)len, file);
6908 	if (n != len)
6909 		{
6910 		free((char *)s);
6911 		return 0;
6912 		}
6913 	return s;
6914 	}
6915 
6916 static char *
CvtXmStringToStr(XmString str)6917 CvtXmStringToStr(XmString str)
6918 	{
6919 	XmStringContext context;
6920 	XmStringCharSet charset;
6921 	XmStringDirection dir;
6922 	Boolean sep;
6923 	char *text, *c;
6924 	int len, size;
6925 
6926 	if (!XmStringInitContext(&context, str))
6927 		return 0;
6928 	size = 0;
6929 	c = 0;
6930 	while (XmStringGetNextSegment(context, &text, &charset, &dir, &sep))
6931 		{
6932 		len = strlen(text);
6933 		size += len + 3;
6934 		if (!c)
6935 			{
6936 			c = (char *)malloc(size);
6937 			*c = 0;
6938 			}
6939 		else
6940 			c = (char *)realloc(c, size);
6941 		strcat(c, text);
6942 		if (sep == True)
6943 			{
6944 			len = strlen(c);
6945 			c[len] = '\\';
6946 			c[len + 1] = 'n';
6947 			c[len + 2] = 0;
6948 			}
6949 		XtFree(text);
6950 		XtFree(charset);
6951 		}
6952 	XmStringFreeContext(context);
6953 	return c;
6954 	}
6955 
6956 static XmLGridWidget
WidgetToGrid(Widget w,char * funcname)6957 WidgetToGrid(Widget w,
6958 	     char *funcname)
6959 	{
6960 	char buf[256];
6961 
6962 	if (!XmLIsGrid(w))
6963 		{
6964 		sprintf(buf, "%s - widget not an XmLGrid", funcname);
6965 		XmLWarning(w, buf);
6966 		return 0;
6967 		}
6968 	return (XmLGridWidget)w;
6969 	}
6970 
6971 /*
6972    Actions, Callbacks and Handlers
6973 */
6974 
6975 static void
ButtonMotion(Widget w,XEvent * event,String * params,Cardinal * nparam)6976 ButtonMotion(Widget w,
6977 	     XEvent *event,
6978 	     String *params,
6979 	     Cardinal *nparam)
6980 	{
6981 	XmLGridWidget g;
6982 	XMotionEvent *me;
6983 	char dragTimerSet;
6984 	int row, col, x, y;
6985 
6986 	if (event->type != MotionNotify)
6987 		return;
6988 	g = (XmLGridWidget)w;
6989 	me = (XMotionEvent *)event;
6990 	if (g->grid.inMode == InResize)
6991 		{
6992 		if (g->grid.resizeIsVert)
6993 			DrawResizeLine(g, me->y, 0);
6994 		else
6995             {
6996 			DrawResizeLine(g, me->x, 0);
6997             if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
6998                 ResizeColumnToFit(g, me->x);
6999             }
7000 		}
7001 
7002 	/* drag scrolling */
7003 	dragTimerSet = 0;
7004 	if (g->grid.inMode == InSelect)
7005 		{
7006 		if (g->grid.vsPolicy == XmCONSTANT)
7007 			{
7008 			y = g->grid.reg[4].y;
7009 			if (g->grid.selectionPolicy == XmSELECT_CELL &&
7010 				g->grid.extendRow != -1 &&
7011 				g->grid.extendCol != -1 &&
7012 				RowPosToType(g, g->grid.extendRow) == XmHEADING)
7013 				;
7014 			else if (me->y < y)
7015 				dragTimerSet |= DragUp;
7016 			y += g->grid.reg[4].height;
7017 			if (me->y > y)
7018 				dragTimerSet |= DragDown;
7019 			}
7020 		if (g->grid.hsPolicy == XmCONSTANT)
7021 			{
7022 			x = g->grid.reg[4].x;
7023 			if (g->grid.selectionPolicy == XmSELECT_CELL &&
7024 				g->grid.extendCol != -1 &&
7025 				g->grid.extendRow != -1 &&
7026 				ColPosToType(g, g->grid.extendCol) == XmHEADING)
7027 				;
7028 			else if (me->x < x)
7029 				dragTimerSet |= DragLeft;
7030 			x += g->grid.reg[4].width;
7031 			if (me->x > x)
7032 				dragTimerSet |= DragRight;
7033 			}
7034 		}
7035 	if (!g->grid.dragTimerSet && dragTimerSet)
7036 		g->grid.dragTimerId = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
7037 			80, DragTimer, (caddr_t)g);
7038 	else if (g->grid.dragTimerSet && !dragTimerSet)
7039 		XtRemoveTimeOut(g->grid.dragTimerId);
7040 	g->grid.dragTimerSet = dragTimerSet;
7041 
7042 	/* Extend Selection */
7043 	if (g->grid.inMode == InSelect && XYToRowCol(g, me->x, me->y,
7044 		&row, &col) != -1)
7045 		{
7046 		TextAction(g, TEXT_EDIT_CANCEL);
7047 		if (g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW &&
7048 			RowPosToType(g, row) == XmCONTENT)
7049 			ExtendSelect(g, event, False, row, col);
7050 		else if (g->grid.selectionPolicy == XmSELECT_CELL)
7051 			ExtendSelect(g, event, False, row, col);
7052 		}
7053 
7054 	if (g->grid.inMode == InSelect &&
7055 		g->grid.selectionPolicy == XmSELECT_BROWSE_ROW &&
7056 		XYToRowCol(g, me->x, me->y, &row, &col) != -1)
7057 		{
7058 		if (RowPosToType(g, row) == XmCONTENT)
7059 			{
7060 			if (!SetFocus(g, row, col, 0, 1))
7061 				SelectTypeArea(g, SelectRow, event,
7062 					RowPosToTypePos(g, XmCONTENT,
7063 					g->grid.focusRow), 0, True, True);
7064 			}
7065 		}
7066 	}
7067 
7068 static void
DragTimer(XtPointer clientData,XtIntervalId * intervalId)7069 DragTimer(XtPointer clientData,
7070 	  XtIntervalId *intervalId)
7071 	{
7072 	Widget w;
7073 	XmLGridWidget g;
7074 	XRectangle rect;
7075 	XmLGridRow rowp;
7076 	XmLGridColumn colp;
7077 	int r, c, min, max, inc, pi, ss, value, newValue;
7078 	int extRow, extCol;
7079 
7080 	g = (XmLGridWidget)clientData;
7081 	w = (Widget)g;
7082 	extRow = -1;
7083 	extCol = -1;
7084 	if (g->grid.vsPolicy == XmCONSTANT && ((g->grid.dragTimerSet & DragUp) ||
7085 		(g->grid.dragTimerSet & DragDown)))
7086 		{
7087 		XtVaGetValues(g->grid.vsb,
7088 			XmNminimum, &min,
7089 			XmNmaximum, &max,
7090 			XmNvalue, &value,
7091 			XmNsliderSize, &ss,
7092 			XmNincrement, &inc,
7093 			XmNpageIncrement, &pi,
7094 			NULL);
7095 		newValue = value;
7096 		if (g->grid.dragTimerSet & DragUp)
7097 			newValue--;
7098 		else
7099 			newValue++;
7100 		if (newValue != value && newValue >= min && newValue <= (max - ss))
7101 			{
7102 			XmScrollBarSetValues(g->grid.vsb, newValue, ss, inc, pi, True);
7103 			r = g->grid.reg[4].row;
7104 			if (g->grid.dragTimerSet & DragDown)
7105 				r += g->grid.reg[4].nrow - 1;
7106 			/* simple check to make sure row selected is totally visible */
7107 			if (g->grid.reg[4].nrow)
7108 				{
7109 				rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
7110 				if (rowp && !RowColToXY(g, r, 0, True, &rect))
7111 					{
7112 					if (GetRowHeight(g, r) != rect.height)
7113 						r--;
7114 					}
7115 				}
7116 			if (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW)
7117 				{
7118 				if (!SetFocus(g, r, g->grid.focusCol, -1, 1))
7119 					SelectTypeArea(g, SelectRow, (XEvent *)0,
7120 						RowPosToTypePos(g, XmCONTENT, g->grid.focusRow),
7121 						0, True, True);
7122 				}
7123 			else if (g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW)
7124 				ExtendSelect(g, (XEvent *)0, False, r, g->grid.focusCol);
7125 			else if (g->grid.selectionPolicy == XmSELECT_CELL)
7126 				{
7127 				extRow = r;
7128 				extCol = g->grid.extendToCol;
7129 				}
7130 			}
7131 		}
7132 	if (g->grid.hsPolicy == XmCONSTANT && ((g->grid.dragTimerSet & DragLeft) ||
7133 		(g->grid.dragTimerSet & DragRight)))
7134 		{
7135 		XtVaGetValues(g->grid.hsb,
7136 			XmNminimum, &min,
7137 			XmNmaximum, &max,
7138 			XmNvalue, &value,
7139 			XmNsliderSize, &ss,
7140 			XmNincrement, &inc,
7141 			XmNpageIncrement, &pi,
7142 			NULL);
7143 		newValue = value;
7144 		if (g->grid.dragTimerSet & DragLeft)
7145 			newValue--;
7146 		else
7147 			newValue++;
7148 		if (newValue != value && newValue >= min && newValue <= (max - ss))
7149 			{
7150 			XmScrollBarSetValues(g->grid.hsb, newValue, ss, inc, pi, True);
7151 			c = g->grid.reg[4].col;
7152 			if (g->grid.dragTimerSet & DragRight)
7153 				c += g->grid.reg[4].ncol - 1;
7154 			if (g->grid.selectionPolicy == XmSELECT_CELL)
7155 				{
7156 				/* simple check to make sure col selected is totally visible */
7157 				if (g->grid.reg[4].ncol)
7158 					{
7159 					colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
7160 					if (colp && !RowColToXY(g, c, 0, True, &rect))
7161 						{
7162 						if (GetColWidth(g, c) != rect.width)
7163 							c--;
7164 						}
7165 					}
7166 				if (extRow == -1)
7167 					extRow = g->grid.extendToRow;
7168 				extCol = c;
7169 				}
7170 			}
7171 		}
7172 	if (extRow != -1 && extCol != -1)
7173 		ExtendSelect(g, (XEvent *)0, False, extRow, extCol);
7174 	g->grid.dragTimerId = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
7175 		80, DragTimer, (caddr_t)g);
7176 	}
7177 
7178 /*----------------------------------------------------------------------*/
7179 static void
CursorMotion(Widget w,XEvent * event,String * params,Cardinal * nparam)7180 CursorMotion(Widget w,
7181 			 XEvent *event,
7182 			 String *params,
7183 			 Cardinal *nparam)
7184 {
7185 	XmLGridWidget g;
7186 	XMotionEvent *me;
7187 	int isVert, row, col;
7188 	char defineCursor;
7189 
7190 	if (event->type != MotionNotify)
7191 		return;
7192 	g = (XmLGridWidget)w;
7193 	me = (XMotionEvent *)event;
7194 	defineCursor = CursorNormal;
7195 
7196 	{
7197 		int motionRow;
7198 		int motionCol;
7199 		int newMotionRow = -1;
7200 		int newMotionCol = -1;
7201 		Boolean invokeEnterCellCallback = False;
7202 
7203 		if (XYToRowCol(g,me->x,me->y,&motionRow,&motionCol) != -1)
7204 		{
7205 			if (motionRow != g->grid.lastCursorMotionRow ||
7206 				motionCol != g->grid.lastCursorMotionCol)
7207 			{
7208 				newMotionRow = motionRow;
7209 				newMotionCol = motionCol;
7210 
7211 				invokeEnterCellCallback = True;
7212 			}
7213 		}
7214 
7215 		if (g->grid.lastCursorMotionRow != -1 &&
7216 			g->grid.lastCursorMotionCol != -1)
7217 		{
7218 			/* Invoke XmNleaveCellCallback */
7219 			GridInvokeCellCrossingCallbacks(w,
7220 											g->grid.leaveCellCallback,
7221 											XmCR_LEAVE_CELL,
7222 											event,
7223 											g->grid.lastCursorMotionRow,
7224 											g->grid.lastCursorMotionCol);
7225 		}
7226 
7227 		if (invokeEnterCellCallback)
7228 		{
7229 			/* Invoke XmNenterCellCallback */
7230 			GridInvokeCellCrossingCallbacks(w,
7231 											g->grid.enterCellCallback,
7232 											XmCR_ENTER_CELL,
7233 											event,
7234 											newMotionRow,
7235 											newMotionCol);
7236 		}
7237 
7238 		g->grid.lastCursorMotionRow = newMotionRow;
7239 		g->grid.lastCursorMotionCol = newMotionCol;
7240 	}
7241 
7242 	if (PosIsResize(g, me->x, me->y, &row, &col, &isVert))
7243 	{
7244 		if (isVert)
7245 			defineCursor = CursorVResize;
7246 		else
7247 			defineCursor = CursorHResize;
7248 	}
7249 
7250 	DefineCursor(g, defineCursor);
7251 }
7252 /*----------------------------------------------------------------------*/
7253 static void
Edit(Widget w,XEvent * event,String * params,Cardinal * nparam)7254 Edit(Widget w,
7255      XEvent *event,
7256      String *params,
7257      Cardinal *nparam)
7258 	{
7259 	XmLGridWidget g;
7260 
7261 	g = (XmLGridWidget)XtParent(w);
7262 	TextAction(g, TEXT_EDIT_INSERT);
7263 	}
7264 
7265 static void
EditCancel(Widget w,XEvent * event,String * params,Cardinal * nparam)7266 EditCancel(Widget w,
7267 	   XEvent *event,
7268 	   String *params,
7269 	   Cardinal *nparam)
7270 	{
7271 	XmLGridWidget g;
7272 
7273 	g = (XmLGridWidget)XtParent(w);
7274 	TextAction(g, TEXT_EDIT_CANCEL);
7275 	}
7276 
7277 static void
EditComplete(Widget w,XEvent * event,String * params,Cardinal * nparam)7278 EditComplete(Widget w,
7279 	     XEvent *event,
7280 	     String *params,
7281 	     Cardinal *nparam)
7282 	{
7283 	XmLGridWidget g;
7284 
7285 	g = (XmLGridWidget)XtParent(w);
7286 	TextAction(g, TEXT_EDIT_COMPLETE);
7287 	if (*nparam == 1)
7288 		Traverse(w, event, params, nparam);
7289 	}
7290 
7291 #ifndef MOTIF11
7292 extern Widget _XmGetTextualDragIcon(Widget);
7293 #endif
7294 
7295 static void
DragStart(Widget w,XEvent * event,String * params,Cardinal * nparam)7296 DragStart(Widget w,
7297 	  XEvent *event,
7298 	  String *params,
7299 	  Cardinal *nparam)
7300 	{
7301 #ifndef MOTIF11
7302 	XmLGridWidget g;
7303 	Widget dragIcon;
7304 	Atom exportTargets[1];
7305 	Arg args[10];
7306 	char *data;
7307 	XButtonEvent *be;
7308 	int row, col;
7309 	XmLGridColumn colp;
7310 	XmLGridRow rowp;
7311 	XmLGridCell cell;
7312 	static XtCallbackRec dragFinish[2] =
7313 		{ { DragFinish, NULL }, { NULL, NULL } };
7314 
7315 	g = (XmLGridWidget)w;
7316 	be = (XButtonEvent *)event;
7317 	if (!g->grid.allowDrag || !be)
7318 		return;
7319 	if (XYToRowCol(g, be->x, be->y, &row, &col) == -1)
7320 		return;
7321 	rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
7322 	colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
7323 	cell = GetCell(g, row, col);
7324 	if (!rowp || !colp || !cell)
7325 		return;
7326 	if (XmLGridRowIsSelected(rowp) == False &&
7327 		XmLGridColumnIsSelected(colp) == False &&
7328 		XmLGridCellIsSelected(cell) == False)
7329 		return;
7330 	data = CopyDataCreate(g, 1, 0, 0, 0, 0);
7331 	if (!data)
7332 		return;
7333 	dragIcon = _XmGetTextualDragIcon((Widget)w);
7334 	exportTargets[0] = XA_STRING;
7335 	dragFinish[0].closure = (XtPointer)data;
7336 	XtSetArg(args[0], XmNconvertProc, DragConvert);
7337 	XtSetArg(args[1], XmNexportTargets, exportTargets);
7338 	XtSetArg(args[2], XmNnumExportTargets, 1);
7339 	XtSetArg(args[3], XmNdragOperations, XmDROP_COPY);
7340 	XtSetArg(args[4], XmNsourceCursorIcon, dragIcon);
7341 	XtSetArg(args[4], XmNclientData, (XtPointer)data);
7342 	XtSetArg(args[5], XmNdragDropFinishCallback, dragFinish);
7343 	XmDragStart(w, event, args, 6);
7344 #endif
7345 	}
7346 
7347 static Boolean
DragConvert(Widget w,Atom * selection,Atom * target,Atom * type,XtPointer * value,unsigned long * length,int * format)7348 DragConvert(Widget w,
7349 	    Atom *selection,
7350 	    Atom *target,
7351 	    Atom *type,
7352 	    XtPointer *value,
7353 	    unsigned long *length,
7354 	    int *format)
7355 	{
7356 #ifdef MOTIF11
7357 	return FALSE;
7358 #else
7359 	Atom targetsA, timestampA, multipleA, *exportTargets;
7360 	int n;
7361 	char *data, *dataCopy;
7362 
7363 	if (!XmIsDragContext(w))
7364 		return FALSE;
7365 	targetsA = XInternAtom(XtDisplay(w), "TARGETS", FALSE);
7366 	timestampA = XInternAtom(XtDisplay(w), "TIMESTAMP", FALSE);
7367 	multipleA = XInternAtom(XtDisplay(w), "MULTIPLE", FALSE);
7368 	if (*target == targetsA)
7369 		{
7370 		n = 4;
7371 		exportTargets = (Atom *)XtMalloc(sizeof(Atom) * n);
7372 		exportTargets[0] = XA_STRING;
7373 		exportTargets[1] = targetsA;
7374 		exportTargets[2] = multipleA;
7375 		exportTargets[3] = timestampA;
7376 		*type = XA_ATOM;
7377 		*value = (XtPointer)exportTargets;
7378 		*format = 32;
7379 		*length = (n * sizeof(Atom)) >> 2;
7380 		return TRUE;
7381 		}
7382 	else if (*target == XA_STRING)
7383 		{
7384 		XtVaGetValues(w, XmNclientData, &data, NULL);
7385   		*type = XA_STRING;
7386 		dataCopy = XtMalloc(strlen(data));
7387 		strncpy(dataCopy, data, strlen(data));
7388   		*value = (XtPointer)dataCopy;
7389   		*length = strlen(data);
7390   		*format = 8;
7391   		return TRUE;
7392 		}
7393 	return FALSE;
7394 #endif
7395 	}
7396 
7397 static void
DragFinish(Widget w,XtPointer clientData,XtPointer callData)7398 DragFinish(Widget w,
7399 	   XtPointer clientData,
7400 	   XtPointer callData)
7401 	{
7402 	free ((char *)clientData);
7403 	}
7404 
7405 static void
DropRegister(XmLGridWidget g,Boolean set)7406 DropRegister(XmLGridWidget g, Boolean set)
7407 	{
7408 #ifndef MOTIF11
7409 	Atom importTargets[1];
7410 	Arg args[4];
7411 
7412 	if (set == True)
7413 		{
7414 		importTargets[0] = XA_STRING;
7415 		XtSetArg(args[0], XmNdropSiteOperations, XmDROP_COPY);
7416 		XtSetArg(args[1], XmNimportTargets, importTargets);
7417 		XtSetArg(args[2], XmNnumImportTargets, 1);
7418 		XtSetArg(args[3], XmNdropProc, DropStart);
7419 		XmDropSiteRegister((Widget)g, args, 4);
7420 		}
7421 	else
7422 		XmDropSiteUnregister((Widget)g);
7423 #endif
7424 	}
7425 
7426 static void
DropStart(Widget w,XtPointer clientData,XtPointer callData)7427 DropStart(Widget w,
7428 	  XtPointer clientData,
7429 	  XtPointer callData)
7430 	{
7431 #ifndef MOTIF11
7432 	XmLGridWidget g;
7433 	XmDropProcCallbackStruct *cbs;
7434 	XmDropTransferEntryRec te[2];
7435 	Atom *exportTargets;
7436 	Arg args[10];
7437 	int row, col, i, n, valid;
7438 
7439 	g = (XmLGridWidget)w;
7440 	cbs = (XmDropProcCallbackStruct *)callData;
7441 	if (g->grid.allowDrop == False || cbs->dropAction == XmDROP_HELP)
7442 		{
7443 		cbs->dropSiteStatus = XmINVALID_DROP_SITE;
7444 		return;
7445 		}
7446 	valid = 0;
7447 	if (XYToRowCol(g, cbs->x, cbs->y, &row, &col) != -1 &&
7448 		cbs->dropAction == XmDROP && cbs->operation == XmDROP_COPY)
7449 		{
7450 		XtVaGetValues(cbs->dragContext,
7451 			XmNexportTargets, &exportTargets,
7452 			XmNnumExportTargets, &n,
7453 			NULL);
7454 		for (i = 0; i < n; i++)
7455 			if (exportTargets[i] == XA_STRING)
7456 				valid = 1;
7457 		}
7458 	if (!valid)
7459 		{
7460 		cbs->operation = (long)XmDROP_NOOP;
7461 		cbs->dropSiteStatus = XmINVALID_DROP_SITE;
7462 		XtSetArg(args[0], XmNtransferStatus, XmTRANSFER_FAILURE);
7463 		XtSetArg(args[1], XmNnumDropTransfers, 0);
7464 		XmDropTransferStart(cbs->dragContext, args, 2);
7465 		return;
7466 		}
7467 	g->grid.dropLoc.row = row;
7468 	g->grid.dropLoc.col = col;
7469 	cbs->operation = (long)XmDROP_COPY;
7470 	te[0].target = XA_STRING;
7471 	te[0].client_data = (XtPointer)g;
7472 	XtSetArg(args[0], XmNdropTransfers, te);
7473 	XtSetArg(args[1], XmNnumDropTransfers, 1);
7474 	XtSetArg(args[2], XmNtransferProc, DropTransfer);
7475 	XmDropTransferStart(cbs->dragContext, args, 3);
7476 #endif
7477 	}
7478 
7479 static void
DropTransfer(Widget w,XtPointer clientData,Atom * selType,Atom * type,XtPointer value,unsigned long * length,int * format)7480 DropTransfer(Widget w,
7481 	     XtPointer clientData,
7482 	     Atom *selType,
7483 	     Atom *type,
7484 	     XtPointer value,
7485 	     unsigned long *length,
7486 	     int *format)
7487 	{
7488 #ifndef MOTIF11
7489 	XmLGridWidget g;
7490 	char *buf;
7491 	int len;
7492 
7493 	if (!value)
7494 		return;
7495 	g = (XmLGridWidget)clientData;
7496 	len = (int)*length;
7497 	if (len < 0)
7498 		return;
7499 	buf = (char *)malloc(len + 1);
7500 	strncpy(buf, (char *)value, len);
7501 	XtFree((char *)value);
7502 	buf[len] = 0;
7503 	Read(g, XmFORMAT_DROP, 0, g->grid.dropLoc.row, g->grid.dropLoc.col, buf);
7504 	free((char *)buf);
7505 #endif
7506 	}
7507 
7508 static void
Select(Widget w,XEvent * event,String * params,Cardinal * nparam)7509 Select(Widget w,
7510        XEvent *event,
7511        String *params,
7512        Cardinal *nparam)
7513 	{
7514 	XmLGridWidget g;
7515 	Display *dpy;
7516 	Window win;
7517 	static XrmQuark qACTIVATE, qBEGIN, qEXTEND, qEND;
7518 	static XrmQuark qTOGGLE;
7519 	static int quarksValid = 0;
7520 	XrmQuark q;
7521 	int isVert;
7522 	int row, col, resizeRow, resizeCol;
7523 	XButtonEvent *be;
7524 	XRectangle rect;
7525 	XmLGridRow rowp;
7526 	XmLGridCell cellp;
7527 	XmLGridColumn colp;
7528 	XmLGridCallbackStruct cbs;
7529 	Boolean flag;
7530 
7531 	if (*nparam != 1)
7532 		return;
7533 
7534 	if (XmLIsGrid(w))
7535 		g = (XmLGridWidget)w;
7536 	else
7537 		g = (XmLGridWidget)XtParent(w);
7538 	dpy = XtDisplay(g);
7539 	win = XtWindow(g);
7540 	if (!quarksValid)
7541 		{
7542 		qACTIVATE = XrmStringToQuark("ACTIVATE");
7543 		qBEGIN = XrmStringToQuark("BEGIN");
7544 		qEXTEND = XrmStringToQuark("EXTEND");
7545 		qEND = XrmStringToQuark("END");
7546 		qTOGGLE = XrmStringToQuark("TOGGLE");
7547 		}
7548 	q = XrmStringToQuark(params[0]);
7549 	be = 0;
7550 	if (event->type == KeyPress || event->type == KeyRelease)
7551 		{
7552 		row = g->grid.focusRow;
7553 		col = g->grid.focusCol;
7554 		}
7555 	else /* Button */
7556 		{
7557 		be = (XButtonEvent *)event;
7558 		if (XYToRowCol(g, be->x, be->y, &row, &col) == -1)
7559 			{
7560 			row = -1;
7561 			col = -1;
7562 			}
7563 		}
7564 
7565 	/* double click activate check */
7566 	if (q == qBEGIN && be)
7567 		{
7568 		if (row != -1 && col != -1
7569             && row == g->grid.focusRow && col == g->grid.focusCol
7570             )
7571             {
7572             int doubleClickTime = XtGetMultiClickTime(dpy);
7573             Time timeSinceLastClick = be->time - g->grid.lastSelectTime;
7574             if (timeSinceLastClick < doubleClickTime)
7575                 {
7576                 /* Clear inplace editing if some other event happens */
7577                 if (g->grid.editTimerSet)
7578                     {
7579                     XtRemoveTimeOut(g->grid.editTimerId);
7580                     g->grid.editTimerSet = 0;
7581                     }
7582 
7583                 /* Second click came within double click time */
7584                 q = qACTIVATE;
7585                 }
7586             else if (!g->grid.editTimerSet && g->grid.lastSelectTime != 0)
7587                 {
7588                    /* Only begin an edit when we are sure we don't
7589                     * have a double click
7590                     */
7591                    if (!g->grid.singleClickActivation) {
7592                       g->grid.editTimerId =
7593                       XtAppAddTimeOut(XtWidgetToApplicationContext(w),
7594                                     doubleClickTime*2, EditTimer, (caddr_t)g);
7595                       g->grid.editTimerSet = 1;
7596                    }
7597                 }
7598             }
7599 		g->grid.lastSelectRow = row;
7600 		g->grid.lastSelectCol = col;
7601 		g->grid.lastSelectTime = be->time;
7602 		}
7603 	else if (q == qBEGIN)
7604 		g->grid.lastSelectTime = 0;
7605 
7606 	if (q == qBEGIN && be && PosIsResize(g, be->x, be->y,
7607 		&resizeRow, &resizeCol, &isVert))
7608 		{
7609 		g->grid.resizeIsVert = isVert;
7610 		g->grid.inMode = InResize;
7611 		g->grid.resizeLineXY = -1;
7612 		g->grid.resizeRow = resizeRow;
7613 		g->grid.resizeCol = resizeCol;
7614 		if (isVert)
7615 			{
7616 			DrawResizeLine(g, be->y, 0);
7617 			DefineCursor(g, CursorVResize);
7618 			}
7619 		else
7620 			{
7621 			DrawResizeLine(g, be->x, 0);
7622 			DefineCursor(g, CursorHResize);
7623 			}
7624 		}
7625 	else if (q == qBEGIN || q == qEXTEND || q == qTOGGLE)
7626 		{
7627 		if (g->grid.inMode != InNormal)
7628 			return;
7629 		if (row == -1 || col == -1)
7630 			return;
7631 		if (RowPosToType(g, row) == XmCONTENT &&
7632 			ColPosToType(g, col) == XmCONTENT)
7633 			{
7634 			TextAction(g, TEXT_EDIT_COMPLETE);
7635 			if (q != qEXTEND)
7636 				{
7637 				SetFocus(g, row, col, 0, 1);
7638 				ExtendSelect(g, event, False, -1, -1);
7639 				}
7640 			XmProcessTraversal(g->grid.text, XmTRAVERSE_CURRENT);
7641 			}
7642 		if (g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW &&
7643 			RowPosToType(g, row) == XmCONTENT)
7644 			{
7645 			flag = True;
7646 			rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
7647 #if 0
7648 /* Don't want single click to unselect something. -slamm */
7649 			if (q == qBEGIN && rowp && XmLGridRowIsSelected(rowp) == True)
7650 				flag = False;
7651 #endif /* 0 -slamm */
7652 			if (q == qTOGGLE && rowp && XmLGridRowIsSelected(rowp) == True)
7653 				flag = False;
7654 			if (q == qBEGIN)
7655 				SelectTypeArea(g, SelectRow, event, -1, 0, False, True);
7656 			if (be && q == qEXTEND)
7657 				ExtendSelect(g, event, False, row, col);
7658 			else
7659 				SelectTypeArea(g, SelectRow, event,
7660 					RowPosToTypePos(g, XmCONTENT, row), 0, flag, True);
7661 			}
7662 		if (g->grid.selectionPolicy == XmSELECT_CELL)
7663 			{
7664 			if (q == qBEGIN)
7665 				{
7666 				SelectTypeArea(g, SelectCell, event, -1, -1, False, True);
7667 				SelectTypeArea(g, SelectRow, event, -1, 0, False, True);
7668 				SelectTypeArea(g, SelectCol, event, 0, -1, False, True);
7669 				}
7670 			else if (q == qTOGGLE)
7671 				ExtendSelect(g, event, False, -1, -1);
7672 			if (RowPosToType(g, row) == XmFOOTER ||
7673 				ColPosToType(g, col) == XmFOOTER)
7674 				ExtendSelect(g, event, False, -1, -1);
7675 			if (be && q == qEXTEND)
7676 				ExtendSelect(g, event, False, row, col);
7677 			else if (RowPosToType(g, row) == XmCONTENT &&
7678 				ColPosToType(g, col) == XmCONTENT)
7679 				{
7680 				flag = True;
7681 				cellp = GetCell(g, row, col);
7682 				if (q == qTOGGLE && cellp &&
7683 					XmLGridCellIsSelected(cellp) == True)
7684 					flag = False;
7685 				SelectTypeArea(g, SelectCell, event,
7686 					RowPosToTypePos(g, XmCONTENT, row),
7687 					ColPosToTypePos(g, XmCONTENT, col), flag, True);
7688 				}
7689 			else if (RowPosToType(g, row) == XmHEADING &&
7690 				ColPosToType(g, col) == XmCONTENT)
7691 				{
7692 				if (q == qTOGGLE)
7693 					{
7694 					colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
7695 					if (colp && XmLGridColumnIsSelected(colp) == True)
7696 						g->grid.extendSelect = False;
7697 					}
7698 				ExtendSelect(g, event, True, row, col);
7699 				}
7700 			else if (ColPosToType(g, col) == XmHEADING &&
7701 				RowPosToType(g, row) == XmCONTENT)
7702 				{
7703 				if (q == qTOGGLE)
7704 					{
7705 					rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
7706 					if (rowp && XmLGridRowIsSelected(rowp) == True)
7707 						g->grid.extendSelect = False;
7708 					}
7709 				ExtendSelect(g, event, True, row, col);
7710 				}
7711 			}
7712 		if (g->grid.selectionPolicy == XmSELECT_SINGLE_ROW &&
7713 			RowPosToType(g, row) == XmCONTENT)
7714 			{
7715 			flag = True;
7716 			rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
7717 			if (rowp && XmLGridRowIsSelected(rowp) == True)
7718 				flag = False;
7719 			SelectTypeArea(g, SelectRow, event,
7720 				RowPosToTypePos(g, XmCONTENT, row), 0, flag, True);
7721 			}
7722 		if (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW &&
7723 			RowPosToType(g, row) == XmCONTENT)
7724 			SelectTypeArea(g, SelectRow, event,
7725 				RowPosToTypePos(g, XmCONTENT, row), 0, True, True);
7726 		if (g->grid.selectionPolicy == XmSELECT_NONE ||
7727 			(g->grid.selectionPolicy == XmSELECT_BROWSE_ROW &&
7728 			RowPosToType(g, row) != XmCONTENT) ||
7729 			(g->grid.selectionPolicy == XmSELECT_SINGLE_ROW &&
7730 			RowPosToType(g, row) != XmCONTENT) ||
7731 			(g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW &&
7732 			RowPosToType(g, row) != XmCONTENT) )
7733 			{
7734 			cbs.reason = XmCR_SELECT_CELL;
7735 			cbs.event = event;
7736 			cbs.columnType = ColPosToType(g, col);
7737 			cbs.column = ColPosToTypePos(g, cbs.columnType, col);
7738 			cbs.rowType = RowPosToType(g, row);
7739 			cbs.row = RowPosToTypePos(g, cbs.rowType, row);
7740 			XtCallCallbackList((Widget)g, g->grid.selectCallback,
7741 				(XtPointer)&cbs);
7742 			}
7743 		g->grid.inMode = InSelect;
7744 		}
7745 	else if (q == qEND && g->grid.inMode == InResize)
7746 		{
7747 		int r, c, width, height;
7748 		r = g->grid.resizeRow;
7749 		c = g->grid.resizeCol;
7750 		g->grid.resizeRow = -1;
7751 		g->grid.resizeCol = -1;
7752 		if (!RowColToXY(g, r, c, False, &rect))
7753 			{
7754 			if (g->grid.resizeIsVert)
7755 				{
7756 				cbs.rowType = RowPosToType(g, r);
7757 				cbs.row = RowPosToTypePos(g, cbs.rowType, r);
7758 				height = 0;
7759 				if (g->grid.resizeLineXY > rect.y)
7760 					height = g->grid.resizeLineXY - rect.y -
7761 						(rect.height - GetRowHeight(g, r));
7762 				if (height < 6 && g->grid.allowRowHide == False)
7763 					height = 6;
7764 				XtVaSetValues((Widget)g,
7765 					XmNrowType, cbs.rowType,
7766 					XmNrow, cbs.row,
7767 					XmNrowHeight, height,
7768 					XmNrowSizePolicy, XmCONSTANT,
7769 					NULL);
7770 				cbs.reason = XmCR_RESIZE_ROW;
7771 				}
7772 			else
7773 				{
7774 				cbs.columnType = ColPosToType(g, c);
7775 				cbs.column = ColPosToTypePos(g, cbs.columnType, c);
7776 				width = 0;
7777 				if (g->grid.resizeLineXY > rect.x)
7778 					width = g->grid.resizeLineXY - rect.x -
7779 						(rect.width - GetColWidth(g, c));
7780 				if (width < 6 && g->grid.allowColHide == False)
7781 					width = 6;
7782 				XtVaSetValues((Widget)g,
7783 					XmNcolumnType, cbs.columnType,
7784 					XmNcolumn, cbs.column,
7785 					XmNcolumnWidth, width,
7786 					XmNcolumnSizePolicy, XmCONSTANT,
7787 					NULL);
7788 				cbs.reason = XmCR_RESIZE_COLUMN;
7789 
7790 				}
7791 			XtCallCallbackList((Widget)g, g->grid.resizeCallback,
7792 				(XtPointer)&cbs);
7793 			}
7794 		DrawResizeLine(g, 0, 2);
7795 		DefineCursor(g, CursorNormal);
7796 		g->grid.inMode = InNormal;
7797 		}
7798 	else if (q == qEND)
7799 		{
7800 		g->grid.inMode = InNormal;
7801 		if (g->grid.dragTimerSet)
7802 			XtRemoveTimeOut(g->grid.dragTimerId);
7803 		g->grid.dragTimerSet = 0;
7804 
7805 		/* XFE Additions to handle button up events in menus - they generate activate events */
7806 		  {
7807 		    if (XmIsMenuShell(XmLShellOfWidget((Widget)g)))
7808 		    {
7809 		      cbs.reason = XmCR_ACTIVATE;
7810 		      cbs.event = event;
7811 		      cbs.columnType = ColPosToType(g, col);
7812 		      cbs.column = ColPosToTypePos(g, cbs.columnType, col);
7813 		      cbs.rowType = RowPosToType(g, row);
7814 		      cbs.row = RowPosToTypePos(g, cbs.rowType, row);
7815 		      XtCallCallbackList((Widget)g, g->grid.activateCallback,
7816 					 (XtPointer)&cbs);
7817 		    }
7818 		  }
7819 		}
7820       if (q == qBEGIN  && g->grid.singleClickActivation) {
7821 		cbs.reason = XmCR_ACTIVATE;
7822 		cbs.event = event;
7823 		cbs.columnType = ColPosToType(g, col);
7824 		cbs.column = ColPosToTypePos(g, cbs.columnType, col);
7825 		cbs.rowType = RowPosToType(g, row);
7826 		cbs.row = RowPosToTypePos(g, cbs.rowType, row);
7827 		XtCallCallbackList((Widget)g, g->grid.activateCallback,
7828 			(XtPointer)&cbs);
7829     }
7830 	if (q == qACTIVATE)
7831 		{
7832 		cbs.reason = XmCR_ACTIVATE;
7833 		cbs.event = event;
7834 		cbs.columnType = ColPosToType(g, col);
7835 		cbs.column = ColPosToTypePos(g, cbs.columnType, col);
7836 		cbs.rowType = RowPosToType(g, row);
7837 		cbs.row = RowPosToTypePos(g, cbs.rowType, row);
7838 		XtCallCallbackList((Widget)g, g->grid.activateCallback,
7839 			(XtPointer)&cbs);
7840 		}
7841 	}
7842 
7843 /*
7844  * Selection policy when posting a context menu.
7845  *   If over a current selection, leave the selection alone.
7846  *   Otherwise, change the selection the same as Select(),
7847  *   except do not allow dragging to extend the selection.
7848  */
7849 static void
PopupSelect(Widget w,XEvent * event,String * params,Cardinal * nparam)7850 PopupSelect(Widget w,
7851        XEvent *event,
7852        String *params,
7853        Cardinal *nparam)
7854 {
7855 	XmLGridWidget g;
7856 	int row, col;
7857 	XButtonEvent *be;
7858 	XmLGridRow rowp;
7859 	XmLGridCallbackStruct cbs;
7860 
7861 	if (*nparam != 1)
7862 		return;
7863 
7864 	if (XmLIsGrid(w))
7865 		g = (XmLGridWidget)w;
7866 	else
7867 		g = (XmLGridWidget)XtParent(w);
7868 
7869 	be = 0;
7870 	if (event->type == KeyPress || event->type == KeyRelease)
7871     {
7872 		row = g->grid.focusRow;
7873 		col = g->grid.focusCol;
7874     }
7875 	else /* Button */
7876     {
7877 		be = (XButtonEvent *)event;
7878 		if (XYToRowCol(g, be->x, be->y, &row, &col) == -1)
7879         {
7880 			row = -1;
7881 			col = -1;
7882         }
7883     }
7884     if (RowPosToType(g, row) == XmCONTENT)
7885     {
7886         XmLGridRow rowp;
7887         rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
7888         if (rowp && !XmLGridRowIsSelected(rowp))
7889         {
7890             String end_params[1];
7891             end_params[0] = "END";
7892             Select(w, event, params, nparam);
7893             Select(w, event, end_params, nparam);
7894         }
7895     }
7896     if (XtHasCallbacks(w, XmNpopupCallback) == XtCallbackHasSome)
7897     {
7898 		cbs.reason = XmCR_SHOW_POPUP;
7899 		cbs.event = event;
7900 		cbs.columnType = ColPosToType(g, col);
7901 		cbs.column = ColPosToTypePos(g, cbs.columnType, col);
7902 		cbs.rowType = RowPosToType(g, row);
7903 		cbs.row = RowPosToTypePos(g, cbs.rowType, row);
7904 		XtCallCallbackList((Widget)g, g->grid.popupCallback,
7905                            (XtPointer)&cbs);
7906     }
7907 }
7908 
7909 static void
Traverse(Widget w,XEvent * event,String * params,Cardinal * nparam)7910 Traverse(Widget w,
7911 	 XEvent *event,
7912 	 String *params,
7913 	 Cardinal *nparam)
7914 	{
7915 	XmLGridWidget g;
7916 	static XrmQuark qDOWN, qEXTEND_DOWN, qEXTEND_LEFT;
7917 	static XrmQuark qEXTEND_PAGE_DOWN, qEXTEND_PAGE_LEFT;
7918 	static XrmQuark qEXTEND_PAGE_RIGHT, qEXTEND_PAGE_UP;
7919 	static XrmQuark qEXTEND_RIGHT, qEXTEND_UP, qLEFT, qPAGE_DOWN;
7920 	static XrmQuark qPAGE_LEFT, qPAGE_RIGHT, qPAGE_UP, qRIGHT;
7921 	static XrmQuark qTO_BOTTOM, qTO_BOTTOM_RIGHT, qTO_LEFT;
7922 	static XrmQuark qTO_RIGHT, qTO_TOP, qTO_TOP_LEFT, qUP;
7923 	static int quarksValid = 0;
7924 	int extend, focusRow, focusCol, rowDir, colDir;
7925 	int rowLoc, colLoc, prevRowLoc, prevColLoc;
7926 	int scrollRow, scrollCol, prevScrollRow, prevScrollCol;
7927 	XrmQuark q;
7928 
7929 	g = (XmLGridWidget)XtParent(w);
7930 	if (*nparam != 1)
7931 		return;
7932 	if (!quarksValid)
7933 		{
7934 		qDOWN = XrmStringToQuark("DOWN");
7935 		qEXTEND_DOWN = XrmStringToQuark("EXTEND_DOWN");
7936 		qEXTEND_LEFT = XrmStringToQuark("EXTEND_LEFT");
7937 		qEXTEND_PAGE_DOWN = XrmStringToQuark("EXTEND_PAGE_DOWN");
7938 		qEXTEND_PAGE_LEFT = XrmStringToQuark("EXTEND_PAGE_LEFT");
7939 		qEXTEND_PAGE_RIGHT = XrmStringToQuark("EXTEND_PAGE_RIGHT");
7940 		qEXTEND_PAGE_UP = XrmStringToQuark("EXTEND_PAGE_UP");
7941 		qEXTEND_RIGHT = XrmStringToQuark("EXTEND_RIGHT");
7942 		qEXTEND_UP = XrmStringToQuark("EXTEND_UP");
7943 		qLEFT = XrmStringToQuark("LEFT");
7944 		qPAGE_DOWN = XrmStringToQuark("PAGE_DOWN");
7945 		qPAGE_LEFT = XrmStringToQuark("PAGE_LEFT");
7946 		qPAGE_RIGHT = XrmStringToQuark("PAGE_RIGHT");
7947 		qPAGE_UP = XrmStringToQuark("PAGE_UP");
7948 		qRIGHT = XrmStringToQuark("RIGHT");
7949 		qTO_BOTTOM = XrmStringToQuark("TO_BOTTOM");
7950 		qTO_BOTTOM_RIGHT = XrmStringToQuark("TO_BOTTOM_RIGHT");
7951 		qTO_LEFT = XrmStringToQuark("TO_LEFT");
7952 		qTO_RIGHT = XrmStringToQuark("TO_RIGHT");
7953 		qTO_TOP = XrmStringToQuark("TO_TOP");
7954 		qTO_TOP_LEFT = XrmStringToQuark("TO_TOP_LEFT");
7955 		qUP = XrmStringToQuark("UP");
7956 		quarksValid = 1;
7957 		}
7958 	q = XrmStringToQuark(params[0]);
7959 	extend = 0;
7960 	/* map the extends to their counterparts and set extend flag */
7961 	if (q == qEXTEND_DOWN)
7962 		{
7963 		q = qDOWN;
7964 		extend = 1;
7965 		}
7966 	else if (q == qEXTEND_LEFT)
7967 		{
7968 		q = qLEFT;
7969 		extend = 1;
7970 		}
7971 	else if (q == qEXTEND_PAGE_DOWN)
7972 		{
7973 		q = qPAGE_DOWN;
7974 		extend = 1;
7975 		}
7976 	else if (q == qEXTEND_PAGE_LEFT)
7977 		{
7978 		q = qPAGE_LEFT;
7979 		extend = 1;
7980 		}
7981 	else if (q == qEXTEND_PAGE_RIGHT)
7982 		{
7983 		q = qPAGE_RIGHT;
7984 		extend = 1;
7985 		}
7986 	else if (q == qEXTEND_PAGE_UP)
7987 		{
7988 		q = qPAGE_UP;
7989 		extend = 1;
7990 		}
7991 	else if (q == qEXTEND_RIGHT)
7992 		{
7993 		q = qRIGHT;
7994 		extend = 1;
7995 		}
7996 	else if (q == qEXTEND_UP)
7997 		{
7998 		q = qUP;
7999 		extend = 1;
8000 		}
8001 	if (extend && g->grid.selectionPolicy != XmSELECT_MULTIPLE_ROW &&
8002 		g->grid.selectionPolicy != XmSELECT_CELL)
8003 		return;
8004 	if (extend && g->grid.extendRow != -1 && g->grid.extendCol != -1)
8005 		{
8006 		focusRow = g->grid.extendToRow;
8007 		focusCol = g->grid.extendToCol;
8008 		}
8009 	else
8010 		{
8011 		focusRow = g->grid.focusRow;
8012 		focusCol = g->grid.focusCol;
8013 		}
8014 	rowDir = 0;
8015 	colDir = 0;
8016 	if (focusRow < g->grid.topFixedCount)
8017 		prevRowLoc = 0;
8018 	else if (focusRow >= XmLArrayGetCount(g->grid.rowArray) -
8019 		g->grid.bottomFixedCount)
8020 		prevRowLoc = 2;
8021 	else
8022 		prevRowLoc = 1;
8023 	if (focusCol < g->grid.leftFixedCount)
8024 		prevColLoc = 0;
8025 	else if (focusCol >= XmLArrayGetCount(g->grid.colArray) -
8026 		g->grid.rightFixedCount)
8027 		prevColLoc = 2;
8028 	else
8029 		prevColLoc = 1;
8030 	/* calculate new focus row, col and walk direction */
8031 	if (q == qDOWN)
8032 		{
8033 		focusRow++;
8034 		rowDir = 1;
8035 		}
8036 	else if (q == qLEFT)
8037 		{
8038 		focusCol--;
8039 		colDir = -1;
8040 		}
8041 	else if (q == qPAGE_DOWN)
8042 		{
8043 		if (prevRowLoc == 1)
8044 			focusRow = g->grid.reg[4].row + g->grid.reg[4].nrow - 1;
8045 		if (focusRow == g->grid.focusRow)
8046 			focusRow += 4;
8047 		rowDir = 1;
8048 		}
8049 	else if (q == qPAGE_LEFT)
8050 		{
8051 		if (prevColLoc == 1)
8052 			focusCol = g->grid.reg[4].col - 1;
8053 		if (focusCol == g->grid.focusCol)
8054 			focusCol -= 4;
8055 		colDir = -1;
8056 		}
8057 	else if (q == qPAGE_RIGHT)
8058 		{
8059 		if (prevColLoc == 1)
8060 			focusCol = g->grid.reg[4].col + g->grid.reg[4].ncol - 1;
8061 		if (focusCol == g->grid.focusCol)
8062 			focusCol += 4;
8063 		colDir = 1;
8064 		}
8065 	else if (q == qPAGE_UP)
8066 		{
8067 		if (prevRowLoc == 1)
8068 			focusRow = g->grid.reg[4].row - 1;
8069 		if (focusRow == g->grid.focusRow)
8070 			focusRow -= 4;
8071 		rowDir = -1;
8072 		}
8073 	else if (q == qRIGHT)
8074 		{
8075 		focusCol++;
8076 		colDir = 1;
8077 		}
8078 	else if (q == qTO_BOTTOM)
8079 		{
8080 		focusRow = XmLArrayGetCount(g->grid.rowArray) - 1;
8081 		rowDir = -1;
8082 		}
8083 	else if (q == qTO_BOTTOM_RIGHT)
8084 		{
8085 		focusCol = XmLArrayGetCount(g->grid.colArray) - 1;
8086 		focusRow = XmLArrayGetCount(g->grid.rowArray) - 1;
8087 		rowDir = -1;
8088 		colDir = -1;
8089 		}
8090 	else if (q == qTO_LEFT)
8091 		{
8092 		focusCol = 0;
8093 		colDir = 1;
8094 		}
8095 	else if (q == qTO_RIGHT)
8096 		{
8097 		focusCol = XmLArrayGetCount(g->grid.colArray) - 1;
8098 		colDir = -1;
8099 		}
8100 	else if (q == qTO_TOP)
8101 		{
8102 		focusRow = 0;
8103 		rowDir = 1;
8104 		}
8105 	else if (q == qTO_TOP_LEFT)
8106 		{
8107 		focusCol = 0;
8108 		focusRow = 0;
8109 		rowDir = 1;
8110 		colDir = 1;
8111 		}
8112 	else if (q == qUP)
8113 		{
8114 		focusRow -= 1;
8115 		rowDir = -1;
8116 		}
8117 	if (!rowDir && !colDir)
8118 		return;
8119 	if (extend)
8120 		{
8121 		if (FindNextFocus(g, focusRow, focusCol, rowDir, colDir,
8122 			&focusRow, &focusCol) == -1)
8123 			return;
8124 		ExtendSelect(g, event, False, focusRow, focusCol);
8125 		}
8126 	else
8127 		{
8128 		if (SetFocus(g, focusRow, focusCol, rowDir, colDir) == -1)
8129 			return;
8130 		ExtendSelect(g, event, False, -1, -1);
8131 		focusRow = g->grid.focusRow;
8132 		focusCol = g->grid.focusCol;
8133 		if (g->grid.selectionPolicy == XmSELECT_CELL)
8134 			{
8135 			SelectTypeArea(g, SelectRow, event, -1, 0, False, True);
8136 			SelectTypeArea(g, SelectCol, event, 0, -1, False, True);
8137 			SelectTypeArea(g, SelectCell, event, -1, -1, False, True);
8138 			SelectTypeArea(g, SelectCell, event,
8139 				RowPosToTypePos(g, XmCONTENT, focusRow),
8140 				ColPosToTypePos(g, XmCONTENT, focusCol),
8141 				True, True);
8142 			}
8143 		else if (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW)
8144 			SelectTypeArea(g, SelectRow, event,
8145 				RowPosToTypePos(g, XmCONTENT, focusRow), 0, True, True);
8146 		}
8147 	scrollRow = -1;
8148 	scrollCol = -1;
8149 	if (q == qPAGE_UP)
8150 		scrollRow = ScrollRowBottomPos(g, focusRow);
8151 	else if (q == qPAGE_DOWN)
8152 		scrollRow = focusRow;
8153 	else if (q == qPAGE_LEFT)
8154 		scrollCol = ScrollColRightPos(g, focusCol);
8155 	else if (q == qPAGE_RIGHT)
8156 		scrollCol = focusCol;
8157 	else
8158 		{
8159 		if (focusRow < g->grid.topFixedCount)
8160 			rowLoc = 0;
8161 		else if (focusRow >= XmLArrayGetCount(g->grid.rowArray) -
8162 			g->grid.bottomFixedCount)
8163 			rowLoc = 2;
8164 		else
8165 			rowLoc = 1;
8166 		if (prevRowLoc != 0 && rowLoc == 0)
8167 			scrollRow = g->grid.reg[0].nrow;
8168 		else if (prevRowLoc != 2 && rowLoc == 2)
8169 			scrollRow = g->grid.reg[6].row - 1;
8170 
8171 		if (focusCol < g->grid.leftFixedCount)
8172 			colLoc = 0;
8173 		else if (focusCol >= XmLArrayGetCount(g->grid.colArray) -
8174 			g->grid.rightFixedCount)
8175 			colLoc = 2;
8176 		else
8177 			colLoc = 1;
8178 		if (prevColLoc != 0 && colLoc == 0)
8179 			scrollCol = g->grid.reg[0].ncol;
8180 		else if (prevColLoc != 2 && colLoc == 2)
8181 			scrollCol = g->grid.reg[2].col - 1;
8182 		}
8183 	if (g->grid.vsPolicy == XmVARIABLE)
8184 		;
8185 	else if (scrollRow != -1)
8186 		{
8187 		prevScrollRow = g->grid.scrollRow;
8188 		g->grid.scrollRow = scrollRow;
8189 		VertLayout(g, 0);
8190 		if (g->grid.scrollRow != prevScrollRow)
8191 			DrawArea(g, DrawVScroll, 0, 0);
8192 		}
8193 	else
8194 		MakeRowVisible(g, focusRow);
8195 	if (g->grid.hsPolicy == XmVARIABLE)
8196 		;
8197 	else if (scrollCol != -1)
8198 		{
8199 		prevScrollCol = g->grid.scrollCol;
8200 		g->grid.scrollCol = scrollCol;
8201 		HorizLayout(g, 0);
8202 		if (g->grid.scrollCol != prevScrollCol)
8203 			DrawArea(g, DrawHScroll, 0, 0);
8204 		}
8205 	else
8206 		MakeColVisible(g, focusCol);
8207 	}
8208 
8209 static void
TextActivate(Widget w,XtPointer clientData,XtPointer callData)8210 TextActivate(Widget w,
8211 	     XtPointer clientData,
8212 	     XtPointer callData)
8213 	{
8214 	XmLGridWidget g;
8215 	XmAnyCallbackStruct *cbs;
8216 	String params[1];
8217 	Cardinal nparam;
8218 
8219 	cbs = (XmAnyCallbackStruct *)callData;
8220 	g = (XmLGridWidget)XtParent(w);
8221 	if (g->grid.inEdit)
8222 		{
8223 		nparam = 0;
8224 		EditComplete(w, cbs->event, params, &nparam);
8225 		}
8226 	else
8227 		{
8228 		params[0] = "ACTIVATE";
8229 		nparam = 1;
8230 		Select(XtParent(w), cbs->event, params, &nparam);
8231 		}
8232 	}
8233 
8234 static void
TextFocus(Widget w,XtPointer clientData,XtPointer callData)8235 TextFocus(Widget w,
8236 	  XtPointer clientData,
8237 	  XtPointer callData)
8238 	{
8239 	XmLGridWidget g;
8240 	XmAnyCallbackStruct *cbs;
8241 	int focusRow, focusCol;
8242 
8243 	cbs = (XmAnyCallbackStruct *)callData;
8244 	g = (XmLGridWidget)XtParent(w);
8245 	if (cbs->reason == XmCR_FOCUS)
8246 		g->grid.focusIn = 1;
8247 	else
8248 		g->grid.focusIn = 0;
8249 	focusRow = g->grid.focusRow;
8250 	focusCol = g->grid.focusCol;
8251 	if (focusRow != -1 && focusCol != -1)
8252 		{
8253 		if (g->grid.highlightRowMode == True)
8254 			DrawArea(g, DrawRow, focusRow, 0);
8255 		else
8256 			DrawArea(g, DrawCell, focusRow, focusCol);
8257 		}
8258 	}
8259 
8260 static void
TextMapped(Widget w,XtPointer clientData,XEvent * event,Boolean * con)8261 TextMapped(Widget w,
8262 	   XtPointer clientData,
8263 	   XEvent *event,
8264 	   Boolean *con)
8265 	{
8266 	XmLGridWidget g;
8267 
8268 	g = (XmLGridWidget)(XtParent(w));
8269 	if (event->type != MapNotify)
8270 		return;
8271 	if (g->grid.textHidden)
8272 		XtUnmapWidget(g->grid.text);
8273 	}
8274 
8275 static void
TextModifyVerify(Widget w,XtPointer clientData,XtPointer callData)8276 TextModifyVerify(Widget w,
8277 		 XtPointer clientData,
8278 		 XtPointer callData)
8279 	{
8280 	XmLGridWidget g;
8281 	XmTextVerifyCallbackStruct *cbs;
8282 
8283 	g = (XmLGridWidget)XtParent(w);
8284 	cbs = (XmTextVerifyCallbackStruct *)callData;
8285 	if (!cbs->event || g->grid.ignoreModifyVerify || g->grid.inEdit)
8286 		return;
8287 	TextAction(g, TEXT_EDIT);
8288 	if (!g->grid.inEdit)
8289 		cbs->doit = False;
8290 	}
8291 
8292 /*
8293    XmLGridRow
8294 */
8295 
8296 static
XmLGridRowNew(Widget grid)8297 XmLGridRow XmLGridRowNew(Widget grid)
8298 	{
8299 	return XmLGridClassPartOfWidget(grid).rowNewProc(grid);
8300 	}
8301 
8302 /* Only to be called through Grid class */
8303 static XmLGridRow
_GridRowNew(Widget grid)8304 _GridRowNew(Widget grid)
8305 	{
8306 	XmLGridWidget g;
8307 	XmLGridRow row;
8308 	int size;
8309 
8310 	g = (XmLGridWidget)grid;
8311 	size = XmLGridClassPartOfWidget(grid).rowRecSize;
8312 	row = (XmLGridRow)malloc(size);
8313 	row->grid.grid = grid;
8314 	row->grid.heightInPixels = 0;
8315 	row->grid.heightInPixelsValid = 0;
8316 	row->grid.height = 1;
8317 	row->grid.selected = False;
8318 	row->grid.sizePolicy = XmVARIABLE;
8319 	row->grid.userData = 0;
8320 	row->grid.cellArray = XmLArrayNew(0, 0);
8321 	return row;
8322 	}
8323 
8324 static void
XmLGridRowFree(Widget grid,XmLGridRow row)8325 XmLGridRowFree(Widget grid,
8326 	       XmLGridRow row)
8327 	{
8328 	XmLGridClassPartOfWidget(grid).rowFreeProc(row);
8329 	}
8330 
8331 /* Only to be called through Grid class */
8332 static void
_GridRowFree(XmLGridRow row)8333 _GridRowFree(XmLGridRow row)
8334 	{
8335 	int i, count;
8336 
8337 	count = XmLArrayGetCount(row->grid.cellArray);
8338 	for (i = 0; i < count; i++)
8339 		XmLGridCellFree(row->grid.grid,
8340 			(XmLGridCell)XmLArrayGet(row->grid.cellArray, i));
8341 	XmLArrayFree(row->grid.cellArray);
8342 	free ((char *)row);
8343 	}
8344 
8345 static
XmLGridRowCells(XmLGridRow row)8346 XmLArray XmLGridRowCells(XmLGridRow row)
8347 	{
8348 	return row->grid.cellArray;
8349 	}
8350 
8351 static int
XmLGridRowGetPos(XmLGridRow row)8352 XmLGridRowGetPos(XmLGridRow row)
8353 	{
8354 	return row->grid.pos;
8355 	}
8356 
8357 static int
XmLGridRowGetVisPos(XmLGridRow row)8358 XmLGridRowGetVisPos(XmLGridRow row)
8359 	{
8360 	return row->grid.visPos;
8361 	}
8362 
8363 static Boolean
XmLGridRowIsHidden(XmLGridRow row)8364 XmLGridRowIsHidden(XmLGridRow row)
8365 	{
8366 	if (!row->grid.height)
8367 		return True;
8368 	return False;
8369 	}
8370 
8371 static Boolean
XmLGridRowIsSelected(XmLGridRow row)8372 XmLGridRowIsSelected(XmLGridRow row)
8373 	{
8374 	return row->grid.selected;
8375 	}
8376 
8377 static void
XmLGridRowSetSelected(XmLGridRow row,Boolean selected)8378 XmLGridRowSetSelected(XmLGridRow row,
8379 		      Boolean selected)
8380 	{
8381 	row->grid.selected = selected;
8382 	}
8383 
8384 static void
XmLGridRowSetVisPos(XmLGridRow row,int visPos)8385 XmLGridRowSetVisPos(XmLGridRow row,
8386 		    int visPos)
8387 	{
8388 	row->grid.visPos = visPos;
8389 	}
8390 
8391 static int
XmLGridRowHeightInPixels(XmLGridRow row)8392 XmLGridRowHeightInPixels(XmLGridRow row)
8393 	{
8394 	int i, count;
8395 	Dimension height, maxHeight;
8396 	XmLGridWidget g;
8397 	XmLGridCell cell;
8398 	XmLGridCallbackStruct cbs;
8399 	XmLGridCellRefValues *cellValues;
8400 
8401 	if (row->grid.sizePolicy == XmCONSTANT)
8402 		return row->grid.height;
8403 	if (!row->grid.height)
8404 		return 0;
8405 	if (!row->grid.heightInPixelsValid)
8406 		{
8407 		g = (XmLGridWidget)row->grid.grid;
8408 		count = XmLArrayGetCount(row->grid.cellArray);
8409 		if (!count)
8410 			{
8411 			cellValues = g->grid.defCellValues;
8412 			maxHeight = 4 + row->grid.height * cellValues->fontHeight +
8413 				cellValues->topMargin + cellValues->bottomMargin;
8414 			}
8415 		else
8416 			maxHeight = 0;
8417 		for (i = 0; i < count; i++)
8418 			{
8419 			cell = (XmLGridCell)XmLArrayGet(row->grid.cellArray, i);
8420 			cbs.reason = XmCR_PREF_HEIGHT;
8421 			cbs.rowType = RowPosToType(g, row->grid.pos);
8422 			cbs.row = RowPosToTypePos(g, cbs.rowType, row->grid.pos);
8423 			cbs.columnType = ColPosToType(g, i);
8424 			cbs.column = ColPosToTypePos(g, cbs.columnType, i);
8425 			cbs.object = (void *)row;
8426 			height = XmLGridCellAction(cell, (Widget)g, &cbs);
8427 			if (height > maxHeight)
8428 				maxHeight = height;
8429 			}
8430 		row->grid.heightInPixels = maxHeight;
8431 		row->grid.heightInPixelsValid = 1;
8432 		}
8433 	return row->grid.heightInPixels;
8434 	}
8435 
8436 static void
XmLGridRowHeightChanged(XmLGridRow row)8437 XmLGridRowHeightChanged(XmLGridRow row)
8438 	{
8439 	row->grid.heightInPixelsValid = 0;
8440 	}
8441 
8442 /*
8443    XmLGridColumn
8444 */
8445 
8446 static XmLGridColumn
XmLGridColumnNew(Widget grid)8447 XmLGridColumnNew(Widget grid)
8448 	{
8449 	return XmLGridClassPartOfWidget(grid).columnNewProc(grid);
8450 	}
8451 
8452 /* Only to be called through Grid class */
8453 static XmLGridColumn
_GridColumnNew(Widget grid)8454 _GridColumnNew(Widget grid)
8455 	{
8456 	XmLGridWidget g;
8457 	XmLGridColumn column;
8458 	int size;
8459 
8460 	g = (XmLGridWidget)grid;
8461 	size = XmLGridClassPartOfWidget(grid).columnRecSize;
8462 	column = (XmLGridColumn)malloc(size);
8463 	column->grid.grid = grid;
8464 	column->grid.widthInPixels = 0;
8465 	column->grid.widthInPixelsValid = 0;
8466 	column->grid.defCellValues = 0;
8467 	column->grid.selected = False;
8468 	column->grid.sizePolicy = XmVARIABLE;
8469 	column->grid.width = 8;
8470 	column->grid.userData = 0;
8471 	column->grid.resizable = True;
8472     column->grid.hidden = 0;
8473 	return column;
8474 	}
8475 
8476 static void
XmLGridColumnFree(Widget grid,XmLGridColumn column)8477 XmLGridColumnFree(Widget grid,
8478 		  XmLGridColumn column)
8479 	{
8480 	XmLGridClassPartOfWidget(grid).columnFreeProc(column);
8481 	}
8482 
8483 /* Only to be called through Grid class */
8484 static void
_GridColumnFree(XmLGridColumn column)8485 _GridColumnFree(XmLGridColumn column)
8486 	{
8487 	if (column->grid.defCellValues)
8488 		XmLGridCellDerefValues(column->grid.defCellValues);
8489 	free((char *)column);
8490 	}
8491 
8492 static int
XmLGridColumnGetPos(XmLGridColumn column)8493 XmLGridColumnGetPos(XmLGridColumn column)
8494 	{
8495 	return column->grid.pos;
8496 	}
8497 
8498 static int
XmLGridColumnGetVisPos(XmLGridColumn column)8499 XmLGridColumnGetVisPos(XmLGridColumn column)
8500 	{
8501 	return column->grid.visPos;
8502 	}
8503 
8504 static Boolean
XmLGridColumnIsHidden(XmLGridColumn column)8505 XmLGridColumnIsHidden(XmLGridColumn column)
8506 	{
8507     return column->grid.width == 0
8508         || column->grid.hidden;
8509 	}
8510 
8511 static Boolean
XmLGridColumnIsSelected(XmLGridColumn column)8512 XmLGridColumnIsSelected(XmLGridColumn column)
8513 	{
8514 	return column->grid.selected;
8515 	}
8516 
8517 static void
XmLGridColumnSetSelected(XmLGridColumn column,Boolean selected)8518 XmLGridColumnSetSelected(XmLGridColumn column,
8519 			 Boolean selected)
8520 	{
8521 	column->grid.selected = selected;
8522 	}
8523 
8524 static void
XmLGridColumnSetVisPos(XmLGridColumn column,int visPos)8525 XmLGridColumnSetVisPos(XmLGridColumn column,
8526 		       int visPos)
8527 	{
8528 	column->grid.visPos = visPos;
8529 	}
8530 
8531 static int
XmLGridColumnWidthInPixels(XmLGridColumn column)8532 XmLGridColumnWidthInPixels(XmLGridColumn column)
8533 	{
8534 	int i, count;
8535 	Dimension width, maxWidth;
8536 	XmLGridCell cell;
8537 	XmLGridWidget g;
8538 	XmLGridCallbackStruct cbs;
8539 	XmLGridCellRefValues *cellValues;
8540 
8541 	if (column->grid.sizePolicy == XmCONSTANT)
8542 		return column->grid.width;
8543 	if (!column->grid.width)
8544 		return 0;
8545 	if (!column->grid.widthInPixelsValid)
8546 		{
8547 		g = (XmLGridWidget)column->grid.grid;
8548 		count = XmLArrayGetCount(g->grid.rowArray);
8549 		if (!count)
8550 			{
8551 			cellValues = g->grid.defCellValues;
8552 			maxWidth = 4 + column->grid.width * cellValues->fontWidth +
8553 				cellValues->leftMargin + cellValues->rightMargin;
8554 			}
8555 		else
8556 			maxWidth = 0;
8557 		for (i = 0; i < count; i++)
8558 			{
8559 			cell = GetCell(g, i, column->grid.pos);
8560 			cbs.reason = XmCR_PREF_WIDTH;
8561 			cbs.rowType = RowPosToType(g, i);
8562 			cbs.row = RowPosToTypePos(g, cbs.rowType, i);
8563 			cbs.columnType = ColPosToType(g, column->grid.pos);
8564 			cbs.column = ColPosToTypePos(g, cbs.columnType, column->grid.pos);
8565 			cbs.object = (void *)column;
8566 			width = XmLGridCellAction(cell, (Widget)g, &cbs);
8567 			if (width > maxWidth)
8568 				maxWidth = width;
8569 			}
8570 		column->grid.widthInPixels = maxWidth;
8571 		column->grid.widthInPixelsValid = 1;
8572 		}
8573 	return column->grid.widthInPixels;
8574 	}
8575 
8576 static void
XmLGridColumnWidthChanged(XmLGridColumn column)8577 XmLGridColumnWidthChanged(XmLGridColumn column)
8578 	{
8579 	column->grid.widthInPixelsValid = 0;
8580 	}
8581 
8582 /*
8583    XmLGridCell
8584 */
8585 
8586 static XmLGridCell
XmLGridCellNew(void)8587 XmLGridCellNew(void)
8588 	{
8589 	XmLGridCell c;
8590 
8591 	c = (XmLGridCell)malloc(sizeof(struct _XmLGridCellRec));
8592 	c->cell.refValues = 0;
8593 	c->cell.flags = 0;
8594 	return c;
8595 	}
8596 
8597 static void
XmLGridCellFree(Widget grid,XmLGridCell cell)8598 XmLGridCellFree(Widget grid,
8599 		XmLGridCell cell)
8600 	{
8601 	XmLGridCallbackStruct cbs;
8602 
8603 	cbs.reason = XmCR_FREE_VALUE;
8604 	XmLGridCellAction(cell, grid, &cbs);
8605 	XmLGridCellDerefValues(cell->cell.refValues);
8606 	free((char *)cell);
8607 	}
8608 
8609 static int
XmLGridCellAction(XmLGridCell cell,Widget w,XmLGridCallbackStruct * cbs)8610 XmLGridCellAction(XmLGridCell cell,
8611 		  Widget w,
8612 		  XmLGridCallbackStruct *cbs)
8613 	{
8614 	return XmLGridClassPartOfWidget(w).cellActionProc(cell, w, cbs);
8615 	}
8616 
8617 /* Only to be called through Grid class */
8618 static int
_GridCellAction(XmLGridCell cell,Widget w,XmLGridCallbackStruct * cbs)8619 _GridCellAction(XmLGridCell cell,
8620 		Widget w,
8621 		XmLGridCallbackStruct *cbs)
8622 	{
8623 	int ret;
8624 
8625 	ret = 0;
8626 	switch (cbs->reason)
8627 		{
8628 		case XmCR_CELL_DRAW:
8629 			_XmLGridCellDrawBackground(cell, w, cbs->clipRect, cbs->drawInfo);
8630 			_XmLGridCellDrawValue(cell, w, cbs->clipRect, cbs->drawInfo);
8631 			_XmLGridCellDrawBorders(cell, w, cbs->clipRect, cbs->drawInfo);
8632 			break;
8633 		case XmCR_CELL_FOCUS_IN:
8634 			break;
8635 		case XmCR_CELL_FOCUS_OUT:
8636 			break;
8637 		case XmCR_CONF_TEXT:
8638 			_XmLGridCellConfigureText(cell, w, cbs->clipRect);
8639 			break;
8640 		case XmCR_EDIT_BEGIN:
8641 			ret = _XmLGridCellBeginTextEdit(cell, w, cbs->clipRect);
8642 			break;
8643 		case XmCR_EDIT_CANCEL:
8644 			break;
8645 		case XmCR_EDIT_COMPLETE:
8646 			_XmLGridCellCompleteTextEdit(cell, w);
8647 			break;
8648 		case XmCR_EDIT_INSERT:
8649 			ret = _XmLGridCellBeginTextEdit(cell, w, cbs->clipRect);
8650 			if (ret)
8651 				_XmLGridCellInsertText(cell, w);
8652 			break;
8653 		case XmCR_FREE_VALUE:
8654 			_XmLGridCellFreeValue(cell);
8655 			break;
8656 		case XmCR_PREF_HEIGHT:
8657 			ret = _XmLGridCellGetHeight(cell, w,(XmLGridRow)cbs->object);
8658 			break;
8659 		case XmCR_PREF_WIDTH:
8660 			ret = _XmLGridCellGetWidth(cell, w,(XmLGridColumn)cbs->object);
8661 			break;
8662 		}
8663 	return ret;
8664 	}
8665 
8666 static XmLGridCellRefValues *
XmLGridCellGetRefValues(XmLGridCell cell)8667 XmLGridCellGetRefValues(XmLGridCell cell)
8668 	{
8669 	return cell->cell.refValues;
8670 	}
8671 
8672 static void
XmLGridCellSetRefValues(XmLGridCell cell,XmLGridCellRefValues * values)8673 XmLGridCellSetRefValues(XmLGridCell cell,
8674 			XmLGridCellRefValues *values)
8675 	{
8676 	values->refCount++;
8677 	XmLGridCellDerefValues(cell->cell.refValues);
8678 	cell->cell.refValues = values;
8679 	}
8680 
8681 static void
XmLGridCellDerefValues(XmLGridCellRefValues * values)8682 XmLGridCellDerefValues(XmLGridCellRefValues *values)
8683 	{
8684 	if (!values)
8685 		return;
8686 	values->refCount--;
8687 	if (!values->refCount)
8688 		{
8689 		XmFontListFree(values->fontList);
8690 		free((char *)values);
8691 		}
8692 	}
8693 
8694 static Boolean
XmLGridCellInRowSpan(XmLGridCell cell)8695 XmLGridCellInRowSpan(XmLGridCell cell)
8696 	{
8697 	if (cell->cell.flags & XmLGridCellInRowSpanFlag)
8698 		return True;
8699 	return False;
8700 	}
8701 
8702 static Boolean
XmLGridCellInColumnSpan(XmLGridCell cell)8703 XmLGridCellInColumnSpan(XmLGridCell cell)
8704 	{
8705 	if (cell->cell.flags & XmLGridCellInColumnSpanFlag)
8706 		return True;
8707 	return False;
8708 	}
8709 
8710 static Boolean
XmLGridCellIsSelected(XmLGridCell cell)8711 XmLGridCellIsSelected(XmLGridCell cell)
8712 	{
8713 	if (cell->cell.flags & XmLGridCellSelectedFlag)
8714 		return True;
8715 	return False;
8716 	}
8717 
8718 static Boolean
XmLGridCellIsValueSet(XmLGridCell cell)8719 XmLGridCellIsValueSet(XmLGridCell cell)
8720 	{
8721 	if (cell->cell.flags & XmLGridCellValueSetFlag)
8722 		return True;
8723 	return False;
8724 	}
8725 
8726 static void
XmLGridCellSetValueSet(XmLGridCell cell,Boolean set)8727 XmLGridCellSetValueSet(XmLGridCell cell,
8728 		       Boolean set)
8729 	{
8730 	cell->cell.flags |= XmLGridCellValueSetFlag;
8731 	if (set != True)
8732 		cell->cell.flags ^= XmLGridCellValueSetFlag;
8733 	}
8734 
8735 static void
XmLGridCellSetInRowSpan(XmLGridCell cell,Boolean set)8736 XmLGridCellSetInRowSpan(XmLGridCell cell,
8737 			Boolean set)
8738 	{
8739 	cell->cell.flags |= XmLGridCellInRowSpanFlag;
8740 	if (set != True)
8741 		cell->cell.flags ^= XmLGridCellInRowSpanFlag;
8742 	}
8743 
8744 static void
XmLGridCellSetInColumnSpan(XmLGridCell cell,Boolean set)8745 XmLGridCellSetInColumnSpan(XmLGridCell cell,
8746 			   Boolean set)
8747 	{
8748 	cell->cell.flags |= XmLGridCellInColumnSpanFlag;
8749 	if (set != True)
8750 		cell->cell.flags ^= XmLGridCellInColumnSpanFlag;
8751 	}
8752 
8753 static void
XmLGridCellSetSelected(XmLGridCell cell,Boolean selected)8754 XmLGridCellSetSelected(XmLGridCell cell,
8755 		       Boolean selected)
8756 	{
8757 	cell->cell.flags |= XmLGridCellSelectedFlag;
8758 	if (selected != True)
8759 		cell->cell.flags ^= XmLGridCellSelectedFlag;
8760 	}
8761 
8762 /*Xfe Additions*/
8763 static Boolean
XmLGridCellDrawSort(XmLGridCell cell)8764 XmLGridCellDrawSort(XmLGridCell cell)
8765 	{
8766 	if (cell->cell.flags & XmLGridCellDrawSortFlag)
8767 		return True;
8768 	return False;
8769 	}
8770 static Boolean
XmLGridCellSortAscending(XmLGridCell cell)8771 XmLGridCellSortAscending(XmLGridCell cell)
8772 	{
8773 	if (cell->cell.flags & XmLGridCellSortAscendingFlag)
8774 		return True;
8775 	return False;
8776 	}
8777 static void
XmLGridCellSetDrawSort(XmLGridCell cell,Boolean drawSort)8778 XmLGridCellSetDrawSort(XmLGridCell cell, Boolean drawSort)
8779 	{
8780 	cell->cell.flags |= XmLGridCellDrawSortFlag;
8781 	if (drawSort != True)
8782 		cell->cell.flags ^= XmLGridCellDrawSortFlag;
8783 	}
8784 static void
XmLGridCellSetSortAscending(XmLGridCell cell,Boolean ascending)8785 XmLGridCellSetSortAscending(XmLGridCell cell, Boolean ascending)
8786 	{
8787 	cell->cell.flags |= XmLGridCellSortAscendingFlag;
8788 	if (ascending != True)
8789 		cell->cell.flags ^= XmLGridCellSortAscendingFlag;
8790 	}
8791 
8792 
8793 static void
XmLGridCellAllocIcon(XmLGridCell cell)8794 XmLGridCellAllocIcon(XmLGridCell cell)
8795 	{
8796 	XmLGridCellIcon *icon;
8797 
8798 	icon = (XmLGridCellIcon *)malloc(sizeof(XmLGridCellIcon));
8799 	icon->pix.pixmap = XmUNSPECIFIED_PIXMAP;
8800 	icon->pix.pixmask = XmUNSPECIFIED_PIXMAP;
8801 	icon->pix.width = 0;
8802 	icon->pix.height = 0;
8803 	icon->string = 0;
8804 	cell->cell.value = (void *)icon;
8805 	XmLGridCellSetValueSet(cell, True);
8806 	}
8807 
8808 static void
XmLGridCellAllocPixmap(XmLGridCell cell)8809 XmLGridCellAllocPixmap(XmLGridCell cell)
8810 	{
8811 	XmLGridCellPixmap *pix;
8812 
8813 	pix = (XmLGridCellPixmap *)malloc(sizeof(XmLGridCellPixmap));
8814 	pix->width = 0;
8815 	pix->height = 0;
8816 	pix->pixmap = XmUNSPECIFIED_PIXMAP;
8817 	pix->pixmask = XmUNSPECIFIED_PIXMAP;
8818 	cell->cell.value = (void *)pix;
8819 	XmLGridCellSetValueSet(cell, True);
8820 	}
8821 
8822 static void
XmLGridCellSetString(XmLGridCell cell,XmString string,Boolean copy)8823 XmLGridCellSetString(XmLGridCell cell,
8824 		     XmString string,
8825 		     Boolean copy)
8826 	{
8827 	XmLGridCellIcon *icon;
8828 
8829 	if (cell->cell.refValues->type == XmSTRING_CELL)
8830 		{
8831 		_XmLGridCellFreeValue(cell);
8832 		if (string)
8833 			{
8834 			if (copy == True)
8835 				cell->cell.value = (void *)XmStringCopy(string);
8836 			else
8837 				cell->cell.value = (void *)string;
8838 			XmLGridCellSetValueSet(cell, True);
8839 			}
8840 		else
8841 			XmLGridCellSetValueSet(cell, False);
8842 		}
8843 	else if (cell->cell.refValues->type == XmICON_CELL)
8844 		{
8845 		if (XmLGridCellIsValueSet(cell) == False)
8846 			XmLGridCellAllocIcon(cell);
8847 		icon = (XmLGridCellIcon *)cell->cell.value;
8848 		if (icon->string)
8849 			XmStringFree(icon->string);
8850 		if (string && copy == True)
8851 			icon->string = XmStringCopy(string);
8852 		else
8853 			icon->string = string;
8854 		}
8855 	else if (string && copy == False)
8856 		XmStringFree(string);
8857 	}
8858 
8859 static XmString
XmLGridCellGetString(XmLGridCell cell)8860 XmLGridCellGetString(XmLGridCell cell)
8861 	{
8862 	XmString str;
8863 
8864 	str = 0;
8865 	if (cell->cell.refValues->type == XmSTRING_CELL)
8866 		{
8867 		if (XmLGridCellIsValueSet(cell) == True)
8868 			str = (XmString)cell->cell.value;
8869 		}
8870 	else if (cell->cell.refValues->type == XmICON_CELL)
8871 		{
8872 		if (XmLGridCellIsValueSet(cell) == True)
8873 			str = ((XmLGridCellIcon *)cell->cell.value)->string;
8874 		}
8875 	return str;
8876 	}
8877 
8878 static void
XmLGridCellSetToggle(XmLGridCell cell,Boolean state)8879 XmLGridCellSetToggle(XmLGridCell cell,
8880 		     Boolean state)
8881 	{
8882 	if (cell->cell.refValues->type == XmTOGGLE_CELL)
8883 		{
8884 		if (state)
8885 			cell->cell.value = (void *)1;
8886 		else
8887 			cell->cell.value = (void *)0;
8888 		XmLGridCellSetValueSet(cell, True);
8889 		}
8890 	}
8891 
8892 static Boolean
XmLGridCellGetToggle(XmLGridCell cell)8893 XmLGridCellGetToggle(XmLGridCell cell)
8894 	{
8895 	Boolean toggled;
8896 
8897 	toggled = False;
8898 	if (cell->cell.refValues->type == XmTOGGLE_CELL)
8899 		{
8900 		if (XmLGridCellIsValueSet(cell) == True &&
8901 			cell->cell.value == (void *)1)
8902 			toggled = True;
8903 		}
8904 	return toggled;
8905 	}
8906 
8907 static void
XmLGridCellSetPixmap(XmLGridCell cell,Pixmap pixmap,Dimension width,Dimension height)8908 XmLGridCellSetPixmap(XmLGridCell cell,
8909 		     Pixmap pixmap,
8910 		     Dimension width,
8911 		     Dimension height)
8912 	{
8913 	XmLGridCellPixmap *pix;
8914 
8915 	pix = 0;
8916 	if (cell->cell.refValues->type == XmPIXMAP_CELL)
8917 		{
8918 		if (XmLGridCellIsValueSet(cell) == False)
8919 			XmLGridCellAllocPixmap(cell);
8920 		pix = (XmLGridCellPixmap *)cell->cell.value;
8921 		}
8922 	else if (cell->cell.refValues->type == XmICON_CELL)
8923 		{
8924 		if (XmLGridCellIsValueSet(cell) == False)
8925 			XmLGridCellAllocIcon(cell);
8926 		pix = &((XmLGridCellIcon *)cell->cell.value)->pix;
8927 		}
8928 	if (!pix)
8929 		return;
8930 	pix->pixmap = pixmap;
8931 	pix->height = height;
8932 	pix->width = width;
8933 	}
8934 
8935 static void
XmLGridCellSetPixmask(XmLGridCell cell,Pixmap pixmask)8936 XmLGridCellSetPixmask(XmLGridCell cell,
8937 		      Pixmap pixmask)
8938 	{
8939 	XmLGridCellPixmap *pix;
8940 
8941 	if (XmLGridCellIsValueSet(cell) == False)
8942 		{
8943 		fprintf(stderr, "XmLGridCellSetPixmask: pixmap must be set ");
8944 		fprintf(stderr, "before pixmask\n");
8945 		return;
8946 		}
8947 	pix = 0;
8948 	if (cell->cell.refValues->type == XmPIXMAP_CELL)
8949 		pix = (XmLGridCellPixmap *)cell->cell.value;
8950 	else if (cell->cell.refValues->type == XmICON_CELL)
8951 		pix = &((XmLGridCellIcon *)cell->cell.value)->pix;
8952 	if (!pix)
8953 		return;
8954 	pix->pixmask = pixmask;
8955 	}
8956 
8957 static XmLGridCellPixmap *
XmLGridCellGetPixmap(XmLGridCell cell)8958 XmLGridCellGetPixmap(XmLGridCell cell)
8959 	{
8960 	XmLGridCellPixmap *pix;
8961 
8962 	pix = 0;
8963 	if (cell->cell.refValues->type == XmPIXMAP_CELL)
8964 		{
8965 		if (XmLGridCellIsValueSet(cell) == True)
8966 			pix = (XmLGridCellPixmap *)cell->cell.value;
8967 		}
8968 	else if (cell->cell.refValues->type == XmICON_CELL)
8969 		{
8970 		if (XmLGridCellIsValueSet(cell) == True)
8971 			pix = &((XmLGridCellIcon *)cell->cell.value)->pix;
8972 		}
8973 	return pix;
8974 	}
8975 
8976 /* Only to be called by XmLGridCellAction() */
8977 void
_XmLGridCellDrawBackground(XmLGridCell cell,Widget w,XRectangle * clipRect,XmLGridDrawStruct * ds)8978 _XmLGridCellDrawBackground(XmLGridCell cell,
8979 			   Widget w,
8980 			   XRectangle *clipRect,
8981 			   XmLGridDrawStruct *ds)
8982 	{
8983 	Display *dpy;
8984 	Window win;
8985 
8986 	dpy = XtDisplay(w);
8987 	win = XtWindow(w);
8988 	if (ds->drawSelected == True)
8989 		XSetForeground(dpy, ds->gc, ds->selectBackground);
8990 	else
8991 		XSetForeground(dpy, ds->gc, ds->background);
8992 	XFillRectangle(dpy, win, ds->gc, clipRect->x, clipRect->y,
8993 		clipRect->width, clipRect->height);
8994 	}
8995 
8996 /* Only to be called by XmLGridCellAction() */
8997 void
_XmLGridCellDrawBorders(XmLGridCell cell,Widget w,XRectangle * clipRect,XmLGridDrawStruct * ds)8998 _XmLGridCellDrawBorders(XmLGridCell cell,
8999 			Widget w,
9000 			XRectangle *clipRect,
9001 			XmLGridDrawStruct *ds)
9002 	{
9003 	XmLGridWidget g;
9004 	Display *dpy;
9005 	Window win;
9006 	GC gc;
9007 	Pixel black, white;
9008 	int x1, x2, y1, y2, loff, roff;
9009 	int drawLeft, drawRight, drawBot, drawTop;
9010 	XRectangle *cellRect;
9011 	unsigned char borderType;
9012 
9013 	g = (XmLGridWidget)w;
9014 	dpy = XtDisplay(w);
9015 	win = XtWindow(w);
9016 	gc = ds->gc;
9017 	cellRect = ds->cellRect;
9018 	black = BlackPixelOfScreen(XtScreen(w));
9019 	white = WhitePixelOfScreen(XtScreen(w));
9020 	x1 = clipRect->x;
9021 	x2 = clipRect->x + clipRect->width - 1;
9022 	y1 = clipRect->y;
9023 	y2 = clipRect->y + clipRect->height - 1;
9024 	drawLeft = 1;
9025 	drawRight = 1;
9026 	drawBot = 1;
9027 	drawTop = 1;
9028 	if (cellRect->x != clipRect->x)
9029 		drawLeft = 0;
9030 	if (cellRect->x + cellRect->width != clipRect->x + clipRect->width)
9031 		drawRight = 0;
9032 	if (cellRect->y != clipRect->y)
9033 		drawTop = 0;
9034 	if (cellRect->y + cellRect->height != clipRect->y + clipRect->height)
9035 		drawBot = 0;
9036 	borderType = cell->cell.refValues->rightBorderType;
9037 	if (borderType != XmBORDER_NONE && drawRight)
9038 		{
9039 		if (borderType == XmBORDER_DASH)
9040 			XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinMiter);
9041 		XSetForeground(dpy, gc, cell->cell.refValues->rightBorderColor);
9042 		XDrawLine(dpy, win, gc, x2, y1, x2, y2);
9043 		if (borderType == XmBORDER_DASH)
9044 			XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinMiter);
9045 		}
9046 	borderType = cell->cell.refValues->bottomBorderType;
9047 	if (borderType != XmBORDER_NONE && drawBot)
9048 		{
9049 		if (borderType == XmBORDER_DASH)
9050 			XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinMiter);
9051 		XSetForeground(dpy, gc, cell->cell.refValues->bottomBorderColor);
9052 		XDrawLine(dpy, win, gc, x1, y2, x2, y2);
9053 		if (borderType == XmBORDER_DASH)
9054 			XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinMiter);
9055 		}
9056 	borderType = cell->cell.refValues->topBorderType;
9057 	if (borderType != XmBORDER_NONE && drawTop)
9058 		{
9059 		if (borderType == XmBORDER_DASH)
9060 			XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinMiter);
9061 		XSetForeground(dpy, gc, cell->cell.refValues->topBorderColor);
9062 		XDrawLine(dpy, win, gc, x1, y1, x2, y1);
9063 		if (borderType == XmBORDER_DASH)
9064 			XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinMiter);
9065 		}
9066 	borderType = cell->cell.refValues->leftBorderType;
9067 	if (borderType != XmBORDER_NONE && drawLeft)
9068 		{
9069 		if (borderType == XmBORDER_DASH)
9070 			XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinMiter);
9071 		XSetForeground(dpy, gc, cell->cell.refValues->leftBorderColor);
9072 		XDrawLine(dpy, win, gc, x1, y1, x1, y2);
9073 		if (borderType == XmBORDER_DASH)
9074 			XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinMiter);
9075 		}
9076 	if (ds->drawFocusType == XmDRAW_FOCUS_NONE)
9077 		return;
9078 	if (ds->drawFocusType == XmDRAW_FOCUS_LEFT)
9079 		drawRight = 0;
9080 	else if (ds->drawFocusType == XmDRAW_FOCUS_RIGHT)
9081 		drawLeft = 0;
9082 	else if (ds->drawFocusType == XmDRAW_FOCUS_MID)
9083 		{
9084 		drawLeft = 0;
9085 		drawRight = 0;
9086 		}
9087 	if (!drawLeft)
9088 		loff = 0;
9089 	else
9090 		loff = 2;
9091 	if (!drawRight)
9092 		roff = 0;
9093 	else
9094 		roff = 2;
9095 	if (g->grid.highlightThickness < 2)
9096 		return;
9097 	XSetForeground(dpy, gc, g->manager.highlight_color);
9098 	if (drawTop)
9099 		XDrawLine(dpy, win, gc, x1, y1, x2, y1);
9100 	if (drawLeft)
9101 		XDrawLine(dpy, win, gc, x1, y1 + 2, x1, y2);
9102 	if (drawRight)
9103 		XDrawLine(dpy, win, gc, x2, y1 + 2, x2, y2);
9104 	if (drawBot)
9105 		XDrawLine(dpy, win, gc, x1 + loff, y2, x2 - roff, y2);
9106 	if (drawTop && clipRect->height > 1)
9107 		XDrawLine(dpy, win, gc, x1, y1 + 1, x2, y1 + 1);
9108 	if (drawBot && (int)clipRect->height > 1 &&
9109 		(int)clipRect->width > roff &&
9110 		(int)clipRect->width > loff)
9111 		XDrawLine(dpy, win, gc, x1 + loff, y2 - 1, x2 - roff, y2 - 1);
9112 	if (clipRect->width > 1 && clipRect->height > 2)
9113 		{
9114 		if (drawLeft)
9115 			XDrawLine(dpy, win, gc, x1 + 1, y1 + 2, x1 + 1, y2);
9116 		if (drawRight)
9117 			XDrawLine(dpy, win, gc, x2 - 1, y1 + 2, x2 - 1, y2);
9118 		}
9119 	}
9120 
9121 /* Only to be called by XmLGridCellAction() */
9122 void
_XmLGridCellDrawValue(XmLGridCell cell,Widget w,XRectangle * clipRect,XmLGridDrawStruct * ds)9123 _XmLGridCellDrawValue(XmLGridCell cell,
9124 		      Widget w,
9125 		      XRectangle *clipRect,
9126 		      XmLGridDrawStruct *ds)
9127 	{
9128 	XmLGridWidget g;
9129 	Display *dpy;
9130 	XmLGridCellPixmap *pix;
9131 	XmLGridCellIcon *icon;
9132 	XRectangle cellRect;
9133 	XmLGridCellRefValues *cellValues;
9134 	int type, horizMargin, vertMargin, xoff;
9135 
9136 	g = (XmLGridWidget)w;
9137 	cellRect = *ds->cellRect;
9138 	cellValues = cell->cell.refValues;
9139 	horizMargin = ds->leftMargin + ds->rightMargin;
9140 	vertMargin = ds->topMargin + ds->bottomMargin;
9141 	if (horizMargin >= (int)cellRect.width ||
9142 		vertMargin >= (int)cellRect.height)
9143 		return;
9144 	type = cellValues->type;
9145 	cellRect.x += ds->leftMargin;
9146 	cellRect.y += ds->topMargin;
9147 	cellRect.width -= horizMargin;
9148 	cellRect.height -= vertMargin;
9149 	dpy = XtDisplay(w);
9150 	if (type == XmSTRING_CELL && XmLGridCellIsValueSet(cell) == True)
9151 		{
9152 		if (ds->drawSelected == True)
9153 			XSetForeground(dpy, ds->gc, ds->selectForeground);
9154 		else
9155 			XSetForeground(dpy, ds->gc, ds->foreground);
9156 		XmLStringDraw(w, (XmString)cell->cell.value, ds->stringDirection,
9157 			ds->fontList, ds->alignment, ds->gc,
9158 			&cellRect, clipRect);
9159 		}
9160 	if (type == XmPIXMAP_CELL && XmLGridCellIsValueSet(cell) == True)
9161 		{
9162 		pix = (XmLGridCellPixmap *)cell->cell.value;
9163 		XmLPixmapDraw(w, pix->pixmap, pix->pixmask,
9164 			pix->width, pix->height, ds->alignment,
9165 			ds->gc, &cellRect, clipRect);
9166 		}
9167 	if (type == XmICON_CELL && XmLGridCellIsValueSet(cell) == True)
9168 		{
9169 		icon = (XmLGridCellIcon *)cell->cell.value;
9170 		if (icon->pix.pixmap != XmUNSPECIFIED_PIXMAP)
9171 			{
9172 			XmLPixmapDraw(w, icon->pix.pixmap, icon->pix.pixmask,
9173 				icon->pix.width, icon->pix.height, ds->alignment,
9174 				ds->gc, &cellRect, clipRect);
9175 			xoff = icon->pix.width + g->grid.iconSpacing;
9176 			cellRect.x += xoff;
9177 			if (xoff < (int)cellRect.width)
9178 				cellRect.width -= xoff;
9179 			else
9180 				cellRect.width = 0;
9181 			}
9182 		if (cellRect.width && icon->string)
9183 			{
9184 			if (ds->drawSelected == True)
9185 				XSetForeground(dpy, ds->gc, ds->selectForeground);
9186 			else
9187 				XSetForeground(dpy, ds->gc, ds->foreground);
9188 			XmLStringDraw(w, icon->string, ds->stringDirection,
9189 				ds->fontList, ds->alignment, ds->gc,
9190 				&cellRect, clipRect);
9191 			}
9192 		}
9193 	if (type == XmTOGGLE_CELL)
9194 		XmLDrawToggle(w, XmLGridCellGetToggle(cell),
9195 			g->grid.toggleSize, ds->alignment, ds->gc,
9196 			ds->background, g->grid.toggleTopColor,
9197 			g->grid.toggleBotColor, ds->foreground,
9198 			&cellRect, clipRect);
9199 
9200     if (cellRect.width > cellRect.height - 4 && XmLGridCellDrawSort(cell))
9201 		{
9202         int arrow_direction = XmLGridCellSortAscending(cell);
9203         int arrow_size = cellRect.height * 0.75;
9204 
9205 		if (arrow_size > 0)
9206 			{
9207 			XSetForeground(dpy, ds->gc, ds->background);
9208 
9209 			_XmDrawArrow(dpy, XtWindow(w),
9210 						 ((XmManagerWidget)g)->manager.bottom_shadow_GC,
9211 						 ((XmManagerWidget)g)->manager.top_shadow_GC,
9212 						 ds->gc,
9213 						 cellRect.x + cellRect.width - arrow_size - 2,
9214 						 cellRect.y + (cellRect.height / 2 - arrow_size / 2),
9215 						 arrow_size,
9216 						 arrow_size,
9217 						 2,
9218 						 arrow_direction);
9219 			}
9220 		}
9221 
9222 	}
9223 
9224 /* Only to be called by XmLGridCellAction() */
9225 static int
_XmLGridCellConfigureText(XmLGridCell cell,Widget w,XRectangle * rect)9226 _XmLGridCellConfigureText(XmLGridCell cell, Widget w, XRectangle *rect)
9227 	{
9228 	XmLGridWidget g;
9229 
9230 	g = (XmLGridWidget)w;
9231 	XtConfigureWidget(g->grid.text, rect->x, rect->y,
9232 		rect->width, rect->height, 0);
9233 	return(0);
9234 	}
9235 
9236 /* Only to be called by XmLGridCellAction() */
9237 static int
_XmLGridCellBeginTextEdit(XmLGridCell cell,Widget w,XRectangle * clipRect)9238 _XmLGridCellBeginTextEdit(XmLGridCell cell,
9239 			  Widget w,
9240 			  XRectangle *clipRect)
9241 	{
9242         XmLGridWidget g = (XmLGridWidget)w;
9243 	Widget text;
9244 
9245 	if ((cell->cell.refValues->type != XmSTRING_CELL &&
9246          cell->cell.refValues->type != XmICON_CELL)
9247         || cell->cell.refValues->editable != True
9248 	    || g->grid.useTextWidget != True)
9249 		return 0;
9250 	XtVaGetValues(w,
9251 		XmNtextWidget, &text,
9252 		NULL);
9253 	XtVaSetValues(text,
9254 		XmNfontList, cell->cell.refValues->fontList,
9255 		NULL);
9256 	return 1;
9257 	}
9258 
9259 /* Only to be called by XmLGridCellAction() */
9260 static void
_XmLGridCellCompleteTextEdit(XmLGridCell cell,Widget w)9261 _XmLGridCellCompleteTextEdit(XmLGridCell cell,
9262 			     Widget w)
9263 	{
9264         XmLGridWidget g = (XmLGridWidget)w;
9265 	Widget text;
9266 	char *s;
9267 	int i, len;
9268 
9269 	if ((cell->cell.refValues->type != XmSTRING_CELL &&
9270          cell->cell.refValues->type != XmICON_CELL)
9271         || cell->cell.refValues->editable != True
9272 	    || g->grid.useTextWidget != True)
9273 		return;
9274 	XtVaGetValues(w,
9275 		XmNtextWidget, &text,
9276 		NULL);
9277 	s = XmTextGetString(text);
9278 	len = strlen(s);
9279 	for (i = 0; i < len - 1; i++)
9280 		if (s[i] == '\\' && s[i + 1] == 'n')
9281 			{
9282 			s[i] = '\n';
9283 			strcpy(&s[i + 1], &s[i + 2]);
9284 			}
9285     XmLGridCellSetString(cell,
9286                          XmStringCreateLtoR(s, XmSTRING_DEFAULT_CHARSET),
9287                          False);
9288 #if 0
9289     if (XmLGridCellIsValueSet(cell) == True)
9290 		XmStringFree((XmString)cell->cell.value);
9291 	if (strlen(s))
9292 		{
9293 		cell->cell.value = (void *)XmStringCreateLtoR(s,
9294 			XmSTRING_DEFAULT_CHARSET);
9295 		XmLGridCellSetValueSet(cell, True);
9296 		}
9297 	else
9298 		XmLGridCellSetValueSet(cell, False);
9299 #endif /*0*/
9300 	XtFree(s);
9301 	}
9302 
9303 /* Only to be called by XmLGridCellAction() */
9304 static void
_XmLGridCellInsertText(XmLGridCell cell,Widget w)9305 _XmLGridCellInsertText(XmLGridCell cell,
9306 		       Widget w)
9307 	{
9308         XmLGridWidget g = (XmLGridWidget)w;
9309 	char *s;
9310 	Widget text = NULL;
9311 
9312 	if ((cell->cell.refValues->type != XmSTRING_CELL &&
9313          cell->cell.refValues->type != XmICON_CELL)
9314         || cell->cell.refValues->editable != True
9315 	    || g->grid.useTextWidget != True)
9316       return;
9317 	XtVaGetValues(w,
9318 		XmNtextWidget, &text,
9319 		NULL);
9320 	s = 0;
9321 	if (XmLGridCellIsValueSet(cell) == True)
9322 		s = CvtXmStringToStr(XmLGridCellGetString(cell));
9323 	if (s)
9324 		{
9325 		XmTextSetString(text, s);
9326 		free(s);
9327 		}
9328 	else
9329 		XmTextSetString(text, "");
9330 	XmTextSetInsertionPosition(text, XmTextGetLastPosition(text));
9331 	XmProcessTraversal(text, XmTRAVERSE_CURRENT);
9332 	}
9333 
9334 /* Only to be called by XmLGridCellAction() */
9335 static int
_XmLGridCellGetHeight(XmLGridCell cell,Widget w,XmLGridRow row)9336 _XmLGridCellGetHeight(XmLGridCell cell,
9337 					  Widget w,
9338 					  XmLGridRow row)
9339 	{
9340 	XmLGridCellPixmap *pix;
9341 	XmLGridCellIcon *icon;
9342 	XmLGridCellRefValues *cellValues;
9343 	int height, pixHeight;
9344 
9345 	cellValues = cell->cell.refValues;
9346 	height = -1;
9347 	if (cellValues->type == XmPIXMAP_CELL)
9348 		{
9349 		if (XmLGridCellIsValueSet(cell) == True)
9350 			{
9351 			pix = (XmLGridCellPixmap *)cell->cell.value;
9352 			if (pix->height)
9353 				height = 4 + pix->height + cellValues->topMargin +
9354 					cellValues->bottomMargin;
9355 			}
9356 		}
9357 	else if (cellValues->type == XmICON_CELL)
9358 		{
9359 		pixHeight = 0;
9360 		if (XmLGridCellIsValueSet(cell) == True)
9361 			{
9362 			icon = (XmLGridCellIcon *)cell->cell.value;
9363 			if (icon->pix.pixmap != XmUNSPECIFIED_PIXMAP && icon->pix.height)
9364 				pixHeight = 4 + icon->pix.height +
9365 					cellValues->topMargin + cellValues->bottomMargin;
9366 			}
9367 		height = 4 + row->grid.height * cellValues->fontHeight +
9368 			cellValues->topMargin + cellValues->bottomMargin;
9369 		if (pixHeight > height)
9370 			height = pixHeight;
9371 		}
9372 	else if (cellValues->type == XmTOGGLE_CELL)
9373 		height = 4 + 16 + cellValues->topMargin +
9374 			cellValues->bottomMargin;
9375 	else if (cellValues->type == XmSTRING_CELL)
9376 		{
9377 		height = 4 + row->grid.height * cellValues->fontHeight +
9378 			cellValues->topMargin + cellValues->bottomMargin;
9379 		}
9380 	if (height < 0 || cellValues->rowSpan)
9381 		height = 4;
9382 	return height;
9383 	}
9384 
9385 /* Only to be called by XmLGridCellAction() */
9386 static int
_XmLGridCellGetWidth(XmLGridCell cell,Widget w,XmLGridColumn col)9387 _XmLGridCellGetWidth(XmLGridCell cell,
9388 					 Widget w,
9389 					 XmLGridColumn col)
9390 	{
9391 	XmLGridWidget g = (XmLGridWidget)w;
9392 	XmLGridCellPixmap *pix;
9393 	XmLGridCellIcon *icon;
9394 	XmLGridCellRefValues *cellValues;
9395 	int width;
9396 
9397 	cellValues = cell->cell.refValues;
9398 	width = -1;
9399 	if (cellValues->type == XmPIXMAP_CELL)
9400 		{
9401 		if (XmLGridCellIsValueSet(cell) == True)
9402 			{
9403 			pix = (XmLGridCellPixmap *)cell->cell.value;
9404 			if (pix->width)
9405 				width = 4 + pix->width + cellValues->leftMargin +
9406 					cellValues->rightMargin;
9407 			}
9408 		}
9409 	else if (cellValues->type == XmICON_CELL)
9410 		{
9411 		width = 4 + col->grid.width * cellValues->fontWidth +
9412 			cellValues->leftMargin + cellValues->rightMargin;
9413 		if (XmLGridCellIsValueSet(cell) == True)
9414 			{
9415 			icon = (XmLGridCellIcon *)cell->cell.value;
9416 			if (icon->pix.pixmap != XmUNSPECIFIED_PIXMAP && icon->pix.width)
9417 				width += icon->pix.width + g->grid.iconSpacing;
9418 			}
9419 		}
9420 	else if (cellValues->type == XmTOGGLE_CELL)
9421 		width = 4 + 16 + cellValues->leftMargin +
9422 			cellValues->rightMargin;
9423 	else if (cellValues->type == XmSTRING_CELL)
9424 		width = 4 + col->grid.width * cellValues->fontWidth +
9425 			cellValues->leftMargin + cellValues->rightMargin;
9426 	if (width < 0 || cellValues->columnSpan)
9427 		width = 4;
9428 	return width;
9429 	}
9430 
9431 /* Only to be called by XmLGridCellAction() */
9432 static void
_XmLGridCellFreeValue(XmLGridCell cell)9433 _XmLGridCellFreeValue(XmLGridCell cell)
9434 	{
9435 	int type;
9436 	XmLGridCellIcon *icon;
9437 
9438 	if (XmLGridCellIsValueSet(cell) == False)
9439 		return;
9440 	type = cell->cell.refValues->type;
9441 	if (type == XmSTRING_CELL)
9442 		XmStringFree((XmString)cell->cell.value);
9443 	else if (type == XmPIXMAP_CELL)
9444 		free((char *)cell->cell.value);
9445 	else if (type == XmICON_CELL)
9446 		{
9447 		icon = (XmLGridCellIcon *)cell->cell.value;
9448 		if (icon->string)
9449 			XmStringFree(icon->string);
9450 		free((char *)icon);
9451 		}
9452 	XmLGridCellSetValueSet(cell, False);
9453 	}
9454 
9455 /*
9456    Public Functions
9457 */
9458 
9459 Widget
XmLCreateGrid(Widget parent,char * name,ArgList arglist,Cardinal argcount)9460 XmLCreateGrid(Widget parent,
9461 	      char *name,
9462 	      ArgList arglist,
9463 	      Cardinal argcount)
9464 	{
9465 	return XtCreateWidget(name, xmlGridWidgetClass, parent,
9466 		arglist, argcount);
9467 	}
9468 
9469 void
XmLGridAddColumns(Widget w,unsigned char type,int position,int count)9470 XmLGridAddColumns(Widget w,
9471 		  unsigned char type,
9472 		  int position,
9473 		  int count)
9474 	{
9475 	XmLGridWidget g;
9476 	XmLGridColumn col;
9477 	XmLGridRow row;
9478 	XmLGridCell cell;
9479 	XmLGridCallbackStruct cbs;
9480 	int i, j, rowCount, hasAddCB, redraw;
9481 
9482 	g = WidgetToGrid(w, "AddColumns()");
9483 	if (!g)
9484 		return;
9485 	if (count <= 0)
9486 		return;
9487 	redraw = 0;
9488 	position = ColTypePosToPos(g, type, position, 1);
9489 	if (position < 0)
9490 		position = ColTypePosToPos(g, type, -1, 1);
9491 	/* adjust count */
9492 	if (type == XmHEADING)
9493 		{
9494 		g->grid.headingColCount += count;
9495 		g->grid.leftFixedCount += count;
9496 		redraw = 1;
9497 		}
9498 	else if (type == XmFOOTER)
9499 		{
9500 		g->grid.footerColCount += count;
9501 		g->grid.rightFixedCount += count;
9502 		redraw = 1;
9503 		}
9504 	else /* XmCONTENT */
9505 		g->grid.colCount += count;
9506 
9507 	hasAddCB = 0;
9508 	if (XtHasCallbacks(w, XmNaddCallback) == XtCallbackHasSome)
9509 		hasAddCB = 1;
9510 	/* add columns */
9511 	XmLArrayAdd(g->grid.colArray, position, count);
9512 	for (i = 0; i < count; i++)
9513 		{
9514 		col = 0;
9515 		if (hasAddCB)
9516 			{
9517 			cbs.reason = XmCR_ADD_COLUMN;
9518 			cbs.columnType = type;
9519 			cbs.object = 0;
9520 			XtCallCallbackList(w, g->grid.addCallback, (XtPointer)&cbs);
9521 			col = (XmLGridColumn)cbs.object;
9522 			}
9523 		if (!col)
9524 			col = XmLGridColumnNew(w);
9525 		XmLArraySet(g->grid.colArray, position + i, col);
9526 		}
9527 	/* add cells */
9528 	rowCount = XmLArrayGetCount(g->grid.rowArray);
9529 	for (j = 0; j < rowCount; j++)
9530 		{
9531 		row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, j);
9532 		XmLArrayAdd(XmLGridRowCells(row), position, count);
9533 		for (i = position; i < position + count; i++)
9534 			{
9535 			cell = 0;
9536 			if (hasAddCB)
9537 				{
9538 				cbs.reason = XmCR_ADD_CELL;
9539 				cbs.rowType = RowPosToType(g, j);
9540 				cbs.columnType = type;
9541 				cbs.object = 0;
9542 				XtCallCallbackList(w, g->grid.addCallback, (XtPointer)&cbs);
9543 				cell = (XmLGridCell)cbs.object;
9544 				}
9545 			if (!cell)
9546 				cell = XmLGridCellNew();
9547 			col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
9548 			if (col->grid.defCellValues)
9549 				XmLGridCellSetRefValues(cell, col->grid.defCellValues);
9550 			else
9551 				XmLGridCellSetRefValues(cell, g->grid.defCellValues);
9552 			XmLArraySet(XmLGridRowCells(row), i, cell);
9553 			}
9554 		XmLGridRowHeightChanged(row);
9555 		}
9556 	for (i = position; i < position + count; i++)
9557 		{
9558 		col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
9559 		XmLGridColumnWidthChanged(col);
9560 		}
9561 	/* sanity check */
9562 	if (XmLArrayGetCount(g->grid.colArray) != g->grid.headingColCount +
9563 		g->grid.colCount + g->grid.footerColCount)
9564 			XmLWarning(w, "AddColumns() - count sanity check failed");
9565 
9566 	/* maintain scroll and focus position */
9567 	if (g->grid.hsPolicy == XmCONSTANT)
9568 		{
9569 		if (type == XmCONTENT && g->grid.colCount == count)
9570 			g->grid.scrollCol = 0;
9571 		else if (position <= g->grid.scrollCol)
9572 			g->grid.scrollCol += count;
9573 		}
9574 	if (position <= g->grid.focusCol)
9575 		g->grid.focusCol += count;
9576 	VisPosChanged(g, 0);
9577 	HorizLayout(g, 1);
9578 	VertLayout(g, 1);
9579 	if (g->grid.focusCol == -1 && type == XmCONTENT)
9580 		{
9581 		if (g->grid.focusRow != -1)
9582 			SetFocus(g, g->grid.focusRow, position, 0, 0);
9583 		else
9584 			g->grid.focusCol = position;
9585 		}
9586 	for (i = position; i < position + count; i++)
9587 		redraw |= ColIsVisible(g, i);
9588 	if (redraw)
9589 		DrawArea(g, DrawAll, 0, 0);
9590 	}
9591 
9592 void
XmLGridAddRows(Widget w,unsigned char type,int position,int count)9593 XmLGridAddRows(Widget w,
9594 	       unsigned char type,
9595 	       int position,
9596 	       int count)
9597 	{
9598 	XmLGridWidget g;
9599 	XmLGridRow row;
9600 	XmLGridColumn col;
9601 	XmLGridCell cell;
9602 	XmLGridCallbackStruct cbs;
9603 	int i, j, hasAddCB, redraw, colCount;
9604 
9605 	g = WidgetToGrid(w, "AddRows()");
9606 	if (!g)
9607 		return;
9608 	if (count <= 0)
9609 		return;
9610 	redraw = 0;
9611 	position = RowTypePosToPos(g, type, position, 1);
9612 	if (position < 0)
9613 		position = RowTypePosToPos(g, type, -1, 1);
9614 	/* adjust count */
9615 	if (type == XmHEADING)
9616 		{
9617 		g->grid.headingRowCount += count;
9618 		g->grid.topFixedCount += count;
9619 		redraw = 1;
9620 		}
9621 	else if (type == XmFOOTER)
9622 		{
9623 		g->grid.footerRowCount += count;
9624 		g->grid.bottomFixedCount += count;
9625 		redraw = 1;
9626 		}
9627 	else /* XmCONTENT */
9628 		g->grid.rowCount += count;
9629 
9630 	/* add rows and cells */
9631 	XmLArrayAdd(g->grid.rowArray, position, count);
9632 	colCount = XmLArrayGetCount(g->grid.colArray);
9633 	hasAddCB = 0;
9634 	if (XtHasCallbacks(w, XmNaddCallback) == XtCallbackHasSome)
9635 		hasAddCB = 1;
9636 	for (i = 0; i < count; i++)
9637 		{
9638 		row = 0;
9639 		if (hasAddCB)
9640 			{
9641 			cbs.reason = XmCR_ADD_ROW;
9642 			cbs.rowType = type;
9643 			cbs.object = 0;
9644 			XtCallCallbackList(w, g->grid.addCallback, (XtPointer)&cbs);
9645 			row = (XmLGridRow)cbs.object;
9646 			}
9647 		if (!row)
9648 			row = XmLGridRowNew(w);
9649 		XmLArraySet(g->grid.rowArray, position + i, row);
9650 		XmLArrayAdd(XmLGridRowCells(row), 0, colCount);
9651 		for (j = 0; j < colCount; j++)
9652 			{
9653 			cell = 0;
9654 			if (hasAddCB)
9655 				{
9656 				cbs.reason = XmCR_ADD_CELL;
9657 				cbs.rowType = type;
9658 				cbs.columnType = ColPosToType(g, j);
9659 				cbs.object = 0;
9660 				XtCallCallbackList(w, g->grid.addCallback, (XtPointer)&cbs);
9661 				cell = (XmLGridCell)cbs.object;
9662 				}
9663 			if (!cell)
9664 				cell = XmLGridCellNew();
9665 			col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, j);
9666 			if (col->grid.defCellValues)
9667 				XmLGridCellSetRefValues(cell, col->grid.defCellValues);
9668 			else
9669 				XmLGridCellSetRefValues(cell, g->grid.defCellValues);
9670 			XmLArraySet(XmLGridRowCells(row), j, cell);
9671 			}
9672 		XmLGridRowHeightChanged(row);
9673 		}
9674 	for (j = 0; j < colCount; j++)
9675 		{
9676 		col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, j);
9677 		XmLGridColumnWidthChanged(col);
9678 		}
9679 	/* sanity check */
9680 	if (XmLArrayGetCount(g->grid.rowArray) != g->grid.headingRowCount +
9681 		g->grid.rowCount + g->grid.footerRowCount)
9682 			XmLWarning(w, "AddRows() - count sanity check failed");
9683 
9684 	/* maintain scroll and focus position */
9685 	if (g->grid.vsPolicy == XmCONSTANT)
9686 		{
9687 		if (type == XmCONTENT && g->grid.rowCount == count)
9688 			g->grid.scrollRow = 0;
9689 		else if (position <= g->grid.scrollRow)
9690 			g->grid.scrollRow += count;
9691 		}
9692 	if (position <= g->grid.focusRow)
9693 		g->grid.focusRow += count;
9694 	VisPosChanged(g, 1);
9695 	HorizLayout(g, 1);
9696 	VertLayout(g, 1);
9697 	if (g->grid.focusRow == -1 && type == XmCONTENT)
9698 		{
9699 		if (g->grid.focusCol != -1)
9700 			SetFocus(g, position, g->grid.focusCol, 0, 0);
9701 		else
9702 			g->grid.focusRow = position;
9703 		}
9704 	for (i = position; i < position + count; i++)
9705 		redraw |= RowIsVisible(g, i);
9706 	if (redraw)
9707 		DrawArea(g, DrawAll, 0, 0);
9708 
9709 #ifdef XmLEVAL
9710 	if (g->grid.rowCount > 100)
9711 		{
9712 		fprintf(stderr, "XmL: evaluation version only supports <= 100 rows\n");
9713 		exit(0);
9714 		}
9715 #endif
9716 	}
9717 
9718 void
XmLGridDeleteAllColumns(Widget w,unsigned char type)9719 XmLGridDeleteAllColumns(Widget w,
9720 			unsigned char type)
9721 	{
9722 	XmLGridWidget g;
9723 	int n;
9724 
9725 	g = WidgetToGrid(w, "DeleteAllColumns()");
9726 	if (!g)
9727 		return;
9728 	if (type == XmHEADING)
9729 		n = g->grid.headingColCount;
9730 	else if (type == XmCONTENT)
9731 		n = g->grid.colCount;
9732 	else if (type == XmFOOTER)
9733 		n = g->grid.footerColCount;
9734 	else
9735 		{
9736 		XmLWarning(w, "DeleteAllColumns() - invalid type");
9737 		return;
9738 		}
9739 	if (!n)
9740 		return;
9741 	XmLGridDeleteColumns(w, type, 0, n);
9742 	}
9743 
9744 void
XmLGridDeleteAllRows(Widget w,unsigned char type)9745 XmLGridDeleteAllRows(Widget w,
9746 		     unsigned char type)
9747 	{
9748 	XmLGridWidget g;
9749 	int n;
9750 
9751 	g = WidgetToGrid(w, "DeleteAllRows()");
9752 	if (!g)
9753 		return;
9754 	if (type == XmHEADING)
9755 		n = g->grid.headingRowCount;
9756 	else if (type == XmCONTENT)
9757 		n = g->grid.rowCount;
9758 	else if (type == XmFOOTER)
9759 		n = g->grid.footerRowCount;
9760 	else
9761 		{
9762 		XmLWarning(w, "DeleteAllRows() - invalid type");
9763 		return;
9764 		}
9765 	if (!n)
9766 		return;
9767 	XmLGridDeleteRows(w, type, 0, n);
9768 	}
9769 
9770 void
XmLGridDeselectAllRows(Widget w,Boolean notify)9771 XmLGridDeselectAllRows(Widget w,
9772 		       Boolean notify)
9773 	{
9774 	XmLGridWidget g;
9775 
9776 	g = WidgetToGrid(w, "DeselectAllRows()");
9777 	if (!g)
9778 		return;
9779 	SelectTypeArea(g, SelectRow, (XEvent *)0, -1, 0, False, notify);
9780 	}
9781 
9782 void
XmLGridDeselectAllColumns(Widget w,Boolean notify)9783 XmLGridDeselectAllColumns(Widget w,
9784 			  Boolean notify)
9785 	{
9786 	XmLGridWidget g;
9787 
9788 	g = WidgetToGrid(w, "DeselectAllColumns()");
9789 	if (!g)
9790 		return;
9791 	SelectTypeArea(g, SelectCol, (XEvent *)0, 0, -1, False, notify);
9792 	}
9793 
9794 void
XmLGridDeselectAllCells(Widget w,Boolean notify)9795 XmLGridDeselectAllCells(Widget w,
9796 			Boolean notify)
9797 	{
9798 	XmLGridWidget g;
9799 
9800 	g = WidgetToGrid(w, "DeselectAllCells()");
9801 	if (!g)
9802 		return;
9803 	SelectTypeArea(g, SelectCell, (XEvent *)0, -1, -1, False, notify);
9804 	}
9805 
9806 void
XmLGridDeselectCell(Widget w,int row,int column,Boolean notify)9807 XmLGridDeselectCell(Widget w,
9808 		    int row,
9809 		    int column,
9810 		    Boolean notify)
9811 	{
9812 	XmLGridWidget g;
9813 
9814 	g = WidgetToGrid(w, "DeselectCell()");
9815 	if (!g)
9816 		return;
9817 	SelectTypeArea(g, SelectCell, (XEvent *)0, row, column, False, notify);
9818 	}
9819 
9820 void
XmLGridDeselectColumn(Widget w,int column,Boolean notify)9821 XmLGridDeselectColumn(Widget w,
9822 		      int column,
9823 		      Boolean notify)
9824 	{
9825 	XmLGridWidget g;
9826 
9827 	g = WidgetToGrid(w, "DeselectColumn()");
9828 	if (!g)
9829 		return;
9830 	SelectTypeArea(g, SelectCol, (XEvent *)0, 0, column, False, notify);
9831 	}
9832 
9833 void
XmLGridDeselectRow(Widget w,int row,Boolean notify)9834 XmLGridDeselectRow(Widget w,
9835 		   int row,
9836 		   Boolean notify)
9837 	{
9838 	XmLGridWidget g;
9839 
9840 	g = WidgetToGrid(w, "DeselectRow()");
9841 	if (!g)
9842 		return;
9843 	SelectTypeArea(g, SelectRow, (XEvent *)0, row, 0, False, notify);
9844 	}
9845 
9846 void
XmLGridDeleteColumns(Widget w,unsigned char type,int position,int count)9847 XmLGridDeleteColumns(Widget w,
9848 		     unsigned char type,
9849 		     int position,
9850 		     int count)
9851 	{
9852 	XmLGridWidget g;
9853 	XmLGridRow row;
9854 	XmLGridColumn col;
9855 	XmLGridCallbackStruct cbs;
9856 	int changeFocus, i, j, rowCount, lastPos, redraw;
9857 
9858 	g = WidgetToGrid(w, "DeleteColumns()");
9859 	if (!g)
9860 		return;
9861 	if (count <= 0)
9862 		return;
9863 	lastPos = ColTypePosToPos(g, type, position + count - 1, 0);
9864 	position = ColTypePosToPos(g, type, position, 0);
9865 	if (position < 0 || lastPos < 0)
9866 		{
9867 		XmLWarning(w, "DeleteColumns() - invalid position");
9868 		return;
9869 		}
9870 	changeFocus = 0;
9871 	if (position <= g->grid.focusCol && lastPos >= g->grid.focusCol)
9872 		{
9873 		/* deleting focus col */
9874 		TextAction(g, TEXT_EDIT_CANCEL);
9875 		ChangeFocus(g, g->grid.focusRow, -1);
9876 		changeFocus = 1;
9877 		}
9878 	redraw = 0;
9879 
9880 	if (XtHasCallbacks(w, XmNdeleteCallback) == XtCallbackHasSome)
9881 		for (i = position; i < position + count; i++)
9882 			{
9883 			rowCount = XmLArrayGetCount(g->grid.rowArray);
9884 			for (j = 0; j < rowCount; j++)
9885 				{
9886 				row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, j);
9887 				cbs.reason = XmCR_DELETE_CELL;
9888 				cbs.rowType = RowPosToType(g, j);
9889                 cbs.row = RowPosToTypePos(g, cbs.rowType, i);
9890 				cbs.columnType = type;
9891                 cbs.column = RowPosToTypePos(g, cbs.columnType, j);
9892 				cbs.object = XmLArrayGet(XmLGridRowCells(row), i);
9893 				XtCallCallbackList(w, g->grid.deleteCallback, (XtPointer)&cbs);
9894 				}
9895 			cbs.reason = XmCR_DELETE_COLUMN;
9896 			cbs.columnType = type;
9897             cbs.column = RowPosToTypePos(g, cbs.columnType, i);
9898 			cbs.object = XmLArrayGet(g->grid.colArray, i);
9899 			XtCallCallbackList(w, g->grid.deleteCallback, (XtPointer)&cbs);
9900 			}
9901 
9902 	/* adjust count */
9903 	if (type == XmHEADING)
9904 		{
9905 		g->grid.headingColCount -= count;
9906 		g->grid.leftFixedCount -= count;
9907 		redraw = 1;
9908 		}
9909 	else if (type == XmFOOTER)
9910 		{
9911 		g->grid.footerColCount -= count;
9912 		g->grid.rightFixedCount -= count;
9913 		redraw = 1;
9914 		}
9915 	else /* XmCONTENT */
9916 		g->grid.colCount -= count;
9917 
9918 	for (i = position; i < position + count; i++)
9919 		{
9920 		col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
9921 		if (XmLGridColumnIsHidden(col) == True)
9922 			g->grid.hiddenColCount--;
9923 		redraw |= ColIsVisible(g, i);
9924 		}
9925 
9926 	/* delete columns */
9927 	for (i = position; i < position + count; i++)
9928 		{
9929 		col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
9930 		XmLGridColumnFree(w, col);
9931 		}
9932 	XmLArrayDel(g->grid.colArray, position, count);
9933 	/* delete cells */
9934 	rowCount = XmLArrayGetCount(g->grid.rowArray);
9935 	for (i = 0; i < rowCount; i++)
9936 		{
9937 		row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
9938 		for (j = position; j < position + count; j++)
9939 			XmLGridCellFree(w,
9940 				(XmLGridCell)XmLArrayGet(XmLGridRowCells(row), j));
9941 		XmLArrayDel(XmLGridRowCells(row), position, count);
9942 		XmLGridRowHeightChanged(row);
9943 		}
9944 	/* sanity check */
9945 	if (XmLArrayGetCount(g->grid.colArray) != g->grid.headingColCount +
9946 		g->grid.colCount + g->grid.footerColCount)
9947 			XmLWarning(w, "DeleteColumns() - count sanity check failed");
9948 
9949 	/* maintain scroll and focus position */
9950 	if (g->grid.hsPolicy == XmCONSTANT)
9951 		{
9952 		if (lastPos < g->grid.scrollCol)
9953 			g->grid.scrollCol -= count;
9954 		else if (position <= g->grid.scrollCol)
9955 			g->grid.scrollCol = position;
9956 		}
9957 	if (lastPos < g->grid.focusCol)
9958 		g->grid.focusCol -= count;
9959 	VisPosChanged(g, 0);
9960 	HorizLayout(g, 1);
9961 	VertLayout(g, 1);
9962 	if (changeFocus)
9963 		{
9964 		SetFocus(g, g->grid.focusRow, position, 0, 1);
9965 		if (g->grid.focusCol == -1)
9966 			SetFocus(g, g->grid.focusRow, position, 0, -1);
9967 		}
9968 	if (redraw)
9969 		DrawArea(g, DrawAll, 0, 0);
9970 	}
9971 
9972 void
XmLGridDeleteRows(Widget w,unsigned char type,int position,int count)9973 XmLGridDeleteRows(Widget w,
9974 		  unsigned char type,
9975 		  int position,
9976 		  int count)
9977 	{
9978 	XmLGridWidget g;
9979 	XmLGridRow row;
9980 	XmLGridColumn col;
9981 	XmLGridCallbackStruct cbs;
9982 	int changeFocus, i, j, colCount, lastPos, redraw;
9983 
9984 	g = WidgetToGrid(w, "DeleteRows()");
9985 	if (!g)
9986 		return;
9987 	if (count <= 0)
9988 		return;
9989 	lastPos = RowTypePosToPos(g, type, position + count - 1, 0);
9990 	position = RowTypePosToPos(g, type, position, 0);
9991 	if (position < 0 || lastPos < 0)
9992 		{
9993 		XmLWarning(w, "DeleteRows() - invalid position");
9994 		return;
9995 		}
9996 	changeFocus = 0;
9997 	if (position <= g->grid.focusRow && lastPos >= g->grid.focusRow)
9998 		{
9999 		/* deleting focus row */
10000 		TextAction(g, TEXT_EDIT_CANCEL);
10001 		ChangeFocus(g, -1, g->grid.focusCol);
10002 		changeFocus = 1;
10003 		}
10004 	redraw = 0;
10005 
10006 	if (XtHasCallbacks(w, XmNdeleteCallback) == XtCallbackHasSome)
10007 		for (i = position; i < position + count; i++)
10008 			{
10009 			row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
10010 			colCount = XmLArrayGetCount(g->grid.colArray);
10011 			for (j = 0; j < colCount; j++)
10012 				{
10013 				cbs.reason = XmCR_DELETE_CELL;
10014 				cbs.rowType = type;
10015                 cbs.row = RowPosToTypePos(g, cbs.rowType, i);
10016 				cbs.columnType = ColPosToType(g, j);
10017                 cbs.column = ColPosToTypePos(g, cbs.columnType, j);
10018 				cbs.object = XmLArrayGet(XmLGridRowCells(row), j);
10019 				XtCallCallbackList(w, g->grid.deleteCallback, (XtPointer)&cbs);
10020 				}
10021 			cbs.reason = XmCR_DELETE_ROW;
10022 			cbs.rowType = type;
10023             cbs.row = RowPosToTypePos(g, cbs.rowType, i);
10024 			cbs.object = (void *)row;
10025 			XtCallCallbackList(w, g->grid.deleteCallback, (XtPointer)&cbs);
10026 			}
10027 
10028 	/* adjust count */
10029 	if (type == XmHEADING)
10030 		{
10031 		g->grid.headingRowCount -= count;
10032 		g->grid.topFixedCount -= count;
10033 		redraw = 1;
10034 		}
10035 	else if (type == XmFOOTER)
10036 		{
10037 		g->grid.footerRowCount -= count;
10038 		g->grid.bottomFixedCount -= count;
10039 		redraw = 1;
10040 		}
10041 	else /* XmCONTENT */
10042 		g->grid.rowCount -= count;
10043 
10044 	for (i = position; i < position + count; i++)
10045 		{
10046 		row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
10047 		if (XmLGridRowIsHidden(row) == True)
10048 			g->grid.hiddenRowCount--;
10049 		redraw |= RowIsVisible(g, i);
10050 		}
10051 
10052 	/* delete rows and cells */
10053 	for (i = position; i < position + count; i++)
10054 		{
10055 		row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
10056 		XmLGridRowFree(w, row);
10057 		}
10058 	XmLArrayDel(g->grid.rowArray, position, count);
10059 	colCount = XmLArrayGetCount(g->grid.colArray);
10060 	for (i = 0; i < colCount; i++)
10061 		{
10062 		col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
10063 		XmLGridColumnWidthChanged(col);
10064 		}
10065 	/* sanity check */
10066 	if (XmLArrayGetCount(g->grid.rowArray) != g->grid.headingRowCount +
10067 		g->grid.rowCount + g->grid.footerRowCount)
10068 			XmLWarning(w, "DeleteRows() - count sanity check failed");
10069 
10070 	/* maintain scroll and focus position */
10071 	if (g->grid.vsPolicy == XmCONSTANT)
10072 		{
10073 		if (lastPos < g->grid.scrollRow)
10074 			g->grid.scrollRow -= count;
10075 		else if (position <= g->grid.scrollRow)
10076 			g->grid.scrollRow = position;
10077 		}
10078 	if (lastPos < g->grid.focusRow)
10079 		g->grid.focusRow -= count;
10080 	VisPosChanged(g, 1);
10081 	HorizLayout(g, 1);
10082 	VertLayout(g, 1);
10083 	if (changeFocus)
10084 		{
10085 		SetFocus(g, position, g->grid.focusCol, 1, 0);
10086 		if (g->grid.focusRow == -1)
10087 			SetFocus(g, position, g->grid.focusCol, -1, 0);
10088 		}
10089 	if (redraw)
10090 		DrawArea(g, DrawAll, 0, 0);
10091 	}
10092 
10093 void
XmLGridGetFocus(Widget w,int * row,int * column,Boolean * focusIn)10094 XmLGridGetFocus(Widget w,
10095 		int *row,
10096 		int *column,
10097 		Boolean *focusIn)
10098 	{
10099 	XmLGridWidget g;
10100 	unsigned char rowType, colType;
10101 
10102 	g = WidgetToGrid(w, "GetFocus()");
10103 	if (!g)
10104 		return;
10105 	if (g->grid.focusIn)
10106 		*focusIn = True;
10107 	else
10108 		*focusIn = False;
10109 	if (g->grid.focusRow < 0 || g->grid.focusCol < 0)
10110 		{
10111 		*row = -1;
10112 		*column = -1;
10113 		return;
10114 		}
10115 	rowType = RowPosToType(g, g->grid.focusRow);
10116 	colType = ColPosToType(g, g->grid.focusCol);
10117 	if (rowType != XmCONTENT || colType != XmCONTENT)
10118 		{
10119 		*row = -1;
10120 		*column = -1;
10121 		XmLWarning(w, "GetFocus() - focus row/column invalid\n");
10122 		return;
10123 		}
10124 	*row = RowPosToTypePos(g, XmCONTENT, g->grid.focusRow);
10125 	*column = ColPosToTypePos(g, XmCONTENT, g->grid.focusCol);
10126 	}
10127 
10128 XmLGridRow
XmLGridGetRow(Widget w,unsigned char rowType,int row)10129 XmLGridGetRow(Widget w,
10130 	      unsigned char rowType,
10131 	      int row)
10132 
10133 	{
10134 	XmLGridWidget g;
10135 	XmLGridRow r;
10136 	int pos;
10137 
10138 	g = WidgetToGrid(w, "GetRow()");
10139 	if (!g)
10140 		return 0;
10141 	pos = RowTypePosToPos(g, rowType, row, 0);
10142 	r = (XmLGridRow)XmLArrayGet(g->grid.rowArray, pos);
10143 	if (!r)
10144 		XmLWarning(w, "GetRow() - invalid row");
10145 	return r;
10146 	}
10147 
10148 int
XmLGridEditBegin(Widget w,Boolean insert,int row,int column)10149 XmLGridEditBegin(Widget w,
10150 		 Boolean insert,
10151 		 int row,
10152 		 int column)
10153 	{
10154 	XmLGridWidget g;
10155 	int r, c;
10156 	XRectangle rect;
10157 
10158 	g = WidgetToGrid(w, "EditBegin()");
10159 	if (!g)
10160 		return -1;
10161 	if (column < 0 || column >= g->grid.colCount)
10162 		{
10163 		XmLWarning(w, "EditBegin() - invalid column");
10164 		return -1;
10165 		}
10166 	if (row < 0 || row >= g->grid.rowCount)
10167 		{
10168 		XmLWarning(w, "EditBegin() - invalid row");
10169 		return -1;
10170 		}
10171 	r = RowTypePosToPos(g, XmCONTENT, row, 0);
10172 	c = ColTypePosToPos(g, XmCONTENT, column, 0);
10173 	if (RowColToXY(g, r, c, True, &rect) == -1)
10174 		{
10175 		XmLWarning(w, "EditBegin() - cell must be visible to begin edit");
10176 		return -1;
10177 		}
10178 	if (SetFocus(g, r, c, 0, 0) == -1)
10179 		{
10180 		XmLWarning(w, "EditBegin() - can't set focus to cell");
10181 		return -1;
10182 		}
10183 	if (insert == False)
10184 		TextAction(g, TEXT_EDIT);
10185 	else
10186 		TextAction(g, TEXT_EDIT_INSERT);
10187 	return 0;
10188 	}
10189 
10190 void
XmLGridEditCancel(Widget w)10191 XmLGridEditCancel(Widget w)
10192 	{
10193 	XmLGridWidget g;
10194 
10195 	g = WidgetToGrid(w, "EditCancel()");
10196 	if (!g)
10197 		return;
10198 	TextAction(g, TEXT_EDIT_CANCEL);
10199 	}
10200 
10201 void
XmLGridEditComplete(Widget w)10202 XmLGridEditComplete(Widget w)
10203 	{
10204 	XmLGridWidget g;
10205 
10206 	g = WidgetToGrid(w, "EditComplete()");
10207 	if (!g)
10208 		return;
10209 	TextAction(g, TEXT_EDIT_COMPLETE);
10210 	}
10211 
10212 XmLGridColumn
XmLGridGetColumn(Widget w,unsigned char columnType,int column)10213 XmLGridGetColumn(Widget w,
10214 		 unsigned char columnType,
10215 		 int column)
10216 	{
10217 	XmLGridWidget g;
10218 	XmLGridColumn c;
10219 	int pos;
10220 
10221 	g = WidgetToGrid(w, "GetColumn()");
10222 	if (!g)
10223 		return 0;
10224 	pos = ColTypePosToPos(g, columnType, column, 0);
10225 	c = (XmLGridColumn)XmLArrayGet(g->grid.colArray, pos);
10226 	if (!c)
10227 		XmLWarning(w, "GetColumn() - invalid column");
10228 	return c;
10229 	}
10230 
10231 int
XmLGridGetSelectedCellCount(Widget w)10232 XmLGridGetSelectedCellCount(Widget w)
10233 	{
10234 	XmLGridWidget g;
10235 
10236 	g = WidgetToGrid(w, "GetSelectedCellCount()");
10237 	if (!g)
10238 		return -1;
10239 	return GetSelectedArea(g, SelectCell, 0, 0, 0);
10240 	}
10241 
10242 int
XmLGridGetSelectedCells(Widget w,int * rowPositions,int * columnPositions,int count)10243 XmLGridGetSelectedCells(Widget w,
10244 			int *rowPositions,
10245 			int *columnPositions,
10246 			int count)
10247 	{
10248 	XmLGridWidget g;
10249 	int n;
10250 
10251 	g = WidgetToGrid(w, "GetSelectedCells()");
10252 	if (!g)
10253 		return -1;
10254 	n = GetSelectedArea(g, SelectCell, rowPositions, columnPositions, count);
10255 	if (count != n)
10256 		{
10257 		XmLWarning(w, "GetSelectedCells() - count is incorrect");
10258 		return -1;
10259 		}
10260 	return 0;
10261 	}
10262 
10263 int
XmLGridGetSelectedColumnCount(Widget w)10264 XmLGridGetSelectedColumnCount(Widget w)
10265 	{
10266 	XmLGridWidget g;
10267 
10268 	g = WidgetToGrid(w, "GetSelectedColumnCount()");
10269 	if (!g)
10270 		return -1;
10271 	return GetSelectedArea(g, SelectCol, 0, 0, 0);
10272 	}
10273 
10274 int
XmLGridGetSelectedColumns(Widget w,int * positions,int count)10275 XmLGridGetSelectedColumns(Widget w,
10276 			  int *positions,
10277 			  int count)
10278 	{
10279 	XmLGridWidget g;
10280 	int n;
10281 
10282 	g = WidgetToGrid(w, "GetSelectedColumns()");
10283 	if (!g)
10284 		return -1;
10285 	n = GetSelectedArea(g, SelectCol, 0, positions, count);
10286 	if (count != n)
10287 		{
10288 		XmLWarning(w, "GetSelectedColumns() - count is incorrect");
10289 		return -1;
10290 		}
10291 	return 0;
10292 	}
10293 
10294 int
XmLGridGetSelectedRow(Widget w)10295 XmLGridGetSelectedRow(Widget w)
10296 	{
10297 	XmLGridWidget g;
10298 	int n, pos;
10299 
10300 	g = WidgetToGrid(w, "GetSelectedRow()");
10301 	if (!g)
10302 		return -1;
10303 	n = GetSelectedArea(g, SelectRow, &pos, 0, 1);
10304 	if (n != 1)
10305 		return -1;
10306 	return pos;
10307 	}
10308 
10309 int
XmLGridGetSelectedRowCount(Widget w)10310 XmLGridGetSelectedRowCount(Widget w)
10311 	{
10312 	XmLGridWidget g;
10313 
10314 	g = WidgetToGrid(w, "GetSelectedRowCount()");
10315 	if (!g)
10316 		return -1;
10317 	return GetSelectedArea(g, SelectRow, 0, 0, 0);
10318 	}
10319 
10320 int
XmLGridGetSelectedRows(Widget w,int * positions,int count)10321 XmLGridGetSelectedRows(Widget w,
10322 		       int *positions,
10323 		       int count)
10324 	{
10325 	XmLGridWidget g;
10326 	int n;
10327 
10328 	g = WidgetToGrid(w, "GetSelectedRows()");
10329 	if (!g)
10330 		return -1;
10331 	n = GetSelectedArea(g, SelectRow, positions, 0, count);
10332 	if (count != n)
10333 		{
10334 		XmLWarning(w, "GetSelectedRows() - count is incorrect");
10335 		return -1;
10336 		}
10337 	return 0;
10338 	}
10339 
10340 Boolean
XmLGridColumnIsVisible(Widget w,int col)10341 XmLGridColumnIsVisible(Widget w,
10342 		       int col)
10343 	{
10344 	XmLGridWidget g;
10345 
10346 	g = WidgetToGrid(w, "ColumnIsVisible()");
10347 	if (!g)
10348 		return -1;
10349 	if (!ColIsVisible(g, g->grid.headingColCount + col))
10350 		return False;
10351 	return True;
10352 	}
10353 
10354 void
XmLGridMoveColumns(Widget w,int newPosition,int position,int count)10355 XmLGridMoveColumns(Widget w,
10356 		   int newPosition,
10357 		   int position,
10358 		   int count)
10359 	{
10360 	XmLGridWidget g;
10361 	XmLGridRow row;
10362 	int i, np, p, rowCount;
10363 
10364 	g = WidgetToGrid(w, "MoveColumns()");
10365 	if (!g)
10366 		return;
10367 	np = ColTypePosToPos(g, XmCONTENT, newPosition, 0);
10368 	p = ColTypePosToPos(g, XmCONTENT, position, 0);
10369 	if (XmLArrayMove(g->grid.colArray, np, p, count) == -1)
10370 		{
10371 		XmLWarning(w, "MoveColumns() - invalid position");
10372 		return;
10373 		}
10374 	rowCount = XmLArrayGetCount(g->grid.rowArray);
10375 	for (i = 0; i < rowCount; i++)
10376 		{
10377 		row = XmLArrayGet(g->grid.rowArray, i);
10378 		XmLArrayMove(XmLGridRowCells(row), np, p, count);
10379 		}
10380 	VisPosChanged(g, 0);
10381 	HorizLayout(g, 1);
10382 	DrawArea(g, DrawAll, 0, 0);
10383 	}
10384 
10385 void
XmLGridMoveRows(Widget w,int newPosition,int position,int count)10386 XmLGridMoveRows(Widget w,
10387 		int newPosition,
10388 		int position,
10389 		int count)
10390 	{
10391 	XmLGridWidget g;
10392 	int np, p;
10393 
10394 	g = WidgetToGrid(w, "MoveRows()");
10395 	if (!g)
10396 		return;
10397 	np = RowTypePosToPos(g, XmCONTENT, newPosition, 0);
10398 	p = RowTypePosToPos(g, XmCONTENT, position, 0);
10399 	if (XmLArrayMove(g->grid.rowArray, np, p, count) == -1)
10400 		{
10401 		XmLWarning(w, "MoveRows() - invalid position/count");
10402 		return;
10403 		}
10404 	VisPosChanged(g, 1);
10405 	VertLayout(g, 1);
10406 	DrawArea(g, DrawAll, 0, 0);
10407 	}
10408 
10409 void
XmLGridReorderColumns(Widget w,int * newPositions,int position,int count)10410 XmLGridReorderColumns(Widget w,
10411 		      int *newPositions,
10412 		      int position,
10413 		      int count)
10414 	{
10415 	XmLGridWidget g;
10416 	XmLGridRow row;
10417 	int i, *np, p, rowCount, status;
10418 
10419 	g = WidgetToGrid(w, "ReorderColumns()");
10420 	if (!g)
10421 		return;
10422 	if (count <= 0)
10423 		return;
10424 	p = ColTypePosToPos(g, XmCONTENT, position, 0);
10425 	np = (int *)malloc(sizeof(int) * count);
10426 	for (i = 0; i < count; i++)
10427 		np[i] = ColTypePosToPos(g, XmCONTENT, newPositions[i], 0);
10428 	status = XmLArrayReorder(g->grid.colArray, np, p, count);
10429 	if (status < 0)
10430 		{
10431 		free((char *)np);
10432 		XmLWarning(w, "ReorderColumns() - invalid position/count");
10433 		return;
10434 		}
10435 	rowCount = XmLArrayGetCount(g->grid.rowArray);
10436 	for (i = 0; i < rowCount; i++)
10437 		{
10438 		row = XmLArrayGet(g->grid.rowArray, i);
10439 		XmLArrayReorder(XmLGridRowCells(row), np, p, count);
10440 		}
10441 	free((char *)np);
10442 	VisPosChanged(g, 0);
10443 	HorizLayout(g, 1);
10444 	DrawArea(g, DrawAll, 0, 0);
10445 	}
10446 
10447 void
XmLGridReorderRows(Widget w,int * newPositions,int position,int count)10448 XmLGridReorderRows(Widget w,
10449 		   int *newPositions,
10450 		   int position,
10451 		   int count)
10452 	{
10453 	XmLGridWidget g;
10454 	int i, *np, p, status;
10455 
10456 	g = WidgetToGrid(w, "ReorderRows()");
10457 	if (!g)
10458 		return;
10459 	if (count <= 0)
10460 		return;
10461 	p = RowTypePosToPos(g, XmCONTENT, position, 0);
10462 	np = (int *)malloc(sizeof(int) * count);
10463 	for (i = 0; i < count; i++)
10464 		np[i] = RowTypePosToPos(g, XmCONTENT, newPositions[i], 0);
10465 	status = XmLArrayReorder(g->grid.rowArray, np, p, count);
10466 	free((char *)np);
10467 	if (status == -1)
10468 		{
10469 		XmLWarning(w, "ReorderRows() - invalid position/count");
10470 		return;
10471 		}
10472 	VisPosChanged(g, 1);
10473 	VertLayout(g, 1);
10474 	DrawArea(g, DrawAll, 0, 0);
10475 	}
10476 
10477 int
XmLGridRowColumnToXY(Widget w,unsigned char rowType,int row,unsigned char columnType,int column,Boolean clipped,XRectangle * rect)10478 XmLGridRowColumnToXY(Widget w,
10479 		     unsigned char rowType,
10480 		     int row,
10481 		     unsigned char columnType,
10482 		     int column,
10483 		     Boolean clipped,
10484 		     XRectangle *rect)
10485 	{
10486 	XmLGridWidget g;
10487 	int r, c;
10488 
10489 	g = WidgetToGrid(w, "RowColumnToXY()");
10490 	if (!g)
10491 		return -1;
10492 	r = RowTypePosToPos(g, rowType, row, 0);
10493 	c = ColTypePosToPos(g, columnType, column, 0);
10494 	if (r < 0 || r >= XmLArrayGetCount(g->grid.rowArray) ||
10495 		c < 0 || c >= XmLArrayGetCount(g->grid.colArray))
10496 		{
10497 /*		XmLWarning(w, "RowColumnToXY() - invalid position");*/
10498 		return -1;
10499 		}
10500 	return RowColToXY(g, r, c, clipped, rect);
10501 	}
10502 
10503 Boolean
XmLGridRowIsVisible(Widget w,int row)10504 XmLGridRowIsVisible(Widget w, int row)
10505 	{
10506 	XmLGridWidget g;
10507 
10508 	g = WidgetToGrid(w, "RowIsVisible()");
10509 	if (!g)
10510 		return -1;
10511 	if (!RowIsVisible(g, g->grid.headingRowCount + row))
10512 		return False;
10513 	return True;
10514 	}
10515 
10516 void
XmLGridSelectAllRows(Widget w,Boolean notify)10517 XmLGridSelectAllRows(Widget w,
10518 		     Boolean notify)
10519 	{
10520 	XmLGridWidget g;
10521 
10522 	g = WidgetToGrid(w, "SelectAllRows()");
10523 	if (!g)
10524 		return;
10525 	SelectTypeArea(g, SelectRow, (XEvent *)0, -1, 0, True, notify);
10526 	}
10527 
10528 void
XmLGridSelectAllColumns(Widget w,Boolean notify)10529 XmLGridSelectAllColumns(Widget w,
10530 			Boolean notify)
10531 	{
10532 	XmLGridWidget g;
10533 
10534 	g = WidgetToGrid(w, "SelectAllColumns()");
10535 	if (!g)
10536 		return;
10537 	SelectTypeArea(g, SelectCol, (XEvent *)0, 0, -1, True, notify);
10538 	}
10539 
10540 void
XmLGridSelectAllCells(Widget w,Boolean notify)10541 XmLGridSelectAllCells(Widget w,
10542 		      Boolean notify)
10543 	{
10544 	XmLGridWidget g;
10545 
10546 	g = WidgetToGrid(w, "SelectAllCells()");
10547 	if (!g)
10548 		return;
10549 	SelectTypeArea(g, SelectCell, (XEvent *)0, -1, -1, True, notify);
10550 	}
10551 
10552 void
XmLGridSelectCell(Widget w,int row,int column,Boolean notify)10553 XmLGridSelectCell(Widget w,
10554 		  int row,
10555 		  int column,
10556 		  Boolean notify)
10557 	{
10558 	XmLGridWidget g;
10559 
10560 	g = WidgetToGrid(w, "SelectCell()");
10561 	if (!g)
10562 		return;
10563 	SelectTypeArea(g, SelectCell, (XEvent *)0, row, column, True, notify);
10564 	}
10565 
10566 void
XmLGridSelectColumn(Widget w,int column,Boolean notify)10567 XmLGridSelectColumn(Widget w,
10568 		    int column,
10569 		    Boolean notify)
10570 	{
10571 	XmLGridWidget g;
10572 
10573 	g = WidgetToGrid(w, "SelectColumn()");
10574 	if (!g)
10575 		return;
10576 	SelectTypeArea(g, SelectCol, (XEvent *)0, 0, column, True, notify);
10577 	}
10578 
10579 void
XmLGridSelectRow(Widget w,int row,Boolean notify)10580 XmLGridSelectRow(Widget w,
10581 		 int row,
10582 		 Boolean notify)
10583 	{
10584 	XmLGridWidget g;
10585 
10586 	g = WidgetToGrid(w, "SelectRow()");
10587 	if (!g)
10588 		return;
10589 	SelectTypeArea(g, SelectRow, (XEvent *)0, row, 0, True, notify);
10590 	}
10591 
10592 int
XmLGridSetFocus(Widget w,int row,int column)10593 XmLGridSetFocus(Widget w,
10594 		int row,
10595 		int column)
10596 	{
10597 	XmLGridWidget g;
10598 	int r, c;
10599 
10600 	g = WidgetToGrid(w, "SetFocus()");
10601 	if (!g)
10602 		return -1;
10603 	if (row < 0 || row >= g->grid.rowCount)
10604 		{
10605 		XmLWarning(w, "SetFocus() - invalid row");
10606 		return -1;
10607 		}
10608 	if (column < 0 || column >= g->grid.colCount)
10609 		{
10610 		XmLWarning(w, "SetFocus() - invalid column");
10611 		return -1;
10612 		}
10613 	r = RowTypePosToPos(g, XmCONTENT, row, 0);
10614 	c = ColTypePosToPos(g, XmCONTENT, column, 0);
10615 	return SetFocus(g, r, c, 0, 0);
10616 	}
10617 
10618 int
XmLGridXYToRowColumn(Widget w,int x,int y,unsigned char * rowType,int * row,unsigned char * columnType,int * column)10619 XmLGridXYToRowColumn(Widget w,
10620 		     int x,
10621 		     int y,
10622 		     unsigned char *rowType,
10623 		     int *row,
10624 		     unsigned char *columnType,
10625 		     int *column)
10626 	{
10627 	XmLGridWidget g;
10628 	int r, c;
10629 
10630 	g = WidgetToGrid(w, "XYToRowColumn()");
10631 	if (!g)
10632 		return -1;
10633 	if (XYToRowCol(g, x, y, &r, &c) == -1)
10634 		return -1;
10635 	*rowType = RowPosToType(g, r);
10636 	*row = RowPosToTypePos(g, *rowType, r);
10637 	*columnType = ColPosToType(g, c);
10638 	*column = ColPosToTypePos(g, *columnType, c);
10639 	return 0;
10640 	}
10641 
10642 void
XmLGridRedrawAll(Widget w)10643 XmLGridRedrawAll(Widget w)
10644 	{
10645 	XmLGridWidget g;
10646 
10647 	g = WidgetToGrid(w, "RedrawAll()");
10648 	if (!g)
10649 		return;
10650 	DrawArea(g, DrawAll, 0, 0);
10651 	}
10652 
10653 void
XmLGridRedrawCell(Widget w,unsigned char rowType,int row,unsigned char columnType,int column)10654 XmLGridRedrawCell(Widget w,
10655 		  unsigned char rowType,
10656 		  int row,
10657 		  unsigned char columnType,
10658 		  int column)
10659 	{
10660 	XmLGridWidget g;
10661 	int r, c;
10662 
10663 	g = WidgetToGrid(w, "RedrawCell()");
10664 	if (!g)
10665 		return;
10666 	r = RowTypePosToPos(g, rowType, row, 0);
10667 	c = ColTypePosToPos(g, columnType, column, 0);
10668 	DrawArea(g, DrawCell, r, c);
10669 	}
10670 
10671 void
XmLGridRedrawColumn(Widget w,unsigned char type,int column)10672 XmLGridRedrawColumn(Widget w,
10673 		    unsigned char type,
10674 		    int column)
10675 	{
10676 	XmLGridWidget g;
10677 	int c;
10678 
10679 	g = WidgetToGrid(w, "RedrawColumn()");
10680 	if (!g)
10681 		return;
10682 	c = ColTypePosToPos(g, type, column, 0);
10683 	DrawArea(g, DrawCol, 0, c);
10684 	}
10685 
10686 void
XmLGridRedrawRow(Widget w,unsigned char type,int row)10687 XmLGridRedrawRow(Widget w,
10688 		 unsigned char type,
10689 		 int row)
10690 	{
10691 	XmLGridWidget g;
10692 	int r;
10693 
10694 	g = WidgetToGrid(w, "RedrawRow()");
10695 	if (!g)
10696 		return;
10697 	r = RowTypePosToPos(g, type, row, 0);
10698 	DrawArea(g, DrawRow, r, 0);
10699 	}
10700 
10701 int
XmLGridRead(Widget w,FILE * file,int format,char delimiter)10702 XmLGridRead(Widget w,
10703 	    FILE *file,
10704 	    int format,
10705 	    char delimiter)
10706 	{
10707 	XmLGridWidget g;
10708 	char *data;
10709 	int n;
10710 
10711 	g = WidgetToGrid(w, "Read()");
10712 	if (!g)
10713 		return 0;
10714 	if (!file)
10715 		{
10716 		XmLWarning(w, "Read() - file is NULL");
10717 		return 0;
10718 		}
10719 	data = FileToString(file);
10720 	if (!data)
10721 		{
10722 		XmLWarning(w, "Read() - error loading file");
10723 		return 0;
10724 		}
10725 	n = Read(g, format, delimiter, 0, 0, data);
10726 	free((char *)data);
10727 	return n;
10728 	}
10729 
10730 int
XmLGridReadPos(Widget w,FILE * file,int format,char delimiter,unsigned char rowType,int row,unsigned char columnType,int column)10731 XmLGridReadPos(Widget w,
10732 	       FILE *file,
10733 	       int format,
10734 	       char delimiter,
10735 	       unsigned char rowType,
10736 	       int row,
10737 	       unsigned char columnType,
10738 	       int column)
10739 	{
10740 	XmLGridWidget g;
10741 	char *data;
10742 	int r, c, n;
10743 
10744 	g = WidgetToGrid(w, "ReadPos()");
10745 	if (!g)
10746 		return 0;
10747 	if (!file)
10748 		{
10749 		XmLWarning(w, "ReadPos() - file is NULL");
10750 		return 0;
10751 		}
10752 	data = FileToString(file);
10753 	if (!data)
10754 		{
10755 		XmLWarning(w, "ReadPos() - error loading file");
10756 		return 0;
10757 		}
10758 	r = RowTypePosToPos(g, rowType, row, 0);
10759 	c = ColTypePosToPos(g, columnType, column, 0);
10760 	n = Read(g, format, delimiter, r, c, data);
10761 	free((char *)data);
10762 	return n;
10763 	}
10764 
10765 int
XmLGridSetStrings(Widget w,char * data)10766 XmLGridSetStrings(Widget w,
10767 		  char *data)
10768 	{
10769 	XmLGridWidget g;
10770 
10771 	g = WidgetToGrid(w, "SetStrings()");
10772 	if (!g)
10773 		return 0;
10774 	return Read(g, XmFORMAT_DELIMITED, '|', 0, 0, data);
10775 	}
10776 
10777 int
XmLGridSetStringsPos(Widget w,unsigned char rowType,int row,unsigned char columnType,int column,char * data)10778 XmLGridSetStringsPos(Widget w,
10779 		     unsigned char rowType,
10780 		     int row,
10781 		     unsigned char columnType,
10782 		     int column,
10783 		     char *data)
10784 	{
10785 	XmLGridWidget g;
10786 	int r, c;
10787 
10788 	g = WidgetToGrid(w, "SetStringsPos()");
10789 	if (!g)
10790 		return 0;
10791 	r = RowTypePosToPos(g, rowType, row, 0);
10792 	c = ColTypePosToPos(g, columnType, column, 0);
10793 	return Read(g, XmFORMAT_DELIMITED, '|', r, c, data);
10794 	}
10795 
10796 int
XmLGridWrite(Widget w,FILE * file,int format,char delimiter,Boolean skipHidden)10797 XmLGridWrite(Widget w,
10798 	     FILE *file,
10799 	     int format,
10800 	     char delimiter,
10801 	     Boolean skipHidden)
10802 	{
10803 	XmLGridWidget g;
10804 	int nrow, ncol;
10805 
10806 	g = WidgetToGrid(w, "Write()");
10807 	if (!g)
10808 		return 0;
10809 	nrow = XmLArrayGetCount(g->grid.rowArray);
10810 	ncol = XmLArrayGetCount(g->grid.colArray);
10811 	Write(g, file, format, delimiter, skipHidden, 0, 0, nrow, ncol);
10812 	return 0;
10813 	}
10814 
10815 int
XmLGridWritePos(Widget w,FILE * file,int format,char delimiter,Boolean skipHidden,unsigned char rowType,int row,unsigned char columnType,int column,int nrow,int ncolumn)10816 XmLGridWritePos(Widget w,
10817 		FILE *file,
10818 		int format,
10819 		char delimiter,
10820 		Boolean skipHidden,
10821 		unsigned char rowType,
10822 		int row,
10823 		unsigned char columnType,
10824 		int column,
10825 		int nrow,
10826 		int ncolumn)
10827 	{
10828 	XmLGridWidget g;
10829 	int r, c;
10830 
10831 	g = WidgetToGrid(w, "WritePos()");
10832 	if (!g)
10833 		return 0;
10834 	r = RowTypePosToPos(g, rowType, row, 0);
10835 	c = ColTypePosToPos(g, columnType, column, 0);
10836 	Write(g, file, format, delimiter, skipHidden, r, c, nrow, ncolumn);
10837 	return 0;
10838 	}
10839 
10840 Boolean
XmLGridCopyPos(Widget w,Time time,unsigned char rowType,int row,unsigned char columnType,int column,int nrow,int ncolumn)10841 XmLGridCopyPos(Widget w,
10842 	       Time time,
10843 	       unsigned char rowType,
10844 	       int row,
10845 	       unsigned char columnType,
10846 	       int column,
10847 	       int nrow,
10848 	       int ncolumn)
10849 	{
10850 	XmLGridWidget g;
10851 	int r, c;
10852 
10853 	g = WidgetToGrid(w, "CopyPos()");
10854 	if (!g)
10855 		return False;
10856 	r = RowTypePosToPos(g, rowType, row, 0);
10857 	c = ColTypePosToPos(g, columnType, column, 0);
10858 	return Copy(g, time, 0, r, c, nrow, ncolumn);
10859 	}
10860 
10861 Boolean
XmLGridCopySelected(Widget w,Time time)10862 XmLGridCopySelected(Widget w,
10863 		    Time time)
10864 	{
10865 	XmLGridWidget g;
10866 
10867 	g = WidgetToGrid(w, "CopySelected()");
10868 	if (!g)
10869 		return False;
10870 	return Copy(g, time, 1, 0, 0, 0, 0);
10871 	}
10872 
10873 Boolean
XmLGridPaste(Widget w)10874 XmLGridPaste(Widget w)
10875 	{
10876 	XmLGridWidget g;
10877 	int r, c;
10878 
10879 	g = WidgetToGrid(w, "Paste()");
10880 	if (!g)
10881 		return False;
10882 	r = g->grid.focusRow;
10883 	c = g->grid.focusCol;
10884 	if (r < 0 || c < 0)
10885 		{
10886 		XmLWarning(w, "Paste() - no cell has focus");
10887 		return False;
10888 		}
10889 	return Paste(g, r, c);
10890 	}
10891 
10892 Boolean
XmLGridPastePos(Widget w,unsigned char rowType,int row,unsigned char columnType,int column)10893 XmLGridPastePos(Widget w,
10894 		unsigned char rowType,
10895 		int row,
10896 		unsigned char columnType,
10897 		int column)
10898 	{
10899 	XmLGridWidget g;
10900 	int r, c;
10901 
10902 	g = WidgetToGrid(w, "PastePos()");
10903 	if (!g)
10904 		return False;
10905 	r = RowTypePosToPos(g, rowType, row, 0);
10906 	c = ColTypePosToPos(g, columnType, column, 0);
10907 	return Paste(g, r, c);
10908 	}
10909 
10910 /* XFE Additions below here */
10911 static void
EditTimer(XtPointer clientData,XtIntervalId * intervalId)10912 EditTimer(XtPointer clientData,
10913           XtIntervalId *intervalId)
10914 {
10915 	XmLGridWidget g;
10916 
10917 	g = (XmLGridWidget)clientData;
10918 
10919     g->grid.editTimerSet = 0;
10920     g->grid.lastSelectTime = 0;
10921     TextAction(g,TEXT_EDIT_INSERT);
10922 }
10923 
10924 void
XmLGridSetVisibleColumnCount(Widget w,int new_num_visible)10925 XmLGridSetVisibleColumnCount(Widget w, int new_num_visible)
10926 {
10927   XmLGridWidget g = (XmLGridWidget)w;
10928   int ii, num_columns, visible_count;
10929   XmLGridColumn colp;
10930 
10931 
10932   visible_count = 0;
10933   num_columns = XmLArrayGetCount(g->grid.colArray);
10934 
10935   if (new_num_visible == 0)
10936       return;
10937   for (ii = 0; ii < num_columns; ii ++)
10938   {
10939       colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, ii);
10940 
10941       if (colp->grid.hidden && visible_count < new_num_visible)
10942       {
10943           colp->grid.hidden = False;
10944       }
10945       else if (!colp->grid.hidden && visible_count >= new_num_visible)
10946       {
10947           colp->grid.hidden = True;
10948       }
10949       if (!colp->grid.hidden)
10950           visible_count++;
10951   }
10952   if (visible_count < num_columns)
10953       g->grid.visibleCols = visible_count;
10954   else
10955       g->grid.visibleCols = 0;
10956 
10957   setHideUnhideSensitivity(w);
10958 
10959   HorizLayout(g, 1);
10960   DrawArea(g, DrawAll, 0, 0);
10961 }
10962 
10963 static void
HideColumn(Widget w,XtPointer clientData,XtPointer callData)10964 HideColumn(Widget w, XtPointer clientData, XtPointer callData)
10965 {
10966 	Widget g = (Widget) clientData;
10967 
10968     XmLGridHideRightColumn(g);
10969 }
10970 static void
UnhideColumn(Widget w,XtPointer clientData,XtPointer callData)10971 UnhideColumn(Widget w, XtPointer clientData, XtPointer callData)
10972 {
10973 	Widget g = (Widget) clientData;
10974 
10975     XmLGridUnhideRightColumn(g);
10976 }
10977 
10978 static void
CreateHideUnhideButtons(XmLGridWidget g)10979 CreateHideUnhideButtons(XmLGridWidget g)
10980 {
10981 	if (!g->grid.hideUnhideButtons)
10982         {
10983         XmLWarning((Widget)g,"CreateHideUnhideButtons - Creating buttons when XmNhideUnhideButtons is False.");
10984         return;
10985         }
10986 
10987     g->grid.hideButton = XtVaCreateWidget(
10988 		    "hide", xmDrawnButtonWidgetClass,
10989    		    (Widget)g, XmNhighlightThickness, 0,
10990 		    XmNshadowThickness, 1,
10991    		    XmNtraversalOn, False,
10992   		    XmNbackground, g->core.background_pixel,
10993 		    XmNforeground, g->manager.foreground,
10994 		    XmNtopShadowColor, g->manager.top_shadow_color,
10995 		    XmNbottomShadowColor, g->manager.bottom_shadow_color,
10996 		    NULL);
10997 
10998     g->grid.unhideButton = XtVaCreateWidget(
10999 		    "unhide", xmDrawnButtonWidgetClass,
11000    		    (Widget)g, XmNhighlightThickness, 0,
11001 		    XmNshadowThickness, 1,
11002    		    XmNtraversalOn, False,
11003   		    XmNbackground, g->core.background_pixel,
11004 		    XmNforeground, g->manager.foreground,
11005 		    XmNtopShadowColor, g->manager.top_shadow_color,
11006 		    XmNbottomShadowColor, g->manager.bottom_shadow_color,
11007 		    NULL);
11008 
11009     XmLDrawnButtonSetType(g->grid.hideButton,   XmDRAWNB_SMALLARROW,
11010                           XmDRAWNB_RIGHT);
11011     XmLDrawnButtonSetType(g->grid.unhideButton, XmDRAWNB_SMALLARROW,
11012                           XmDRAWNB_LEFT);
11013 
11014 
11015     XtAddCallback(g->grid.hideButton, XmNactivateCallback,
11016                   HideColumn, (XtPointer)g);
11017     XtAddCallback(g->grid.unhideButton, XmNactivateCallback,
11018                   UnhideColumn, (XtPointer)g);
11019 #if 0
11020     XtOverrideTranslations(g->grid.unhideButton,
11021                            g->grid.unhideButtonTrans);
11022     XtOverrideTranslations(g->grid.hideButton,
11023                            g->grid.hideButtonTrans);
11024 #endif /*0*/
11025 }
11026 
11027 static void
HideAction(Widget w,XEvent * event,String * params,Cardinal * num_params)11028 HideAction(Widget w,
11029 	   XEvent *event,
11030 	   String *params,
11031 	   Cardinal *num_params)
11032 {
11033   XmLGridHideRightColumn(w);
11034 }
11035 
11036 static void
UnhideAction(Widget w,XEvent * event,String * params,Cardinal * num_params)11037 UnhideAction(Widget w,
11038 	     XEvent *event,
11039 	     String *params,
11040 	     Cardinal *num_params)
11041 {
11042   XmLGridUnhideRightColumn(w);
11043 }
11044 
11045 static void
setHideUnhideSensitivity(Widget w)11046 setHideUnhideSensitivity(Widget w)
11047 {
11048   XmLGridWidget g = (XmLGridWidget)w;
11049   int total_columns = XmLArrayGetCount(g->grid.colArray);
11050   Boolean can_unhide, can_hide;
11051 
11052   if (!g->grid.hideUnhideButtons) return;
11053 
11054   /* If visibleCols is zero, that means all the columns are visible. */
11055   if (g->grid.visibleCols == 0) {
11056       can_unhide = 0;
11057       can_hide   = (total_columns > 1);
11058   } else {
11059       can_unhide = (g->grid.visibleCols < total_columns);
11060       can_hide   = (g->grid.visibleCols > 1);
11061   }
11062   XtSetSensitive(g->grid.unhideButton, can_unhide);
11063   XtSetSensitive(g->grid.hideButton, can_hide);
11064 }
11065 
11066 void
XmLGridHideRightColumn(Widget w)11067 XmLGridHideRightColumn(Widget w)
11068 {
11069   XmLGridWidget g = (XmLGridWidget)w;
11070   int total_columns = XmLArrayGetCount(g->grid.colArray);
11071   if (total_columns <= 1)
11072       return;
11073 
11074   /* If visibleCols is zero, that means all the columns are visible. */
11075   if (g->grid.visibleCols == 0 || g->grid.visibleCols > total_columns)
11076       XmLGridSetVisibleColumnCount(w, total_columns - 1);
11077   else
11078       XmLGridSetVisibleColumnCount(w, g->grid.visibleCols - 1);
11079 }
11080 
11081 void
XmLGridUnhideRightColumn(Widget w)11082 XmLGridUnhideRightColumn(Widget w)
11083 {
11084   XmLGridWidget g = (XmLGridWidget)w;
11085   int total_columns = XmLArrayGetCount(g->grid.colArray);
11086 
11087   /* If visibleCols is zero, that means all the columns are visible. */
11088   if ( g->grid.visibleCols != 0 && g->grid.visibleCols < total_columns)
11089       XmLGridSetVisibleColumnCount(w, g->grid.visibleCols + 1);
11090 }
11091 
11092 static void
MenuArm(Widget w,XEvent * event,String * params,Cardinal * num_params)11093 MenuArm(Widget w,
11094 	XEvent *event,
11095 	String *params,
11096 	Cardinal *num_params)
11097 {
11098     XmLGridWidget g = (XmLGridWidget)w;
11099 
11100     SelectTypeArea(g, SelectRow, (XEvent *)0, g->grid.lastSelectRow, 0, False, False);
11101 
11102     g->grid.inMode = InSelect;
11103 }
11104 
11105 static void
MenuDisarm(Widget w,XEvent * event,String * params,Cardinal * num_params)11106 MenuDisarm(Widget w,
11107 	   XEvent *event,
11108 	   String *params,
11109 	   Cardinal *num_params)
11110 {
11111     XmLGridWidget g = (XmLGridWidget)w;
11112 
11113     g->grid.inMode = InNormal;
11114 }
11115 
11116 static void
ResizeColumnToFit(XmLGridWidget g,int new_x)11117 ResizeColumnToFit(XmLGridWidget g, int new_x)
11118 {
11119     XmLGridColumn colp;
11120     int width = 0;
11121     XRectangle rect;
11122     if (!RowColToXY(g, 0, g->grid.resizeCol, False, &rect))
11123     {
11124         if (new_x > rect.x)
11125             width = (new_x - rect.x) -
11126                 (rect.width - GetColWidth(g, g->grid.resizeCol));
11127         if (width < g->grid.minColWidth)
11128             width = g->grid.minColWidth;
11129 
11130         /*printf("col(%d) resize_xy(%3d) colx(%3d) colw(%3d) column_width(%3d) new_width(%3d)\n", g->grid.resizeCol, g->grid.resizeLineXY, rect.x, rect.width, GetColWidth(g, g->grid.resizeCol), width);*/
11131 
11132         /* Resize all columns to the right */
11133         colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray,
11134                                           g->grid.resizeCol);
11135         colp->grid.width = width;
11136         SizeColumnsToFit(g, g->grid.resizeCol + 1);
11137         HorizLayout(g, 0);
11138         DrawArea(g, DrawAll, 0, 0);
11139         g->grid.resizeLineXY = rect.x + width;
11140     }
11141 }
11142 
11143 
11144 static int
SizeColumnsToFit(XmLGridWidget g,int starting_at)11145 SizeColumnsToFit(XmLGridWidget g, int starting_at)
11146 {
11147 	int resizable_width = 0;
11148     int delta = 0;
11149     float hidden_col_adjust;
11150 	int ii, num_columns;
11151     XmLGridColumn colp;
11152 
11153     /* Total the width of the columns and
11154        also total how much of that can be resized */
11155     delta = g->core.width;
11156     delta -= g->manager.shadow_thickness * 2;
11157 
11158 	if (g->grid.hideUnhideButtons)
11159         {
11160             delta -= g->grid.unhideButton->core.width;
11161             delta -= g->grid.hideButton->core.width;
11162         }
11163     else if (XtIsManaged(g->grid.vsb))
11164 		{
11165             delta -= g->grid.vsb->core.width;
11166 		}
11167 
11168     num_columns = g->grid.colCount + g->grid.headingColCount
11169         + g->grid.footerColCount;
11170     for (ii = 0; ii < num_columns; ii ++)
11171         {
11172             colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, ii);
11173 
11174             if (colp->grid.sizePolicy != XmCONSTANT)
11175                 {
11176                     if (g->grid.debugLevel)
11177                         XmLWarning((Widget)g, "SizeColumnsToFit() - only valid for XmNcolumnSizePolicy == XmCONSTANT");
11178                     colp->grid.sizePolicy = XmCONSTANT;
11179                 }
11180             if (!g->grid.visibleCols || ii < g->grid.visibleCols)
11181                 {
11182                     delta -= colp->grid.width;
11183 
11184                     if (ii >= starting_at && colp->grid.resizable)
11185                         resizable_width += colp->grid.width;
11186                 }
11187         }
11188     if (delta == 0 || resizable_width <= 0)
11189         return delta;
11190 
11191     if (g->grid.debugLevel)
11192         {
11193             fprintf(stderr,"Applying delta(%d) from %d to %d (%d resizable)\n",
11194                     delta, starting_at, num_columns - 1, resizable_width);
11195         }
11196 
11197     hidden_col_adjust = (float)delta / resizable_width;
11198 
11199     /* Adjust each column to fit based on its percentage of the total width */
11200 	for (ii = starting_at; ii < num_columns ; ii ++)
11201 		{
11202 			int col_width;
11203 			int col_delta;
11204 			int new_col_width;
11205 
11206             colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, ii);
11207             col_width = colp->grid.width;
11208 
11209 			if (!colp->grid.resizable || col_width == 0)
11210                 continue;
11211 
11212             if (colp->grid.hidden)
11213                 col_delta = (int)(hidden_col_adjust * col_width);
11214             else
11215                 if (col_width < resizable_width && resizable_width > 0)
11216                     col_delta = delta * ((float)col_width / resizable_width);
11217                 else
11218                     col_delta = delta;
11219 
11220 			new_col_width = col_width + col_delta;
11221 
11222 			if (new_col_width < g->grid.minColWidth)
11223 				{
11224 					new_col_width = g->grid.minColWidth;
11225 					col_delta = col_width - new_col_width;
11226 				}
11227 
11228             if (!colp->grid.hidden)
11229                 {
11230                     delta -= col_delta;
11231                     resizable_width -= col_width;
11232                 }
11233 
11234 			colp->grid.width = new_col_width;
11235 
11236             if (g->grid.debugLevel)
11237                 fprintf (stderr, "Column %d, width %d -> %d, new delta %d, new resizable width %d\n",
11238                          ii, col_width, new_col_width,
11239                          delta, resizable_width);
11240 		}
11241 
11242 	return delta;
11243 }
11244 
11245 
11246 void
XmLGridGetSort(Widget w,int * column,unsigned char * sortType)11247 XmLGridGetSort(Widget w, int *column, unsigned char *sortType)
11248 {
11249     XmLGridWidget g = (XmLGridWidget)w;
11250     XmLGridColumn colp;
11251     int num_columns = XmLArrayGetCount(g->grid.colArray);
11252     int ii;
11253 
11254     *column = 0;
11255     *sortType = XmSORT_NONE;
11256 
11257     for (ii = 0; ii < num_columns; ii ++)
11258     {
11259         colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, ii);
11260 
11261         if (colp && colp->grid.sort != XmSORT_NONE)
11262         {
11263             *column = ii;
11264             *sortType = colp->grid.sort;
11265             break;
11266         }
11267     }
11268 }
11269 
11270 void
XmLGridSetSort(Widget w,int column,unsigned char sortType)11271 XmLGridSetSort(Widget w, int column, unsigned char sortType)
11272 {
11273     XmLGridWidget g = (XmLGridWidget)w;
11274     XmLGridRow rowp;
11275     XmLGridColumn colp;
11276     XmLGridCell cellp;
11277     int old_sort_column;
11278     unsigned char old_sort_type;
11279 
11280     /*printf("XmLGridSetSort: (%d,%s)\n", column,
11281            sortType == XmSORT_NONE ? "none" :
11282            sortType == XmSORT_ASCENDING ? "ascending" : "descending");
11283      */
11284 
11285     /* Clear old sort resource */
11286     XmLGridGetSort(w, &old_sort_column, &old_sort_type);
11287     if (old_sort_type != XmSORT_NONE)
11288     {
11289         colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, old_sort_column);
11290         if (colp)
11291             colp->grid.sort = XmSORT_NONE;
11292     }
11293 
11294     colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, column);
11295     colp->grid.sort = sortType;
11296 
11297     /* Clear any existing cell sort masks. */
11298     rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, 0);
11299     if (rowp)
11300     {
11301         int ii, count;
11302 
11303         count = XmLArrayGetCount(rowp->grid.cellArray);
11304         for (ii = 0; ii < count; ii++)
11305         {
11306             cellp = (XmLGridCell)XmLArrayGet(rowp->grid.cellArray, ii);
11307 
11308             if (XmLGridCellDrawSort(cellp))
11309             {
11310                 DrawArea(g, DrawCell, 0, ii);
11311                 XmLGridCellSetDrawSort(cellp, False);
11312             }
11313         }
11314     }
11315 
11316     /* Set the cell mask of the heading cell. */
11317     cellp = GetCell(g, 0, column);
11318 
11319     if (cellp)
11320     {
11321         XmLGridCellSetDrawSort(cellp, True);
11322         if (sortType == XmSORT_NONE)
11323             XmLGridCellSetDrawSort(cellp, False);
11324         else if (sortType == XmSORT_ASCENDING)
11325             XmLGridCellSetSortAscending(cellp, True);
11326         else if (sortType == XmSORT_DESCENDING)
11327             XmLGridCellSetSortAscending(cellp, False);
11328 
11329 		DrawArea(g, DrawCell, 0, column);
11330     }
11331 
11332 }
11333 
11334 /*----------------------------------------------------------------------*/
11335 static void
GridInvokeCallbacks(Widget w,XtCallbackList list,int reason,XEvent * event)11336 GridInvokeCallbacks(Widget			w,
11337 					XtCallbackList	list,
11338 					int				reason,
11339 					XEvent *		event)
11340 {
11341     XmLGridWidget g = (XmLGridWidget)w;
11342 
11343 	/* Make sure widget is alive and callback list is not NULL */
11344 	if (!g->core.being_destroyed && list)
11345 	{
11346 		XmAnyCallbackStruct cbs;
11347 
11348 		cbs.event 	= event;
11349 		cbs.reason	= reason;
11350 
11351 		/* Invoke the Callback List */
11352 		XtCallCallbackList(w,list,&cbs);
11353 	}
11354 }
11355 /*----------------------------------------------------------------------*/
11356 static void
GridInvokeCellCrossingCallbacks(Widget w,XtCallbackList list,int reason,XEvent * event,int row,int col)11357 GridInvokeCellCrossingCallbacks(Widget			w,
11358 								XtCallbackList	list,
11359 								int				reason,
11360 								XEvent *		event,
11361 								int				row,
11362 								int				col)
11363 {
11364     XmLGridWidget g = (XmLGridWidget)w;
11365 
11366 	/* Make sure widget is alive and callback list is not NULL */
11367 	if (!g->core.being_destroyed && list)
11368 	{
11369 		if (row != -1 && col != -1)
11370 		{
11371 			XmLGridCell				cell;
11372 			XmLGridCallbackStruct	cbs;
11373 
11374 			cell = GetCell(g, row, col);
11375 
11376 			if (cell)
11377 			{
11378 				cbs.reason		= XmCR_CELL_FOCUS_OUT;
11379 				cbs.columnType	= ColPosToType(g, col);
11380 				cbs.column		= ColPosToTypePos(g, cbs.columnType, col);
11381 				cbs.rowType		= RowPosToType(g, row);
11382 				cbs.row			= RowPosToTypePos(g, cbs.rowType, row);
11383 
11384 /* 				XmLGridCellAction(cell, (Widget)g, &cbs); */
11385 
11386 				/* Invoke the Callback List */
11387 				XtCallCallbackList(w,list,&cbs);
11388 			}
11389 		}
11390 	}
11391 }
11392 /*----------------------------------------------------------------------*/
11393 static void
GridCrossingEH(Widget w,XtPointer closure,XEvent * event,Boolean * ctd)11394 GridCrossingEH(Widget		w,
11395 			   XtPointer	closure,
11396 			   XEvent *		event,
11397 			   Boolean *	ctd)
11398 {
11399     XmLGridWidget g = (XmLGridWidget)w;
11400 
11401 	if (event)
11402 	{
11403 		if (event->type == EnterNotify)
11404 		{
11405 			/* Invoke XmNenterGridCallback */
11406 			GridInvokeCallbacks(w,
11407 								g->grid.enterGridCallback,
11408 								XmCR_ENTER_GRID,
11409 								event);
11410 
11411 /* 			printf("Enter(%s)\n",XtName(w)); */
11412 		}
11413 		else if (event->type == LeaveNotify)
11414 		{
11415 			g->grid.lastCursorMotionRow = -1;
11416 			g->grid.lastCursorMotionCol = -1;
11417 
11418 			/* Invoke XmNleaveGridCallback */
11419 			GridInvokeCallbacks(w,
11420 								g->grid.leaveGridCallback,
11421 								XmCR_LEAVE_GRID,
11422 								event);
11423 
11424 /* 			printf("Leave(%s)\n",XtName(w)); */
11425 		}
11426 	}
11427 
11428 	*ctd = True;
11429 }
11430 /*----------------------------------------------------------------------*/
11431