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