rust/cargo-c: update to 0.10.7+cargo-0.84.0
[oi-userland.git] / components / x11 / libXaw4 / src / Xaw3_1List.c
blobda910397aadf5a0f54b85450098e0b6bb8727059
1 #if ( !defined(lint) && !defined(SABER))
2 static char Xrcs_id[] = "$XConsortium: List.c,v 1.26 89/12/11 15:08:31 kit Exp $";
3 #endif
5 /*
6 * Copyright 1989 Massachusetts Institute of Technology
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of M.I.T. not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission. M.I.T. makes no representations about the
15 * suitability of this software for any purpose. It is provided "as is"
16 * without express or implied warranty.
18 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
20 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
22 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 * List.c - List widget
30 * This is the List widget, it is useful to display a list, without the
31 * overhead of having a widget for each item in the list. It allows
32 * the user to select an item in a list and notifies the application through
33 * a callback function.
35 * Created: 8/13/88
36 * By: Chris D. Peterson
37 * MIT X Consortium
40 #include <stdio.h>
41 #include <ctype.h>
43 #include <X11/IntrinsicP.h>
44 #include <X11/StringDefs.h>
46 #include <X11/Xmu/Drawing.h>
48 #include <./Xaw3_1XawInit.h>
49 #include <./Xaw3_1ListP.h>
52 /*
53 * Default Translation table.
56 static char defaultTranslations[] =
57 "<Btn1Down>: Set()\n\
58 <Btn1Up>: Notify()";
60 /****************************************************************
62 * Full class record constant
64 ****************************************************************/
66 /* Private Data */
68 #define offset(field) XtOffset(ListWidget, field)
70 static XtResource resources[] = {
71 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
72 offset(list.foreground), XtRString, "XtDefaultForeground"},
73 {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
74 offset(simple.cursor), XtRString, "left_ptr"},
75 {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
76 offset(list.font),XtRString, "XtDefaultFont"},
77 {XtNlist, XtCList, XtRPointer, sizeof(char **),
78 offset(list.list), XtRString, NULL},
79 {XtNdefaultColumns, XtCColumns, XtRInt, sizeof(int),
80 offset(list.default_cols), XtRImmediate, (caddr_t)2},
81 {XtNlongest, XtCLongest, XtRInt, sizeof(int),
82 offset(list.longest), XtRImmediate, (caddr_t)0},
83 {XtNnumberStrings, XtCNumberStrings, XtRInt, sizeof(int),
84 offset(list.nitems), XtRImmediate, (caddr_t)0},
85 {XtNpasteBuffer, XtCBoolean, XtRBoolean, sizeof(Boolean),
86 offset(list.paste), XtRString, (caddr_t) "False"},
87 {XtNforceColumns, XtCColumns, XtRBoolean, sizeof(Boolean),
88 offset(list.force_cols), XtRString, (caddr_t) "False"},
89 {XtNverticalList, XtCBoolean, XtRBoolean, sizeof(Boolean),
90 offset(list.vertical_cols), XtRString, (caddr_t) "False"},
91 {XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension),
92 offset(list.internal_width), XtRImmediate, (caddr_t)4},
93 {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension),
94 offset(list.internal_height), XtRImmediate, (caddr_t)2},
95 {XtNcolumnSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
96 offset(list.column_space), XtRImmediate, (caddr_t)6},
97 {XtNrowSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
98 offset(list.row_space), XtRImmediate, (caddr_t)2},
99 {XtNcallback, XtCCallback, XtRCallback, sizeof(caddr_t),
100 offset(list.callback), XtRCallback, NULL},
103 static void Initialize();
104 static void ChangeSize();
105 static void Resize();
106 static void Redisplay();
107 static Boolean Layout();
108 static XtGeometryResult PreferredGeom();
109 static Boolean SetValues();
110 static void Notify(), Set(), Unset();
112 static XtActionsRec actions[] = {
113 {"Notify", Notify},
114 {"Set", Set},
115 {"Unset", Unset},
116 {NULL,NULL}
119 ListClassRec listClassRec = {
121 /* core_class fields */
122 #define superclass (&simpleClassRec)
123 /* superclass */ (WidgetClass) superclass,
124 /* class_name */ "List",
125 /* widget_size */ sizeof(ListRec),
126 /* class_initialize */ XawInitializeWidgetSet,
127 /* class_part_initialize */ NULL,
128 /* class_inited */ FALSE,
129 /* initialize */ Initialize,
130 /* initialize_hook */ NULL,
131 /* realize */ XtInheritRealize,
132 /* actions */ actions,
133 /* num_actions */ XtNumber(actions),
134 /* resources */ resources,
135 /* num_resources */ XtNumber(resources),
136 /* xrm_class */ NULLQUARK,
137 /* compress_motion */ TRUE,
138 /* compress_exposure */ FALSE,
139 /* compress_enterleave */ TRUE,
140 /* visible_interest */ FALSE,
141 /* destroy */ NULL,
142 /* resize */ Resize,
143 /* expose */ Redisplay,
144 /* set_values */ SetValues,
145 /* set_values_hook */ NULL,
146 /* set_values_almost */ XtInheritSetValuesAlmost,
147 /* get_values_hook */ NULL,
148 /* accept_focus */ NULL,
149 /* version */ XtVersion,
150 /* callback_private */ NULL,
151 /* tm_table */ defaultTranslations,
152 /* query_geometry */ PreferredGeom,
154 /* Simple class fields initialization */
156 /* change_sensitive */ XtInheritChangeSensitive
160 WidgetClass listWidgetClass = (WidgetClass)&listClassRec;
162 /****************************************************************
164 * Private Procedures
166 ****************************************************************/
168 static void GetGCs(w)
169 Widget w;
171 XGCValues values;
172 ListWidget lw = (ListWidget) w;
174 values.foreground = lw->list.foreground;
175 values.font = lw->list.font->fid;
176 lw->list.normgc = XtGetGC(w, (unsigned) GCForeground | GCFont,
177 &values);
179 values.foreground = lw->core.background_pixel;
180 lw->list.revgc = XtGetGC(w, (unsigned) GCForeground | GCFont,
181 &values);
183 values.tile = XmuCreateStippledPixmap(XtScreen(w),
184 lw->list.foreground,
185 lw->core.background_pixel,
186 lw->core.depth);
187 values.fill_style = FillTiled;
189 lw->list.graygc = XtGetGC(w, (unsigned) GCFont | GCTile | GCFillStyle,
190 &values);
193 /* Function Name: ResetList
194 * Description: Resets the new list when important things change.
195 * Arguments: w - the widget.
196 * changex, changey - allow the height or width to change?
197 * Returns: none.
200 static void
201 ResetList(w, changex, changey)
202 Widget w;
203 Boolean changex, changey;
205 ListWidget lw = (ListWidget) w;
206 Dimension width = w->core.width;
207 Dimension height = w->core.height;
208 register int i, len;
211 * If list is NULL then the list will just be the name of the widget.
214 if (lw->list.list == NULL) {
215 lw->list.list = &(lw->core.name);
216 lw->list.nitems = 1;
219 if (lw->list.nitems == 0) /* Get number of items. */
220 for ( ; lw->list.list[lw->list.nitems] != NULL ; lw->list.nitems++);
222 if (lw->list.longest == 0) /* Get column width. */
223 for ( i = 0 ; i < lw->list.nitems; i++) {
224 len = XTextWidth(lw->list.font, lw->list.list[i],
225 strlen(lw->list.list[i]));
226 if (len > lw->list.longest)
227 lw->list.longest = len;
230 lw->list.col_width = lw->list.longest + lw->list.column_space;
232 if (Layout(w, changex, changey, &width, &height))
233 ChangeSize(w, width, height);
236 /* Function Name: ChangeSize.
237 * Description: Laysout the widget.
238 * Arguments: w - the widget to try change the size of.
239 * Returns: none.
242 static void
243 ChangeSize(w, width, height)
244 Widget w;
245 Dimension width, height;
247 XtWidgetGeometry request, reply;
249 request.request_mode = CWWidth | CWHeight;
250 request.width = width;
251 request.height = height;
253 switch ( XtMakeGeometryRequest(w, &request, &reply) ) {
254 case XtGeometryYes:
255 case XtGeometryNo:
256 break;
257 case XtGeometryAlmost:
258 Layout(w, (request.height != reply.height),
259 (request.width != reply.width),
260 &(reply.width), &(reply.height));
261 request = reply;
262 switch (XtMakeGeometryRequest(w, &request, &reply) ) {
263 case XtGeometryYes:
264 case XtGeometryNo:
265 break;
266 case XtGeometryAlmost:
267 request = reply;
268 if (Layout(w, FALSE, FALSE,
269 &(request.width), &(request.height))) {
270 char buf[BUFSIZ];
271 sprintf(buf, "List Widget: %s %s",
272 "Size Changed when it shouldn't have",
273 "when computing layout");
274 XtAppWarning(XtWidgetToApplicationContext(w), buf);
276 request.request_mode = CWWidth | CWHeight;
277 XtMakeGeometryRequest(w, &request, &reply);
278 break;
279 default:
280 XtAppWarning(XtWidgetToApplicationContext(w),
281 "List Widget: Unknown geometry return.");
282 break;
284 break;
285 default:
286 XtAppWarning(XtWidgetToApplicationContext(w),
287 "List Widget: Unknown geometry return.");
288 break;
292 /* Function Name: Initialize
293 * Description: Function that initilizes the widget instance.
294 * Arguments: junk - NOT USED.
295 * new - the new widget.
296 * Returns: none
299 /* ARGSUSED */
300 static void
301 Initialize(junk, new)
302 Widget junk, new;
304 ListWidget lw = (ListWidget) new;
307 * Initialize all private resources.
310 GetGCs(new);
312 /* Set row height. */
313 lw->list.row_height = lw->list.font->max_bounds.ascent
314 + lw->list.font->max_bounds.descent
315 + lw->list.row_space;
317 ResetList(new, (new->core.width == 0), (new->core.height == 0));
319 lw->list.highlight = lw->list.is_highlighted = NO_HIGHLIGHT;
321 } /* Initialize */
323 /* Function Name: CvtToItem
324 * Description: Converts Xcoord to item number of item containing that
325 * point.
326 * Arguments: w - the list widget.
327 * xloc, yloc - x location, and y location.
328 * Returns: the item number.
331 static int
332 CvtToItem(w, xloc, yloc, item)
333 Widget w;
334 int xloc, yloc;
335 int *item;
337 int one, another;
338 ListWidget lw = (ListWidget) w;
339 int ret_val = OKAY;
341 if (lw->list.vertical_cols) {
342 one = lw->list.nrows * ((xloc - (int) lw->list.internal_width)
343 / lw->list.col_width);
344 another = (yloc - (int) lw->list.internal_height)
345 / lw->list.row_height;
346 /* If out of range, return minimum possible value. */
347 if (another >= lw->list.nrows) {
348 another = lw->list.nrows - 1;
349 ret_val = OUT_OF_RANGE;
352 else {
353 one = (lw->list.ncols * ((yloc - (int) lw->list.internal_height)
354 / lw->list.row_height)) ;
355 /* If in right margin handle things right. */
356 another = (xloc - (int) lw->list.internal_width) / lw->list.col_width;
357 if (another >= lw->list.ncols) {
358 another = lw->list.ncols - 1;
359 ret_val = OUT_OF_RANGE;
362 if ((xloc < 0) || (yloc < 0))
363 ret_val = OUT_OF_RANGE;
364 if (one < 0) one = 0;
365 if (another < 0) another = 0;
366 *item = one + another;
367 if (*item >= lw->list.nitems) return(OUT_OF_RANGE);
368 return(ret_val);
371 /* Function Name: FindCornerItems.
372 * Description: Find the corners of the rectangle in item space.
373 * Arguments: w - the list widget.
374 * event - the event structure that has the rectangle it it.
375 * ul_ret, lr_ret - the corners ** RETURNED **.
376 * Returns: none.
379 FindCornerItems(w, event, ul_ret, lr_ret)
380 Widget w;
381 XEvent * event;
382 int *ul_ret, *lr_ret;
384 int xloc, yloc;
386 xloc = event->xexpose.x;
387 yloc = event->xexpose.y;
388 CvtToItem(w, xloc, yloc, ul_ret);
389 xloc += event->xexpose.width;
390 yloc += event->xexpose.height;
391 CvtToItem(w, xloc, yloc, lr_ret);
394 /* Function Name: ItemInRectangle
395 * Description: returns TRUE if the item passed is in the given rectangle.
396 * Arguments: w - the list widget.
397 * ul, lr - corners of the rectangle in item space.
398 * item - item to check.
399 * Returns: TRUE if the item passed is in the given rectangle.
402 ItemInRectangle(w, ul, lr, item)
403 Widget w;
404 int ul, lr, item;
406 ListWidget lw = (ListWidget) w;
407 register int mod_item;
408 int things;
410 if (item < ul || item > lr)
411 return(FALSE);
412 if (lw->list.vertical_cols)
413 things = lw->list.nrows;
414 else
415 things = lw->list.ncols;
417 mod_item = item % things;
418 if ( (mod_item >= ul % things) && (mod_item <= lr % things ) )
419 return(TRUE);
420 return(FALSE);
423 /* Function Name: HighlightBackground
424 * Description: paints the color of the background for the given item.
425 * Arguments: w - the widget.
426 * x, y - ul corner of the area item occupies.
427 * item - the item we are dealing with.
428 * gc - the gc that is used to paint this rectangle
429 * Returns:
432 HighlightBackground(w, x, y, item, gc)
433 Widget w;
434 int x, y, item;
435 GC gc;
437 ListWidget lw = (ListWidget) w;
438 int hl_x, hl_y, width, height;
440 hl_x = x - lw->list.column_space/2;
441 width = XTextWidth(lw->list.font, lw->list.list[item],
442 strlen(lw->list.list[item])) + lw->list.column_space;
443 hl_y = y - lw->list.row_space/2;
444 height = lw->list.row_height + lw->list.row_space;
446 XFillRectangle(XtDisplay(w), XtWindow(w), gc, hl_x, hl_y, width, height);
449 /* Function Name: PaintItemName
450 * Description: paints the name of the item in the appropriate location.
451 * Arguments: w - the list widget.
452 * item - the item to draw.
453 * Returns: none.
455 * NOTE: no action taken on an unrealized widget.
458 PaintItemName(w, item)
459 Widget w;
460 int item;
462 char * str;
463 GC gc;
464 int x, y, str_y;
465 ListWidget lw = (ListWidget) w;
467 if (!XtIsRealized(w)) return; /* Just in case... */
469 if (lw->list.vertical_cols) {
470 x = lw->list.col_width * (item / lw->list.nrows)
471 + lw->list.internal_width;
472 y = lw->list.row_height * (item % lw->list.nrows)
473 + lw->list.internal_height;
475 else {
476 x = lw->list.col_width * (item % lw->list.ncols)
477 + lw->list.internal_width;
478 y = lw->list.row_height * (item / lw->list.ncols)
479 + lw->list.internal_height;
482 str_y = y + lw->list.font->max_bounds.ascent;
484 if (item == lw->list.is_highlighted) {
485 if (item == lw->list.highlight) {
486 gc = lw->list.revgc;
487 HighlightBackground(w, x, y, item, lw->list.normgc);
489 else {
490 if (XtIsSensitive(w))
491 gc = lw->list.normgc;
492 else
493 gc = lw->list.graygc;
494 HighlightBackground(w, x, y, item, lw->list.revgc);
495 lw->list.is_highlighted = NO_HIGHLIGHT;
498 else {
499 if (item == lw->list.highlight) {
500 gc = lw->list.revgc;
501 HighlightBackground(w, x, y, item, lw->list.normgc);
502 lw->list.is_highlighted = item;
504 else {
505 if (XtIsSensitive(w))
506 gc = lw->list.normgc;
507 else
508 gc = lw->list.graygc;
512 str = lw->list.list[item]; /* draw it */
513 XDrawString(XtDisplay(w), XtWindow(w), gc, x, str_y, str, strlen(str));
516 /* Function Name: Redisplay
517 * Description: Repaints the widget window on expose events.
518 * Arguments: w - the list widget.
519 * event - the expose event for this repaint.
520 * junk - NOT USED.
521 * Returns:
524 /* ARGSUSED */
525 static void
526 Redisplay(w, event, junk)
527 Widget w;
528 XEvent *event;
529 Region junk;
531 int item; /* an item to work with. */
532 int ul_item, lr_item; /* corners of items we need to paint. */
533 ListWidget lw = (ListWidget) w;
535 if (event == NULL) { /* repaint all. */
536 ul_item = 0;
537 lr_item = lw->list.nrows * lw->list.ncols - 1;
538 XClearWindow(XtDisplay(w), XtWindow(w));
540 else
541 FindCornerItems(w, event, &ul_item, &lr_item);
543 for (item = ul_item; (item <= lr_item && item < lw->list.nitems) ; item++)
544 if (ItemInRectangle(w, ul_item, lr_item, item))
545 PaintItemName(w, item);
548 /* Function Name: PreferredGeom
549 * Description: This tells the parent what size we would like to be
550 * given certain constraints.
551 * Arguments: w - the widget.
552 * intended - what the parent intends to do with us.
553 * requested - what we want to happen.
554 * Returns: none.
557 static XtGeometryResult
558 PreferredGeom(w, intended, requested)
559 Widget w;
560 XtWidgetGeometry *intended, *requested;
562 Dimension new_width, new_height;
563 Boolean change, width_req, height_req;
565 width_req = intended->request_mode & CWWidth;
566 height_req = intended->request_mode & CWHeight;
568 if (width_req)
569 new_width = intended->width;
570 else
571 new_width = w->core.width;
573 if (height_req)
574 new_height = intended->height;
575 else
576 new_height = w->core.height;
578 requested->request_mode = 0;
581 * We only care about our height and width.
584 if ( !width_req && !height_req)
585 return(XtGeometryYes);
587 change = Layout(w, !width_req, !height_req, &new_width, &new_height);
589 requested->request_mode |= CWWidth;
590 requested->width = new_width;
591 requested->request_mode |= CWHeight;
592 requested->height = new_height;
594 if (change)
595 return(XtGeometryAlmost);
596 return(XtGeometryYes);
599 /* Function Name: Resize
600 * Description: resizes the widget, by changing the number of rows and
601 * columns.
602 * Arguments: w - the widget.
603 * Returns: none.
606 static void
607 Resize(w)
608 Widget w;
610 Dimension width, height;
612 width = w->core.width;
613 height = w->core.height;
615 if (Layout(w, FALSE, FALSE, &width, &height))
616 XtAppWarning(XtWidgetToApplicationContext(w),
617 "List Widget: Size changed when it shouldn't have when resising.");
620 /* Function Name: Layout
621 * Description: lays out the item in the list.
622 * Arguments: w - the widget.
623 * xfree, yfree - TRUE if we are free to resize the widget in
624 * this direction.
625 * width, height - the is the current width and height that
626 * we are going to layout the list widget to,
627 * depending on xfree and yfree of course.
629 * Returns: TRUE if width or height have been changed.
632 static Boolean
633 Layout(w, xfree, yfree, width, height)
634 Widget w;
635 Boolean xfree, yfree;
636 Dimension *width, *height;
638 ListWidget lw = (ListWidget) w;
639 Boolean change = FALSE;
642 * If force columns is set then always use number of columns specified
643 * by default_cols.
646 if (lw->list.force_cols) {
647 lw->list.ncols = lw->list.default_cols;
648 if (lw->list.ncols <= 0) lw->list.ncols = 1;
649 /* 12/3 = 4 and 10/3 = 4, but 9/3 = 3 */
650 lw->list.nrows = ( ( lw->list.nitems - 1) / lw->list.ncols) + 1 ;
651 if (xfree) { /* If allowed resize width. */
652 *width = lw->list.ncols * lw->list.col_width
653 + 2 * lw->list.internal_width;
654 change = TRUE;
656 if (yfree) { /* If allowed resize height. */
657 *height = (lw->list.nrows * lw->list.row_height)
658 + 2 * lw->list.internal_height;
659 change = TRUE;
661 return(change);
665 * If both width and height are free to change the use default_cols
666 * to determine the number columns and set new width and height to
667 * just fit the window.
670 if (xfree && yfree) {
671 lw->list.ncols = lw->list.default_cols;
672 if (lw->list.ncols <= 0) lw->list.ncols = 1;
673 lw->list.nrows = ( ( lw->list.nitems - 1) / lw->list.ncols) + 1 ;
674 *width = lw->list.ncols * lw->list.col_width
675 + 2 * lw->list.internal_width;
676 *height = (lw->list.nrows * lw->list.row_height)
677 + 2 * lw->list.internal_height;
678 change = TRUE;
681 * If the width is fixed then use it to determine the number of columns.
682 * If the height is free to move (width still fixed) then resize the height
683 * of the widget to fit the current list exactly.
685 else if (!xfree) {
686 lw->list.ncols = ( (*width - 2 * lw->list.internal_width)
687 / lw->list.col_width);
688 if (lw->list.ncols <= 0) lw->list.ncols = 1;
689 lw->list.nrows = ( ( lw->list.nitems - 1) / lw->list.ncols) + 1 ;
690 if ( yfree ) {
691 *height = (lw->list.nrows * lw->list.row_height)
692 + 2 * lw->list.internal_height;
693 change = TRUE;
697 * The last case is xfree and !yfree we use the height to determine
698 * the number of rows and then set the width to just fit the resulting
699 * number of columns.
701 else if (!yfree) { /* xfree must be TRUE. */
702 lw->list.nrows = (*height - 2 * lw->list.internal_height)
703 / lw->list.row_height;
704 if (lw->list.nrows <= 0) lw->list.nrows = 1;
705 lw->list.ncols = (( lw->list.nitems - 1 ) / lw->list.nrows) + 1;
706 *width = lw->list.ncols * lw->list.col_width
707 + 2 * lw->list.internal_width;
708 change = TRUE;
710 return(change);
713 /* Function Name: Notify
714 * Description: Notifies the user that a button has been pressed, and
715 * calles the callback, if the XtNpasteBuffer resource
716 * is true then the name of the item is also put in the
717 * X cut buffer ( buf (0) ).
718 * Arguments: w - the widget that the notify occured in.
719 * event - event that caused this notification.
720 * params, num_params - not used.
721 * Returns: none.
724 /* ARGSUSED */
725 static void
726 Notify(w, event, params, num_params)
727 Widget w;
728 XEvent * event;
729 String * params;
730 Cardinal *num_params;
732 ListWidget lw = ( ListWidget ) w;
733 int item, item_len;
734 XawListReturnStruct ret_value;
737 * Find item and if out of range then unhighlight and return.
739 * If the current item is unhighlighted then the user has aborted the
740 * notify, so unhighlight and return.
743 if ( ((CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
744 == OUT_OF_RANGE) || (lw->list.highlight != item) ) {
745 XawListUnhighlight(w);
746 return;
749 item_len = strlen(lw->list.list[item]);
751 if ( lw->list.paste ) /* if XtNpasteBuffer set then paste it. */
752 XStoreBytes(XtDisplay(w), lw->list.list[item], item_len);
755 * Call Callback function.
758 ret_value.string = lw->list.list[item];
759 ret_value.list_index = item;
761 XtCallCallbacks( w, XtNcallback, (caddr_t) &ret_value);
764 /* Function Name: Unset
765 * Description: unhighlights the current element.
766 * Arguments: w - the widget that the event occured in.
767 * event - not used.
768 * params, num_params - not used.
769 * Returns: none.
772 /* ARGSUSED */
773 static void
774 Unset(w, event, params, num_params)
775 Widget w;
776 XEvent * event;
777 String * params;
778 Cardinal *num_params;
780 XawListUnhighlight(w);
783 /* Function Name: Set
784 * Description: Highlights the current element.
785 * Arguments: w - the widget that the event occured in.
786 * event - event that caused this notification.
787 * params, num_params - not used.
788 * Returns: none.
791 /* ARGSUSED */
792 static void
793 Set(w, event, params, num_params)
794 Widget w;
795 XEvent * event;
796 String * params;
797 Cardinal *num_params;
799 int item;
800 ListWidget lw = (ListWidget) w;
802 if ( (CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
803 == OUT_OF_RANGE)
804 XawListUnhighlight(w); /* Unhighlight current item. */
805 else if ( lw->list.is_highlighted != item ) /* If this item is not */
806 XawListHighlight(w, item); /* highlighted then do it. */
810 * Set specified arguments into widget
813 static Boolean
814 SetValues(current, request, new)
815 Widget current, request, new;
817 ListWidget cl = (ListWidget) current;
818 ListWidget rl = (ListWidget) request;
819 ListWidget nl = (ListWidget) new;
820 Boolean redraw = FALSE;
822 if ((cl->list.foreground != rl->list.foreground) ||
823 (cl->core.background_pixel != rl->core.background_pixel) ||
824 (cl->list.font != rl->list.font) ) {
825 XtDestroyGC(cl->list.normgc);
826 XtDestroyGC(cl->list.graygc);
827 XtDestroyGC(cl->list.revgc);
828 GetGCs(new);
829 redraw = TRUE;
832 /* Reset row height. */
834 if ((cl->list.row_space != rl->list.row_space) ||
835 (cl->list.font != rl->list.font))
836 nl->list.row_height = nl->list.font->max_bounds.ascent
837 + nl->list.font->max_bounds.descent
838 + nl->list.row_space;
840 if ((cl->core.width != rl->core.width) ||
841 (cl->core.height != rl->core.height) ||
842 (cl->list.internal_width != rl->list.internal_width) ||
843 (cl->list.internal_height != rl->list.internal_height) ||
844 (cl->list.column_space != rl->list.column_space) ||
845 (cl->list.row_space != rl->list.row_space) ||
846 (cl->list.default_cols != rl->list.default_cols) ||
847 ( (cl->list.force_cols != rl->list.force_cols) &&
848 (rl->list.force_cols != rl->list.ncols) ) ||
849 (cl->list.vertical_cols != rl->list.vertical_cols) ||
850 (cl->list.longest != rl->list.longest) ||
851 (cl->list.nitems != rl->list.nitems) ||
852 (cl->list.font != rl->list.font) ||
853 (cl->list.list != rl->list.list) ) {
855 ResetList(new, TRUE, TRUE);
856 redraw = TRUE;
859 if (cl->list.list != rl->list.list)
860 nl->list.highlight = NO_HIGHLIGHT;
862 if ((cl->core.sensitive != rl->core.sensitive) ||
863 (cl->core.ancestor_sensitive != rl->core.ancestor_sensitive)) {
864 nl->list.highlight = NO_HIGHLIGHT;
865 redraw = TRUE;
868 if (!XtIsRealized(current))
869 return(FALSE);
871 return(redraw);
874 /* Exported Functions */
876 /* Function Name: XawListChange.
877 * Description: Changes the list being used and shown.
878 * Arguments: w - the list widget.
879 * list - the new list.
880 * nitems - the number of items in the list.
881 * longest - the length (in Pixels) of the longest element
882 * in the list.
883 * resize - if TRUE the the list widget will
884 * try to resize itself.
885 * Returns: none.
886 * NOTE: If nitems of longest are <= 0 then they will be calculated.
887 * If nitems is <= 0 then the list needs to be NULL terminated.
890 void
891 XawListChange(w, list, nitems, longest, resize_it)
892 Widget w;
893 char ** list;
894 int nitems, longest;
895 Boolean resize_it;
897 ListWidget lw = (ListWidget) w;
899 lw->list.list = list;
901 if (nitems <= 0) nitems = 0;
902 lw->list.nitems = nitems;
903 if (longest <= 0) longest = 0;
904 lw->list.longest = longest;
906 ResetList(w, resize_it, resize_it);
907 lw->list.is_highlighted = lw->list.highlight = NO_HIGHLIGHT;
908 if ( XtIsRealized(w) )
909 Redisplay(w, NULL, NULL);
912 /* Function Name: XawListUnhighlight
913 * Description: unlights the current highlighted element.
914 * Arguments: w - the widget.
915 * Returns: none.
918 void
919 XawListUnhighlight(w)
920 Widget w;
922 ListWidget lw = ( ListWidget ) w;
924 lw->list.highlight = NO_HIGHLIGHT;
925 if (lw->list.is_highlighted != NO_HIGHLIGHT)
926 PaintItemName(w, lw->list.is_highlighted); /* unhighlight this one. */
929 /* Function Name: XawListHighlight
930 * Description: Highlights the given item.
931 * Arguments: w - the list widget.
932 * item - the item to hightlight.
933 * Returns: none.
936 void
937 XawListHighlight(w, item)
938 Widget w;
939 int item;
941 ListWidget lw = ( ListWidget ) w;
943 if (XtIsSensitive(w)) {
944 lw->list.highlight = item;
945 if (lw->list.is_highlighted != NO_HIGHLIGHT)
946 PaintItemName(w, lw->list.is_highlighted); /* Unhighlight. */
947 PaintItemName(w, item); /* HIGHLIGHT this one. */
951 /* Function Name: XawListShowCurrent
952 * Description: returns the currently highlighted object.
953 * Arguments: w - the list widget.
954 * Returns: the info about the currently highlighted object.
957 XawListReturnStruct *
958 XawListShowCurrent(w)
959 Widget w;
961 ListWidget lw = ( ListWidget ) w;
962 XawListReturnStruct * ret_val;
964 ret_val = (XawListReturnStruct *) XtMalloc (sizeof (XawListReturnStruct));
966 ret_val->list_index = lw->list.highlight;
967 if (ret_val->list_index == XAW_LIST_NONE)
968 ret_val->string = "";
969 else
970 ret_val->string = lw->list.list[ ret_val->list_index ];
972 return(ret_val);