~ubuntu-branches/ubuntu/quantal/openmotif/quantal

« back to all changes in this revision

Viewing changes to demos/programs/airport/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bauer
  • Date: 2010-06-23 12:12:31 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100623121231-u89gxdp51sg9wjj2
Tags: 2.3.0-1
* New Maintainer (Closes: #379258) 
* Acknowledge NMU changes
* New upstream release (Closes: #494375)
* Get rid of security patches as they are already part of new upstream
  release (00-xpmvuln.openmotif.patch, 342092-CVE-2005-3964.patch)
* Bump Standards to 3.8.4
* Added {misc:Depends} to make the package lintian cleaner
* Fix weak-library-dev-dependency by adding ${binary:Version}) for the
  -dev Package of openmotif
* Let package depend on autotools-dev to use newer autotools-helper-files
* Work around an autoconf-bug (Gentoo-Bug #1475)
* Added Client-side anti-aliased fonts support via XFT
* Added UTF-8 and UTF8_STRING atom support
* Ability to show text and pixmaps in Label, LabelGadget and all
  derived widgets
* Support of PNG/JPEG image formats in the same way as XPM is supported
* Increase FILE_OFFSET_BITS to 64 to show files >2GB in file-selector
  Idea taken from Magne Oestlyngen (Closes: #288537)

Show diffs side-by-side

added added

removed removed

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