2
/* Lefteris Koutsofios - AT&T Bell Laboratories */
9
#define WAU widget->u.a
11
extern WidgetClass arrayWidgetClass;
13
static void awcallback (Widget, XtPointer, XtPointer);
15
int GAcreatewidget (Gwidget_t *parent, Gwidget_t *widget,
16
int attrn, Gwattr_t *attrp) {
23
Gerr (POS, G_ERRNOPARENTWIDGET);
27
ps.x = ps.y = MINAWSIZE;
29
for (ai = 0; ai < attrn; ai++) {
30
switch (attrp[ai].id) {
32
GETSIZE (attrp[ai].u.s, ps, MINAWSIZE);
34
case G_ATTRBORDERWIDTH:
35
ADD2ARGS (XtNborderWidth, attrp[ai].u.i);
38
if (Strcmp ("horizontal", attrp[ai].u.t) == 0) {
39
ADD2ARGS (XtNorientation, XtorientHorizontal);
40
WAU->mode = G_AWHARRAY;
41
} else if (Strcmp ("vertical", attrp[ai].u.t) == 0) {
42
WAU->mode = G_AWVARRAY;
44
Gerr (POS, G_ERRBADATTRVALUE, attrp[ai].u.t);
49
if (Strcmp ("on", attrp[ai].u.t) == 0)
50
Gawsetmode (widget, FALSE);
51
else if (Strcmp ("off", attrp[ai].u.t) == 0)
52
Gawsetmode (widget, TRUE);
54
Gerr (POS, G_ERRBADATTRVALUE, attrp[ai].u.t);
59
color = attrp[ai].u.c.index;
60
if (color != 0 && color != 1) {
61
Gerr (POS, G_ERRBADCOLORINDEX, color);
64
c.red = attrp[ai].u.c.r * 257;
65
c.green = attrp[ai].u.c.g * 257;
66
c.blue = attrp[ai].u.c.b * 257;
68
Gdisplay, DefaultColormap (Gdisplay, Gscreenn), &c
71
ADD2ARGS (XtNbackground, c.pixel);
73
ADD2ARGS (XtNforeground, c.pixel);
76
Gerr (POS, G_ERRCANNOTSETATTR1, "windowid");
79
WAU->func = (Gawcoordscb) attrp[ai].u.func;
82
widget->udata = attrp[ai].u.u;
85
Gerr (POS, G_ERRBADATTRID, attrp[ai].id);
89
ADD2ARGS (XtNwidth, ps.x);
90
ADD2ARGS (XtNheight, ps.y);
91
if (!(widget->w = XtCreateWidget ("array", arrayWidgetClass,
92
parent->w, argp, argn))) {
93
Gerr (POS, G_ERRCANNOTCREATEWIDGET);
96
XtAddCallback (widget->w, XtNcallback, awcallback, (XtPointer) NULL);
97
Glazymanage (widget->w);
101
int GAsetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) {
106
for (ai = 0; ai < attrn; ai++) {
107
switch (attrp[ai].id) {
109
GETSIZE (attrp[ai].u.s, ps, MINAWSIZE);
110
ADD2ARGS (XtNwidth, ps.x);
111
ADD2ARGS (XtNheight, ps.y);
113
case G_ATTRBORDERWIDTH:
114
ADD2ARGS (XtNborderWidth, attrp[ai].u.i);
117
Gerr (POS, G_ERRCANNOTSETATTR2, "mode");
120
if (Strcmp ("on", attrp[ai].u.t) == 0)
121
Gawsetmode (widget, FALSE);
122
else if (Strcmp ("off", attrp[ai].u.t) == 0)
123
Gawsetmode (widget, TRUE);
125
Gerr (POS, G_ERRBADATTRVALUE, attrp[ai].u.t);
130
Gerr (POS, G_ERRCANNOTSETATTR2, "windowid");
133
WAU->func = (Gawcoordscb) attrp[ai].u.func;
136
widget->udata = attrp[ai].u.u;
139
Gerr (POS, G_ERRBADATTRID, attrp[ai].id);
143
XtSetValues (widget->w, argp, argn);
147
int GAgetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) {
148
Dimension width, height;
151
for (ai = 0; ai < attrn; ai++) {
153
switch (attrp[ai].id) {
155
ADD2ARGS (XtNwidth, &width);
156
ADD2ARGS (XtNheight, &height);
157
XtGetValues (widget->w, argp, argn);
158
attrp[ai].u.s.x = width, attrp[ai].u.s.y = height;
160
case G_ATTRBORDERWIDTH:
161
ADD2ARGS (XtNborderWidth, &width);
162
XtGetValues (widget->w, argp, argn);
163
attrp[ai].u.i = width;
166
attrp[ai].u.t = (WAU->mode == G_AWHARRAY) ?
167
"horizontal" : "vertical";
170
attrp[ai].u.t = (Gawgetmode (widget)) ? "off" : "on";
173
sprintf (&Gbufp[0], "0x%lx", XtWindow (widget->w));
174
attrp[ai].u.t = &Gbufp[0];
177
attrp[ai].u.func = WAU->func;
180
attrp[ai].u.u = widget->udata;
183
Gerr (POS, G_ERRBADATTRID, attrp[ai].id);
190
int GAdestroywidget (Gwidget_t *widget) {
191
XtDestroyWidget (widget->w);
195
static void awcallback (Widget w, XtPointer clientdata, XtPointer calldata) {
198
if (!(widget = findwidget ((unsigned long) w, G_ARRAYWIDGET)))
201
(*WAU->func) (widget - &Gwidgets[0], (Gawdata_t *) calldata);
203
Gawdefcoordscb (widget - &Gwidgets[0], (Gawdata_t *) calldata);
206
/* the rest of this file contains the implementation of the array widget */
208
#include <X11/IntrinsicP.h>
210
typedef struct _ArrayClassRec *ArrayWidgetClass;
211
typedef struct _ArrayRec *ArrayWidget;
213
typedef struct _ArrayClassPart {
214
int dummy; /* not used */
217
typedef struct _ArrayClassRec {
218
CoreClassPart core_class;
219
CompositeClassPart composite_class;
220
ArrayClassPart array_class;
223
typedef struct _ArrayPart {
224
XtCallbackList callbacks;
225
XtOrientation orientation;
230
typedef struct _ArrayRec {
232
CompositePart composite;
237
#define CHILDSIZE sizeof (Gawcarray_t)
239
static XtResource resources[] = {
245
XtOffsetOf (ArrayRec, array.callbacks),
246
XtRCallback, (XtPointer) NULL
252
sizeof (XtOrientation),
253
XtOffsetOf (ArrayRec, array.orientation),
254
XtRImmediate, (XtPointer) XtorientVertical
258
static void ClassInitialize (void);
259
static void Initialize (Widget, Widget, ArgList, Cardinal *);
260
static void Destroy (Widget);
261
static void Resize (Widget);
262
static Boolean SetValues (Widget, Widget, Widget, ArgList, Cardinal *);
263
static XtGeometryResult GeometryManager(Widget,
264
XtWidgetGeometry *, XtWidgetGeometry *);
265
static void ChangeManaged (Widget);
266
static void InsertChild (Widget);
267
static void DeleteChild (Widget);
268
static void dolayout (ArrayWidget, int);
270
ArrayClassRec arrayClassRec = {
271
{ /* core_class fields */
272
/* superclass */ (WidgetClass) &compositeClassRec,
273
/* class_name */ "Array",
274
/* widget_size */ sizeof(ArrayRec),
275
/* class_initialize */ ClassInitialize,
276
/* class_part_init */ NULL,
277
/* class_inited */ FALSE,
278
/* initialize */ Initialize,
279
/* initialize_hook */ NULL,
280
/* realize */ XtInheritRealize,
283
/* resources */ resources,
284
/* num_resources */ XtNumber (resources),
285
/* xrm_class */ NULLQUARK,
286
/* compress_motion */ TRUE,
287
/* compress_exposure */ TRUE,
288
/* compress_enterleave */ TRUE,
289
/* visible_interest */ FALSE,
290
/* destroy */ Destroy,
292
/* expose */ XtInheritExpose,
293
/* set_values */ SetValues,
294
/* set_values_hook */ NULL,
295
/* set_values_almost */ XtInheritSetValuesAlmost,
296
/* get_values_hook */ NULL,
297
/* accept_focus */ NULL,
298
/* version */ XtVersion,
299
/* callback_private */ NULL,
301
/* query_geometry */ XtInheritQueryGeometry,
302
/* display_accelerator */ XtInheritDisplayAccelerator,
305
{ /* composite_class fields */
306
/* geometry_manager */ GeometryManager,
307
/* change_managed */ ChangeManaged,
308
/* insert_child */ InsertChild,
309
/* delete_child */ DeleteChild,
312
{ /* array_class fields */
317
WidgetClass arrayWidgetClass = (WidgetClass)&arrayClassRec;
319
int Gaworder (Gwidget_t *widget, void *data, Gawordercb func) {
322
aw = (ArrayWidget) widget->w;
323
(*func) (data, &aw->array.data);
328
int Gawsetmode (Gwidget_t *widget, int mode) {
331
aw = (ArrayWidget) widget->w;
332
aw->array.batchmode = mode;
337
int Gawgetmode (Gwidget_t *widget) {
340
aw = (ArrayWidget) widget->w;
341
return aw->array.batchmode;
344
void Gawdefcoordscb (int wi, Gawdata_t *dp) {
346
int sx, sy, csx, csy, ci;
348
sx = dp->sx, sy = dp->sy;
350
for (ci = 0; ci < dp->cj; ci++) {
351
cp = &dp->carray[ci];
354
cp->ox = csx, cp->oy = csy;
355
if (dp->type == G_AWVARRAY)
356
cp->sx = sx - 2 * cp->bs, csy += cp->sy + 2 * cp->bs;
358
cp->sy = sy - 2 * cp->bs, csx += cp->sx + 2 * cp->bs;
360
if (dp->type == G_AWVARRAY)
366
static void ClassInitialize (void) {
367
XtAddConverter( XtRString, XtROrientation, XmuCvtStringToOrientation,
371
static void Initialize (Widget reqw, Widget neww,
372
ArgList args, Cardinal *num_args) {
375
aw = (ArrayWidget) neww;
376
if (aw->array.orientation == XtorientVertical)
377
aw->array.data.type = G_AWVARRAY;
379
aw->array.data.type = G_AWHARRAY;
380
aw->array.data.carray = Marrayalloc ((long) CHILDINCR * CHILDSIZE);
381
aw->array.data.cn = CHILDINCR;
382
aw->array.data.cj = 0;
383
aw->array.batchmode = FALSE;
384
if (aw->core.width == 0)
385
aw->core.width = 100;
386
if (aw->core.height == 0)
387
aw->core.height = 100;
390
static void Destroy (Widget w) {
393
aw = (ArrayWidget) w;
394
Marrayfree (aw->array.data.carray);
395
aw->array.data.cn = aw->array.data.cj = 0;
398
static void Resize (Widget w) {
399
dolayout ((ArrayWidget) w, FALSE);
402
static Boolean SetValues (Widget curw, Widget reqw, Widget neww,
403
ArgList args, Cardinal *num_args) {
407
curaw = (ArrayWidget) curw;
408
newaw = (ArrayWidget) neww;
409
if (curaw->array.orientation != newaw->array.orientation) {
410
if (newaw->array.orientation == XtorientVertical)
411
newaw->array.data.type = G_AWVARRAY;
413
newaw->array.data.type = G_AWHARRAY;
414
dolayout (newaw, TRUE);
420
static XtGeometryResult GeometryManager(Widget w,
421
XtWidgetGeometry *req, XtWidgetGeometry *rep) {
422
Dimension width, height;
424
if (req->request_mode & ~(CWX | CWY | CWWidth | CWHeight))
427
if (req->request_mode & (CWX | CWY | CWWidth | CWHeight)) {
428
width = (req->request_mode & CWWidth) ? req->width : w->core.width;
429
height = (req->request_mode & CWHeight) ? req->height : w->core.height;
430
w->core.width = width, w->core.height = height;
431
dolayout ((ArrayWidget) XtParent (w), TRUE);
432
return XtGeometryYes;
434
return XtGeometryYes;
437
static void ChangeManaged (Widget w) {
440
aw = (ArrayWidget) w;
441
if (!aw->array.batchmode)
445
static void InsertChild (Widget w) {
447
CompositeWidgetClass sclass;
449
sclass = (CompositeWidgetClass) compositeWidgetClass;
450
(*sclass->composite_class.insert_child) (w);
451
aw = (ArrayWidget) XtParent (w);
452
if (aw->array.data.cj == aw->array.data.cn) {
453
aw->array.data.carray = Marraygrow (aw->array.data.carray,
454
(long) (aw->array.data.cn + CHILDINCR) * CHILDSIZE);
455
aw->array.data.cn += CHILDINCR;
457
aw->array.data.carray[aw->array.data.cj++].w = w;
460
static void DeleteChild (Widget w) {
462
CompositeWidgetClass sclass;
465
sclass = (CompositeWidgetClass) compositeWidgetClass;
466
(*sclass->composite_class.delete_child) (w);
467
aw = (ArrayWidget) XtParent (w);
468
for (ci = 0; ci < aw->array.data.cj; ci++)
469
if (aw->array.data.carray[ci].w == w)
471
if (ci < aw->array.data.cj) {
472
for (; ci + 1 < aw->array.data.cj; ci++)
473
aw->array.data.carray[ci].w = aw->array.data.carray[ci + 1].w;
478
static void dolayout (ArrayWidget aw, int flag) {
479
XtWidgetGeometry req, ret_req;
484
if (aw->array.batchmode)
486
dp = &aw->array.data;
487
for (ci = 0; ci < dp->cj; ci++) {
488
if (!XtIsManaged (dp->carray[ci].w)) {
489
dp->carray[ci].flag = 0;
492
cp = &dp->carray[ci];
494
cp->ox = cp->w->core.x;
495
cp->oy = cp->w->core.y;
496
cp->sx = cp->w->core.width;
497
cp->sy = cp->w->core.height;
498
cp->bs = cp->w->core.border_width;
500
dp->sx = aw->core.width, dp->sy = aw->core.height;
501
XtCallCallbackList ((Widget) aw, aw->array.callbacks, dp);
502
if ((sx = dp->sx) < MINAWSIZE)
504
if ((sy = dp->sy) < MINAWSIZE)
506
if (flag && (aw->core.width != sx || aw->core.height != sy)) {
507
req.width = sx, req.height = sy;
508
req.request_mode = CWWidth | CWHeight;
509
if (XtMakeGeometryRequest ((Widget) aw, &req, &ret_req) ==
512
XtMakeGeometryRequest ((Widget) aw, &req, &ret_req);
513
dp->sx = req.width, dp->sy = req.height;
514
XtCallCallbackList ((Widget) aw, aw->array.callbacks, dp);
517
for (ci = 0; ci < dp->cj; ci++) {
518
cp = &dp->carray[ci];
521
XtConfigureWidget (cp->w, cp->ox, cp->oy, cp->sx, cp->sy, cp->bs);