1 /* $TOG: main.c /main/6 1997/03/31 13:47:48 dbl $ */
2 /*
3 * Motif
4 *
5 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
6 *
7 * These libraries and programs are free software; you can
8 * redistribute them and/or modify them under the terms of the GNU
9 * Lesser General Public License as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * These libraries and programs are distributed in the hope that
14 * they will be useful, but WITHOUT ANY WARRANTY; without even the
15 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with these librararies and programs; if not, write
21 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
22 * Floor, Boston, MA 02110-1301 USA
23 */
24 /*
25 * HISTORY
26 */
27
28 /*
29 * The Airport Drag And Drop Demo
30 */
31
32 #include "main.h"
33
34 /* ============================ local constants ======================= */
35
36 #define MAX_ARGS 8
37
38 /* ============================ prototypes ======================= */
39
40 static Widget MenuBarEntry(Widget menubar, String entry, String labels[],
41 XtCallbackProc procs[], XtPointer private[], int count);
42
43 static void HelpCallback(Widget button, Airport this, XtPointer cbs);
44
45 static void ExitCallback(Widget button, Airport this, XtPointer cbs);
46
47 static void ResizeAirport(Widget area, Airport this, XtPointer cbs);
48 /* resize callback of airport */
49
50 static void ShowAirport(Widget area, Airport this, XtPointer cbs);
51 /* expose callback of airport */
52
53 static void AirportInput(Widget area, Airport this, XtPointer cbs);
54 /* Callback when pointer or keyboard input in airport */
55
56 static void ConfigureAirport(Widget area, Airport this);
57 /* configure geometry */
58
59 static void Warning(Airport this, XmString s1, XmString s2);
60 /* issue a warning to user */
61
62
63 /* ==============================================================
64 * Main loop
65 */
66
67 int
main(int argc,char * argv[])68 main(int argc, char *argv[])
69 {
70 #define MAIN_CHILDREN 3
71 #define FORM_CHILDREN 3
72 #define PLANE_CHILDREN 6
73 #define TRAFFIC_CHILDREN 3
74 #define SetMenuEntry(k,l,p,d) labels[k]=l;procs[k]=p;private[k]=d;
75
76 Pixmap flying;
77 Pixmap parked;
78 Pixmap mask;
79 Widget theWidgetRoot;
80 Widget main_tab[MAIN_CHILDREN];
81 Widget from_tab[PLANE_CHILDREN];
82 Widget to_tab[TRAFFIC_CHILDREN];
83 Widget form_tab[FORM_CHILDREN];
84 Widget framed[2];
85 Widget entry;
86 static char myClass[] = "XmdAirport";
87 Arg args[10];
88 int n ;
89 String labels[4];
90 XtCallbackProc procs[4];
91 XtPointer private[4];
92 XGCValues gcv;
93 Airport this;
94
95
96 /*
97 * Initialize
98 */
99 this = (Airport) XtCalloc(sizeof(AirportRec), 1);
100
101 XtSetLanguageProc(NULL, (XtLanguageProc) NULL, NULL);
102
103 theWidgetRoot = XtVaOpenApplication( &this->context,
104 myClass,
105 NULL,
106 0,
107 &argc,
108 argv,
109 NULL,
110 sessionShellWidgetClass,
111 XmNallowShellResize, True,
112 NULL);
113
114 this->display = XtDisplay(theWidgetRoot);
115 FlightAtom = XmInternAtom(this->display, "FLIGHT", False);
116 DeleteAtom = XmInternAtom(this->display, "DELETE", False);
117
118 XtGetApplicationResources(theWidgetRoot, &AirportResources,
119 AirportResourcesSpecs,
120 XtNumber(AirportResourcesSpecs),
121 (ArgList) NULL, 0);
122
123 /*
124 * Create the Main Window, the menubar and the pulldown menus
125 */
126 n = 0;
127 this->main = XmCreateMainWindow(theWidgetRoot, "main", args, n);
128
129 n = 0;
130 main_tab[0] = XmCreateMenuBar(this->main, "menubar", args, n);
131 n = 0;
132 SetMenuEntry(n, "Exit",
133 (XtCallbackProc) ExitCallback, (XtPointer) this ); n++;
134 entry = MenuBarEntry(main_tab[0], "File", labels, procs, private, n);
135 n = 0;
136 SetMenuEntry(0, "Tutorial",
137 (XtCallbackProc) HelpCallback, (XtPointer) this); n++;
138 entry = MenuBarEntry(main_tab[0], "Help", labels, procs, private, n);
139 n = 0;
140 XtSetArg(args[n], XmNmenuHelpWidget, entry); n++;
141 XtSetValues(main_tab[0], args, n);
142
143 /*
144 * Create the Airport widget structure.
145 * Two framed radio boxes show state.
146 * A drawing area in the middle show track and planes
147 */
148
149 n = 0;
150 this->screen_width = WidthOfScreen(XtScreenOfObject(this->main));
151 this->screen_height = HeightOfScreen(XtScreenOfObject(this->main));
152 XtSetArg(args[n], XmNwidth, this->screen_width*3/7); n++;
153 XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
154 main_tab[1] = XmCreateForm(this->main, "airport", args, n);
155
156 n = 0;
157 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
158 XtSetArg(args[n], XmNbottomAttachment,XmATTACH_FORM); n++;
159 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM) ; n++;
160 form_tab[0] = XmCreateFrame(main_tab[1], "flight", args, n);
161
162 n = 0;
163 XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++;
164 framed[0] = XmCreateLabel(form_tab[0], "title", args, n);
165
166 n = 0;
167 XtSetArg(args[n], XmNchildType, XmFRAME_WORKAREA_CHILD); n++;
168 XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++;
169 XtSetArg(args[n], XmNradioBehavior, True); n++;
170 framed[1] = XmCreateRadioBox(form_tab[0], "panel", args, n);
171
172 n = 0;
173 XtSetArg(args[n], XmNset, True); n++;
174 XtSetArg(args[n], XmNvisibleWhenOff, False); n++;
175 this->from.departure =
176 from_tab[0] = XmCreateToggleButton(framed[1],
177 "departure", args, n);
178 n = 0;
179 XtSetArg(args[n], XmNvisibleWhenOff, False); n++;
180 this->from.over_ocean =
181 from_tab[1] = XmCreateToggleButton(framed[1],
182 "over_ocean", args, n);
183 n = 0;
184 XtSetArg(args[n], XmNvisibleWhenOff, False); n++;
185 this->from.over_land =
186 from_tab[2] = XmCreateToggleButton(framed[1],
187 "over_land", args, n);
188 n = 0;
189 XtSetArg(args[n], XmNvisibleWhenOff, False); n++;
190 this->from.over_site =
191 from_tab[3] = XmCreateToggleButton(framed[1],
192 "radar", args, n);
193 n = 0;
194 XtSetArg(args[n], XmNvisibleWhenOff, False); n++;
195 this->from.landing =
196 from_tab[4] = XmCreateToggleButton(framed[1], "landing", args, n);
197
198 n = 0;
199 XtSetArg(args[n], XmNvisibleWhenOff, False); n++;
200 this->from.landed =
201 from_tab[5] = XmCreateToggleButton(framed[1], "landed", args, n);
202 XtManageChildren(from_tab, PLANE_CHILDREN);
203 XtManageChildren(framed, 2);
204
205 /*
206 * Create the Airport Traffic control state
207 */
208
209 n = 0;
210 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
211 XtSetArg(args[n], XmNbottomAttachment,XmATTACH_FORM); n++;
212 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM) ; n++;
213 form_tab[1] = XmCreateFrame(main_tab[1], "traffic", args, n);
214
215 n = 0;
216 XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++;
217 framed[0] = XmCreateLabel(form_tab[1], "title", args, n);
218
219 n = 0;
220 XtSetArg(args[n], XmNchildType, XmFRAME_WORKAREA_CHILD); n++;
221 XtSetArg(args[n], XmNradioBehavior, True); n++;
222 framed[1] = XmCreateRadioBox(form_tab[1], "traffic_box", args, n);
223
224 n = 0;
225 XtSetArg(args[n], XmNset, True); n++;
226 XtSetArg(args[n], XmNvisibleWhenOff, False); n++;
227 this->to.leave =
228 to_tab[1] = XmCreateToggleButton(framed[1],
229 "no_traffic", args, n);
230 n = 0;
231 XtSetArg(args[n], XmNvisibleWhenOff, False); n++;
232 this->to.enter =
233 to_tab[0] = XmCreateToggleButton(framed[1],
234 "radar_echo", args, n);
235 n = 0;
236 XtSetArg(args[n], XmNvisibleWhenOff, False); n++;
237 this->to.landing =
238 to_tab[2] = XmCreateToggleButton(framed[1],
239 "landing", args, n);
240
241 XtManageChildren(to_tab, TRAFFIC_CHILDREN);
242 XtManageChildren(framed, 2);
243
244 /*
245 * Create the Airport picture
246 */
247 n = 0;
248 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
249 XtSetArg(args[n], XmNbottomAttachment,XmATTACH_FORM); n++;
250 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET) ; n++;
251 XtSetArg(args[n], XmNleftWidget, form_tab[0]) ; n++;
252 XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET) ; n++;
253 XtSetArg(args[n], XmNrightWidget, form_tab[1]) ; n++;
254 this->airport =
255 form_tab[2] = XmCreateDrawingArea(main_tab[1], "da", args, n);
256 XtAddCallback(this->airport, XmNexposeCallback,
257 (XtCallbackProc) ShowAirport, (XtPointer) this);
258 XtAddCallback(this->airport, XmNresizeCallback,
259 (XtCallbackProc) ResizeAirport, (XtPointer) this);
260 XtAddCallback(this->airport, XmNinputCallback,
261 (XtCallbackProc) AirportInput, (XtPointer) this);
262 /*
263 * Create the Airport Message area
264 */
265
266 n = 0;
267 main_tab[2] = XmCreateFrame(this->main, "message", args, n);
268
269 n = 0;
270 XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++;
271 framed[0] = XmCreateLabel(main_tab[2], "title", args, n);
272
273 n = 0;
274 XtSetArg(args[n], XmNchildType, XmFRAME_WORKAREA_CHILD); n++;
275 XtSetArg(args[n], XmNvisibleItemCount, 4); n++;
276 this->msg_area = XmCreateScrolledList(main_tab[2], "msg_list", args, n);
277 XtManageChild(this->msg_area);
278 framed[1] = XtParent(this->msg_area);
279 XtManageChildren(framed, 2);
280
281 n = 0;
282 XtSetArg(args[n], XmNmenuBar, main_tab[0]); n++;
283 XtSetArg(args[n], XmNworkWindow, main_tab[1]); n++;
284 XtSetArg(args[n], XmNmessageWindow, main_tab[2]); n++;
285 XtSetValues(this->main, args, n);
286 XtManageChildren(form_tab, FORM_CHILDREN);
287 XtManageChildren(main_tab, MAIN_CHILDREN);
288 XtManageChild(this->main);
289
290 XtRealizeWidget(theWidgetRoot);
291
292 /*
293 * Create the drag icon
294 */
295
296 parked = XCreateBitmapFromData(this->display,
297 XtWindow(this->main), (char*)plane_bits,
298 plane_width, plane_height);
299
300 flying = XCreateBitmapFromData(this->display,
301 XtWindow(this->main), (char*)flying_bits,
302 flying_icon_width, flying_icon_height);
303
304 mask = XCreateBitmapFromData(this->display,
305 XtWindow(this->main), (char*)flying_mask_bits,
306 flying_mask_width, flying_mask_height);
307 n = 0;
308 XtSetArg(args[n], XmNpixmap, flying); n++;
309 XtSetArg(args[n], XmNdepth, 1); n++;
310 XtSetArg(args[n], XmNmask, mask); n++;
311 XtSetArg(args[n], XmNwidth, flying_icon_width); n++;
312 XtSetArg(args[n], XmNheight, flying_icon_height) ; n++;
313 this->dragIcon = XmCreateDragIcon(form_tab[2], "drag", args, n);
314 if (this->dragIcon == NULL) {
315 printf("cannot create drag icon\n");
316 exit(0);
317 }
318 /* Create GC for drawing planes */
319 gcv.function = GXcopy;
320 gcv.fill_style = FillOpaqueStippled;
321 gcv.stipple = parked;
322 gcv.foreground = AirportResources.spot_foreground;
323 gcv.background = AirportResources.spot_background;
324 this->park.gc = XCreateGC(this->display, XtWindow(this->main),
325 GCFunction|GCStipple|GCFillStyle
326 |GCForeground|GCBackground,
327 &gcv);
328
329 gcv.line_style = LineDoubleDash;
330 gcv.line_width = AirportResources.track_border_width;
331 gcv.fill_style = FillSolid;
332 gcv.foreground = AirportResources.track_foreground;
333 gcv.background = AirportResources.track_background;
334 this->track.gc = XCreateGC(this->display, XtWindow(this->main),
335 GCFunction|GCLineWidth|GCLineStyle
336 |GCFillStyle|GCForeground|GCBackground,
337 &gcv);
338 XtAppMainLoop(this->context);
339
340 return 0; /* make compiler happy */
341 }
342
343 /* ===============================================================
344 * Create a cascade and a pulldown entry into a menubar,
345 * from a list of push button specs.
346 * If the label is NULL, create a separator instead of a push button.
347 */
348
MenuBarEntry(Widget menubar,String entry,String labels[],XtCallbackProc procs[],XtPointer private[],int count)349 static Widget MenuBarEntry(Widget menubar, String entry, String labels[],
350 XtCallbackProc procs[], XtPointer private[],
351 int count)
352 {
353 Widget menu;
354 Widget child;
355 Arg args[8];
356 int n;
357 int i;
358 char name[128];
359
360 n = 0;
361 menu = XmCreatePulldownMenu(menubar,
362 strcat(strcpy(name, entry), "Menu"),
363 args, n);
364 for( i = 0; i < count; i++) {
365 n = 0;
366 if (labels[i] == NULL) {
367 child = XmCreateSeparator(menu, "sep", args, n);
368 }
369 else {
370 child = XmCreatePushButton(menu, labels[i], args, n);
371 if (procs[i] != NULL)
372 XtAddCallback(child, XmNactivateCallback, procs[i], private[i]);
373 }
374 XtManageChild(child);
375 }
376 n = 0;
377 XtSetArg(args[n], XmNlabelString, XmStringCreateSimple(entry)); n++;
378 XtSetArg(args[n], XmNsubMenuId, menu); n++;
379 child = XmCreateCascadeButton(menubar, entry, args, n);
380 XtManageChild(child);
381 return child;
382 }
383
384
385 /* ===============================================================
386 * The Exit Callback. Exit properly.
387 */
388
ExitCallback(Widget button,Airport this,XtPointer cbs)389 static void ExitCallback(Widget button, Airport this, XtPointer cbs)
390 {
391 XtCloseDisplay(this->display);
392 exit(0);
393 }
394
395 /* ======================================================================
396 * Help Callback
397 */
398
HelpCallback(Widget button,Airport this,XtPointer cbs)399 static void HelpCallback(Widget button, Airport this, XtPointer cbs)
400 {
401 static char helpmsg[] = "Read the README file, please...";
402
403 if ( this->help_dialog == NULL ) {
404 Arg args[8];
405 int n = 0;
406
407 XtSetArg(args[n], XmNmessageString,
408 XmStringCreateLocalized(helpmsg)); n++;
409 this->help_dialog = XmCreateInformationDialog(button,
410 "helpdialog", args, n);
411 }
412 XtManageChild(this->help_dialog);
413 }
414
415 /* ===============================================================
416 * Create Airport tracks. Open airport to traffic.
417 *
418 */
419
ConfigureAirport(Widget area,Airport this)420 static void ConfigureAirport(Widget area, Airport this)
421 {
422 Arg args[10];
423 int i, n;
424 Window root, parent, *wlist;
425 unsigned int count;
426 Dimension width, height;
427 int min_width, min_height;
428
429 /*
430 * Try to make the screen background window the ocean.
431 * Be aware of running without a window manager,
432 * or with a reparenting window manager
433 * or a window manager like HP VUEWM who have a background window
434 */
435
436 this->ocean = (Window) NULL;
437 if (XQueryTree(this->display, XtWindow(XtParent(this->main)),
438 &root, &parent, &wlist, &count) != 0) {
439 Window current;
440
441 do {
442 XWindowAttributes wa;
443
444 current = this->ocean = parent;
445 if (XQueryTree(this->display, current, &root, &parent,
446 &wlist, &count) == 0)
447 break;
448
449 if (current == root)
450 {
451 /* beware of HP-VUE */
452
453 XGetWindowAttributes(this->display, wlist[0], &wa);
454 this->ocean = (wa.width >= this->screen_width
455 && wa.height >= this->screen_height) ?
456 wlist[0] : root;
457 }
458 else {
459 XGetWindowAttributes(this->display, current, &wa);
460 if (wa.width >= this->screen_width
461 && wa.height >= this->screen_height)
462 {
463 this->ocean = current;
464 break;
465 }
466 }
467 } while (root != current);
468 }
469
470 n = 0;
471 XtSetArg(args[n], XmNwidth, &width); n++;
472 XtSetArg(args[n], XmNheight, &height); n++;
473 XtGetValues(area, args, n);
474
475 if (this->state == open) { /* destroy current data */
476 XtFree((char *)this->park.spots);
477 XClearWindow(this->display, XtWindow(area) );
478 this->park.spot_count = 0;
479 }
480 min_height = AirportResources.track_margin * 4 + plane_height*2
481 + AirportResources.track_border_width*2 + MIN_TRACK_SIZE;
482 min_width = AirportResources.track_margin*2 + plane_width ;
483 if ( min_height > (int) height || min_width > (int) width)
484 {
485 Warning(this,
486 XmStringCreateLocalized(AirportResources.too_small),
487 NULL);
488 this->state = closed;
489 }
490 else
491 {
492 Position x, y;
493
494 this->track.bbox.x = (short) AirportResources.track_margin;
495 this->track.bbox.y = (short) AirportResources.track_margin*2
496 + plane_height;
497 this->track.bbox.width = width - AirportResources.track_margin*2;
498 this->track.bbox.height = height - 2*this->track.bbox.y;
499 this->park.plane_count = (int) this->track.bbox.width / plane_width;
500 this->park.spot_count = 2 * this->park.plane_count;
501 this->park.spots = (Spot) XtCalloc(sizeof(SpotRec),
502 this->park.spot_count);
503 x = AirportResources.track_margin;
504 y = AirportResources.track_margin;
505 for (i = 0; i < this->park.plane_count ; i++) {
506 this->park.spots[i].empty = False;
507 this->park.spots[i].x = x ;
508 this->park.spots[i].y = y ;
509 x += plane_width;
510
511 }
512 x = AirportResources.track_margin;
513 y += this->track.bbox.y + this->track.bbox.height
514 + AirportResources.track_margin;
515 for (i = this->park.plane_count; i < this->park.spot_count ; i++) {
516 this->park.spots[i].empty = True;
517 this->park.spots[i].x = x ;
518 this->park.spots[i].y = y ;
519 x += plane_width;
520 }
521 this->park.state = normal;
522 }
523 }
524
525 /* ===============================================================
526 * On Resize, clear the data structure and reset airport
527 * So the first time it is initialized.
528 */
529
ResizeAirport(Widget area,Airport this,XtPointer cbs)530 static void ResizeAirport(Widget area, Airport this, XtPointer cbs)
531 {
532
533 if (! XtIsRealized(area) || this->state == closed)
534 return ;
535 ConfigureAirport(area, this);
536
537 }
538
539 /* ===============================================================
540 * Expose callback. Redraw the airport
541 */
ShowAirport(Widget area,Airport this,XtPointer cbs)542 static void ShowAirport(Widget area, Airport this, XtPointer cbs)
543 {
544
545 if (this->state == closed) {
546 ConfigureAirport(area, this);
547 MakeAirportDropSite(area, this);
548 this->state = open;
549 }
550 DrawAirport(this, XtWindow(area), AirportResources.track_background,
551 AirportResources.track_foreground);
552 }
553
554 /* ===============================================================
555 * Input callback. On button 2 drag plane.
556 */
557
AirportInput(Widget area,Airport this,XtPointer cbs)558 static void AirportInput(Widget area, Airport this, XtPointer cbs)
559 {
560 int i;
561 XButtonEvent *evt;
562 XmDrawingAreaCallbackStruct *call_data = (XmDrawingAreaCallbackStruct *)cbs;
563
564 if ((call_data->event->type != ButtonPress)
565 && (call_data->event->type != ButtonRelease))
566 return;
567
568 evt = (XButtonEvent *) call_data->event;
569 switch(evt->type) {
570
571 case ButtonPress:
572 switch (evt->button) {
573
574 case Button2: /* start drag ?? */
575
576 for (i = 0; i < this->park.spot_count ; i++) {
577 if (evt->x >= this->park.spots[i].x
578 && evt->y >= this->park.spots[i].y
579 && evt->x <= this->park.spots[i].x + plane_width
580 && evt->y <= this->park.spots[i].y + plane_height ) {
581 /* hit detection of the starting gate */
582 if (this->park.spots[i].empty == False)
583 TakeOff(area, this, evt, i);
584 break;
585 }
586 }
587 break;
588
589 default:
590 return;
591 }
592 break;
593
594 default:
595 return;
596 }
597 }
598
599 /* ===============================================================
600 *
601 */
DrawAirport(Airport this,Window wd,Pixel bg,Pixel fg)602 void DrawAirport(Airport this, Window wd, Pixel bg, Pixel fg)
603 {
604 int i;
605 Position y;
606
607 XSetForeground(this->display, this->track.gc, fg);
608 XSetBackground(this->display, this->track.gc, bg);
609 XFillRectangle(this->display, wd, this->track.gc,
610 this->track.bbox.x, this->track.bbox.y,
611 this->track.bbox.width, this->track.bbox.height);
612 XDrawLine(this->display, wd, this->track.gc,
613 this->track.bbox.x,
614 this->track.bbox.y + AirportResources.track_border_width,
615 this->track.bbox.x + this->track.bbox.width,
616 this->track.bbox.y + AirportResources.track_border_width);
617 y = this->track.bbox.y + this->track.bbox.height
618 - AirportResources.track_border_width;
619 XDrawLine(this->display, wd, this->track.gc,
620 this->track.bbox.x, y,
621 this->track.bbox.x + this->track.bbox.width, y);
622
623 for (i = 0; i < this->park.spot_count ; i++) {
624 if (this->park.spots[i].empty == False) {
625 XSetTSOrigin(this->display, this->park.gc,
626 this->park.spots[i].x, this->park.spots[i].y);
627 XFillRectangle(this->display, wd, this->park.gc,
628 this->park.spots[i].x, this->park.spots[i].y,
629 plane_width, plane_height);
630 }
631 }
632 }
633
634 /* ===============================================================
635 * Display a message in the message area
636 */
Paging(Airport this,String msg)637 void Paging(Airport this, String msg)
638 {
639 XmString item;
640
641 item = XmStringCreateLocalized(msg);
642 XmListDeselectAllItems(this->msg_area);
643 XmListAddItem(this->msg_area, item, 0);
644 XmListSetBottomItem(this->msg_area, item);
645 }
646
647 /* =====================================================================
648 * Show application modal warning dialogue box with specified messages
649 */
650
Warning(Airport this,XmString s1,XmString s2)651 static void Warning(Airport this, XmString s1, XmString s2)
652 {
653 XmString msg;
654
655 if (s1 == NULL)
656 msg = s2;
657 else if (s2 == NULL)
658 msg = s1;
659 else
660 msg = XmStringConcat(s1, s2);
661
662 if (this->warning_dialog == NULL) {
663 Arg args[8];
664 int n = 0;
665
666 XtSetArg(args[n], XmNdialogStyle,
667 XmDIALOG_FULL_APPLICATION_MODAL);
668 n++;
669 this->warning_dialog = XmCreateWarningDialog(this->main,
670 "warning", args, n);
671 }
672 XtVaSetValues(this->warning_dialog, XmNmessageString, msg, NULL);
673 XtManageChild(this->warning_dialog);
674 }
675