1 /*
2  * Motif
3  *
4  * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22 */
23 #ifdef REV_INFO
24 #ifndef lint
25 static char rcsid[] = "$XConsortium: Simple.c /main/11 1995/09/19 23:08:54 cde-sun $"
26 #endif
27 #endif
28 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 
33 
34 #include <stdio.h>
35 #include <X11/StringDefs.h>
36 #include <Xm/RowColumnP.h>
37 #include <Xm/PushBG.h>
38 #include <Xm/ToggleBG.h>
39 #include <Xm/CascadeBG.h>
40 #include <Xm/LabelG.h>
41 #include <Xm/SeparatoG.h>
42 #include "XmI.h"
43 
44 /********    Static Function Declarations    ********/
45 
46 static void EvaluateConvenienceStructure(
47                         Widget wid,
48                         XmSimpleMenu sm) ;
49 
50 /********    End Static Function Declarations    ********/
51 
52 static XtResource SimpleMenuResources[] =
53 {
54 	{ XmNbuttonCount, XmCButtonCount, XmRInt, sizeof(int),
55 	  XtOffsetOf( struct _XmSimpleMenuRec, count),
56 	  XmRImmediate, (XtPointer) 0
57 	},
58 	{ XmNpostFromButton, XmCPostFromButton, XmRInt, sizeof(int),
59 	  XtOffsetOf( struct _XmSimpleMenuRec, post_from_button),
60 	  XmRImmediate, (XtPointer) -1
61 	},
62 	{ XmNsimpleCallback, XmCCallback, XmRCallbackProc,
63 	  sizeof(XtCallbackProc), XtOffsetOf( struct _XmSimpleMenuRec, callback),
64 	  XmRImmediate, (XtPointer) NULL
65 	},
66 	{ XmNbuttons, XmCButtons, XmRXmStringTable,
67 	  sizeof(XmStringTable), XtOffsetOf( struct _XmSimpleMenuRec, label_string),
68 	  XmRImmediate, (XtPointer) NULL
69 	},
70 	{ XmNbuttonAccelerators, XmCButtonAccelerators, XmRStringTable,
71 	  sizeof(String *), XtOffsetOf( struct _XmSimpleMenuRec,  accelerator),
72 	  XmRImmediate, (XtPointer) NULL
73 	},
74 	{ XmNbuttonAcceleratorText, XmCButtonAcceleratorText,
75 	  XmRXmStringTable, sizeof(XmStringTable),
76 	  XtOffsetOf( struct _XmSimpleMenuRec, accelerator_text),
77 	  XmRImmediate, (XtPointer) NULL
78 	},
79 	{ XmNbuttonMnemonics, XmCButtonMnemonics, XmRKeySymTable,
80 	  sizeof(XmKeySymTable), XtOffsetOf( struct _XmSimpleMenuRec, mnemonic),
81 	  XmRImmediate, (XtPointer) NULL
82 	},
83 	{ XmNbuttonMnemonicCharSets, XmCButtonMnemonicCharSets,
84 	  XmRCharSetTable, sizeof(XmStringCharSetTable),
85 	  XtOffsetOf( struct _XmSimpleMenuRec, mnemonic_charset),
86 	  XmRImmediate, (XtPointer) NULL
87 	},
88 	{ XmNbuttonType, XmCButtonType, XmRButtonType,
89 	  sizeof(XmButtonTypeTable), XtOffsetOf( struct _XmSimpleMenuRec, button_type),
90 	  XmRImmediate, (XtPointer) NULL
91 	},
92 	{ XmNbuttonSet, XmCButtonSet, XmRInt,
93 	  sizeof(int), XtOffsetOf( struct _XmSimpleMenuRec, button_set),
94 	  XmRImmediate, (XtPointer) -1
95 	},
96 	{ XmNoptionLabel, XmCOptionLabel, XmRXmString,
97 	  sizeof(XmString), XtOffsetOf( struct _XmSimpleMenuRec, option_label),
98 	  XmRImmediate, (XtPointer) NULL
99 	},
100 	{ XmNoptionMnemonic, XmCOptionMnemonic, XmRKeySym,
101 	  sizeof (KeySym), XtOffsetOf( struct _XmSimpleMenuRec, option_mnemonic),
102           XmRImmediate, (XtPointer) NULL
103 	},
104 };
105 
106 static void
EvaluateConvenienceStructure(Widget wid,XmSimpleMenu sm)107 EvaluateConvenienceStructure(
108         Widget wid,
109         XmSimpleMenu sm )
110 {
111         XmRowColumnWidget rc = (XmRowColumnWidget) wid ;
112 	int i, n;
113 	char name_buf[20];
114 	int button_count = 0;
115 	int separator_count = 0;
116 	int label_count = 0;
117 	Arg args[6];
118 	Widget child;
119 	XmButtonType btype;
120 
121 	for (i = 0; i < sm->count; i++)
122 	{
123 		n = 0;
124 		if (sm->label_string && sm->label_string[i])
125 		{
126 			XtSetArg(args[n], XmNlabelString, sm->label_string[i]);
127 			n++;
128 		}
129 		if (sm->accelerator && sm->accelerator[i])
130 		{
131 			XtSetArg(args[n], XmNaccelerator, sm->accelerator[i]);
132 			n++;
133 		}
134 		if (sm->accelerator_text && sm->accelerator_text[i])
135 		{
136 			XtSetArg(args[n], XmNacceleratorText,
137 				sm->accelerator_text[i]);
138 			n++;
139 		}
140 		if (sm->mnemonic && sm->mnemonic[i])
141 		{
142 			XtSetArg(args[n], XmNmnemonic, sm->mnemonic[i]);
143 			n++;
144 		}
145 		if (sm->mnemonic_charset && sm->mnemonic_charset[i])
146 		{
147 			XtSetArg(args[n], XmNmnemonicCharSet,
148 				sm->mnemonic_charset[i]);
149 			n++;
150 		}
151 
152 		/* Dynamic Defaulting of button type */
153 
154 		if (sm->button_type && sm->button_type[i])
155 			btype = sm->button_type[i];
156 		else
157 			btype = XmNONE;
158 
159 		if (btype == XmNONE)
160 		{
161 			if (rc->row_column.type == XmMENU_BAR)
162 				btype = XmCASCADEBUTTON;
163 			else
164 				btype = XmPUSHBUTTON;
165 		}
166 
167 		switch (btype)
168 		{
169 			case XmTITLE:
170 				sprintf(name_buf,"label_%d", label_count++);
171 				child = XtCreateManagedWidget( name_buf,
172                                      xmLabelGadgetClass, (Widget) rc, args, n);
173 			break;
174 			case XmDOUBLE_SEPARATOR:
175 				XtSetArg(args[n], XmNseparatorType, XmDOUBLE_LINE); n++;
176 			case XmSEPARATOR:
177 				sprintf(name_buf,"separator_%d", separator_count++);
178 				child = XtCreateManagedWidget(name_buf,
179                                  xmSeparatorGadgetClass, (Widget) rc, args, n);
180 			break;
181 			case XmPUSHBUTTON:
182 				sprintf(name_buf,"button_%d", button_count++);
183 				child = XtCreateManagedWidget(name_buf,
184                                                        xmPushButtonGadgetClass,
185                                                          (Widget) rc, args, n);
186 				if (sm->callback)
187 					XtAddCallback(child,
188                                              XmNactivateCallback, sm->callback,
189                                                (XtPointer)(unsigned long)(button_count - 1));
190 			break;
191 			case XmRADIOBUTTON:
192 				XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++;
193 			case XmCHECKBUTTON:
194 				sprintf(name_buf,"button_%d", button_count++);
195 				XtSetArg(args[n], XmNindicatorOn, TRUE); n++;
196 				child = XtCreateManagedWidget(name_buf,
197                                                      xmToggleButtonGadgetClass,
198                                                          (Widget) rc, args, n);
199 				if (sm->callback)
200 					XtAddCallback(child,
201                                          XmNvalueChangedCallback, sm->callback,
202                                                (XtPointer)(unsigned long)(button_count - 1));
203 			break;
204 			case XmCASCADEBUTTON:
205 				sprintf(name_buf,"button_%d", button_count++);
206 				child = XtCreateManagedWidget(name_buf,
207                                                     xmCascadeButtonGadgetClass,
208                                                          (Widget) rc, args, n);
209 				if (sm->callback)
210 					XtAddCallback(child,
211                                              XmNactivateCallback, sm->callback,
212                                                (XtPointer)(unsigned long)(button_count - 1));
213 			break;
214 			default:
215 				/* this is an error condition */
216 				;
217 			break;
218 		}
219 	}
220 }
221 
222 Widget
XmCreateSimpleMenuBar(Widget parent,String name,ArgList args,Cardinal arg_count)223 XmCreateSimpleMenuBar(
224         Widget parent,
225         String name,
226         ArgList args,
227         Cardinal arg_count )
228 {
229 	Widget rc;
230 	XmSimpleMenuRec mr;
231 	_XmWidgetToAppContext(parent);
232 
233 	_XmAppLock(app);
234 
235 	XtGetSubresources(parent, &mr, name, XmCSimpleMenuBar,
236 		SimpleMenuResources, XtNumber(SimpleMenuResources),
237 		args, arg_count);
238 
239 	rc = XmCreateMenuBar(parent, name, args, arg_count);
240 
241 	EvaluateConvenienceStructure( rc, &mr);
242 
243 	_XmAppUnlock(app);
244 	return(rc);
245 }
246 
247 Widget
XmCreateSimplePopupMenu(Widget parent,String name,ArgList args,Cardinal arg_count)248 XmCreateSimplePopupMenu(
249         Widget parent,
250         String name,
251         ArgList args,
252         Cardinal arg_count )
253 {
254 	Widget rc;
255 	XmSimpleMenuRec mr;
256 	_XmWidgetToAppContext(parent);
257 
258 	_XmAppLock(app);
259 
260 	XtGetSubresources(parent, &mr, name, XmCSimplePopupMenu,
261 		SimpleMenuResources, XtNumber(SimpleMenuResources),
262 		args, arg_count);
263 
264 	rc = XmCreatePopupMenu(parent, name, args, arg_count);
265 
266 	EvaluateConvenienceStructure( rc, &mr);
267 
268 	_XmAppUnlock(app);
269 	return(rc);
270 }
271 
272 Widget
XmCreateSimplePulldownMenu(Widget parent,String name,ArgList args,Cardinal arg_count)273 XmCreateSimplePulldownMenu(
274         Widget parent,
275         String name,
276         ArgList args,
277         Cardinal arg_count )
278 {
279 	Widget rc;
280 	XmSimpleMenuRec mr;
281 	int n, i;
282 	Arg local_args[3];
283 	WidgetList buttons;
284 	Cardinal num_buttons;
285 
286 	_XmWidgetToAppContext(parent);
287 	_XmAppLock(app);
288 
289 	XtGetSubresources(parent, &mr, name, XmCSimplePulldownMenu,
290 		SimpleMenuResources, XtNumber(SimpleMenuResources),
291 		args, arg_count);
292 
293 	rc = XmCreatePulldownMenu(parent, name, args, arg_count);
294 
295 	EvaluateConvenienceStructure(rc, &mr);
296 
297 	if (mr.post_from_button >= 0)
298 	{
299 		n = 0;
300 		XtSetArg(local_args[n], XtNchildren, &buttons); n++;
301 		XtSetArg(local_args[n], XtNnumChildren, &num_buttons); n++;
302 		XtGetValues(parent, local_args, n);
303 
304 		if (!num_buttons)
305 		{
306 			/* error condition */
307 			_XmAppUnlock(app);
308 			return(rc);
309 		}
310 		else
311 		{
312 			for (i = 0; i < num_buttons; i++)
313 			{
314 				if (((XmIsCascadeButtonGadget(buttons[i])) ||
315 					(XmIsCascadeButton(buttons[i])))
316 					&&
317 					(i == mr.post_from_button))
318 					break;
319 			}
320 
321 			if ( i < num_buttons)
322 			{
323 				n = 0;
324 				XtSetArg(local_args[n], XmNsubMenuId, rc); n++;
325 				XtSetValues(buttons[i], local_args, n);
326 			}
327 		}
328 	}
329 	_XmAppUnlock(app);
330 	return(rc);
331 }
332 
333 Widget
XmCreateSimpleOptionMenu(Widget parent,String name,ArgList args,Cardinal arg_count)334 XmCreateSimpleOptionMenu(
335         Widget parent,
336         String name,
337         ArgList args,
338         Cardinal arg_count )
339 {
340 	Widget rc, sub_rc;
341 	XmSimpleMenuRec mr;
342 	int n, i, button_count;
343 	Arg local_args[5];
344 	WidgetList buttons;
345 	Cardinal num_buttons;
346 	_XmWidgetToAppContext(parent);
347 
348 	_XmAppLock(app);
349 
350 	XtGetSubresources(parent, &mr, name, XmCSimpleOptionMenu,
351 		SimpleMenuResources, XtNumber(SimpleMenuResources),
352 		args, arg_count);
353 
354 	rc = XmCreateOptionMenu(parent, name, args, arg_count);
355 
356 	sub_rc = XmCreatePulldownMenu(parent, name, args, arg_count);
357 
358 	EvaluateConvenienceStructure(sub_rc, &mr);
359 
360 	n = 0;
361 	if (mr.option_label)
362 	{
363 		XtSetArg(local_args[n], XmNlabelString, mr.option_label); n++;
364 	}
365 	if (mr.option_mnemonic)
366 	{
367 		XtSetArg(local_args[n], XmNmnemonic, mr.option_mnemonic); n++;
368 	}
369 
370 	XtSetArg(local_args[n], XmNsubMenuId, sub_rc); n++;
371 	XtSetValues(rc, local_args, n);
372 
373 	if (mr.button_set >= 0)
374 	{
375 		n = 0;
376 		XtSetArg(local_args[n], XtNchildren, &buttons); n++;
377 		XtSetArg(local_args[n], XtNnumChildren, &num_buttons); n++;
378 		XtGetValues(sub_rc, local_args, n);
379 
380 		if (!num_buttons)
381 		{
382 			/* error condition */
383 			_XmAppUnlock(app);
384 			return(rc);
385 		}
386 		else
387 		{
388 			button_count = 0;
389 			for (i = 0; i < num_buttons; i++)
390 			{				/* count only PushB */
391 				if ((XmIsPushButtonGadget(buttons[i])) ||
392 					(XmIsPushButton(buttons[i])))
393 				{
394 					if (button_count == mr.button_set)
395 						break;
396 					button_count++;
397 				}
398 			}
399 
400 			if ( i < num_buttons)
401 			{
402 				n = 0;
403 				XtSetArg(local_args[n], XmNmenuHistory, buttons[i]); n++;
404 				XtSetValues(rc, local_args, n);
405 			}
406 		}
407 	}
408 
409 	_XmAppUnlock(app);
410 	return(rc);
411 }
412 
413 Widget
XmCreateSimpleRadioBox(Widget parent,String name,ArgList args,Cardinal arg_count)414 XmCreateSimpleRadioBox(
415         Widget parent,
416         String name,
417         ArgList args,
418         Cardinal arg_count )
419 {
420 	Arg local_args[5];
421 	Widget rc, child;
422 	int i, n;
423 	XmSimpleMenuRec mr;
424 	char name_buf[20];
425 
426 	rc = XmCreateRadioBox(parent, name, args, arg_count);
427 
428 	XtGetSubresources(parent, &mr, name, XmCSimpleRadioBox,
429 		SimpleMenuResources, XtNumber(SimpleMenuResources),
430 		args, arg_count);
431 
432 	for(i=0; i < mr.count; i++)
433 	{
434 		sprintf(name_buf,"button_%d", i);
435 
436 		n = 0;
437 		if (mr.label_string && mr.label_string[i])
438 		{
439 			XtSetArg(local_args[n],
440 				XmNlabelString, mr.label_string[i]); n++;
441 		}
442 		if (mr.button_set == i)
443 		{
444 			XtSetArg(local_args[n], XmNset, TRUE); n++;
445 		}
446 		child = XtCreateManagedWidget(name_buf,
447 			xmToggleButtonGadgetClass, (Widget) rc, local_args, n);
448 		if (mr.callback)
449 			XtAddCallback(child, XmNvalueChangedCallback,
450 				mr.callback, (XtPointer)(unsigned long)i);
451 	}
452 
453 	return(rc);
454 }
455 
456 Widget
XmCreateSimpleCheckBox(Widget parent,String name,ArgList args,Cardinal arg_count)457 XmCreateSimpleCheckBox(
458         Widget parent,
459         String name,
460         ArgList args,
461         Cardinal arg_count )
462 {
463 	Arg local_args[5];
464 	Widget rc, child;
465 	int i, n;
466 	XmSimpleMenuRec mr;
467 	char name_buf[20];
468 
469 
470 	rc = XmCreateRadioBox(parent, name, args, arg_count);
471 
472 	n = 0;
473         XtSetArg(local_args[n], XmNradioBehavior, FALSE); n++;
474 
475 	XtSetValues(rc, local_args, n);
476 
477 
478 	XtGetSubresources(parent, &mr, name, XmCSimpleCheckBox,
479 		SimpleMenuResources, XtNumber(SimpleMenuResources),
480 		args, arg_count);
481 
482 	for(i=0; i < mr.count; i++)
483 	{
484 		sprintf(name_buf,"button_%d", i);
485 
486 		n = 0;
487 		if (mr.label_string && mr.label_string[i])
488 		{
489 			XtSetArg(local_args[n],
490 				XmNlabelString, mr.label_string[i]); n++;
491 		}
492 		child = XtCreateManagedWidget(name_buf,
493 			xmToggleButtonGadgetClass, (Widget) rc, local_args, n);
494 		if (mr.callback)
495 			XtAddCallback(child, XmNvalueChangedCallback,
496 				mr.callback, (XtPointer)(unsigned long)i);
497 	}
498 
499 	return(rc);
500 }
501