|
|
1.1 root 1: /* $Header: Menu.c,v 1.1 87/09/11 07:58:12 toddb Exp $ */
2: #ifndef lint
3: static char *sccsid = "@(#)Menu.c 1.6 2/26/87";
4: #endif lint
5:
6: /*
7: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
8: *
9: * All Rights Reserved
10: *
11: * Permission to use, copy, modify, and distribute this software and its
12: * documentation for any purpose and without fee is hereby granted,
13: * provided that the above copyright notice appear in all copies and that
14: * both that copyright notice and this permission notice appear in
15: * supporting documentation, and that the name of Digital Equipment
16: * Corporation not be used in advertising or publicity pertaining to
17: * distribution of the software without specific, written prior permission.
18: *
19: *
20: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
21: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
22: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
23: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
24: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
25: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26: * SOFTWARE.
27: */
28:
29: /*
30: * Menu.c - Basic menu widget
31: *
32: * Author: M. Gancarz, based on ButtonBox.c by haynes
33: */
34:
35: #include "Xlib.h"
36: #include "Intrinsic.h"
37: #include "Menu.h"
38: #include "Atoms.h"
39:
40: #define X10
41:
42: #define MAXHEIGHT ((1 << 31)-1)
43: #define MAXWIDTH ((1 << 31)-1)
44:
45: #define max(x, y) (((x) > (y)) ? (x) : (y))
46: #define min(x, y) (((x) < (y)) ? (x) : (y))
47: #define assignmax(x, y) if ((y) > (x)) x = (y)
48: #define assignmin(x, y) if ((y) < (x)) x = (y)
49:
50: #define all_items i = 0, item = data->entries;\
51: i < data->numentries; i++, item = item->next
52: #define item_w (item->lug.w)
53: #define item_x (item->lug.wb.x)
54: #define item_y (item->lug.wb.y)
55: #define item_width (item->lug.wb.width)
56: #define item_height (item->lug.wb.height)
57: #define item_borderWidth (item->lug.wb.borderWidth)
58:
59: /****************************************************************
60: *
61: * Private Types
62: *
63: ****************************************************************/
64:
65: typedef void (*MenuProc)();
66:
67: typedef struct _WidgetEntryRec {
68: struct _WidgetEntryRec *next; /* ptr to next entry */
69: struct _WidgetEntryRec *prev; /* ptr to previous entry */
70: WindowLug lug; /* data for this entry */
71: } WidgetEntryRec, *WidgetEntry;
72:
73: typedef struct _WidgetDataRec {
74: Display *dpy; /* widget display connection */
75: Window w; /* widget window */
76: Position x,y; /* widget location */
77: Dimension width, height; /* widget window width and height */
78: Dimension borderWidth; /* widget window border width */
79: XtOrientation orient; /* menu orientation */
80: Pixel bp; /* widget window border pixmap */
81: Pixel bg; /* widget window background pixmap */
82: Dimension space; /* inter-entry spacing */
83: Dimension hpad, vpad; /* pad between entries and parent */
84: unsigned long notify; /* events which cause a callback */
85: MenuProc proc; /* procedure to invoke for callback */
86: caddr_t tag; /* widget client data */
87: int numentries; /* number of entries */
88: WidgetEntry entries; /* list of entries */
89: } WidgetDataRec, *WidgetData;
90:
91: typedef struct _ParameterDataRec {
92: XtMenuEntry *entry; /* arg MenuEntry */
93: int i; /* arg index */
94: } ParameterDataRec, *ParameterData;
95:
96:
97: /****************************************************************
98: *
99: * Private Data
100: *
101: ****************************************************************/
102:
103: static int BlPixel, WhPixel;
104: static XContext widgetContext;
105:
106: extern void Dummy();
107:
108: static WidgetDataRec globaldata;
109: static WidgetDataRec globalinit = {
110: NULL, /* Display dpy; */
111: NULL, /* Window w; */
112: 0,0, /* x,y */
113: 1, 1, /* int width, height; */
114: 1, /* int borderWidth; */
115: XtorientVertical, /* XtOrientation orient; */
116: 0, /* Border pixel */
117: 1, /* Background pixel */
118: 1, /* int space; */
119: 2, 2, /* int hpad, vpad; */
120: 0, /* int notify; */
121: Dummy, /* void (*Proc)(); */
122: NULL, /* caddr_t tag; */
123: 0, /* int numentries; */
124: NULL /* WidgetEntry entries; */
125: };
126:
127: static Resource resources[] = {
128: {XtNwindow, XtCWindow, XrmRWindow,
129: sizeof(Window), (caddr_t)&globaldata.w, (caddr_t)NULL},
130: {XtNx, XtCX, XrmRInt,
131: sizeof(int),(caddr_t)&globaldata.x,(caddr_t)NULL},
132: {XtNy, XtCY, XrmRInt,
133: sizeof(int),(caddr_t)&globaldata.y,(caddr_t)NULL},
134: {XtNwidth, XtCWidth, XrmRInt,
135: sizeof(int), (caddr_t)&globaldata.width, (caddr_t)NULL},
136: {XtNheight, XtCHeight, XrmRInt,
137: sizeof(int), (caddr_t)&globaldata.height, (caddr_t)NULL},
138: {XtNorientation, XtCOrientation, XtROrientation,
139: sizeof(XtOrientation), (caddr_t)&globaldata.orient, (caddr_t)NULL},
140: {XtNborderWidth, XtCBorderWidth, XrmRInt,
141: sizeof(int), (caddr_t)&globaldata.borderWidth, (caddr_t)NULL},
142: {XtNborder, XtCColor, XrmRPixmap,
143: sizeof(Pixmap), (caddr_t)&globaldata.bp, (caddr_t)NULL},
144: {XtNbackground, XtCColor, XrmRPixmap,
145: sizeof(Pixmap), (caddr_t)&globaldata.bg, (caddr_t)NULL},
146: {XtNinternalWidth, XtCWidth, XrmRInt,
147: sizeof(int), (caddr_t)&globaldata.hpad, (caddr_t)NULL},
148: {XtNinternalHeight, XtCHeight, XrmRInt,
149: sizeof(int), (caddr_t)&globaldata.vpad, (caddr_t)NULL},
150: {XtNspace, XtCSpace, XrmRInt,
151: sizeof(int), (caddr_t)&globaldata.space, (caddr_t)NULL},
152: {XtNnotify, XtCNotify, XrmRInt,
153: sizeof(int), (caddr_t)&globaldata.notify, (caddr_t)NULL},
154: {XtNfunction, XtCFunction, XtRFunction,
155: sizeof(MenuProc), (caddr_t)&globaldata.proc, (caddr_t)NULL},
156: {XtNparameter, XtCParameter, XrmRPointer,
157: sizeof(caddr_t), (caddr_t)&globaldata.tag, (caddr_t)NULL},
158: };
159:
160:
161: static ParameterDataRec parms;
162: static ParameterDataRec parminit = {
163: NULL, /* MenuEntry entry */
164: -1, /* int i; */
165: };
166:
167: static Resource parmResources[] = {
168: {XtNmenuEntry, XtCMenuEntry, XrmRPointer,
169: sizeof(XtMenuEntry), (caddr_t)&parms.entry, (caddr_t)NULL},
170: };
171:
172: /****************************************************************
173: *
174: * Private Routines
175: *
176: ****************************************************************/
177:
178: static Boolean initialized = FALSE;
179:
180: static void MenuInitialize(dpy)
181: Display *dpy;
182: {
183: if (initialized)
184: return;
185: initialized = TRUE;
186:
187: BlPixel = BlackPixel(dpy, DefaultScreen(dpy));
188: WhPixel = WhitePixel(dpy, DefaultScreen(dpy));
189:
190: globalinit.bp = BlPixel;
191: globalinit.bg = WhPixel;
192:
193: globalinit.orient = XtorientVertical;
194: widgetContext = XUniqueContext();
195: }
196:
197: /*
198: * Given a display and window, get the widget data.
199: */
200:
201: static WidgetData DataFromWindow(dpy, window)
202: Display *dpy;
203: Window window;
204: {
205: WidgetData result;
206: if (XFindContext(dpy, window, widgetContext, (caddr_t *)&result))
207: return NULL;
208: return result;
209: }
210:
211: /*
212: * Default callback procedure
213: */
214: /*ARGSUSED*/
215: static void Dummy(tag)
216: caddr_t tag;
217: {
218: (void) puts("Menu: dummy callback");
219: }
220:
221: extern void Destroy();
222:
223: /*
224: *
225: * Do a layout, either actually assigning positions, or just calculating size
226: *
227: */
228:
229: static int DoLayout(data)
230: WidgetData data;
231: {
232: int i;
233: int vpad, hpad, sp;
234: Dimension maxheight = 0, maxwidth = 0, maxborderWidth = 0;
235: Dimension menuwidth, menuheight, dmaxborderWidth, borderWidth;
236: Position newx, newy, xoffset, yoffset;
237: Dimension newwidth, newheight;
238: WidgetEntry item;
239:
240: if (data->numentries == 0) return(0);
241:
242: sp = data->space;
243: hpad = data->hpad;
244: vpad = data->vpad;
245:
246: for (all_items) {
247: assignmax(maxheight, item->lug.wb.height);
248: assignmax(maxwidth, item_width);
249: assignmax(maxborderWidth, item_borderWidth);
250: }
251:
252: dmaxborderWidth = maxborderWidth << 1;
253: if (data->orient == XtorientVertical) {
254: menuwidth = (hpad << 1) + maxwidth + dmaxborderWidth;
255: menuheight = (data->numentries * (maxheight + dmaxborderWidth)) +
256: ((data->numentries - 1) * sp) + (vpad << 1);
257: } else {
258: menuwidth = (data->numentries * (maxwidth + dmaxborderWidth)) +
259: ((data->numentries - 1) * sp) + (hpad << 1);
260: menuheight = (vpad << 1) + maxheight + dmaxborderWidth;
261: }
262: (void) TryLayout(data, menuwidth, menuheight);
263:
264: newx = hpad;
265: newy = vpad;
266: xoffset = maxwidth + dmaxborderWidth;
267: yoffset = maxheight + dmaxborderWidth;
268: for (all_items) {
269: borderWidth = item_borderWidth << 1;
270: newwidth = xoffset - borderWidth;
271: newheight = yoffset - borderWidth;
272: if (newwidth != item_width || newheight != item_height
273: || newx != item_x || newy != item_y) {
274: XMoveResizeWindow(data->dpy, item_w,
275: newx, newy, newwidth, newheight);
276: XtSendConfigureNotify(item_w,&(item->lug.wb));
277: }
278: item_x = newx;
279: item_y = newy;
280: item_width = newwidth;
281: item_height = newheight;
282: if (data->orient == XtorientVertical)
283: newy += sp + yoffset;
284: else newx += sp + xoffset;
285: }
286:
287: return (1);
288: }
289:
290: /*
291: *
292: * Compute the layout of the menu
293: *
294: */
295:
296: /* ||| Why Layout calls DoLayout I don't know... */
297:
298: static void Layout(data)
299: WidgetData data;
300: {
301: (void) DoLayout(data);
302: }
303:
304: /*
305: *
306: * Generic widget event handler
307: *
308: */
309:
310: static XtEventReturnCode EventHandler(event, eventdata)
311: XEvent *event;
312: caddr_t eventdata;
313: {
314: WidgetData data = (WidgetData) eventdata;
315:
316: switch (event->type) {
317: case ConfigureNotify:
318: /* we expect to get an expose window on resize */
319: if ((data->height != event->xconfigure.height) ||
320: (data->width != event->xconfigure.width)) {
321: data->height = event->xconfigure.height;
322: data->width = event->xconfigure.width;
323: Layout(data);
324: }
325: break;
326:
327: case DestroyNotify: Destroy(data); break;
328:
329:
330: case Expose:
331: break;
332: }
333:
334: return (XteventHandled);
335: }
336:
337: /*
338: * Widget notify event handler
339: */
340: /*ARGSUSED*/
341: static XtEventReturnCode Notify(event, eventdata)
342: XEvent *event;
343: caddr_t eventdata;
344: {
345: WidgetData data = (WidgetData)eventdata;
346:
347: data->proc(data->tag);
348: return(XteventHandled);
349: }
350:
351: /*
352: *
353: * Destroy the widget
354: *
355: */
356:
357: static void Destroy(data)
358: WidgetData data;
359: {
360: WidgetEntry item;
361: int i;
362: /* send destroy messages to all my subwindows */
363: for (all_items) {
364: (void) XtSendDestroyNotify(data->dpy, item_w); }
365:
366: XtFree((char *) data->entries);
367:
368: XtClearEventHandlers(data->dpy, data->w);
369: (void) XDeleteContext(data->dpy, data->w, widgetContext);
370: XDestroyWindow (data->dpy,data->w);
371: XtFree ((char *) data);
372: }
373:
374: /*
375: *
376: * Find Entry
377: *
378: */
379:
380: static WidgetEntry FindEntry(data, w)
381: WidgetData data;
382: Window w;
383: {
384: int i;
385: WidgetEntry item;
386:
387: for (all_items)
388: if (item_w == w) return (item);
389:
390: return NULL;
391: }
392:
393: /*
394: *
395: * Resize Entry
396: *
397: */
398:
399: static void ResizeEntry(data, b, reqBox, replBox)
400: WidgetData data;
401: WindowLugPtr b;
402: WindowBox *reqBox;
403: WindowBox *replBox; /* RETURN */
404: {
405: b->wb = *reqBox;
406: XResizeWindow(data->dpy,b->w, b->wb.width, b->wb.height);
407: Layout(data);
408: *replBox = b->wb;
409: }
410:
411: /*
412: *
413: * Try to do a new layout within a particular width and height
414: *
415: */
416:
417: static int TryLayout(data, width, height)
418: WidgetData data;
419: Dimension width, height;
420: {
421: WindowBox box, rbox;
422:
423: /* let's see if our parent will go for it. */
424: box.width = width;
425: box.height = height;
426: switch (XtMakeGeometryRequest(data->dpy, data->w, XtgeometryResize, &box, &rbox)) {
427:
428: case XtgeometryNoManager:
429: XResizeWindow(data->dpy,data->w, box.width, box.height);
430: /* fall through to "yes" */
431:
432: case XtgeometryYes:
433: data->width = box.width;
434: data->height = box.height;
435: return (1);
436:
437:
438: case XtgeometryNo:
439: return (0);
440:
441:
442: case XtgeometryAlmost:
443: box = rbox;
444: (void) XtMakeGeometryRequest(data->dpy, data->w, XtgeometryResize, &box, &rbox);
445: data->width = box.width;
446: data->height = box.height;
447: return (1);
448:
449: }
450: return (0);
451: }
452:
453: /*
454: *
455: * Try to do a new layout
456: *
457: */
458:
459: static int TryNewLayout(data)
460: WidgetData data;
461: {
462: if (TryLayout(data, data->width, data->height)) return (1);
463: if (TryLayout(data, data->width, MAXHEIGHT)) return (1);
464: if (TryLayout(data, MAXWIDTH, MAXHEIGHT)) return(1);
465: return (0);
466: }
467:
468: /*
469: *
470: * Entry Resize Request
471: *
472: */
473:
474: static XtGeometryReturnCode ResizeEntryRequest(data, w, reqBox, replBox)
475: WidgetData data;
476: Window w;
477: WindowBox *reqBox;
478: WindowBox *replBox; /* RETURN */
479:
480: {
481: WidgetEntry item;
482: WindowLug oldb;
483:
484: item = FindEntry(data, w);
485: if (item == NULL) return (XtgeometryNo);
486: oldb = item->lug;
487: item->lug.wb = *reqBox;
488:
489: if ((reqBox->width <= item_width) && (reqBox->height <= item_height)) {
490: /* making the button smaller always works */
491: ResizeEntry(data, &(item->lug), reqBox, replBox);
492: return (XtgeometryYes);
493: }
494:
495: if (TryNewLayout(data)) {
496: ResizeEntry(data, &(item->lug), reqBox, replBox);
497: return (XtgeometryYes);
498: }
499:
500: item->lug = oldb;
501: return (XtgeometryNo);
502: }
503:
504: /*
505: *
506: * Menu Entry Geometry Manager
507: *
508: */
509:
510: static XtGeometryReturnCode EntryGeometryManager(
511: dpy, w, req, reqBox, replBox)
512: Display *dpy;
513: Window w;
514: XtGeometryRequest req;
515: WindowBox *reqBox;
516: WindowBox *replBox; /* RETURN */
517: {
518: WidgetData data;
519:
520: if (XFindContext(dpy, w, widgetContext, (caddr_t *)&data) == XCNOENT)
521: return (XtgeometryYes);
522: /* requests: move, resize, top, bottom */
523: switch (req) {
524: case XtgeometryTop : return (XtgeometryYes);
525: case XtgeometryBottom : return (XtgeometryYes);
526: case XtgeometryMove : return (XtgeometryNo);
527: case XtgeometryResize :
528: return (ResizeEntryRequest(data, w, reqBox, replBox));
529: }
530: return (XtgeometryNo);
531: }
532:
533: static XtStatus AddEntry(data, w, index)
534: WidgetData data;
535: Window w, index;
536: {
537: int i;
538: Position x, y;
539: Dimension width, height, borderWidth;
540: unsigned depth;
541: Drawable root;
542: WidgetEntry newentry;
543: WidgetEntry item;
544:
545: /*
546: * Return an error if one of the following conditions is true:
547: * 1. The specified window doesn't exist
548: * 2. The specified window is already an entry in this widget
549: * 3. An index was specified, even though no entries exist
550: */
551: (void) XGetGeometry(data->dpy, w, &root, &x, &y, &width, &height,
552: &borderWidth, &depth);
553: if (FindEntry(data, w) != NULL) return (0);
554: if ((data->numentries == 0) && index) return(0);
555:
556: newentry = (WidgetEntry) XtCalloc(1, sizeof(WidgetEntryRec));
557: newentry->lug.w = w;
558: newentry->lug.wb.x = x;
559: newentry->lug.wb.y = y;
560: newentry->lug.wb.width = width;
561: newentry->lug.wb.height = height;
562: newentry->lug.wb.borderWidth = borderWidth;
563:
564: if (data->numentries == 0)
565: data->entries = newentry;
566: else {
567: if (FindEntry(data, index)) {
568: for (all_items) {
569: if (item_w == index) {
570: newentry->next = item;
571: if (item->prev == NULL)
572: data->entries = item->prev = newentry;
573: else {
574: (item->prev)->next = newentry;
575: item->prev = newentry;
576: }
577: break;
578: }
579: }
580: } else {
581: for (all_items) /* NULL */ ;
582: for (i = 0, item = data->entries; i < data->numentries - 1;
583: i++, item = item->next) /* NULL */;
584: item->next = newentry;
585: newentry->prev = item;
586: }
587:
588: }
589:
590: data->numentries++;
591: (void) XSaveContext(data->dpy, newentry->lug.w, widgetContext, (caddr_t)data);
592: (void) XtSetGeometryHandler(data->dpy, newentry->lug.w, EntryGeometryManager);
593:
594: return(1);
595: }
596:
597: static void BatchAddEntries(data, args, argCount)
598: WidgetData data;
599: ArgList args;
600: int argCount;
601: {
602: if (argCount) {
603: for ( ; --argCount >= 0; args++) {
604: if (strcmp(args->name , XtNmenuEntry)==0) {
605: (void) AddEntry(data, (*((XtMenuEntry *)args->value)).w,
606: (*((XtMenuEntry *)args->value)).index);
607: }
608: }
609: /* (void) TryNewLayout(data); */
610: Layout(data);
611: }
612: }
613:
614:
615: /****************************************************************
616: *
617: * Public Routines
618: *
619: ****************************************************************/
620:
621: Window XtMenuCreate(dpy, parent, args, argCount)
622: Display *dpy;
623: Window parent;
624: ArgList args;
625: int argCount;
626: {
627: WidgetData data;
628: XrmNameList names;
629: XrmClassList classes;
630: XSetWindowAttributes wvals;
631: int valuemask;
632:
633: if (!initialized) MenuInitialize(dpy);
634:
635: data = (WidgetData) XtMalloc(sizeof(WidgetDataRec));
636:
637: globaldata = globalinit;
638: globaldata.dpy = dpy;
639: XtGetResources(dpy, resources, XtNumber(resources), args, argCount, parent,
640: "menu", "Menu", &names, &classes);
641: *data = globaldata;
642: if (data->width == 0)
643: data->width = ((data->hpad != 0) ? data->hpad : 10);
644: if (data->height == 0)
645: data->height = ((data->vpad != 0) ? data->vpad : 10);
646:
647: if (data->w != NULL) {
648: XWindowChanges wc;
649: unsigned int valuemask;
650: valuemask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
651: wc.x = data->x; wc.y = data->y; wc.width = data->width;
652: wc.height = data->height; wc.border_width = data->borderWidth;
653: XConfigureWindow(data->dpy,data->w,valuemask, &wc);
654: XReparentWindow(data->dpy,data->w,parent,data->x,data->y);
655: }
656: if (data->w == NULL) {
657: wvals.background_pixel = data->bg;
658: wvals.border_pixel = data->bp;
659: wvals.bit_gravity = CenterGravity;
660:
661: valuemask = CWBackPixel | CWBorderPixel | CWBitGravity;
662: data->w = XCreateWindow(data->dpy, parent, data->x, data->y,
663: data->width, data->height, data->borderWidth,
664: 0, InputOutput, (Visual *)CopyFromParent,
665: valuemask, &wvals);
666:
667: }
668:
669: XtSetNameAndClass(data->dpy, data->w, names, classes);
670: XrmFreeNameList(names);
671: XrmFreeClassList(classes);
672:
673: /* set handler for message and destroy events */
674:
675: XtSetEventHandler(data->dpy, data->w, (XtEventHandler)EventHandler,
676: StructureNotifyMask, (caddr_t) data);
677:
678: /* set handler for notify events, if any */
679: if (data->notify)
680: XtSetEventHandler(data->dpy, data->w, (XtEventHandler)Notify, data->notify,
681: (caddr_t) data);
682:
683: (void) XSaveContext(data->dpy, data->w, widgetContext, (caddr_t)data);
684: (void) XtSetGeometryHandler(data->dpy, data->w, (XtGeometryHandler) XtMenuGeometryManager);
685:
686: /*
687: * Batch add initial entries
688: */
689: BatchAddEntries(data, args, argCount);
690:
691: return (data->w);
692: }
693:
694: XtStatus XtMenuAddEntry(dpy, parent, args, argCount)
695: Display *dpy;
696: Window parent;
697: ArgList args;
698: int argCount;
699: {
700: WidgetData data;
701:
702: if (XFindContext(dpy, parent, widgetContext, (caddr_t *)&data) == XCNOENT)
703: return(0);
704:
705: /*
706: * Batch add all entries
707: */
708: BatchAddEntries(data, args, argCount);
709:
710: return (1);
711: }
712:
713: XtStatus XtMenuDeleteEntry(dpy, parent, args, argCount)
714: Display *dpy;
715: Window parent;
716: ArgList args;
717: int argCount;
718: {
719: WidgetData data;
720: int i;
721: WidgetEntry item;
722:
723: if (XFindContext(dpy, parent, widgetContext, (caddr_t *)&data) == XCNOENT)
724: return(0);
725:
726: parms = parminit;
727: XtSetValues(parmResources, XtNumber(parmResources), args, argCount);
728: if ((parms.entry == NULL) && (parms.i == -1)) return (0);
729:
730: if (parms.i >= 0) i = parms.i;
731: else {
732: for (all_items)
733: if (item_w == parent) break;
734: }
735:
736: if (i >= data->numentries) return (0);
737: if (data->numentries == 1) {
738: data->entries = NULL;
739: } else if (i == data->numentries - 1) {
740: (item->prev)->next = NULL;
741: } else {
742: (item->prev)->next = item->next;
743: (item->next)->prev = item->prev;
744: }
745:
746: (void) XDeleteContext(dpy, item_w, widgetContext);
747: (void) XtClearGeometryHandler(dpy, item_w);
748: data->numentries--;
749: XtFree((char *) item);
750: Layout(data);
751: return (1);
752: }
753:
754: /*
755: * Menu Geometry Manager
756: *
757: * Note: The menu widget client typically should write its own.
758: * However, this one simply says "yes" to any request to aid in
759: * menu prototyping because many clients simply don't care if they're
760: * using the menu as a pop-up.
761: */
762: /*ARGSUSED*/
763: XtGeometryReturnCode XtMenuGeometryManager(dpy, window, req, reqBox, repBox)
764: Display *dpy;
765: Window window;
766: XtGeometryRequest req;
767: WindowBox *reqBox, *repBox;
768: {
769: XResizeWindow(dpy, window, reqBox->width, reqBox->height);
770: *repBox = *reqBox;
771: return(XtgeometryYes);
772: }
773:
774: /*
775: *
776: * Get Attributes
777: *
778: */
779:
780: void XtMenuGetValues (dpy, window, args, argCount)
781: Display *dpy;
782: Window window;
783: ArgList args;
784: int argCount;
785: {
786: WidgetData data;
787: data = DataFromWindow(dpy, window);
788: if (data == NULL) return;
789: globaldata = *data;
790: XtGetValues(resources, XtNumber(resources), args, argCount);
791: }
792:
793: /*
794: *
795: * Set Attributes
796: *
797: */
798:
799: void XtMenuSetValues (dpy, window, args, argCount)
800: Display *dpy;
801: Window window;
802: ArgList args;
803: int argCount;
804: {
805: WidgetData data;
806: data = DataFromWindow(dpy, window);
807: if (data == NULL) return;
808: globaldata = *data;
809: XtSetValues(resources, XtNumber(resources), args, argCount);
810: *data = globaldata;
811: }
812:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.