Use C++ linker
[oweals/cde.git] / cde / programs / dtwm / UI.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-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 /* $XConsortium: UI.c /main/7 1996/11/07 16:35:08 rswiston $ */
24 /*****************************************************************************
25  *
26  *   File:         UI.c
27  *
28  *   Project:       CDE
29  *
30  *   Description:  This file contains the user interface creation and
31  *                 processing code for the CDE front panel
32  *
33  * (c) Copyright 1993, 1994 Hewlett-Packard Company
34  * (c) Copyright 1993, 1994 International Business Machines Corp.
35  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
36  * (c) Copyright 1993, 1994 Novell, Inc.
37  *
38  ****************************************************************************/
39
40
41 #include <Dt/DtP.h>
42 #include <Dt/DbReader.h>
43 #include <Dt/Dnd.h>
44 #include "PanelSP.h"
45 #include <Dt/Control.h>
46 #include "Clock.h"
47 #include <Dt/ControlP.h>
48 #include <Dt/IconFile.h>
49 #include <Dt/Icon.h>
50 #include "Button.h"
51 #include <Dt/GetDispRes.h>
52
53 #include <Xm/Form.h>
54 #include <Xm/ToggleBG.h>
55 #include <Xm/MwmUtil.h>
56 #include <Xm/AtomMgr.h>
57 #include <Xm/DrawingA.h>
58 #include <Xm/RowColumn.h>
59 #include <Xm/SeparatoG.h>
60 #include <Xm/DialogS.h>
61 #include <Xm/ColorObjP.h>
62
63 #include <X11/Xatom.h>
64 #include <X11/keysymdef.h>
65
66 #include <langinfo.h>
67
68 #define MWM_NEED_TIME16
69 #include "WmBitmap.h"
70 #include "WmHelp.h"
71
72 #include "DataBaseLoad.h"
73 #include "PopupMenu.h"
74 #include "UI.h"
75
76
77
78 /************************************************************************
79  *
80  *  External and static function declarations.
81  *
82  ************************************************************************/
83  
84
85 extern void PushCB (Widget, XtPointer, XtPointer); 
86 extern void ArrowCB (Widget, XtPointer, XtPointer); 
87 extern XtTranslations HandleInputTranslations (void);
88 extern void HandleInputCB (Widget, XtPointer, XtPointer); 
89 extern void MinimizeInputCB (Widget, XtPointer, XtPointer); 
90 extern void MenuInputCB (Widget, XtPointer, XtPointer); 
91 extern void SwitchButtonCB (Widget, XtPointer, XtPointer); 
92 extern void SubpanelUnmapCB (Widget, XtPointer, XtPointer); 
93 extern void SubpanelTornEventHandler (Widget, XtPointer, XEvent *, Boolean *);
94 extern void PushRecallRegister (ControlData *, Boolean);
95 extern void EmbeddedClientRegister (ControlData *, Boolean);
96 extern void EmbeddedClientReposition (Widget, Position, Dimension);
97 extern void DropCB (Widget, XtPointer, XtPointer);
98 extern void TransferDropCB (Widget, XtPointer, XtPointer);
99 extern void CustomizeDropCB (Widget, XtPointer, XtPointer);
100 extern void CustomizeTransferDropCB (Widget, XtPointer, XtPointer);
101 extern void FrontPanelCreate (Widget);
102 extern void EmbeddedClientReparent (char *, Widget);
103 extern void DeleteControlActionList (ControlData *);
104 extern Boolean CheckOtherMonitorsOn (SubpanelData *);
105
106 static void   Initialize (DtPanelShellWidget);
107 static void   BoxCreate ();
108 static Widget PanelControlCreate (Widget, char *, String);
109 static void   MainControlCreate (int);
110 static void   SwitchCreate (BoxData *);
111 static void   SubpanelCreate (ControlData *, SubpanelData *);
112 static void   ControlCreate (Widget, ControlData **, int);
113 static void   ArrowCreate (Widget, ControlData **, int, Boolean, Boolean);
114 static void   SetupPushAnimation(ControlData *);
115 static void   SetupDropAnimation(ControlData *);
116
117 void SubpanelControlCreate (SubpanelData *, ControlData *, ControlData *,
118                                    Widget, Boolean, Boolean);
119 void SwitchButtonCreate (SwitchData *, Boolean);
120 void DeleteSubpanelControl (SubpanelData *, ControlData *);
121
122
123
124 static char DTFP_CLASS_NAME[] = "Frontpanel";
125 static char DTFP_APP_NAME[] = "frontpanel";
126
127 static XtCallbackRec dropCB[] = { {DropCB, NULL}, {NULL, NULL} };
128 static XtCallbackRec transferDropCB[] = { {TransferDropCB, NULL},{NULL, NULL} };
129 static XtCallbackRec customizeDropCB[] = { {CustomizeDropCB, NULL}, {NULL, NULL} };
130 static XtCallbackRec customizeTransferDropCB[] = { {CustomizeTransferDropCB, NULL},{NULL, NULL} };
131                                   
132
133 /************************************************************************
134  *
135  *  File local globals.
136  *
137  ************************************************************************/
138
139 String post_arrow_image = NULL;
140 String unpost_arrow_image = NULL;
141 String post_monitor_arrow_image = NULL;
142 String unpost_monitor_arrow_image = NULL;
143 String blank_arrow_image = NULL;
144 String dropzone_image = NULL;
145 String indicator_on_image = NULL;
146 String indicator_off_image = NULL;
147 String minimize_normal_image = NULL;
148 String minimize_selected_image = NULL;
149 String menu_normal_image = NULL;
150 String menu_selected_image = NULL;
151 String handle_image = NULL;
152
153 Pixmap minimize_normal_pixmap;
154 Pixmap minimize_selected_pixmap;
155 Pixmap menu_normal_pixmap;
156 Pixmap menu_selected_pixmap;
157
158 #define HARD_CODED_PRIMARY 3
159 #define _WS_HIGH_COLOR_COUNT 4
160
161 static int _ws_high_color_map[] = { 3, 5, 6, 7 };
162 static  Dimension       switch_height = 0;
163
164 /************************************************************************
165  *
166  *  FrontPanelCreate
167  *
168  ************************************************************************/
169  
170 void
171 FrontPanelCreate (Widget toplevel)
172
173
174 {
175    DtPanelShellWidget panel_shell;
176    char * panel_name = (char *) panel.element_values[PANEL_NAME].parsed_value;
177    unsigned int display_height;
178
179    Arg al[20];
180    int ac;
181
182
183    display_height = DisplayHeight (XtDisplay (toplevel), 
184                                    DefaultScreen (XtDisplay (toplevel)));
185
186    /*   Create panel shell.  */
187    
188    ac = 0;
189    XtSetArg (al[ac], XmNallowShellResize, True); ac++;
190    XtSetArg (al[ac], XmNiconY, display_height); ac++;
191    XtSetArg (al[ac], XmNmwmDecorations, MWM_DECOR_BORDER); ac++;
192    panel.shell =  XtCreatePopupShell (panel_name, dtPanelShellWidgetClass, 
193                                       toplevel, al, ac);
194
195    panel_shell = (DtPanelShellWidget) panel.shell;
196
197
198    /*   Initialize the general data into the panel structure  */
199
200    Initialize (panel_shell);
201
202
203    /*  Set pixel resources.  */
204
205    ac = 0;
206    XtSetArg (al[ac], XmNforeground, panel.inactive_pixel_set->fg);  ac++;
207    XtSetArg (al[ac], XmNbackground, panel.inactive_pixel_set->bg);  ac++;
208    XtSetArg (al[ac], XmNtopShadowColor, panel.inactive_pixel_set->ts);  ac++;
209    XtSetArg (al[ac], XmNbottomShadowColor, panel.inactive_pixel_set->bs);  ac++;
210    XtSetArg (al[ac], XmNselectColor, panel.inactive_pixel_set->sc);  ac++;
211
212
213    /*  Remove all of the tab groups  */
214
215    XtSetArg (al[ac], XmNnavigationType, XmNONE);  ac++;
216
217    /*  Create the outer form widget that will contain the entire panel  */
218    
219    panel.form = XmCreateForm (panel.shell, panel_name, al, ac);
220    XtManageChild (panel.form);
221    
222    /*  Create the handles, menu and iconify  */
223    
224    if ((Boolean) panel.element_values[PANEL_DISPLAY_HANDLES].parsed_value)
225    {
226       XtTranslations handle_translations = HandleInputTranslations();
227
228       panel.left_handle = PanelControlCreate (panel.form, "handle", handle_image);
229       panel.right_handle = PanelControlCreate (panel.form, "handle", handle_image);
230
231       XtOverrideTranslations(panel.left_handle, handle_translations);
232       XtAddCallback (panel.left_handle, XmNinputCallback,
233                      (XtCallbackProc) HandleInputCB, NULL);
234       XtAddCallback (panel.left_handle, XmNhelpCallback,
235                      (XtCallbackProc) GeneralTopicHelpCB, PANEL_HANDLE);
236
237       XtOverrideTranslations(panel.right_handle, handle_translations);
238       XtAddCallback (panel.right_handle, XmNinputCallback,
239                      (XtCallbackProc) HandleInputCB, NULL);
240       XtAddCallback (panel.right_handle, XmNhelpCallback,
241                      (XtCallbackProc) GeneralTopicHelpCB, PANEL_HANDLE);
242
243       if ((Boolean) panel.element_values[PANEL_DISPLAY_MENU].parsed_value)
244       {
245          panel.menu = PanelControlCreate (panel.form, "menu", menu_normal_image);
246
247          XtAddCallback (panel.menu, XmNinputCallback,
248                         (XtCallbackProc) MenuInputCB, NULL);
249          XtAddCallback (panel.menu, XmNhelpCallback,
250                      (XtCallbackProc) GeneralTopicHelpCB, PANEL_MENU);
251
252          ac = 0;
253          XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
254          XtSetArg (al[ac], XmNtopOffset, 1);  ac++;
255          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
256          XtSetArg (al[ac], XmNleftOffset, 1);  ac++;
257          if (panel.resolution == HIGH || panel.resolution == MEDIUM) {
258             XtSetArg (al[ac], XmNwidth, 21);  ac++;
259             XtSetArg (al[ac], XmNheight, 15);  ac++;
260          } else {
261             XtSetArg (al[ac], XmNwidth, 17);  ac++;
262             XtSetArg (al[ac], XmNheight, 13);  ac++;
263          }
264          XtSetValues (panel.menu, al, ac);
265
266          ac = 0;
267          XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET);  ac++;
268          XtSetArg (al[ac], XmNtopWidget, panel.menu);  ac++;
269          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
270          XtSetArg (al[ac], XmNleftOffset, 1);  ac++;
271          XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
272          XtSetArg (al[ac], XmNbottomOffset, 1);  ac++;
273          if (panel.resolution == HIGH || panel.resolution == MEDIUM) {
274             XtSetArg (al[ac], XmNwidth, 20);  ac++;
275          } else {
276             XtSetArg (al[ac], XmNwidth, 16);  ac++;
277          }
278          XtSetValues (panel.left_handle, al, ac);
279       }
280       else
281       {
282          panel.menu = NULL;
283
284          ac = 0;
285          XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
286          XtSetArg (al[ac], XmNtopOffset, 1);  ac++;
287          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
288          XtSetArg (al[ac], XmNleftOffset, 1);  ac++;
289          XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
290          XtSetArg (al[ac], XmNbottomOffset, 1);  ac++;
291          if (panel.resolution == HIGH || panel.resolution == MEDIUM) {
292             XtSetArg (al[ac], XmNwidth, 20);  ac++;
293          } else {
294             XtSetArg (al[ac], XmNwidth, 16);  ac++;
295          }
296          XtSetValues (panel.left_handle, al, ac);
297       }
298
299       if ((Boolean) panel.element_values[PANEL_DISPLAY_MINIMIZE].parsed_value)
300       {
301          panel.iconify = 
302             PanelControlCreate (panel.form, "minimize", minimize_normal_image);
303
304          XtAddCallback (panel.iconify, XmNinputCallback,
305                         (XtCallbackProc) MinimizeInputCB, NULL);
306          XtAddCallback (panel.iconify, XmNhelpCallback,
307                      (XtCallbackProc) GeneralTopicHelpCB, PANEL_ICONIFY);
308
309          ac = 0;
310          XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
311          XtSetArg (al[ac], XmNtopOffset, 1);  ac++;
312          XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
313          XtSetArg (al[ac], XmNrightOffset, 1);  ac++;
314          if (panel.resolution == HIGH || panel.resolution == MEDIUM) {
315             XtSetArg (al[ac], XmNwidth, 21);  ac++;
316             XtSetArg (al[ac], XmNheight, 15);  ac++;
317          } else {
318             XtSetArg (al[ac], XmNwidth, 17);  ac++;
319             XtSetArg (al[ac], XmNheight, 13);  ac++;
320          }
321          XtSetValues (panel.iconify, al, ac);
322
323          ac = 0;
324          XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET);  ac++;
325          XtSetArg (al[ac], XmNtopWidget, panel.iconify);  ac++;
326          XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
327          XtSetArg (al[ac], XmNrightOffset, 1);  ac++;
328          XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
329          XtSetArg (al[ac], XmNbottomOffset, 1);  ac++;
330          if (panel.resolution == HIGH || panel.resolution == MEDIUM) {
331             XtSetArg (al[ac], XmNwidth, 20);  ac++;
332          } else {
333             XtSetArg (al[ac], XmNwidth, 16);  ac++;
334          }
335          XtSetValues (panel.right_handle, al, ac);
336       }
337       else
338       {
339          panel.iconify = NULL;
340
341          ac = 0;
342          XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
343          XtSetArg (al[ac], XmNtopOffset, 1);  ac++;
344          XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
345          XtSetArg (al[ac], XmNrightOffset, 1);  ac++;
346          XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
347          XtSetArg (al[ac], XmNbottomOffset, 1);  ac++;
348          if (panel.resolution == HIGH || panel.resolution == MEDIUM) {
349             XtSetArg (al[ac], XmNwidth, 20);  ac++;
350          } else {
351             XtSetArg (al[ac], XmNwidth, 16);  ac++;
352          }
353          XtSetValues (panel.right_handle, al, ac);
354       }
355    }
356    else
357    {
358       panel.left_handle = NULL;
359       panel.right_handle = NULL;
360    }
361
362
363    /*  Create all of the boxes.  This function, in turn, creates  */
364    /*  all of the controls, switch, subpanels.                    */
365    
366    BoxCreate ();   
367
368
369    /*   Manage the front panel to get it created and layed out  */
370
371    XtSetMappedWhenManaged (panel.shell, False);
372    XtManageChild (panel.shell);
373 }
374
375
376
377
378 /************************************************************************
379  *
380  *  Initialize
381  *      Get all of the default data needed for the panel and put it into
382  *      the panel structure.
383  *
384  ************************************************************************/
385  
386 static void 
387 Initialize (DtPanelShellWidget panel_shell)
388
389
390 {
391    Screen  * screen = XtScreen (panel_shell);
392    Display * display = XtDisplay (panel_shell);
393
394    Pixmap busy_pixmap;
395    Pixmap busy_pixmap_mask;
396    XColor xcolors[2];
397
398    Pixel black_pixel = BlackPixelOfScreen (screen);
399    Pixel white_pixel = WhitePixelOfScreen (screen);
400
401    Boolean use_mask_return;
402    Boolean use_icon_file_cache_return;
403
404    short active, inactive, primary, secondary;
405
406    int color_use, resolution;
407    unsigned int size;
408     
409
410    /*  Create busy cursor.  */
411
412    xcolors[0].pixel = black_pixel;
413    xcolors[1].pixel = white_pixel;
414
415    XQueryColors (display, DefaultColormapOfScreen (screen), xcolors, 2);
416    busy_pixmap = 
417       XCreateBitmapFromData (display, RootWindowOfScreen (screen),
418                              (char *)time16_bits, time16_width, time16_height);
419    busy_pixmap_mask = 
420       XCreateBitmapFromData (display, RootWindowOfScreen (screen),
421                              (char *)time16m_bits, time16_width, time16_height);
422
423    panel.busy_cursor = 
424       XCreatePixmapCursor (display, busy_pixmap, busy_pixmap_mask,
425                            &(xcolors[0]), &(xcolors[1]),
426                            time16_x_hot, time16_y_hot);
427
428    XFreePixmap (display, busy_pixmap);
429    XFreePixmap (display, busy_pixmap_mask);
430
431    
432    panel.resolution = (int) panel.element_values[PANEL_RESOLUTION].parsed_value;
433
434    /*   Extract and validate resolution.  */
435    
436    if (panel.resolution == MATCH_DISPLAY ||
437        (panel.resolution != HIGH &&
438         panel.resolution != MEDIUM &&
439         panel.resolution != LOW))
440    {
441       resolution =
442           _DtGetDisplayResolution (display, XScreenNumberOfScreen(screen));
443
444       switch (resolution)
445       {
446         case HIGH_RES_DISPLAY:
447                 panel.resolution = HIGH;
448         break;
449          
450         case MED_RES_DISPLAY:
451                 panel.resolution = MEDIUM;
452         break;
453          
454         case LOW_RES_DISPLAY:
455         case NO_RES_DISPLAY:
456                 panel.resolution = LOW;
457         break;
458       } 
459    }
460
461    if (panel.resolution == HIGH || panel.resolution == MEDIUM)
462    {
463       panel.main_icon_size = DtLARGE;
464       panel.sub_icon_size = DtMEDIUM;
465       panel.switch_icon_size = DtSMALL;
466    }
467    else
468    {
469       panel.main_icon_size = DtMEDIUM;
470       panel.sub_icon_size = DtTINY;
471       panel.switch_icon_size = DtTINY;
472    }
473
474
475    /*  Set the font list based on the screen resolution  */
476
477    switch(panel.resolution) {
478         case HIGH:
479                 panel.font_list = S_HighResFontList (panel_shell);
480                 panel.date_font_list = S_MediumResFontList (panel_shell);
481                 break;
482
483         case MEDIUM:
484                 panel.font_list = S_MediumResFontList (panel_shell);
485                 panel.date_font_list = S_MediumResFontList (panel_shell);
486                 break;
487
488         case LOW:
489                 panel.font_list = S_LowResFontList (panel_shell);
490                 panel.date_font_list = S_LowResFontList (panel_shell);
491                 break;
492    }
493
494    /* initialize popup_data to NULL */
495    panel.popup_data = NULL; 
496
497    /*  See if using bitonal or multicolor icons.  If bitonal, set the  */
498    /*  pixel set to black and white based on the colors of the parent  */
499    /*  If color, use the color obj to get the color pixel set.         */
500
501    XmeGetIconControlInfo (screen,
502                           &use_mask_return, &panel.use_color_icons,
503                           &use_icon_file_cache_return);
504
505    panel.pixel_set = (XmPixelSet *) 
506      XtMalloc (sizeof(XmPixelSet) * XmCO_NUM_COLORS);
507
508    if (XmeGetPixelData (XScreenNumberOfScreen (screen), 
509                         &color_use, panel.pixel_set, 
510                         &active, &inactive, &primary, &secondary))
511    {
512       panel.color_use = color_use;
513       panel.active_pixel_set = &(panel.pixel_set[active]);
514       panel.inactive_pixel_set = &(panel.pixel_set[inactive]);
515       panel.primary_pixel_set = &(panel.pixel_set[primary]);
516       panel.secondary_pixel_set = &(panel.pixel_set[secondary]);
517    }
518    else
519    {                    
520       XtFree ((char *) panel.pixel_set);
521    
522       panel.pixel_set = (XmPixelSet *) XtMalloc (sizeof (XmPixelSet));
523       panel.active_pixel_set = &(panel.pixel_set[0]);
524       panel.pixel_set_count = 1;
525
526       panel.active_pixel_set->bg = panel_shell->core.background_pixel;
527
528       if (panel.active_pixel_set->bg == black_pixel)
529       {
530          panel.active_pixel_set->fg = white_pixel;
531          panel.active_pixel_set->bg = black_pixel;
532          panel.active_pixel_set->ts = white_pixel;
533          panel.active_pixel_set->bs = white_pixel;
534          panel.active_pixel_set->sc = black_pixel;
535          panel.color_use = XmCO_BLACK_WHITE;
536       }
537       else
538       {
539          if (panel.active_pixel_set->bg == white_pixel)
540          {
541             panel.active_pixel_set->fg = black_pixel;
542             panel.active_pixel_set->bg = white_pixel;
543             panel.active_pixel_set->ts = black_pixel;
544             panel.active_pixel_set->bs = black_pixel;
545             panel.active_pixel_set->sc = white_pixel;
546             panel.color_use = XmCO_BLACK_WHITE;
547          }
548          else
549          {
550            /*  Get the Motif defaults and assign into a single allocated  */
551            /*  pixel set which is then referenced throught the other 3    */
552            /*  pixel set datas.                                           */
553
554             XmGetColors (screen, DefaultColormapOfScreen (screen), 
555                          panel.active_pixel_set->bg,
556                          &(panel.active_pixel_set->fg), 
557                          &(panel.active_pixel_set->ts),
558                          &(panel.active_pixel_set->bs), 
559                          &(panel.active_pixel_set->sc));
560
561             panel.color_use = XmCO_LOW_COLOR;
562          }
563       }
564
565       panel.inactive_pixel_set = panel.active_pixel_set;
566       panel.primary_pixel_set = panel.active_pixel_set;
567       panel.secondary_pixel_set = panel.active_pixel_set;
568    }
569
570
571    /*  Initialize other panel specific information  */
572    
573    panel.busy_light_data = NULL;
574
575    panel.push_recall_list = NULL;
576    panel.push_recall_count = 0;
577    panel.max_push_recall_count = 0;
578
579    panel.embedded_client_list = NULL;
580    panel.embedded_client_count = 0;
581    panel.max_embedded_client_count = 0;
582    
583    panel.dynamic_data_list = NULL;
584    panel.dynamic_data_count = 0;
585    panel.max_dynamic_data_count = 0;
586
587
588    /*  Get the names of the predefined images  */
589
590    /*  Get icon size.  */
591
592
593   /* main panel icons */
594    size = panel.main_icon_size;
595
596    post_arrow_image = GetIconName (UP_ARROW_IMAGE_NAME, size);
597    unpost_arrow_image = GetIconName (DOWN_ARROW_IMAGE_NAME, size);
598    post_monitor_arrow_image = GetIconName (UP_MONITOR_ARROW_IMAGE_NAME, size);
599    unpost_monitor_arrow_image= GetIconName(DOWN_MONITOR_ARROW_IMAGE_NAME, size);
600    blank_arrow_image = GetIconName (BLANK_ARROW_IMAGE_NAME, size);
601    minimize_normal_image = GetIconName (MINIMIZE_NORMAL_IMAGE_NAME, size);
602    minimize_selected_image = GetIconName (MINIMIZE_SELECTED_IMAGE_NAME, size);
603    menu_normal_image = GetIconName (MENU_NORMAL_IMAGE_NAME, size);
604    menu_selected_image = GetIconName (MENU_SELECTED_IMAGE_NAME, size);
605    handle_image = GetIconName (HANDLE_IMAGE_NAME, DtLARGE);
606
607   /* subpanel icons */
608    size = panel.sub_icon_size;
609
610    indicator_off_image = GetIconName (INDICATOR_OFF_IMAGE_NAME, size);
611    indicator_on_image = GetIconName (INDICATOR_ON_IMAGE_NAME, size);
612    dropzone_image = GetIconName (DROPZONE_IMAGE_NAME, size);
613 }
614
615
616
617
618 /************************************************************************
619  *
620  *  PanelControlCreate
621  *      Create the handles, menu or iconify buttons attached to the panel.
622  *
623  ************************************************************************/
624
625 static Widget
626 PanelControlCreate (Widget parent, 
627                     char * control_name,
628                     String image_name)
629
630
631 {
632    Widget w;
633    Pixmap pixmap;
634
635    Pixel fg, bg;
636
637    Arg al[15];
638    int ac;
639
640    if (panel.color_use != XmCO_BLACK_WHITE)
641    {
642      /*      Use background for color set matching.
643       *      Use top shadow for clock hand color.
644       */
645       fg = panel.inactive_pixel_set->ts;
646       bg = panel.inactive_pixel_set->bg;
647    }
648    else
649    {
650       fg = BlackPixelOfScreen (XtScreen (panel.form));
651       bg = WhitePixelOfScreen (XtScreen (panel.form));
652    }
653
654    pixmap = XmGetPixmap (XtScreen (parent), image_name, fg, bg);
655
656    if (strcmp (control_name, "minimize") == 0)
657    {
658       minimize_normal_pixmap = pixmap;
659       minimize_selected_pixmap = 
660          XmGetPixmap (XtScreen (parent), minimize_selected_image, fg, bg);
661    }
662    else if (strcmp (control_name, "menu") == 0)
663    {
664       menu_normal_pixmap = pixmap;
665       menu_selected_pixmap = 
666          XmGetPixmap (XtScreen (parent), menu_selected_image, fg, bg);
667    }
668
669
670    ac = 0;
671    XtSetArg (al[ac], XmNforeground, fg);                ac++;
672    XtSetArg (al[ac], XmNbackground, bg);                ac++;
673    XtSetArg (al[ac], XmNwidth, 11);                     ac++;
674    XtSetArg (al[ac], XmNshadowThickness, 0);            ac++;
675    XtSetArg (al[ac], XmNborderWidth, 0);                ac++;
676    XtSetArg (al[ac], XmNbackgroundPixmap, pixmap);      ac++;
677    XtSetArg (al[ac], XmNtraversalOn, False);            ac++;
678    XtSetArg (al[ac], XmNnavigationType, XmNONE);        ac++;
679
680
681    w = XmCreateDrawingArea (parent, control_name, al, ac);
682    XtManageChild (w);
683
684    return (w);
685 }
686
687
688
689
690 /************************************************************************
691  *
692  *  BoxCreate
693  *      Create all of the boxes defined within the panel data structure.
694  *
695  ************************************************************************/
696
697 static void
698 BoxCreate ()
699
700
701 {
702    int i, j;
703    BoxData * box_data;
704    BoxData * switch_box_data = NULL;
705    Widget    prev_form;
706    int switch_position = POSITION_FIRST;
707
708    Pixmap pixmap;
709
710    Arg al[40];
711    int ac;
712
713
714    /*  Loop through the panels boxes, creating the set outer forms    */
715    /*  necessary to hold the inner forms for the controls, arrows...  */
716
717    prev_form = NULL;
718
719    for (i = 0; i < panel.box_data_count; i++)
720    {
721       box_data = panel.box_data[i];
722
723
724       /*  Create the outer box form which will contain the inner box set  */
725       
726       ac = 0;
727       XtSetArg (al[ac], XmNshadowThickness, 0);  ac++;
728
729       if (panel.left_handle != NULL)
730       {
731          XtSetArg (al[ac], XmNrightAttachment, XmATTACH_WIDGET);  ac++;
732          XtSetArg (al[ac], XmNrightWidget, panel.right_handle);  ac++;
733          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET);  ac++;
734          XtSetArg (al[ac], XmNleftWidget, panel.left_handle);  ac++;
735       }
736       else
737       {
738          XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
739          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
740       }
741
742       if (prev_form != NULL)
743       {
744          XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET);  ac++;
745          XtSetArg (al[ac], XmNtopWidget, prev_form);  ac++;
746       }
747       else
748       {
749          XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
750          XtSetArg (al[ac], XmNtopOffset, 1);  ac++;
751       }
752
753       if (i == panel.box_data_count - 1)
754       {
755          XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
756          XtSetArg (al[ac], XmNbottomOffset, 1);  ac++;
757       }
758
759       if (panel.color_use == XmCO_BLACK_WHITE)
760       {
761          XtSetArg (al[ac], XmNbottomShadowColor,
762                            BlackPixelOfScreen (XtScreen (panel.shell))); ac++;
763       }
764
765       /*  Remove all of the tab groups  */
766
767       XtSetArg (al[ac], XmNnavigationType, XmNONE);  ac++;
768
769
770       XtSetArg (al[ac], XmNbackground, panel.primary_pixel_set->bg);    ac++;
771       XtSetArg (al[ac], XmNforeground, panel.primary_pixel_set->fg);    ac++;
772
773       /*  Create the outer form widget that will contain the entire panel  */
774    
775       box_data->form = 
776          XmCreateForm (panel.form, 
777                        (char *) box_data->element_values[BOX_NAME].parsed_value,
778                         al, ac);
779       XtManageChild (box_data->form);
780
781       prev_form = box_data->form;
782    }
783
784
785    /*  Loop through the panels boxes, creating the set of forms needed    */
786    /*  to contain the controls, arrows, or switch within the front panel  */
787
788    for (i = 0; i < panel.box_data_count; i++)
789    {
790       box_data = panel.box_data[i];
791
792       if (box_data->switch_data != NULL)
793       {
794          switch_box_data = box_data;
795          
796          ac = 0;
797          XtSetArg (al[ac], XmNshadowThickness, 1);  ac++;
798          XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
799          XtSetArg (al[ac], XmNtopOffset, 0);  ac++;
800          XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
801          XtSetArg (al[ac], XmNbottomOffset, 0);  ac++;
802
803          switch_position = 
804             (int) box_data->switch_data->element_values[SWITCH_POSITION_HINTS].parsed_value;
805
806
807          /*  Determine if the defined switch position is actually the  */
808          /*  first or last position.                                   */
809
810          if (switch_position != POSITION_FIRST || switch_position != POSITION_LAST)
811          {
812             for (j = 0; j < box_data->control_data_count; j++)
813             {
814                if (switch_position < (int) ((box_data->control_data[j])->element_values[CONTROL_POSITION_HINTS].parsed_value))
815                   break;
816             }
817
818             if (j == 0)
819                switch_position = POSITION_FIRST;
820             else if (j == box_data->control_data_count)
821                switch_position = POSITION_LAST;
822          }
823
824          if (switch_position == POSITION_FIRST)
825          {
826             XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
827             XtSetArg (al[ac], XmNleftOffset, 0);  ac++;
828          }
829
830          if (switch_position == POSITION_LAST ||
831              box_data->control_data_count == 0)
832          {
833             XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
834             XtSetArg (al[ac], XmNrightOffset, 0);  ac++;
835          }
836
837          XtSetArg (al[ac], XmNuserData, SWITCH); ac++;
838
839
840          /*  Remove all of the tab groups  */
841
842          XtSetArg (al[ac], XmNnavigationType, XmNONE);  ac++;
843
844          if (panel.color_use == XmCO_BLACK_WHITE)
845          {
846             XtSetArg (al[ac], XmNbottomShadowColor,
847                               BlackPixelOfScreen (XtScreen (panel.form))); ac++;
848
849             pixmap = XmGetPixmap (XtScreen (panel.form), "50_foreground",
850                                   panel.inactive_pixel_set->fg,
851                                   panel.inactive_pixel_set->bg);
852
853             XtSetArg (al[ac], XmNbackgroundPixmap, pixmap);  ac++;
854          }
855
856          XtSetArg (al[ac], XmNbackground, panel.primary_pixel_set->bg); ac++;
857          XtSetArg (al[ac], XmNforeground, panel.primary_pixel_set->fg); ac++;
858
859          box_data->switch_form =  
860             XmCreateForm (box_data->form, "switch", al, ac);
861          XtManageChild (box_data->switch_form);
862
863          XtAddCallback (box_data->switch_form, XmNhelpCallback,
864                         (XtCallbackProc) SwitchTopicHelpCB,
865                         box_data->switch_data);
866
867          if (box_data->control_data_count == 0) 
868             continue;
869       }
870
871
872       /*  Create the arrow boxes  */
873
874       if (box_data->switch_form != NULL)
875       {
876          if (switch_position == POSITION_FIRST)
877          {
878             ac = 0;
879             XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET);  ac++;
880             XtSetArg (al[ac], XmNleftWidget, box_data->switch_form);  ac++;
881             XtSetArg (al[ac], XmNleftOffset, -4);  ac++;
882             XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
883             XtSetArg (al[ac], XmNtopOffset, 0);  ac++;
884             XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
885             XtSetArg (al[ac], XmNrightOffset, 0);  ac++;
886
887          }
888          else if (switch_position == POSITION_LAST)
889          {
890             ac = 0;
891             XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
892             XtSetArg (al[ac], XmNleftOffset, 0);  ac++;
893             XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
894             XtSetArg (al[ac], XmNtopOffset, 0);  ac++;
895             XtSetArg (al[ac], XmNrightAttachment, XmATTACH_WIDGET);  ac++;
896             XtSetArg (al[ac], XmNrightWidget, box_data->switch_form);  ac++;
897             XtSetArg (al[ac], XmNrightOffset, 0);  ac++;
898
899          }
900          else
901          {
902             ac = 0;
903             XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET);  ac++;
904             XtSetArg (al[ac], XmNleftWidget, box_data->switch_form);  ac++;
905             XtSetArg (al[ac], XmNleftOffset, -6);  ac++;
906             XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
907             XtSetArg (al[ac], XmNtopOffset, 0);  ac++;
908             XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
909             XtSetArg (al[ac], XmNrightOffset, 0);  ac++;
910
911             XtSetArg (al[ac], XmNbackground, panel.inactive_pixel_set->bg);     ac++;
912             XtSetArg (al[ac], XmNforeground, panel.inactive_pixel_set->fg);     ac++;
913             XtSetArg (al[ac], XmNtopShadowColor, panel.inactive_pixel_set->ts); ac++;
914             XtSetArg (al[ac], XmNselectColor, panel.inactive_pixel_set->sc);    ac++;
915
916             if (panel.color_use == XmCO_BLACK_WHITE)
917             {
918                XtSetArg (al[ac], XmNbottomShadowColor,
919                          BlackPixelOfScreen (XtScreen (panel.form))); ac++;
920
921                pixmap = XmGetPixmap (XtScreen (panel.form), "50_foreground",
922                                      panel.inactive_pixel_set->fg,
923                                      panel.inactive_pixel_set->bg);
924
925                XtSetArg (al[ac], XmNbackgroundPixmap, pixmap);  ac++;
926             }
927             else
928             {
929                XtSetArg (al[ac], XmNbottomShadowColor,
930                                  panel.inactive_pixel_set->bs); ac++;
931             }
932
933
934             /*  Remove all of the tab groups  */
935
936             XtSetArg (al[ac], XmNnavigationType, XmNONE);  ac++;
937
938
939             if (i == 0)
940             {
941                 XtSetArg (al[ac], XmNshadowThickness, 0);  ac++;
942             }
943             else
944             {
945                XtSetArg (al[ac], XmNshadowThickness, 1);  ac++;  
946             }
947
948             box_data->right_arrow_form = 
949                XmCreateForm (box_data->form, "right_arrow_form", al, ac);
950
951             if (box_data->subpanel_count != 0)
952                XtManageChild (box_data->right_arrow_form);
953
954             XtAddCallback (box_data->right_arrow_form, XmNhelpCallback,
955                            (XtCallbackProc) GeneralTopicHelpCB,
956                            SUBPANEL_ACCESS_AREA);
957
958             ac = 0;
959             XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
960             XtSetArg (al[ac], XmNleftOffset, 0);  ac++;
961             XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
962             XtSetArg (al[ac], XmNtopOffset, 0);  ac++;
963             XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
964             XtSetArg (al[ac], XmNrightOffset, -2);  ac++;
965          }
966       }
967       else
968       {
969          ac = 0;
970          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
971          XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
972          XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
973
974          if (i == 0)
975          {
976             XtSetArg (al[ac], XmNtopOffset, 1);  ac++;
977             XtSetArg (al[ac], XmNleftOffset, 1);  ac++;
978             XtSetArg (al[ac], XmNrightOffset, 1);  ac++;
979          }
980          else
981          {
982             XtSetArg (al[ac], XmNtopOffset, 0);  ac++;
983             XtSetArg (al[ac], XmNleftOffset, 0);  ac++;
984             XtSetArg (al[ac], XmNrightOffset, 0);  ac++;
985          }
986       }
987
988       XtSetArg(al[ac], XmNbackground, panel.inactive_pixel_set->bg); ac++;
989       XtSetArg(al[ac], XmNforeground, panel.inactive_pixel_set->fg); ac++;
990       XtSetArg(al[ac], XmNtopShadowColor, panel.inactive_pixel_set->ts);ac++;
991       XtSetArg(al[ac], XmNselectColor, panel.inactive_pixel_set->sc); ac++;
992
993       if (panel.color_use == XmCO_BLACK_WHITE)
994       {
995          XtSetArg (al[ac], XmNbottomShadowColor,
996                    BlackPixelOfScreen (XtScreen (panel.form))); ac++;
997
998          pixmap = XmGetPixmap (XtScreen (panel.form), "50_foreground",
999                                panel.inactive_pixel_set->fg,
1000                                panel.inactive_pixel_set->bg);
1001
1002          XtSetArg (al[ac], XmNbackgroundPixmap, pixmap);  ac++;
1003       }
1004       else
1005       {
1006          XtSetArg (al[ac], XmNbottomShadowColor,
1007                            panel.inactive_pixel_set->bs); ac++;
1008       }
1009
1010
1011       /*  Remove all of the tab groups  */
1012
1013       XtSetArg (al[ac], XmNnavigationType, XmNONE);  ac++;
1014
1015       if (i == 0)
1016       {
1017          XtSetArg (al[ac], XmNshadowThickness, 0);  ac++;
1018       }
1019       else
1020       {
1021          XtSetArg (al[ac], XmNshadowThickness, 1);  ac++;  
1022       }
1023
1024
1025       box_data->left_arrow_form = 
1026          XmCreateForm (box_data->form, "left_arrow_form", al, ac);
1027
1028       if (box_data->subpanel_count != 0)
1029          XtManageChild (box_data->left_arrow_form);
1030
1031       XtAddCallback (box_data->left_arrow_form, XmNhelpCallback,
1032                      (XtCallbackProc) GeneralTopicHelpCB,
1033                      SUBPANEL_ACCESS_AREA);
1034
1035
1036       /*  Now create the control boxes  */
1037       
1038       if (box_data->switch_form != NULL)
1039       {
1040          if (switch_position == POSITION_FIRST ||
1041              switch_position == POSITION_LAST)
1042          {
1043             ac = 0;
1044             XtSetArg (al[ac], XmNshadowThickness, 1);  ac++;
1045
1046             if (switch_position == POSITION_FIRST)
1047             {
1048                XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET);  ac++;
1049                XtSetArg (al[ac], XmNleftWidget, box_data->switch_form);  ac++;
1050                XtSetArg (al[ac], XmNleftOffset, -4);  ac++;
1051                XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
1052                XtSetArg (al[ac], XmNrightOffset, 0);  ac++;
1053             }
1054             else
1055             {
1056                XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
1057                XtSetArg (al[ac], XmNleftOffset, 0);  ac++;
1058                XtSetArg (al[ac], XmNrightAttachment, XmATTACH_WIDGET);  ac++;
1059                XtSetArg (al[ac], XmNrightWidget, box_data->switch_form);  ac++;
1060                XtSetArg (al[ac], XmNrightOffset, 0);  ac++;
1061             }
1062
1063             if (XtIsManaged(box_data->left_arrow_form))
1064             {
1065                XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET);  ac++;
1066                XtSetArg (al[ac], XmNtopWidget, box_data->left_arrow_form);  ac++;
1067             }
1068             else
1069             {
1070                XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
1071                XtSetArg (al[ac], XmNtopOffset, 0);  ac++;
1072             }
1073
1074             XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
1075             XtSetArg (al[ac], XmNbottomOffset, 0);  ac++;
1076
1077             XtSetArg (al[ac], XmNuserData, CONTROL); ac++;
1078
1079
1080             /*  Remove all of the tab groups  */
1081
1082             XtSetArg (al[ac], XmNnavigationType, XmNONE);  ac++;
1083
1084             if (panel.color_use == XmCO_BLACK_WHITE)
1085             {
1086                pixmap = XmGetPixmap (XtScreen (panel.form), "50_foreground",
1087                                      panel.inactive_pixel_set->fg,
1088                                      panel.inactive_pixel_set->bg);
1089
1090                XtSetArg (al[ac], XmNbackgroundPixmap, pixmap);  ac++;
1091             }
1092
1093             XtSetArg (al[ac], XmNbackground, panel.primary_pixel_set->bg); ac++;
1094             XtSetArg (al[ac], XmNforeground, panel.primary_pixel_set->fg); ac++;
1095
1096             box_data->left_control_form = 
1097                XmCreateForm (box_data->form, "left_control_form", al, ac);
1098             XtManageChild (box_data->left_control_form);
1099          }
1100          else
1101          {
1102             ac = 0;
1103             XtSetArg (al[ac], XmNshadowThickness, 1);  ac++;
1104             XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
1105             XtSetArg (al[ac], XmNleftOffset, 0);  ac++;
1106
1107             if (XtIsManaged (box_data->left_arrow_form))
1108             {
1109                XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET);  ac++;
1110                XtSetArg (al[ac], XmNtopWidget, box_data->left_arrow_form);  ac++;
1111             }
1112             else
1113             {
1114                XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
1115                XtSetArg (al[ac], XmNtopOffset, 0);  ac++;
1116             }
1117
1118             XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
1119             XtSetArg (al[ac], XmNbottomOffset, 0);  ac++;
1120
1121             XtSetArg (al[ac], XmNuserData, CONTROL); ac++;
1122
1123
1124             /*  Remove all of the tab groups  */
1125
1126             XtSetArg (al[ac], XmNnavigationType, XmNONE);  ac++;
1127
1128             if (panel.color_use == XmCO_BLACK_WHITE)
1129             {
1130                pixmap = XmGetPixmap (XtScreen (panel.form), "50_foreground",
1131                                      panel.inactive_pixel_set->fg,
1132                                      panel.inactive_pixel_set->bg);
1133
1134                XtSetArg (al[ac], XmNbackgroundPixmap, pixmap);  ac++;
1135             }
1136
1137             XtSetArg (al[ac], XmNbackground, panel.primary_pixel_set->bg); ac++;
1138             XtSetArg (al[ac], XmNforeground, panel.primary_pixel_set->fg); ac++;
1139
1140             box_data->left_control_form =
1141                XmCreateForm (box_data->form, "left_control_form", al, ac);
1142             XtManageChild (box_data->left_control_form);
1143                
1144             ac = 0;
1145             XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET);         ac++;
1146             XtSetArg (al[ac], XmNleftWidget, box_data->left_control_form); ac++;
1147             XtSetArg (al[ac], XmNleftOffset, -3);                          ac++;
1148             XtSetValues (box_data->switch_form, al, ac);
1149
1150
1151             ac = 0;
1152             XtSetArg (al[ac], XmNshadowThickness, 1);  ac++;
1153             XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET);  ac++;
1154             XtSetArg (al[ac], XmNleftWidget, box_data->switch_form);  ac++;
1155             XtSetArg (al[ac], XmNleftOffset, -4);  ac++;
1156             XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
1157             XtSetArg (al[ac], XmNrightOffset, 0);  ac++;
1158
1159             if (XtIsManaged(box_data->right_arrow_form))
1160             {
1161                XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET);  ac++;
1162                XtSetArg (al[ac], XmNtopWidget, box_data->right_arrow_form);  ac++;
1163             }
1164             else
1165             {
1166                XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
1167                XtSetArg (al[ac], XmNtopOffset, 0);  ac++;
1168             }
1169
1170             XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
1171             XtSetArg (al[ac], XmNbottomOffset, 0);  ac++;
1172
1173             XtSetArg (al[ac], XmNuserData, CONTROL); ac++;
1174
1175
1176             /*  Remove all of the tab groups  */
1177
1178             XtSetArg (al[ac], XmNnavigationType, XmNONE);  ac++;
1179
1180             if (panel.color_use == XmCO_BLACK_WHITE)
1181             {
1182                pixmap = XmGetPixmap (XtScreen (panel.form), "50_foreground",
1183                                      panel.inactive_pixel_set->fg,
1184                                      panel.inactive_pixel_set->bg);
1185
1186                XtSetArg (al[ac], XmNbackgroundPixmap, pixmap);  ac++;
1187             }
1188
1189             XtSetArg (al[ac], XmNbackground, panel.primary_pixel_set->bg); ac++;
1190             XtSetArg (al[ac], XmNforeground, panel.primary_pixel_set->fg); ac++;
1191
1192             box_data->right_control_form = 
1193                XmCreateForm (box_data->form, "right_control_form", al, ac);
1194             XtManageChild (box_data->right_control_form);
1195          }
1196       }
1197       else
1198       {
1199          ac = 0;
1200          XtSetArg (al[ac], XmNshadowThickness, 1);  ac++;
1201          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
1202          XtSetArg (al[ac], XmNleftOffset, 0);  ac++;
1203          XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
1204          XtSetArg (al[ac], XmNrightOffset, 0);  ac++;
1205          XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
1206          XtSetArg (al[ac], XmNbottomOffset, 0);  ac++;
1207
1208          if (XtIsManaged(box_data->left_arrow_form))
1209          {
1210             XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET);  ac++;
1211             XtSetArg (al[ac], XmNtopWidget, box_data->left_arrow_form);  ac++;
1212          }
1213          else
1214          {
1215             XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
1216             XtSetArg (al[ac], XmNtopOffset, 0);  ac++;
1217          }
1218
1219          XtSetArg (al[ac], XmNuserData, CONTROL); ac++;
1220
1221
1222          /*  Remove all of the tab groups  */
1223
1224          XtSetArg (al[ac], XmNnavigationType, XmNONE);  ac++;
1225
1226          if (panel.color_use == XmCO_BLACK_WHITE)
1227          {
1228             pixmap = XmGetPixmap (XtScreen (panel.form), "50_foreground",
1229                                   panel.inactive_pixel_set->fg,
1230                                   panel.inactive_pixel_set->bg);
1231
1232             XtSetArg (al[ac], XmNbackgroundPixmap, pixmap);  ac++;
1233          }
1234
1235          XtSetArg (al[ac], XmNbackground, panel.primary_pixel_set->bg); ac++;
1236          XtSetArg (al[ac], XmNforeground, panel.primary_pixel_set->fg); ac++;
1237
1238          box_data->left_control_form = 
1239             XmCreateForm (box_data->form, "left_control_form", al, ac);
1240          XtManageChild (box_data->left_control_form);
1241       }
1242
1243       if (box_data->left_control_form != NULL)
1244       {
1245          if (panel.popup_data == NULL || panel.popup_data->popup == NULL)
1246             CreatePopupMenu(box_data->left_control_form);
1247          else
1248             XmAddToPostFromList(panel.popup_data->popup,
1249                                 box_data->left_control_form);
1250
1251
1252          /* Event handler for posting popup menu */
1253
1254          XtAddEventHandler(box_data->left_control_form, ButtonPressMask, False,
1255                            (XtEventHandler) PostPopupMenu, (XtPointer) NULL);
1256       }
1257
1258       if (box_data->right_control_form != NULL)
1259       {
1260          if (panel.popup_data == NULL || panel.popup_data->popup == NULL)
1261             CreatePopupMenu(box_data->right_control_form);
1262          else
1263             XmAddToPostFromList(panel.popup_data->popup,
1264                                 box_data->right_control_form);
1265
1266
1267          /* Event handler for posting popup menu */
1268
1269          XtAddEventHandler(box_data->right_control_form, ButtonPressMask,False,
1270                            (XtEventHandler) PostPopupMenu, (XtPointer) NULL);
1271       }
1272    }
1273
1274
1275    /*  Once all of the boxes and switch form have been created within  */
1276    /*  the main panel, call the function to create the main panel      */
1277    /*  controls.  This function also creates the arrows.               */
1278    
1279    MainControlCreate (switch_position);
1280    
1281    
1282    /*  Call a function to create the control and button set for the switch  */
1283    
1284    if (switch_box_data != NULL)
1285       SwitchCreate (switch_box_data);
1286
1287    for (i = 0; i < panel.box_data_count; i++)
1288    {
1289       box_data = panel.box_data[i];
1290
1291       if (box_data->switch_data != NULL)
1292       {
1293          if (box_data->switch_form != NULL)
1294          {
1295             if (box_data->switch_data->popup_data == NULL ||
1296                 box_data->switch_data->popup_data->popup == NULL)
1297                CreateWorkspacePopupMenu (box_data->switch_form,
1298                                          box_data->switch_data);
1299             else
1300                XmAddToPostFromList (box_data->switch_data->popup_data->popup,
1301                                     box_data->switch_form);
1302
1303              /* Event handler for posting popup menu */
1304
1305              XtAddEventHandler (box_data->switch_form, ButtonPressMask,
1306                                 False,
1307                                 (XtEventHandler) PostWorkspacePopupMenu,
1308                                 (XtPointer) NULL);
1309          }
1310       }
1311    }
1312 }
1313
1314
1315
1316
1317 /************************************************************************
1318  *
1319  *  MainControlCreate
1320  *
1321  ************************************************************************/
1322  
1323 static void
1324 MainControlCreate (int switch_position)
1325
1326
1327 {
1328    int i;
1329    BoxData * box_data;
1330    Boolean   first_box;
1331    Arg al[1];
1332
1333
1334    /*  Set up a loop to go through each box and create the set of controls  */
1335    /*  subpanel arrows, and subpanels for each box.                         */
1336
1337    for (i = 0; i < panel.box_data_count; i++)
1338    {
1339       box_data = panel.box_data[i];
1340       if (i == 0) first_box = True;
1341       else first_box = False;
1342
1343       if (box_data->control_data_count == 0)
1344          continue;
1345
1346
1347       /*  See if we need to split the control create for the box  */
1348       /*  because the switch is centered between the controls.    */
1349
1350       if (switch_position == POSITION_FIRST ||
1351           switch_position == POSITION_LAST  || 
1352           box_data->switch_form == NULL)
1353       {
1354          ControlCreate (box_data->left_control_form, box_data->control_data,
1355                         box_data->control_data_count);
1356
1357          ArrowCreate (box_data->left_arrow_form, box_data->control_data,
1358                       box_data->control_data_count, False, first_box);
1359       }
1360       else
1361       {
1362          int j;
1363          
1364          
1365          /*  Find the position within the control list that is less than  */
1366          /*  the switch position.                                         */
1367          
1368          for (j = 0; j < box_data->control_data_count; j++)
1369          {
1370             if (switch_position <
1371                 (int) ((box_data->control_data[j])->element_values[CONTROL_POSITION_HINTS].parsed_value))
1372             {
1373                ControlCreate (box_data->left_control_form, 
1374                               &box_data->control_data[0], j);
1375
1376                ControlCreate (box_data->right_control_form, 
1377                               &box_data->control_data[j],
1378                               box_data->control_data_count - j);
1379
1380                ArrowCreate (box_data->left_arrow_form, 
1381                             &box_data->control_data[0], j, False, first_box);
1382
1383                ArrowCreate (box_data->right_arrow_form, 
1384                             &box_data->control_data[j],
1385                             box_data->control_data_count - j, True, first_box);
1386                break;
1387             }
1388          }
1389       }
1390    }
1391 }
1392
1393
1394
1395
1396 /************************************************************************
1397  *
1398  *  ControlSetVisualData
1399  *      Set up the arg list elements for a controls color and font
1400  *      resources.
1401  *
1402  *  Inputs: control_data - a pointer to the control to be created
1403  *          al - a pointer to the arg list to contain the resource data
1404  *          ac - a pointer to the arg list count
1405  *
1406  ************************************************************************/
1407  
1408 static void
1409 ControlSetVisualData (ControlData * control_data,
1410                       ArgList   al,
1411                       int     * ac)
1412
1413
1414 {
1415    XtSetArg (al[*ac], XmNbackground, panel.primary_pixel_set->bg);      (*ac)++;
1416    XtSetArg (al[*ac], XmNforeground, panel.primary_pixel_set->fg);      (*ac)++;
1417
1418    if (panel.color_use == XmCO_BLACK_WHITE)
1419    {
1420       XtSetArg (al[*ac], XmNuseEmbossedText, False);  (*ac)++;
1421       XtSetArg (al[*ac], XmNarmColor, panel.primary_pixel_set->bg);   (*ac)++;
1422    }
1423    else
1424    {
1425       XtSetArg (al[*ac], XmNarmColor, panel.primary_pixel_set->sc);   (*ac)++;
1426    }
1427
1428    if (panel.use_color_icons)
1429    {
1430      /*      Use background for color set matching.
1431       *      Use top shadow for clock hand color.
1432       */
1433       XtSetArg (al[*ac], XmNpixmapBackground, panel.primary_pixel_set->bg);
1434       (*ac)++;
1435       XtSetArg (al[*ac], XmNpixmapForeground, panel.primary_pixel_set->ts);
1436       (*ac)++;
1437    }
1438    else
1439    {
1440       if (control_data != NULL &&
1441         (char) control_data->element_values[CONTROL_TYPE].parsed_value ==
1442                                                                CONTROL_CLOCK)
1443       {
1444          if (panel.color_use != XmCO_BLACK_WHITE)
1445          {
1446            XtSetArg (al[*ac], XmNpixmapForeground, panel.primary_pixel_set->fg);
1447            (*ac)++;
1448            XtSetArg(al[*ac], XmNpixmapBackground, panel.primary_pixel_set->bg);
1449            (*ac)++;
1450          }
1451          else
1452          {
1453            XtSetArg (al[*ac], XmNpixmapForeground,
1454                         BlackPixelOfScreen (XtScreen (panel.form)));  (*ac)++;
1455            XtSetArg (al[*ac], XmNpixmapBackground,
1456                         WhitePixelOfScreen (XtScreen (panel.form)));  (*ac)++;
1457          }
1458       }
1459       else
1460       {
1461          XtSetArg (al[*ac], XmNpixmapBackground,
1462                         WhitePixelOfScreen (XtScreen (panel.form)));  (*ac)++;
1463          XtSetArg (al[*ac], XmNpixmapForeground,
1464                         BlackPixelOfScreen (XtScreen (panel.form)));  (*ac)++;
1465       }
1466    }
1467
1468    XtSetArg (al[*ac], XmNtopShadowColor, panel.primary_pixel_set->ts);  (*ac)++;
1469    XtSetArg (al[*ac], XmNbottomShadowColor, panel.primary_pixel_set->bs);(*ac)++;
1470    XtSetArg (al[*ac], XmNselectColor, panel.primary_pixel_set->sc);     (*ac)++;
1471
1472    if ((char) control_data->element_values[CONTROL_TYPE].parsed_value ==
1473                                                                  CONTROL_DATE)
1474    {
1475 /*
1476       XtSetArg (al[*ac], XmNfontList, panel.date_font_list);    (*ac)++;
1477       XtSetArg (al[*ac], XmNuseEmbossedText, False);            (*ac)++;
1478       XtSetArg (al[*ac], XmNforeground, 
1479                          BlackPixelOfScreen (XtScreen (panel.form)));  (*ac)++;
1480 */
1481       if (panel.color_use == XmCO_BLACK_WHITE)
1482       {
1483          XtSetArg (al[*ac], XmNbackground, 
1484                          WhitePixelOfScreen (XtScreen (panel.form)));  (*ac)++;
1485       }
1486    }
1487    else
1488    {
1489       XtSetArg (al[*ac], XmNfontList, panel.font_list);                 (*ac)++;
1490    }
1491
1492    XtSetArg (al[*ac], XmNbehavior, XmICON_DRAG);                        (*ac)++;
1493 }
1494
1495
1496
1497
1498 /************************************************************************
1499  *
1500  *  ControlSetIconData
1501  *      Set up the arg list elements for a controls icon and label
1502  *      resources.
1503  *
1504  *  Inputs: parent - the widget to be the parent of the control
1505  *          control_data - a pointer to the control to be created
1506  *          icon_label   - a return for an XmString for the control's label
1507  *          container_type - the type of parent the control is going into
1508  *          al - a pointer to the arg list to contain the resource data
1509  *          ac - a pointer to the arg list count
1510  *          icon_name - a pointer to the icon name (free after widget
1511  *                                                  is created)
1512  *          alternate_icon_name - a pointer to the icon name (free after widget
1513  *                                                            is created)
1514  *
1515  ************************************************************************/
1516  
1517 static void
1518 ControlSetIconData (Widget        parent,
1519                     ControlData * control_data,
1520                     XmString    * icon_label,
1521                     int           container_type,
1522                     ArgList       al,
1523                     int         * ac,
1524                     char       ** icon_name,
1525                     char       ** alternate_icon_name)
1526
1527
1528 {
1529    char * control_label;
1530    int    icon_size;
1531    
1532
1533    /*  Set up the icon and alternate icon resources for the control  */
1534    
1535    if (container_type == BOX)
1536       icon_size = panel.main_icon_size;
1537    else if (container_type == SUBPANEL)
1538       icon_size = panel.sub_icon_size;
1539    else
1540       icon_size = panel.switch_icon_size;
1541
1542
1543    *icon_name = 
1544       (char *) control_data->element_values[CONTROL_NORMAL_ICON].parsed_value;
1545
1546    if (*icon_name != NULL)
1547    {
1548       *icon_name = GetIconName (*icon_name, icon_size);
1549       XtSetArg (al[*ac], XmNimageName, *icon_name);                     (*ac)++;
1550    }
1551
1552
1553    *alternate_icon_name = 
1554     (char *) control_data->element_values[CONTROL_ALTERNATE_ICON].parsed_value;
1555
1556    if (*alternate_icon_name != NULL)
1557    {
1558       *alternate_icon_name = GetIconName (*alternate_icon_name, icon_size);
1559       XtSetArg (al[*ac], XmNalternateImage, *alternate_icon_name); (*ac)++;
1560    }
1561
1562
1563    /*  If this is not a subpanel control and the keyword is is set so that  */
1564    /*  labels are not to be displayed, set the string resource to NULL.     */
1565
1566    if (container_type != SUBPANEL && (Boolean) 
1567        panel.element_values[PANEL_DISPLAY_CONTROL_LABELS].parsed_value == False)
1568    {
1569       XtSetArg (al[*ac], XmNstring, NULL);                              (*ac)++;
1570    }
1571    else
1572    {
1573       control_label = 
1574          (char *) control_data->element_values[CONTROL_LABEL].parsed_value;
1575
1576
1577       if ((int) control_data->element_values[CONTROL_TYPE].parsed_value
1578                                                          != CONTROL_BLANK)
1579       {
1580          if (control_label != NULL)
1581          {
1582             *icon_label = XmStringCreateLocalized (control_label);
1583             XtSetArg (al[*ac], XmNstring, *icon_label);                 (*ac)++;
1584          }
1585          else if (icon_name == NULL)
1586          {
1587             control_label = 
1588                (char *) control_data->element_values[CONTROL_NAME].parsed_value;
1589
1590             *icon_label = XmStringCreateLocalized (control_label);
1591             XtSetArg (al[*ac], XmNstring, *icon_label);                 (*ac)++;
1592          }
1593       }
1594       else
1595       {
1596          *icon_label = XmStringCreateLocalized ("");
1597          XtSetArg (al[*ac], XmNstring, *icon_label);                    (*ac)++;
1598       }
1599    }
1600 }
1601
1602
1603
1604
1605 /************************************************************************
1606  *
1607  *  ControlSetBehavior
1608  *      Use the control type value to set the behavior and some visual
1609  *      arg list data to be used to create or set values on a control.
1610  *
1611  *  Inputs: control_data - a pointer to the control to be created
1612  *          al - the arg list to be set
1613  *          ac - a pointer to the count of the arg list elements
1614  *          in_subpanel - a boolean denoting the parent type of the control
1615  *
1616  ************************************************************************/
1617
1618 static void
1619 ControlSetBehavior (ControlData * control_data,
1620                     ArgList       al,
1621                     int         * ac,
1622                     Boolean       in_subpanel,
1623                     String      * expanded_file_name)
1624
1625 {
1626    Boolean sensitive;
1627    Dimension shadow_thickness;
1628    Dimension highlight_thickness;
1629    Dimension margin_width;
1630
1631
1632    /*  Set local shadow thickness and sensitive values to be used  */
1633    /*  to set the resources for the various control types.         */
1634
1635    if (control_data->element_values[CONTROL_DROP_ACTION].parsed_value != NULL)
1636    {
1637       if (panel.resolution == LOW) 
1638          shadow_thickness = 1;
1639       else
1640          shadow_thickness = 2;
1641    }
1642    else
1643       shadow_thickness = 1;
1644
1645    if (control_data->element_values[CONTROL_PUSH_ACTION].parsed_value != NULL)
1646    {
1647       sensitive = True;
1648       highlight_thickness = 1;
1649    }
1650    else
1651    {
1652       sensitive = False;
1653       highlight_thickness = 0;
1654    }
1655
1656    if (panel.resolution == HIGH &&
1657        (char) control_data->element_values[CONTROL_CONTAINER_TYPE].parsed_value == BOX &&
1658        in_subpanel == False)
1659       margin_width = 5;
1660    else
1661       margin_width = 2;
1662
1663
1664
1665    /*  All controls get their user data set to their control data  */
1666    /*  to be used out of callback functions.                       */
1667    
1668    XtSetArg (al[*ac], XmNuserData, control_data);                (*ac)++;
1669
1670
1671    /*  Switch on the controls control type to set the behaviors  */
1672    /*  specific to the individual control types.                 */
1673    
1674    switch ((char) control_data->element_values[CONTROL_TYPE].parsed_value)
1675    {
1676       case CONTROL_BLANK:
1677       {
1678          XtSetArg (al[*ac], XmNshadowThickness, 0);             (*ac)++;
1679          XtSetArg (al[*ac], XmNhighlightThickness, 0);          (*ac)++;
1680          XtSetArg (al[*ac], XmNcontrolType, XmCONTROL_BLANK);   (*ac)++;
1681          XtSetArg (al[*ac], XmNbehavior, XmICON_LABEL);         (*ac)++;
1682          XtSetArg (al[*ac], XmNsensitive, False);               (*ac)++;
1683       }
1684       break;
1685
1686       case CONTROL_BUSY:
1687       {
1688          XtSetArg (al[*ac], XmNshadowThickness, 0);             (*ac)++;
1689          XtSetArg (al[*ac], XmNcontrolType, XmCONTROL_BUSY);    (*ac)++;
1690          XtSetArg (al[*ac], XmNhighlightThickness, 0);          (*ac)++;
1691          XtSetArg (al[*ac], XmNsensitive, False);               (*ac)++;
1692          XtSetArg (al[*ac], XmNmarginWidth, margin_width);      (*ac)++;
1693          panel.busy_light_data = control_data;
1694       }
1695       break;
1696
1697       case CONTROL_ICON:
1698       case CONTROL_FILE:
1699       {
1700          XtSetArg (al[*ac], XmNshadowThickness, shadow_thickness); (*ac)++;
1701          XtSetArg (al[*ac], XmNsensitive, sensitive);              (*ac)++;
1702          XtSetArg (al[*ac], XmNhighlightThickness,highlight_thickness); (*ac)++;
1703          XtSetArg (al[*ac], XmNmarginWidth, margin_width);         (*ac)++;
1704
1705
1706          if ((char) control_data->element_values[CONTROL_MONITOR_TYPE].parsed_value == MONITOR_NONE)
1707          {
1708             XtSetArg (al[*ac], XmNcontrolType, XmCONTROL_BUTTON);  (*ac)++;
1709          }
1710          else if ((char) control_data->element_values[CONTROL_MONITOR_TYPE].parsed_value == MONITOR_FILE)
1711          {
1712             String file_name;
1713          
1714             file_name = (String) control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1715             *expanded_file_name = (String) _DtWmParseFilenameExpand ((unsigned char*) file_name);
1716
1717             XtSetArg (al[*ac], XmNfileName, *expanded_file_name);    (*ac)++;
1718             XtSetArg (al[*ac], XmNcontrolType, XmCONTROL_MONITOR);  (*ac)++;
1719          }
1720          else if ((char) control_data->element_values[CONTROL_MONITOR_TYPE].parsed_value == MONITOR_MAIL)
1721          {
1722             String file_name;
1723          
1724             file_name = (String) control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1725
1726             /*
1727              * Set fileName resource if specified; otherwise, leave
1728              * unset and it will default to the user's mail file.
1729              */
1730             if ((file_name != (String)NULL) &&
1731                 (*file_name != '\0'))
1732             {
1733                 *expanded_file_name = (String)
1734                     _DtWmParseFilenameExpand ((unsigned char*) file_name);
1735                 XtSetArg (al[*ac], XmNfileName, *expanded_file_name); (*ac)++;
1736             }
1737
1738             XtSetArg (al[*ac], XmNcontrolType, XmCONTROL_MAIL);  (*ac)++;
1739          }
1740       }
1741       break;
1742
1743       case CONTROL_CLIENT:
1744       {
1745          GeometryData * geometry_data;
1746
1747          XtSetArg (al[*ac], XmNcontrolType, XmCONTROL_CLIENT);      (*ac)++;
1748          XtSetArg (al[*ac], XmNshadowThickness, shadow_thickness);  (*ac)++;
1749          XtSetArg (al[*ac], XmNsensitive, sensitive);               (*ac)++;
1750          XtSetArg (al[*ac], XmNhighlightThickness,highlight_thickness); (*ac)++;
1751
1752
1753          geometry_data = (GeometryData *) control_data->
1754                           element_values[CONTROL_CLIENT_GEOMETRY].parsed_value;
1755
1756          if (geometry_data)
1757          {
1758             if (geometry_data->flags & WidthValue && geometry_data->width > 0)
1759             {
1760                XtSetArg (al[*ac], XmNwidth, geometry_data->width + 6);  (*ac)++;
1761             }
1762
1763             if (geometry_data->flags & HeightValue && geometry_data->height > 0)
1764             {
1765                XtSetArg (al[*ac], XmNheight, geometry_data->height + 6);(*ac)++;
1766             }
1767          }
1768       }
1769       break;
1770
1771       case CONTROL_CLOCK:
1772       {
1773          int  inset;
1774
1775
1776          XtSetArg (al[*ac], XmNshadowThickness, shadow_thickness); (*ac)++;
1777          XtSetArg (al[*ac], XmNsensitive, sensitive);              (*ac)++;
1778          XtSetArg (al[*ac], XmNhighlightThickness,highlight_thickness); (*ac)++;
1779          XtSetArg (al[*ac], XmNmarginWidth, margin_width);         (*ac)++;
1780
1781
1782          /*  Adjust the size of the clock hands to match the resolution  */
1783
1784          if ((panel.resolution == HIGH || panel.resolution == MEDIUM) &&
1785              in_subpanel == False)
1786             inset = 8;
1787          else
1788             inset = 6;
1789
1790          XtSetArg (al[*ac], XmNleftInset, inset);            (*ac)++;
1791          XtSetArg (al[*ac], XmNrightInset, inset);           (*ac)++;
1792          XtSetArg (al[*ac], XmNtopInset, inset);             (*ac)++;
1793          XtSetArg (al[*ac], XmNbottomInset, inset);          (*ac)++;
1794       }
1795       break;
1796
1797       case CONTROL_DATE:
1798       {
1799          int size;
1800          
1801          XtSetArg (al[*ac], XmNcontrolType, XmCONTROL_DATE);         (*ac)++;
1802          XtSetArg (al[*ac], XmNshadowThickness, shadow_thickness);   (*ac)++;
1803          XtSetArg (al[*ac], XmNsensitive, sensitive);                (*ac)++;
1804          XtSetArg (al[*ac], XmNhighlightThickness,highlight_thickness); (*ac)++;
1805          XtSetArg (al[*ac], XmNmarginWidth, margin_width);           (*ac)++;
1806          XtSetArg (al[*ac], XmNuseLabelAdjustment, False);           (*ac)++;
1807
1808
1809          if (!control_data->element_values[CONTROL_DATE_FORMAT].use_default)
1810          {
1811             XtSetArg (al[*ac], XmNformat, 
1812                control_data->element_values[CONTROL_DATE_FORMAT].parsed_value);
1813             (*ac)++;
1814          }
1815
1816
1817          if (!in_subpanel)
1818          {
1819             XtSetArg (al[*ac], XmNpixmapPosition, XmPIXMAP_MIDDLE);  (*ac)++;
1820             XtSetArg (al[*ac], XmNfontList, panel.date_font_list);  (*ac)++;
1821             XtSetArg (al[*ac], XmNuseEmbossedText, False);          (*ac)++;
1822             XtSetArg (al[*ac], XmNforeground,
1823                       BlackPixelOfScreen (XtScreen (panel.form)));  (*ac)++;
1824          }
1825          else
1826          {
1827             XtSetArg (al[*ac], XmNuseEmbossedText, True);            (*ac)++;
1828          }
1829       }
1830       break;
1831    }
1832 }
1833
1834
1835
1836
1837 /************************************************************************
1838  *
1839  *  ControlCreateAndRegister
1840  *      Create the control, add it callbacks, register it, as needed, 
1841  *      as dropable, as an embedded client, as a push recall client, its
1842  *      animations.
1843  *
1844  *  Inputs: parent - the widget to be the parent of the control
1845  *          control_data - a pointer to the control to be created
1846  *          main_copy - this is a boolean indicating that the control
1847  *                      being created is a copy of the main panel control
1848  *                      that will be contained within a subpanel
1849  *          al - a pointer to the arg list to contain the resource data
1850  *          ac - the arg list count
1851  *
1852  ************************************************************************/
1853  
1854 static Widget
1855 ControlCreateAndRegister (Widget        parent,
1856                           ControlData * control_data,
1857                           Boolean       main_copy,
1858                           ArgList       al,
1859                           int           ac)
1860
1861
1862 {
1863    Widget icon;
1864    unsigned char operations = NULL;
1865    char *format, * next_seg;
1866    Arg al2[4];
1867
1868
1869    /*  Create either a normal control or a clock  */
1870    
1871    if ((int) control_data->element_values[CONTROL_TYPE].parsed_value
1872                                                          == CONTROL_CLOCK)
1873       icon = DtCreateClock (parent, "icon", al, ac);
1874    else
1875       icon = _DtCreateControl (parent, "icon", al, ac);
1876
1877    if ((int)control_data->element_values[CONTROL_TYPE].parsed_value
1878                                                      == CONTROL_DATE &&
1879        (control_data->subpanel_data == NULL || main_copy) &&
1880        (main_copy ||
1881         (int)control_data->element_values[CONTROL_CONTAINER_TYPE].parsed_value
1882                                                      == SUBPANEL))
1883    {
1884          format = nl_langinfo(D_FMT);
1885          XtSetArg (al2[0], XmNformat, format);
1886          XtSetValues(icon, al2, 1);
1887    }
1888
1889    XtManageChild (icon);
1890    XtAddCallback (icon, XmNcallback, (XtCallbackProc) PushCB, control_data);
1891
1892    XtAddCallback (icon, XmNhelpCallback,
1893                      (XtCallbackProc) ControlTopicHelpCB, control_data);
1894
1895    if (!main_copy)
1896       control_data->icon = icon;
1897
1898
1899    /*  Register the animations  */
1900    
1901    if (!main_copy)
1902    {
1903       SetupPushAnimation (control_data);
1904       SetupDropAnimation (control_data);
1905    }
1906    
1907          
1908    /*  Set the drop zone for the icon  */
1909       
1910    /*  Since all file controls have CONTROL_DROP_ACTIONS by default, only    */
1911    /*  register the ones that are either a data type that is an action or    */
1912    /*  a file type the has either move, copy or link actions associated with */
1913    /*  it.  Also register non-file controls that have drop actions as copy.  */
1914
1915    if (control_data->element_values[CONTROL_DROP_ACTION].parsed_value
1916                                                                    != NULL)
1917    {
1918       if ((int)control_data->element_values[CONTROL_TYPE].parsed_value ==
1919                                                              CONTROL_FILE)
1920       {
1921          if (control_data->is_action)
1922          {
1923             operations = XmDROP_COPY;
1924          }
1925          else
1926          {
1927             if (control_data->move_action != NULL)
1928                operations |= XmDROP_MOVE;
1929             if (control_data->copy_action != NULL)
1930                operations |= XmDROP_COPY;
1931             if (control_data->link_action != NULL)
1932                operations |= XmDROP_LINK;
1933          }
1934       }
1935       else
1936       {
1937          operations = XmDROP_COPY;
1938       }
1939
1940       if (operations != NULL)
1941       {
1942          XtSetArg (al2[0], DtNdropAnimateCallback, dropCB);
1943          XtSetArg (al2[1], DtNtextIsBuffer, True);
1944          XtSetArg (al2[2], XmNanimationStyle, XmDRAG_UNDER_SHADOW_IN);
1945          XtSetArg (al2[3], DtNpreserveRegistration, True);
1946
1947          /* Temporarily hard-coded to reject buffer drops on the trash
1948             until the desktop clients have trash actions which can
1949             take appropriate action on calendar appointments, mail
1950             attachments, selected text, etc.  File Manager is also
1951             hard-coded to reject buffer drops on the trash window.
1952             Any changes here should be coordinated with File Manager.
1953           */
1954          if (strcmp(control_data->element_values[CONTROL_NAME].parsed_value,
1955                     "Trash") == 0)
1956            DtDndDropRegister(icon,
1957                              DtDND_FILENAME_TRANSFER,
1958                              operations, transferDropCB, al2, 4);
1959          else
1960            DtDndDropRegister(icon,
1961                              DtDND_FILENAME_TRANSFER|DtDND_BUFFER_TRANSFER, 
1962                              operations, transferDropCB, al2, 4);
1963       }
1964    }
1965
1966
1967    /*  Install the control into the push recall and embedded client list.  */
1968    
1969    if (!main_copy)
1970    {
1971       if ((Boolean) control_data->element_values[CONTROL_PUSH_RECALL].parsed_value)
1972          PushRecallRegister (control_data, True);
1973
1974       if ((char) control_data->element_values[CONTROL_TYPE].parsed_value == CONTROL_CLIENT)
1975          EmbeddedClientRegister (control_data, True);
1976    }
1977
1978    return (icon);
1979 }
1980
1981
1982
1983
1984 /************************************************************************
1985  *
1986  *  SwitchCreate
1987  *      Create the workspace switch area.  This consists of three steps.
1988  *      First, call the window manager to get the set of workspace names.
1989  *      Next, create a row column and switch button set for the workspace
1990  *      switch functionality.  Last, create the set of controls that 
1991  *      surround the switch buttons.
1992  *
1993  ************************************************************************/
1994  
1995 static void
1996 SwitchCreate (BoxData * box_data)
1997
1998
1999 {
2000    SwitchData * switch_data = box_data->switch_data;
2001
2002    int     switch_count = 1;
2003    Atom  * atom_names;
2004    Atom    current_workspace_atom;
2005    int     current_workspace;
2006
2007    Widget switch_button;
2008
2009    XmString label_string;
2010    
2011    XmPixelSet * pixel_set;
2012
2013    Pixmap pixmap;
2014
2015    Widget prev_left = NULL;
2016    Widget prev_right = NULL;
2017
2018    char * icon_name = NULL;
2019    char * alt_icon_name = NULL;
2020
2021    String exp_file_name = NULL;
2022
2023    int ac;
2024    Arg al[40];
2025    Arg al2[4];
2026    int i;
2027
2028
2029    /*  Pre create the text field to be used for renaming the workspaces.  */
2030
2031    box_data->switch_edit = 
2032       (Widget) XmCreateTextField (box_data->switch_form, "switch_edit", al, 0);
2033
2034
2035    /*  Get current workspace from the window manager.  */
2036
2037    DtWsmGetCurrentWorkspace (XtDisplay (box_data->switch_form),
2038                              RootWindowOfScreen (XtScreen (box_data->switch_form)),
2039                              &current_workspace_atom);
2040
2041
2042    /*  Get current workspace list from the window manager.  */
2043
2044    if (DtWsmGetWorkspaceList (XtDisplay (box_data->switch_form),
2045                           RootWindowOfScreen (XtScreen (box_data->switch_form)),
2046                           &atom_names, &switch_count) == 0)
2047    {
2048       switch_data->atom_names = atom_names;
2049       switch_data->switch_count = switch_count;
2050       
2051       switch_data->switch_names = 
2052          (char **) XtMalloc (sizeof(char *) * switch_count);
2053
2054       for (i = 0; i < switch_count; i++)
2055       {
2056          DtWsmWorkspaceInfo * workspace_info;
2057          
2058          DtWsmGetWorkspaceInfo (XtDisplay (box_data->switch_form),
2059                                 RootWindowOfScreen (XtScreen (box_data->switch_form)),
2060                                 atom_names[i], &workspace_info);
2061                                                                          
2062          switch_data->switch_names[i] = XtNewString (workspace_info->pchTitle);
2063
2064          DtWsmFreeWorkspaceInfo (workspace_info);
2065
2066          if (atom_names[i] == current_workspace_atom)
2067             current_workspace = i;
2068       }
2069    }
2070    else
2071    {
2072       switch_data->switch_names = NULL;
2073       switch_data->switch_count = 0;
2074    }
2075
2076    panel.switch_row_count =
2077       (int) (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value);
2078    switch_data->buttons = 
2079       (Widget *) XtMalloc (sizeof (Widget *) * switch_count);
2080
2081    switch_data->popup_data = NULL;
2082
2083
2084    /*  Create the row column within the switch form to contain the  */
2085    /*  workspace buttons.                                           */
2086    
2087    ac = 0;
2088    XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
2089    XtSetArg (al[ac], XmNtopOffset, 1);  ac++;
2090    XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
2091    XtSetArg (al[ac], XmNleftOffset, 1);  ac++;
2092    XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
2093    XtSetArg (al[ac], XmNrightOffset, 1);  ac++;
2094    XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
2095    XtSetArg (al[ac], XmNbottomOffset, 1);  ac++;
2096
2097    XtSetArg (al[ac], XmNnumColumns, panel.switch_row_count);  ac++;
2098    XtSetArg (al[ac], XmNpacking, XmPACK_COLUMN);  ac++;
2099    XtSetArg (al[ac], XmNorientation, XmHORIZONTAL);  ac++;
2100    XtSetArg (al[ac], XmNadjustLast, False);  ac++;
2101
2102
2103    /*  Remove all of the tab groups  */
2104
2105    XtSetArg (al[ac], XmNnavigationType, XmNONE);  ac++;
2106
2107    if (panel.color_use == XmCO_BLACK_WHITE)
2108    {
2109       pixmap = XmGetPixmap (XtScreen (panel.form), "50_foreground",
2110                             panel.inactive_pixel_set->bg,
2111                             panel.inactive_pixel_set->fg);
2112       XtSetArg (al[ac], XmNbackgroundPixmap, pixmap);  ac++;
2113    }
2114
2115    switch_data->rc = 
2116       XmCreateRowColumn (box_data->switch_form, "switch_rc", al, ac);
2117    XtManageChild (switch_data->rc);
2118
2119
2120    /*  Create the switch buttons  */
2121    
2122    SwitchButtonCreate (switch_data, False);
2123
2124
2125    /*  Set the active switch button to the active workspace  */
2126    
2127    XtSetArg (al[0], XmNset, True);
2128    switch_data->active_switch = current_workspace;
2129    XtSetValues (switch_data->buttons[current_workspace], al, 1);
2130    
2131
2132    /* Initialize time stamp for catching multi-click events */
2133
2134    switch_data->time_stamp = 0;
2135
2136
2137    /*  Create each of the switch controls and adjust the switch_rc's  */
2138    /*  constraints to position it properly.                           */
2139
2140    /*  Set up a loop and create each control within the switch  */
2141
2142    for (i = 0; i < switch_data->control_data_count; i++)
2143    {
2144       ControlData * control_data = switch_data->control_data[i];
2145       XmString icon_label = NULL;
2146
2147       ac = 0;
2148       ControlSetVisualData (control_data, al, &ac);
2149
2150       XtSetArg (al[ac], XmNpixmapPosition, XmPIXMAP_TOP);       ac++;
2151
2152       if (i % 2)
2153       {
2154          if (prev_right == NULL)
2155          {
2156             XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
2157             XtSetArg (al[ac], XmNtopOffset, 1);                 ac++;
2158          }
2159          else
2160          {
2161             XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET);       ac++;
2162             XtSetArg (al[ac], XmNtopWidget, prev_right);                ac++;
2163          }
2164
2165          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET);         ac++;
2166          XtSetArg (al[ac], XmNleftWidget, switch_data->rc);             ac++;
2167          XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);          ac++;
2168          XtSetArg (al[ac], XmNrightOffset, 1);                          ac++;
2169       }
2170       else
2171       {
2172          if (prev_left == NULL)
2173          {
2174             XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
2175             XtSetArg (al[ac], XmNtopOffset, 1);                 ac++;
2176          }
2177          else
2178          {
2179             XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET);       ac++;
2180             XtSetArg (al[ac], XmNtopWidget, prev_left);                 ac++;
2181          }
2182
2183          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);   ac++;
2184          XtSetArg (al[ac], XmNleftOffset, 1);                   ac++;
2185       }
2186       
2187       if (i >= switch_data->control_data_count - 2)
2188       {
2189          XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);         ac++;
2190          XtSetArg (al[ac], XmNbottomOffset, 1);                         ac++;
2191       }
2192      
2193
2194       /*  Call the function used to set the control's icon and label data  */
2195       
2196       ControlSetIconData (box_data->switch_form, control_data, 
2197                           &icon_label, SWITCH, al, &ac, &icon_name,
2198                           &alt_icon_name);
2199
2200
2201       /*  Call the function used to set the control's behavioral aspects  */
2202
2203       ControlSetBehavior (control_data, al, &ac, False, &exp_file_name);
2204
2205
2206       /*  Call the function used to create and register the control  */
2207       
2208       control_data->icon = 
2209          ControlCreateAndRegister (box_data->switch_form, 
2210                                    control_data, False, al, ac);
2211
2212       if (icon_label != NULL)
2213          XmStringFree (icon_label);
2214
2215       if (icon_name != NULL)
2216          XtFree(icon_name);
2217
2218       if (alt_icon_name != NULL)
2219          XtFree(alt_icon_name);
2220
2221       if (exp_file_name != NULL)
2222          XtFree(exp_file_name);
2223
2224       if (i % 2)
2225          prev_right = control_data->icon;
2226       else
2227          prev_left = control_data->icon;
2228
2229       if (i == 0)
2230       {
2231          XtSetArg (al2[0], XmNleftAttachment, XmATTACH_WIDGET);
2232          XtSetArg (al2[1], XmNleftWidget, prev_left);
2233          XtSetArg (al2[2], XmNrightAttachment, XmATTACH_NONE);
2234          XtSetValues (switch_data->rc, al2, 3);
2235       }
2236    }
2237 }
2238
2239
2240
2241
2242 /************************************************************************
2243  *
2244  *  SwitchButtonCreate
2245  *      Create either the full set of switch button or one new one.
2246  *
2247  *************************************************************************/
2248  
2249 void
2250 SwitchButtonCreate (SwitchData * switch_data,
2251                     Boolean      one)
2252
2253
2254 {
2255    BoxData    * box_data;
2256    XmPixelSet * pixel_set;
2257    int          switch_count;
2258    XmString     label_string;
2259                  
2260    Arg al[40];
2261    int ac;
2262    int ac_save;
2263
2264    int i;
2265
2266
2267    /*  Find the box data which contains the switch.  This is needed  */
2268    /*  for the switch callback processing.                           */
2269    
2270    box_data = switch_data->box_data;
2271
2272    /* Calculate switch height */
2273    if (!switch_height) {
2274         Dimension       ignore_width;
2275
2276         label_string = XmStringCreateLocalized (switch_data->switch_names[0]);
2277         XmStringExtent(panel.font_list,label_string,
2278                         &ignore_width,&switch_height);
2279         XmStringFree(label_string);
2280         if (panel.resolution == HIGH || panel.resolution == MEDIUM) {
2281                 switch_height += 14;
2282                 if (switch_height < SWITCH_HIGH_BUTTON_HEIGHT) {
2283                         switch_height = SWITCH_HIGH_BUTTON_HEIGHT;
2284                 }
2285         } else {
2286                 switch_height += 8;
2287                 if (switch_height < SWITCH_LOW_BUTTON_HEIGHT) {
2288                         switch_height = SWITCH_LOW_BUTTON_HEIGHT;
2289                 }
2290         }
2291    }
2292
2293    /*  Create Switch Toggles  */
2294
2295    ac = 0;
2296
2297    XtSetArg (al[ac], XmNfillOnArm, False);                      ac++;
2298
2299    if (panel.resolution == HIGH || panel.resolution == MEDIUM)
2300    {
2301       XtSetArg (al[ac], XmNwidth, SWITCH_HIGH_BUTTON_WIDTH);    ac++;
2302       XtSetArg (al[ac], XmNshadowThickness, 3);                 ac++;
2303       XtSetArg (al[ac], XmNmarginWidth, 4);                     ac++;
2304          
2305    }
2306    else
2307    {
2308       XtSetArg (al[ac], XmNwidth, SWITCH_LOW_BUTTON_WIDTH);     ac++;
2309       XtSetArg (al[ac], XmNshadowThickness, 2);                 ac++;
2310       XtSetArg (al[ac], XmNmarginWidth, 2);                     ac++;
2311
2312    }
2313
2314    XtSetArg (al[ac], XmNheight, switch_height);  ac++;
2315    XtSetArg (al[ac], XmNbehavior, XmICON_TOGGLE);               ac++;
2316    XtSetArg (al[ac], XmNfillMode, XmFILL_SELF);                 ac++;
2317    XtSetArg (al[ac], XmNalignment, XmALIGNMENT_BEGINNING);      ac++;
2318    XtSetArg (al[ac], XmNpixmapPosition, XmPIXMAP_BOTTOM);       ac++;
2319    XtSetArg (al[ac], XmNhighlightThickness, 1);                 ac++;
2320    XtSetArg (al[ac], XmNmarginHeight, 0);                       ac++;
2321    XtSetArg (al[ac], XmNspacing, 0);                            ac++;
2322    XtSetArg (al[ac], XmNcontrolType, XmCONTROL_SWITCH);         ac++;
2323    XtSetArg (al[ac], XmNfontList, panel.font_list);             ac++;
2324    XtSetArg (al[ac], XmNrecomputeSize, False);                  ac++;
2325    XtSetArg (al[ac], XmNuserData, box_data);                    ac++;
2326    ac_save = ac;
2327
2328
2329    /*  Set up a loop to either create a full set of switch buttons  */
2330    /*  or just one, depending on the input parameters.              */
2331    
2332    switch_count = switch_data->switch_count;
2333
2334    for (i = 0; i < switch_count; i++)
2335    {
2336       int pixel_set_index, map_index;
2337
2338       if (one == True)
2339          i = switch_count - 1;
2340
2341       ac = ac_save;
2342
2343
2344       /*  Set pixel resources.  */
2345       switch (panel.color_use)
2346       {
2347           case XmCO_BLACK_WHITE:
2348           case XmCO_LOW_COLOR:
2349               pixel_set_index = 1;
2350               break;
2351
2352           case XmCO_MEDIUM_COLOR:
2353               pixel_set_index = HARD_CODED_PRIMARY;
2354               break;
2355
2356           case XmCO_HIGH_COLOR:
2357               map_index = i % _WS_HIGH_COLOR_COUNT;
2358               pixel_set_index = _ws_high_color_map[map_index];
2359               break;
2360       }
2361
2362       pixel_set = &panel.pixel_set[pixel_set_index - 1];
2363
2364       XtSetArg (al[ac], XmNforeground, pixel_set->fg);          ac++;
2365       XtSetArg (al[ac], XmNbackground, pixel_set->bg);          ac++;
2366       XtSetArg (al[ac], XmNarmColor, pixel_set->bg);            ac++;
2367       XtSetArg (al[ac], XmNfillOnArm, False);                   ac++;
2368      
2369       if (panel.color_use == XmCO_BLACK_WHITE)
2370       {
2371          XtSetArg (al[ac], XmNuseEmbossedText, False);  ac++;
2372          XtSetArg (al[ac], XmNpixmapBackground,
2373                    WhitePixelOfScreen (XtScreen (panel.form)));  ac++;
2374          XtSetArg (al[ac], XmNpixmapForeground,
2375                    BlackPixelOfScreen (XtScreen (panel.form)));  ac++;
2376       }
2377       else
2378       {
2379          XtSetArg (al[ac], XmNpixmapBackground, pixel_set->ts);       ac++;
2380          XtSetArg (al[ac], XmNpixmapForeground, pixel_set->bs);       ac++;
2381       }
2382
2383       
2384       /*  Set label.  */
2385
2386       label_string = XmStringCreateLocalized (switch_data->switch_names[i]);
2387       XtSetArg (al[ac], XmNstring, label_string);               ac++;
2388
2389
2390       switch_data->buttons[i] = 
2391          _DtCreateControl (switch_data->rc, "toggle", al, ac);
2392
2393       XtManageChild (switch_data->buttons[i]);
2394
2395       XtAddCallback (switch_data->buttons[i], XmNcallback,
2396                      (XtCallbackProc) SwitchButtonCB, NULL);
2397
2398       XtAddCallback (switch_data->buttons[i], XmNhelpCallback,
2399                   (XtCallbackProc) GeneralTopicHelpCB, SWITCH_BUTTON);
2400
2401       XmStringFree (label_string);
2402    }
2403 }
2404
2405
2406
2407
2408 /************************************************************************
2409  *
2410  *  ControlCreate
2411  *
2412  ************************************************************************/
2413  
2414 static void
2415 ControlCreate (Widget         parent,
2416                ControlData ** control_data,
2417                int            control_count)
2418
2419
2420 {
2421    int i;
2422    Arg al[40];
2423    int ac;
2424    Widget prev_icon = NULL;
2425    
2426    char * icon_name = NULL;
2427    char * alt_icon_name = NULL;
2428    String exp_file_name = NULL;
2429    XmString icon_label = NULL;
2430
2431
2432    /*  Set up a loop and create each control within the box  */
2433
2434    for (i = 0; i < control_count; i++)
2435    {
2436       ac = 0;
2437       ControlSetVisualData (control_data[i], al, &ac);
2438    
2439       XtSetArg (al[ac], XmNpixmapPosition, XmPIXMAP_TOP);       ac++;
2440
2441       XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);       ac++;
2442       XtSetArg (al[ac], XmNtopOffset, 1);                       ac++;
2443       XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);    ac++;
2444       XtSetArg (al[ac], XmNbottomOffset, 1);                    ac++;
2445
2446       if (prev_icon == NULL)
2447       {
2448          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);   ac++;
2449          XtSetArg (al[ac], XmNleftOffset, 1);                   ac++;
2450       }
2451       else
2452       {
2453          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;    
2454          XtSetArg (al[ac], XmNleftWidget, prev_icon);           ac++;    
2455       }
2456
2457       if (i == control_count - 1)
2458       {
2459          XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
2460          XtSetArg (al[ac], XmNrightOffset, 1);                  ac++;
2461       }
2462      
2463
2464       /*  Call the function used to set the control's icon and label data  */
2465       
2466       ControlSetIconData (parent, control_data[i], &icon_label, BOX, al, &ac,
2467                           &icon_name, &alt_icon_name);
2468
2469
2470       /*  Call the function used to set the control's behavioral aspects  */
2471
2472       ControlSetBehavior (control_data[i], al, &ac, False, &exp_file_name);
2473
2474
2475       /*  Call the function used to create and register the control  */
2476
2477       control_data[i]->icon = 
2478          ControlCreateAndRegister (parent, control_data[i], False, al, ac);
2479
2480       if (icon_label != NULL)
2481       {
2482          XmStringFree (icon_label);
2483          icon_label = NULL;
2484       }
2485          
2486       if (icon_name != NULL)
2487       {
2488          XtFree(icon_name);
2489          icon_name = NULL;
2490       }
2491
2492       if (alt_icon_name != NULL)
2493       {
2494          XtFree(alt_icon_name);
2495          alt_icon_name = NULL;
2496       }
2497
2498       if (exp_file_name != NULL)
2499       {
2500          XtFree(exp_file_name);
2501          exp_file_name = NULL;
2502       }
2503
2504       prev_icon = control_data[i]->icon;
2505
2506       if (control_data[i]->subpanel_data != NULL)
2507          SubpanelCreate (control_data[i], control_data[i]->subpanel_data);
2508    }
2509 }
2510
2511
2512
2513
2514 /************************************************************************
2515  *
2516  *  ArrowCreate
2517  *
2518  ************************************************************************/
2519  
2520 static void
2521 ArrowCreate (Widget         parent,
2522              ControlData ** control_data,
2523              int            arrow_count,
2524              Boolean        right_side,
2525              Boolean        first_box)
2526
2527
2528 {
2529    int i;
2530    Widget prev_separator = NULL;
2531    Arg al[40];
2532    Arg al2[30];
2533    Arg al3[1];
2534    int ac;
2535    int ac2;
2536    int ac_save;
2537    int ac2_save;
2538    Dimension control_width;
2539    Pixmap pixmap;
2540
2541
2542    /*  If there is no arrow form (there are no subpanels for the controls)  */
2543    /*  then the parent widget will be null so just return.                  */
2544    
2545    if (parent == NULL)
2546       return;
2547
2548    ac = 0;
2549    if (first_box)
2550    {
2551       XtSetArg (al[ac], XmNtopOffset, 0);                               ac++;
2552       XtSetArg (al[ac], XmNbottomOffset, 0);                            ac++;
2553    }
2554    else
2555    {
2556       XtSetArg (al[ac], XmNtopOffset, 1);                               ac++;
2557       XtSetArg (al[ac], XmNbottomOffset, 1);                            ac++;
2558    }
2559
2560
2561    XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);                  ac++;
2562    XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);               ac++;
2563    XtSetArg (al[ac], XmNbackground, panel.inactive_pixel_set->bg);      ac++;
2564    XtSetArg (al[ac], XmNforeground, panel.inactive_pixel_set->fg);      ac++;
2565    XtSetArg (al[ac], XmNtopShadowColor, panel.inactive_pixel_set->ts);  ac++;
2566    XtSetArg (al[ac], XmNbottomShadowColor, panel.inactive_pixel_set->bs); ac++;
2567    XtSetArg (al[ac], XmNselectColor, panel.inactive_pixel_set->sc);     ac++;
2568    XtSetArg (al[ac], XmNhighlightThickness, 1);                         ac++;
2569    XtSetArg (al[ac], XmNshadowThickness, 0);                            ac++;
2570
2571    if (panel.color_use == XmCO_BLACK_WHITE)
2572    {
2573       pixmap = XmGetPixmap (XtScreen (panel.form), "50_foreground",
2574                             panel.inactive_pixel_set->fg,
2575                             panel.inactive_pixel_set->bg);
2576
2577       XtSetArg (al[ac], XmNbackgroundPixmap, pixmap);  ac++;
2578    }
2579
2580    ac_save = ac;
2581
2582    ac2 = 0;
2583    XtSetArg (al2[ac2], XmNtopAttachment, XmATTACH_FORM);                ac2++;
2584    XtSetArg (al2[ac2], XmNtopOffset, 0);                                ac2++;
2585    XtSetArg (al2[ac2], XmNbottomAttachment, XmATTACH_FORM);             ac2++;
2586    XtSetArg (al2[ac2], XmNbottomOffset, 0);                             ac2++;
2587    XtSetArg (al2[ac2], XmNbackground, panel.inactive_pixel_set->bg);    ac2++;
2588    XtSetArg (al2[ac2], XmNforeground, panel.inactive_pixel_set->fg);    ac2++;
2589    XtSetArg (al2[ac2], XmNtopShadowColor, panel.inactive_pixel_set->ts);ac2++;
2590    XtSetArg (al2[ac2], XmNbottomShadowColor, panel.inactive_pixel_set->bs); ac2++;
2591    XtSetArg (al2[ac2], XmNshadowThickness, 2);                          ac2++;
2592    XtSetArg (al2[ac2], XmNorientation, XmVERTICAL);                     ac2++;
2593    ac2_save = ac2;
2594
2595    
2596    for (i = 0; i < arrow_count; i++)
2597    {
2598       ac = ac_save;
2599       ac2 = ac2_save;
2600
2601       if (prev_separator == NULL)
2602       {
2603          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);   ac++;
2604          if (first_box)
2605          {
2606             XtSetArg (al[ac], XmNleftOffset, 0);                        ac++;
2607          }
2608          else
2609          {
2610             XtSetArg (al[ac], XmNleftOffset, 1);                        ac++;
2611          }
2612       }
2613       else
2614       {
2615          XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
2616          XtSetArg (al[ac], XmNleftWidget, prev_separator);      ac++;
2617       }
2618
2619       control_width = XtWidth (control_data[i]->icon);
2620       control_width += 2;
2621
2622       if (i == 0 && right_side == True)
2623          control_width -= 2;
2624       else if (i == 0 && right_side == False)
2625          control_width -= 2;
2626       else if (i != 0)
2627          control_width -= 4;
2628
2629       if (i == 0 && first_box == False)
2630          control_width -= 2;
2631
2632       XtSetArg (al[ac], XmNwidth, control_width);               ac++;
2633
2634       if (control_data[i]->subpanel_data == NULL)
2635       {
2636          XtSetArg (al[ac], XmNimageName, blank_arrow_image);    ac++;
2637       }
2638       else
2639       {
2640          if ((int) (control_data[i]-> 
2641              element_values[CONTROL_MONITOR_TYPE].parsed_value) != MONITOR_NONE)
2642          {
2643             if (CheckOtherMonitorsOn(control_data[i]->subpanel_data))
2644             {
2645                XtSetArg (al[ac], XmNimageName, post_monitor_arrow_image); ac++;
2646             }
2647             else
2648             {
2649                XtSetArg (al[ac], XmNimageName, post_arrow_image);       ac++;
2650             }
2651          }
2652          else
2653          {
2654             XtSetArg (al[ac], XmNimageName, post_arrow_image);  ac++;
2655          }
2656       }
2657
2658       XtSetArg (al[ac], XmNmultiClick, XmMULTICLICK_DISCARD); ac++;
2659
2660       control_data[i]->arrow = 
2661          DtCreateButtonGadget (parent, "arrow", al, ac);
2662
2663       XtManageChild (control_data[i]->arrow);
2664
2665       if (control_data[i]->subpanel_data == NULL)
2666          XtSetSensitive (control_data[i]->arrow, False);
2667       
2668       XtAddCallback (control_data[i]->arrow, XmNcallback, 
2669                      ArrowCB,
2670                      (XtPointer) control_data[i]);
2671
2672       if (i < arrow_count - 1)
2673       {
2674          XtSetArg (al2[ac2], XmNleftAttachment, XmATTACH_WIDGET);       ac2++;
2675          XtSetArg (al2[ac2], XmNleftWidget, control_data[i]->arrow);    ac2++;
2676
2677          if (i == 0 && right_side == False)
2678          {
2679             XtSetArg (al2[ac2], XmNleftOffset, 1);                      ac2++;
2680          }
2681          else if (i == 0 && right_side == True)
2682          {
2683             XtSetArg (al2[ac2], XmNleftOffset, 3);                      ac2++;
2684          }
2685          else
2686          {
2687             XtSetArg (al2[ac2], XmNleftOffset, 0);                      ac2++;
2688          }
2689
2690          control_data[i]->arrow_separator = 
2691             XmCreateSeparatorGadget (parent, "arrow_separator", al2, ac2);
2692          XtManageChild (control_data[i]->arrow_separator);
2693
2694          prev_separator = control_data[i]->arrow_separator;
2695       }
2696    }
2697 }
2698
2699
2700
2701
2702 /************************************************************************
2703  *
2704  *  SubpanelCreate
2705  *
2706  ************************************************************************/
2707  
2708 static void
2709 SubpanelCreate (ControlData  * main_control_data,
2710                 SubpanelData * subpanel_data)
2711
2712
2713 {
2714    DtPanelShellWidget subpanel_shell;
2715    char * subpanel_name = (char *) subpanel_data->element_values[SUBPANEL_TITLE].parsed_value;
2716    XmString icon_label;
2717
2718    ControlData * control_data;
2719    Widget attach_widget;
2720    Boolean control_install;
2721    Boolean monitor = False;
2722    Boolean main = False;
2723
2724    Pixmap pixmap;
2725
2726    int i;
2727
2728    Arg al[40];
2729    Arg al2[3];
2730    int ac;
2731    int ac_save;
2732
2733
2734    /*   Create the subpanel shell.  */
2735    
2736    ac = 0;
2737    XtSetArg (al[ac], XmNallowShellResize, True); ac++;
2738    XtSetArg (al[ac], XmNmwmDecorations, MWM_DECOR_MENU | MWM_DECOR_TITLE); ac++;
2739    XtSetArg (al[ac], XmNtitle, subpanel_name); ac++;
2740
2741    subpanel_data->shell =  
2742       XtCreatePopupShell (subpanel_name, xmDialogShellWidgetClass,
2743                           panel.shell, al, ac);
2744
2745    XtSetMappedWhenManaged (subpanel_data->shell, False);
2746
2747
2748    /*  Set pixel resources.  */
2749
2750    ac = 0;
2751    XtSetArg (al[ac], XmNforeground, panel.primary_pixel_set->fg);       ac++;
2752    XtSetArg (al[ac], XmNbackground, panel.primary_pixel_set->bg);       ac++;
2753    XtSetArg (al[ac], XmNtopShadowColor, panel.primary_pixel_set->ts);   ac++;
2754    XtSetArg (al[ac], XmNbottomShadowColor, panel.primary_pixel_set->bs);ac++;
2755    XtSetArg (al[ac], XmNselectColor, panel.primary_pixel_set->sc);      ac++;
2756
2757    if (panel.color_use == XmCO_BLACK_WHITE)
2758    {
2759       XtSetArg (al[ac], XmNuseEmbossedText, False);                     ac++;
2760       XtSetArg (al[ac], XmNarmColor, panel.primary_pixel_set->bg);      ac++;
2761       XtSetArg (al[ac], XmNpixmapBackground,
2762                         WhitePixelOfScreen (XtScreen (panel.form)));    ac++;
2763       XtSetArg (al[ac], XmNpixmapForeground,
2764                         BlackPixelOfScreen (XtScreen (panel.form)));    ac++;
2765    }
2766
2767    if (panel.color_use == XmCO_LOW_COLOR)
2768    {
2769       XtSetArg (al[ac], XmNpixmapBackground,
2770                         WhitePixelOfScreen (XtScreen (panel.form)));    ac++;
2771       XtSetArg (al[ac], XmNpixmapForeground, panel.primary_pixel_set->bg); ac++;
2772       XtSetArg (al[ac], XmNpixmapForeground, panel.primary_pixel_set->bg); ac++;
2773    }
2774
2775    ac_save = ac;
2776
2777    XtSetArg (al[ac], XmNshadowThickness, 1);  ac++;
2778
2779
2780    /*  Create the outer form widget that will contain the entire panel  */
2781    
2782    XtSetArg (al[ac], XmNuserData, SUBPANEL); ac++;
2783
2784    if (panel.color_use == XmCO_BLACK_WHITE)
2785    {
2786       pixmap = XmGetPixmap (XtScreen (panel.form), "50_foreground",
2787                             panel.inactive_pixel_set->fg,
2788                             panel.inactive_pixel_set->bg);
2789
2790       XtSetArg (al[ac], XmNbackgroundPixmap, pixmap);  ac++;
2791    }
2792
2793    subpanel_data->form = 
2794       XmCreateForm (subpanel_data->shell, subpanel_name, al, ac);
2795
2796    XtManageChild (subpanel_data->form);
2797
2798    XtAddCallback (subpanel_data->form, XmNhelpCallback,
2799                   (XtCallbackProc) SubpanelTopicHelpCB, subpanel_data);
2800
2801    if (panel.popup_data == NULL || panel.popup_data->popup == NULL)
2802       CreatePopupMenu (subpanel_data->form);
2803    else
2804       XmAddToPostFromList (panel.popup_data->popup, subpanel_data->form);
2805
2806
2807    /* Event handler for posting popup menu */
2808
2809    XtAddEventHandler (subpanel_data->form, ButtonPressMask, False,
2810                       (XtEventHandler) PostPopupMenu, (XtPointer) NULL);
2811
2812
2813    /*  If the value for subpanel control install is true, create  */
2814    /*  the drop zone as the top child of the form                 */
2815
2816    control_install = 
2817       (Boolean) subpanel_data->element_values[SUBPANEL_CONTROL_INSTALL].parsed_value;
2818
2819    if (control_install)
2820    {
2821       icon_label = XmStringCreateLocalized (GETMESSAGE (84, 1, "Install Icon"));
2822
2823       ac = ac_save;
2824       XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);               ac++;
2825       XtSetArg (al[ac], XmNtopOffset, 5);                               ac++;
2826       XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);              ac++;
2827       XtSetArg (al[ac], XmNleftOffset, 5);                              ac++;
2828       XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);             ac++;
2829       XtSetArg (al[ac], XmNrightOffset, 5);                             ac++;
2830       XtSetArg (al[ac], XmNshadowThickness, 2);                         ac++;
2831       XtSetArg (al[ac], XmNhighlightThickness, 1);                      ac++;
2832       XtSetArg (al[ac], XmNmarginWidth, 1);                             ac++;
2833       XtSetArg (al[ac], XmNmarginHeight, 1);                            ac++;
2834       XtSetArg (al[ac], XmNstring, icon_label);                         ac++;
2835       XtSetArg (al[ac], XmNpixmapPosition, XmPIXMAP_LEFT);              ac++;
2836       XtSetArg (al[ac], XmNbehavior, XmICON_LABEL);                     ac++;
2837       XtSetArg (al[ac], XmNimageName, dropzone_image);                  ac++;
2838       XtSetArg (al[ac], XmNuserData, subpanel_data);                    ac++;
2839       XtSetArg (al[ac], XmNfontList, panel.font_list);                  ac++;
2840       XtSetArg (al[ac], XmNtraversalOn, False);                         ac++;
2841
2842       if (panel.color_use == XmCO_BLACK_WHITE)
2843       {
2844          pixmap = XmGetPixmap (XtScreen (panel.form), "50_foreground",
2845                                panel.inactive_pixel_set->fg,
2846                                panel.inactive_pixel_set->bg);
2847
2848          XtSetArg (al[ac], XmNbackgroundPixmap, pixmap);  ac++;
2849       }
2850
2851       subpanel_data->dropzone = 
2852          _DtCreateControl (subpanel_data->form, "dropzone", al, ac);
2853       XtManageChild (subpanel_data->dropzone);
2854       XmStringFree (icon_label);
2855
2856       XtAddCallback (subpanel_data->dropzone, XmNhelpCallback,
2857                      (XtCallbackProc) GeneralTopicHelpCB, INSTALL_ZONE);
2858
2859
2860       /*  Set the drop zone for the install area.  */
2861
2862       XtSetArg (al2[0], DtNdropAnimateCallback, customizeDropCB);
2863       XtSetArg (al2[1], XmNanimationStyle, XmDRAG_UNDER_SHADOW_IN);
2864       XtSetArg (al2[2], DtNpreserveRegistration, True);
2865       
2866       DtDndDropRegister (subpanel_data->dropzone, DtDND_FILENAME_TRANSFER,
2867                          XmDROP_COPY, customizeTransferDropCB, al2, 3);
2868
2869
2870       /*  Create the separator that goes between the dropzone and controls  */
2871    
2872       ac = ac_save;
2873       XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET);             ac++;
2874       XtSetArg (al[ac], XmNtopWidget, subpanel_data->dropzone);         ac++;
2875       XtSetArg (al[ac], XmNtopOffset, 5);                               ac++;
2876       XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);              ac++;
2877       XtSetArg (al[ac], XmNleftOffset, 1);                              ac++;
2878       XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);             ac++;
2879       XtSetArg (al[ac], XmNrightOffset, 1);                             ac++;
2880       XtSetArg (al[ac], XmNshadowThickness, 2);                         ac++;
2881       XtSetArg (al[ac], XmNorientation, XmHORIZONTAL);                  ac++;
2882
2883       subpanel_data->separator = 
2884          XmCreateSeparatorGadget (subpanel_data->form, 
2885                                   "subpanel_separator", al, ac);
2886       XtManageChild (subpanel_data->separator);
2887    }
2888    
2889
2890    /*  Loop through the control set and see if any of the controls   */
2891    /*  have monitor files attached to them.  If so, the constraints  */
2892    /*  for the form need to be set appropriately.                    */
2893
2894    if ((int) (main_control_data->
2895        element_values[CONTROL_MONITOR_TYPE].parsed_value) != MONITOR_NONE)
2896       monitor = True;
2897
2898    if (monitor == False)
2899    {
2900       for (i = 0; i < subpanel_data->control_data_count; i++)
2901       {
2902          if ((int) (subpanel_data->control_data[i]->
2903              element_values[CONTROL_MONITOR_TYPE].parsed_value) != MONITOR_NONE)
2904          {
2905             monitor = True;
2906             break;
2907          }
2908       }
2909    }
2910
2911
2912    if (control_install)
2913       attach_widget = subpanel_data->separator;
2914    else
2915       attach_widget = subpanel_data->form;
2916
2917
2918    /*  Set up a loop and create each control within the subpanel  */
2919    
2920    for (i = -1; i < subpanel_data->control_data_count; i++)
2921    {
2922       if (i == -1)
2923       {
2924          control_data = main_control_data;
2925          main = True;
2926       }
2927       else
2928       {
2929          control_data = subpanel_data->control_data[i];
2930          main = False;
2931       }
2932
2933       SubpanelControlCreate (subpanel_data, main_control_data, control_data,
2934                              attach_widget, main, monitor);
2935
2936       if (main)
2937          attach_widget = subpanel_data->main_panel_icon_copy;
2938       else
2939          attach_widget = control_data->icon;
2940    }
2941
2942
2943    /*  Pad the bottom of the last control in the subpanel  */
2944    
2945    ac = 0;
2946    XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);        ac++;
2947    XtSetArg (al[ac], XmNbottomOffset, 5);                        ac++;
2948    XtSetValues (attach_widget, al, ac);
2949
2950
2951    XtUnmanageChild (subpanel_data->form);
2952    XtSetMappedWhenManaged (subpanel_data->shell, True);
2953
2954
2955    /*  Add the callback for handling subpanel unmaps from the system menu  */
2956
2957    XtAddCallback (subpanel_data->form, XmNunmapCallback,
2958                   (XtCallbackProc) SubpanelUnmapCB,
2959                   (XtPointer) main_control_data);
2960
2961
2962    /*  Set subpanel posting state variables  */
2963
2964    subpanel_data->torn = False;
2965
2966
2967    /*  Initialize the subpanels default control setting to the main  */
2968    /*  panel control.                                                */
2969    
2970    subpanel_data->default_control = main_control_data;
2971
2972    /*  Set the initial XmNcancelButton resource to the default control  */
2973    /*  within the subpanel.                                             */
2974
2975    if (subpanel_data->control_data)
2976       XtSetArg (al[0], XmNcancelButton, subpanel_data->control_data[0]->icon);
2977    else
2978       XtSetArg (al[0], XmNcancelButton, subpanel_data->main_panel_icon_copy);
2979
2980    XtSetValues (subpanel_data->form, al, 1);
2981
2982 }
2983
2984
2985
2986
2987 /************************************************************************
2988  *
2989  *  SubpanelControlCreate
2990  *      Create a control within the subpanel
2991  *
2992  ************************************************************************/
2993
2994 void
2995 SubpanelControlCreate (SubpanelData * subpanel_data,
2996                        ControlData  * main_control_data,
2997                        ControlData  * control_data,
2998                        Widget         attach_widget,
2999                        Boolean        main,
3000                        Boolean        monitor)
3001
3002 {
3003    XmString icon_label = NULL;
3004    Widget control_icon;
3005
3006    Arg al[40];
3007    int ac = 0;
3008    int ac_save;
3009
3010    char m_state;
3011
3012    char * icon_name = NULL;
3013    char * alt_icon_name = NULL;
3014    String exp_file_name = NULL;
3015
3016
3017    /*  Call the function used to set the control's pixel and font data  */
3018
3019    ControlSetVisualData (control_data, al, &ac);
3020    ac_save = ac;
3021
3022
3023    /*  Set the control's positioning resources  */
3024
3025    if (monitor)
3026    {
3027       XtSetArg (al[ac], XmNleftOffset, 20);                     ac++;
3028    }
3029    else
3030    {
3031       XtSetArg (al[ac], XmNleftOffset, 5);                      ac++;
3032    }
3033
3034
3035    XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);         ac++;
3036    XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET);        ac++;
3037    XtSetArg (al[ac], XmNtopWidget, attach_widget);              ac++;
3038    XtSetArg (al[ac], XmNtopOffset, 5);                          ac++;
3039    XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);        ac++;
3040    XtSetArg (al[ac], XmNrightOffset, 5);                        ac++;
3041    XtSetArg (al[ac], XmNmarginWidth, 1);                        ac++;
3042    XtSetArg (al[ac], XmNmarginHeight, 1);                       ac++;
3043
3044
3045    /*  Call the function used to set the control's icon and label data  */
3046       
3047    ControlSetIconData (subpanel_data->form, control_data, 
3048                        &icon_label, SUBPANEL, al, &ac,
3049                        &icon_name, &alt_icon_name);
3050
3051
3052    /*  Call the function used to set the control's behavioral aspects  */
3053
3054    ControlSetBehavior (control_data, al, &ac, True, &exp_file_name);
3055
3056
3057    /*  Call the function used to create and register the control  */
3058
3059    control_icon = 
3060       ControlCreateAndRegister(subpanel_data->form, control_data, main, al, ac);
3061
3062    if (main)
3063       subpanel_data->main_panel_icon_copy = control_icon;
3064    else
3065       control_data->icon = control_icon;
3066
3067
3068    if (icon_label != NULL)
3069       XmStringFree (icon_label);
3070
3071    if (icon_name != NULL)
3072       XtFree(icon_name);
3073
3074    if (alt_icon_name != NULL)
3075       XtFree(alt_icon_name);
3076
3077    if (exp_file_name != NULL)
3078       XtFree(exp_file_name);
3079
3080    /*  If there is a monitor file, create the indicator  */
3081
3082    if ((int) (control_data->
3083        element_values[CONTROL_MONITOR_TYPE].parsed_value) != MONITOR_NONE)
3084    {
3085       ac = ac_save;
3086
3087       m_state = _DtControlGetMonitorState(control_icon);
3088
3089       XtSetArg (al[ac], XmNleftOffset, 3);                              ac++;
3090       XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);              ac++;
3091       XtSetArg (al[ac], XmNtopOffset, 6);                               ac++;
3092       XtSetArg (al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET);    ac++;
3093       XtSetArg (al[ac], XmNtopWidget, control_icon);                    ac++;
3094       XtSetArg (al[ac], XmNhighlightThickness, 0);                      ac++;
3095       XtSetArg (al[ac], XmNmarginWidth, 1);                             ac++;
3096       XtSetArg (al[ac], XmNmarginHeight, 1);                            ac++;
3097       XtSetArg (al[ac], XmNstring, NULL);                               ac++;
3098
3099       if (m_state == DtMONITOR_ON)
3100       {
3101          XtSetArg (al[ac], XmNimageName, indicator_on_image);           ac++;
3102       }
3103       else /* DtMONITOR_OFF */
3104       {
3105          XtSetArg (al[ac], XmNimageName, indicator_off_image);          ac++;
3106       }
3107
3108       control_data->indicator =
3109          _DtCreateControl (subpanel_data->form, "indicator", al, ac);
3110       XtManageChild (control_data->indicator);
3111
3112       XtAddCallback (control_data->indicator, XmNhelpCallback,
3113                   (XtCallbackProc) GeneralTopicHelpCB, MONITOR_INDICATOR);
3114
3115       XtSetSensitive (control_data->indicator, False);
3116    }
3117 }
3118
3119
3120
3121
3122 /************************************************************************
3123  *
3124  *  UpdateSwitchGeometry
3125  *      Updates the geometry of the switch area to layout the switch
3126  *      buttons and switch controls appropriately.
3127  *      
3128  *      Inputs:
3129  *         box_data:  The box that contains the switch.
3130  *
3131  ************************************************************************/
3132
3133
3134 void
3135 UpdateSwitchGeometry (BoxData * box_data)
3136
3137
3138 {
3139    int new_margin;
3140    Dimension switch_rc_height, switch_button_height;
3141    Arg al[2];
3142
3143    if (box_data->switch_data == NULL) return;
3144
3145    XtSetArg (al[0], XmNheight, &switch_rc_height);
3146    XtGetValues (box_data->switch_data->rc, al, 1);
3147
3148    XtSetArg (al[0], XmNheight, &switch_button_height);
3149    XtGetValues (box_data->switch_data->buttons[0], al, 1);
3150               
3151    new_margin = ((int)switch_rc_height -
3152                  (int)switch_button_height * panel.switch_row_count) /
3153                  (panel.switch_row_count + 1);
3154
3155    if (new_margin < 1) new_margin = 1;
3156
3157    XtSetArg (al[0], XmNmarginHeight, new_margin);
3158    XtSetArg (al[1], XmNspacing, new_margin);
3159    XtSetValues (box_data->switch_data->rc, al, 2);
3160 }
3161
3162
3163
3164
3165 /************************************************************************
3166  *
3167  *  AddSubpanel
3168  *      Create and initialize a new subpanel and attach it to control_data
3169  *      
3170  *      Inputs:
3171  *         control_data:  The main panel control to which the subpanel
3172  *                        will be attached.
3173  *
3174  ************************************************************************/
3175  
3176 void
3177 AddSubpanel (ControlData * control_data)
3178
3179
3180 {
3181    ElementValue * element_values;
3182    SubpanelData * subpanel_data;
3183    BoxData * box_data = (BoxData *)control_data->parent_data;
3184
3185    DtWmHints vHints;
3186
3187    Arg al[2];
3188    int i;
3189
3190
3191    if (control_data->subpanel_data == NULL)
3192    {
3193       control_data->subpanel_data =
3194             (SubpanelData *) XtMalloc (sizeof (SubpanelData));   
3195
3196       subpanel_data = control_data->subpanel_data;
3197       
3198       element_values = (ElementValue *) XtMalloc (sizeof(ElementValue) *
3199                                                   SUBPANEL_KEYWORD_COUNT);
3200       
3201       for (i = 0; i < SUBPANEL_KEYWORD_COUNT; i++)
3202       {
3203          (element_values)[i].use_default = True;
3204          (element_values)[i].string_value = NULL;
3205          (element_values)[i].parsed_value = NULL;
3206       }
3207
3208       element_values[SUBPANEL_NAME].string_value = XtNewString(
3209                 control_data->element_values[CONTROL_NAME].parsed_value);
3210       element_values[SUBPANEL_CONTAINER_NAME].string_value = XtNewString(
3211                 control_data->element_values[CONTROL_NAME].parsed_value);
3212       if (control_data->element_values[CONTROL_LABEL].parsed_value != NULL)
3213          element_values[SUBPANEL_TITLE].string_value = XtNewString(
3214                 control_data->element_values[CONTROL_LABEL].parsed_value);
3215       else
3216          element_values[SUBPANEL_TITLE].string_value = XtNewString(
3217                 control_data->element_values[CONTROL_NAME].parsed_value);
3218       
3219       subpanel_data->control_data = NULL;
3220       subpanel_data->control_data_count = 0;
3221       subpanel_data->parent_control_data = control_data;
3222
3223       InitializeSubpanelFields (element_values);
3224
3225       subpanel_data->element_values = element_values;
3226    }
3227
3228    if (!XtIsManaged(XtParent(control_data->arrow)))
3229    {
3230
3231       if (box_data->left_arrow_form)
3232       {
3233          XtSetArg (al[0], XmNtopAttachment, XmATTACH_WIDGET);
3234          XtSetArg (al[1], XmNtopWidget, box_data->left_arrow_form);
3235          XtSetValues(box_data->left_control_form, al, 2);
3236
3237          XtManageChild(box_data->left_arrow_form);
3238       }
3239
3240       if (box_data->right_arrow_form)
3241       {
3242          XtManageChild(box_data->right_arrow_form);
3243
3244          XtSetArg (al[0], XmNtopAttachment, XmATTACH_WIDGET);
3245          XtSetArg (al[1], XmNtopWidget, box_data->right_arrow_form);
3246          XtSetValues(box_data->right_control_form, al, 2);
3247       }
3248
3249       UpdateSwitchGeometry(box_data);
3250
3251    }
3252
3253    box_data->subpanel_count++;
3254
3255    SubpanelCreate (control_data, subpanel_data);
3256
3257
3258    XtSetArg (al[0], XmNimageName, post_arrow_image);
3259    XtSetArg (al[1], XmNsensitive, True);
3260    XtSetValues (control_data->arrow, al, 2);
3261
3262    /*  Set the subpanels hint and transient behavior  */
3263
3264    vHints.flags = DtWM_HINTS_BEHAVIORS | DtWM_HINTS_ATTACH_WINDOW;
3265    vHints.behaviors = DtWM_BEHAVIOR_PANEL | DtWM_BEHAVIOR_SUBPANEL;
3266    vHints.attachWindow = XtWindow (panel.shell);
3267
3268    XtSetArg (al[0], XmNtransientFor, panel.shell);
3269    XtSetValues (subpanel_data->shell, al, 1);
3270
3271    XtRealizeWidget (subpanel_data->form);
3272    _DtWsmSetDtWmHints (XtDisplay (panel.shell), 
3273                       XtWindow (subpanel_data->shell), &vHints);
3274
3275    WriteSubpanelComponentFile(control_data->subpanel_data);
3276 }
3277
3278
3279
3280
3281 /************************************************************************
3282  *
3283  *  DeleteControl
3284  *      Remove a control upon a menu request for deletion.
3285  *
3286  *  Inputs: control_data - a pointer to the control to be deleted.
3287  *
3288  ************************************************************************/
3289
3290
3291 void
3292 DeleteControl (ControlData * control_data)
3293
3294
3295 {
3296    int i;
3297
3298
3299    /*  Remove the control from the push recall and embedded client list.  */
3300    
3301    PushRecallRegister (control_data, False);
3302
3303    EmbeddedClientRegister (control_data, False);
3304
3305
3306    /*  Destroy the widgets allocated by the control  */
3307
3308    if (control_data->indicator)
3309       XtDestroyWidget (control_data->indicator);
3310
3311    if (control_data->icon)
3312    {
3313       if (control_data->element_values[CONTROL_DROP_ACTION].parsed_value
3314                                                                     != NULL)
3315          DtDndDropUnregister(control_data->icon);
3316       XtDestroyWidget (control_data->icon);
3317    }
3318
3319
3320    /*  Remove the copy of the action set and delete the element values  */
3321
3322    DeleteControlActionList (control_data);
3323
3324    RemoveEntry (control_data, CONTROL);
3325 }
3326
3327
3328
3329
3330 /************************************************************************
3331  *
3332  *  DeleteSubpanel
3333  *      Delete the subpanel attached to the control pointed to by
3334  *      control_data.
3335  *
3336  *  Inputs: control_data - a pointer to the main panel control that the
3337  *          subpanel is attached to.
3338  *
3339  ************************************************************************/
3340  
3341
3342 void
3343 DeleteSubpanel (ControlData * control_data)
3344
3345
3346 {
3347    SubpanelData * subpanel_data = control_data->subpanel_data;
3348    BoxData * box_data = (BoxData *) control_data->parent_data;
3349    Arg al[2];
3350    int i;
3351
3352
3353    /*  If the current main control is not within the main panel, call  */
3354    /*  the DeleteSubpanelControl function to delete the main control   */
3355    /*  This will cause the current subpanel control within the main    */
3356    /*  panel to be promoted to a main panel control.                   */
3357    
3358    if (subpanel_data->parent_control_data != control_data)
3359    {
3360       subpanel_data->torn = True;
3361       DeleteSubpanelControl (subpanel_data, subpanel_data->parent_control_data);
3362       subpanel_data->parent_control_data->subpanel_data = NULL;
3363    }
3364
3365
3366    /*  Set the main panel control's arrow to blank and insensitive  */
3367    
3368    XtSetArg (al[0], XmNimageName, blank_arrow_image);
3369    XtSetValues (subpanel_data->parent_control_data->arrow, al, 1);
3370    XtSetSensitive (subpanel_data->parent_control_data->arrow, False);
3371
3372
3373    /*  Either remove a dynamic .fp or write out the subpanel's .fp  */
3374    /*  with the DELETE keyword set                                  */
3375    
3376    RemoveSubpanelComponentFile (subpanel_data);
3377
3378
3379    /*  Delete the controls within the subpanel, destroy the remaining  */
3380    /*  widgets and free up the remaining data.                         */
3381    
3382    for (i = 0; i < subpanel_data->control_data_count; i++)
3383    {
3384       RemoveControlComponentFile (subpanel_data->control_data[i]);
3385       DeleteControl (subpanel_data->control_data[i]);
3386       XtFree ((char *) subpanel_data->control_data[i]);
3387    }
3388
3389   /* Remove install zones */
3390    if (subpanel_data->element_values[SUBPANEL_CONTROL_INSTALL].parsed_value)
3391    {
3392       DtDndDropUnregister (subpanel_data->dropzone);
3393       XtDestroyWidget (subpanel_data->dropzone);
3394    }
3395
3396    XtDestroyWidget (subpanel_data->shell);
3397    XtFree ((char *) subpanel_data->control_data);
3398
3399    RemoveEntry (subpanel_data, SUBPANEL);
3400
3401    XtFree ((char *) subpanel_data);
3402    control_data->subpanel_data = NULL;
3403
3404    box_data->subpanel_count--;
3405
3406    if (box_data->subpanel_count == 0)
3407    {
3408       if (box_data->left_arrow_form)
3409       {
3410          XtSetArg (al[0], XmNtopAttachment, XmATTACH_FORM);
3411          XtSetArg (al[1], XmNtopOffset, 0);
3412          XtSetValues(box_data->left_control_form, al, 2);
3413
3414          XtUnmanageChild(box_data->left_arrow_form);
3415       }
3416
3417       if (box_data->right_arrow_form)
3418       {
3419          XtUnmanageChild(box_data->right_arrow_form);
3420
3421          XtSetArg (al[0], XmNtopAttachment, XmATTACH_FORM);
3422          XtSetArg (al[1], XmNtopOffset, 0);
3423          XtSetValues(box_data->right_control_form, al, 2);
3424       }
3425
3426       UpdateSwitchGeometry(box_data);
3427    }
3428 }
3429
3430
3431
3432  
3433 /************************************************************************
3434  *
3435  *  SwapElementValue
3436  *      Exchange the values between two element value structures.
3437  *
3438  *  Inputs: to_value, from_value - pointer to the two element value 
3439  *          structures in which to exchange the values.
3440  *
3441  ************************************************************************/
3442   
3443
3444 static void
3445 SwapElementValue (ElementValue * to_value,
3446                   ElementValue * from_value)
3447
3448
3449 {
3450    Boolean   use_default;
3451    char    * string_value;
3452    void    * parsed_value;
3453
3454    use_default = from_value->use_default;
3455    string_value = from_value->string_value;
3456    parsed_value = from_value->parsed_value;
3457
3458    from_value->use_default = to_value->use_default;
3459    from_value->string_value = to_value->string_value;
3460    from_value->parsed_value = to_value->parsed_value;
3461
3462    to_value->use_default = use_default;
3463    to_value->string_value = string_value;
3464    to_value->parsed_value = parsed_value;
3465 }
3466
3467
3468
3469
3470 /************************************************************************
3471  *
3472  *  DeleteSubpanelControl
3473  *      This function removes a control contained in control_data from
3474  *      a subpanel.
3475  *
3476  *      Inputs:
3477  *         subpanel_data:  The subpanel the control is being deleted from
3478  *         control_data:   The control to be deleted
3479  *
3480  ************************************************************************/
3481
3482
3483 void
3484 DeleteSubpanelControl (SubpanelData * subpanel_data,
3485                        ControlData  * control_data)
3486
3487
3488 {
3489    ControlData * main_control_data = subpanel_data->parent_control_data;
3490    int           control_data_count;
3491
3492    Widget  * child_list;
3493    int       num_children;
3494    Widget    attach_widget = NULL;
3495    Widget    target_widget = NULL;
3496    Boolean   last = False;
3497    Dimension height;
3498
3499    Boolean control_monitor;
3500
3501    Arg al[2];
3502    int i, j;
3503
3504
3505    /*  Put the subpanel down before mucking with the widget hierarchy  */
3506
3507    if (subpanel_data->torn == False)
3508       XtUnmanageChild (subpanel_data->shell);        
3509
3510
3511    /*  There are 3 deletion cases.                                     */
3512    /*    1. Deletion of the main panel copy when there are 0 subpanel  */
3513    /*       controls.  This involves destroying the copy and deleting  */
3514    /*       the subpanel.                                              */
3515    /*                                                                  */
3516    /*    2. Deletion of the main panel copy when there is subpanel     */
3517    /*       controls.  This involves the full deletion of the main     */
3518    /*       panel control and the promotion of a subpanel control to   */
3519    /*       a full main panel control.                                 */
3520    /*                                                                  */
3521    /*    3. Deletion of a subpanel control.  This involves the full    */
3522    /*       deletion of the subpanel control and if it has been        */
3523    /*       toggled to the main panel another control is selected      */
3524
3525    control_data_count = subpanel_data->control_data_count;
3526
3527    if (main_control_data == control_data && control_data_count == 0)
3528    {
3529       DeleteSubpanel (main_control_data);
3530       return;
3531    }
3532
3533
3534    /*  Look through the controls parent (form) child list to get    */
3535    /*  the position of the control to be deleted and the previous   */
3536    /*  and next control.  This is needed for resetting constraints  */
3537
3538    if (main_control_data == control_data)
3539    {
3540       height = XtHeight (subpanel_data->main_panel_icon_copy);
3541       XtSetArg (al[0], XmNtopWidget, &target_widget);
3542       XtGetValues (subpanel_data->main_panel_icon_copy, al, 1);
3543    }
3544    else
3545    {
3546       height = XtHeight (control_data->icon);
3547       XtSetArg (al[0], XmNtopWidget, &target_widget);
3548       XtGetValues (control_data->icon, al, 1);
3549    }
3550    
3551    XtSetArg (al[0], XmNchildren, &child_list);
3552    XtSetArg (al[1], XmNnumChildren, &num_children);
3553    XtGetValues (subpanel_data->form, al, 2);
3554    
3555    for (i = 0; i < num_children; i++)
3556    {
3557       XtSetArg (al[0], XmNtopWidget, &attach_widget);
3558       XtGetValues (child_list[i], al, 1);
3559
3560       if ((main_control_data == control_data && 
3561           attach_widget == subpanel_data->main_panel_icon_copy) ||
3562           (main_control_data != control_data && 
3563            attach_widget == control_data->icon))
3564       {
3565          attach_widget = child_list[i];
3566          break;
3567       }
3568    }
3569
3570    if (i == num_children)
3571    {
3572       attach_widget = NULL;
3573       last = True;
3574    }
3575
3576
3577    if (main_control_data == control_data)
3578    {
3579       ControlData * subpanel_control_data;
3580       int           subpanel_control_position;
3581       
3582
3583       if (main_control_data == subpanel_data->default_control)
3584          ToggleDefaultControl (main_control_data, subpanel_data,
3585                                subpanel_data->control_data[0]);
3586
3587       subpanel_control_data = subpanel_data->default_control;
3588
3589       
3590       /*  Remove the .fp or write a Delete .fp for both the main panel  */
3591       /*  control and subpanel control.  The subpanel data will then    */
3592       /*  be moved the the main panel data and the new control will be  */
3593       /*  written.                                                      */
3594    
3595       /*  For the main panel control, if a dynamic .fp exists, remove  */
3596       /*  it otherwize, do nothing since a new one will be written.    */
3597       
3598       if (SessionFileNameLookup ((char *) main_control_data->element_values[CONTROL_NAME].parsed_value,
3599                                  (int) CONTROL,
3600                                  (char *) main_control_data->element_values[CONTROL_CONTAINER_NAME].parsed_value,
3601                                  (int) BOX) != NULL)
3602          RemoveControlComponentFile (main_control_data);
3603
3604       RemoveControlComponentFile (subpanel_control_data);
3605
3606
3607       /*  Find the position of the subpanel control data    */
3608       /*  within their parent list, for latter processing   */
3609       
3610       for (subpanel_control_position = 0; 
3611            subpanel_control_position < subpanel_data->control_data_count;
3612            subpanel_control_position++)
3613       {
3614          if (subpanel_data->control_data[subpanel_control_position] == subpanel_control_data)
3615             break;
3616       }
3617
3618
3619       /*  Reset the subpanel values that were switch from the deleted  */
3620       /*  main control when ToggleDefaultControl was called above.     */
3621       
3622       XtDestroyWidget (subpanel_data->main_panel_icon_copy);
3623       subpanel_data->main_panel_icon_copy = subpanel_control_data->icon;
3624       subpanel_data->default_control = main_control_data;
3625
3626       
3627       /*  Move the necessary data from the MP control to the SP control  */
3628       /*  and write out the new control file.                            */
3629
3630       SwapElementValue (&subpanel_control_data->element_values[CONTROL_NAME],
3631                         &main_control_data->element_values[CONTROL_NAME]);
3632       SwapElementValue (&subpanel_control_data->element_values[CONTROL_CONTAINER_NAME],
3633                         &main_control_data->element_values[CONTROL_CONTAINER_NAME]);
3634       SwapElementValue (&subpanel_control_data->element_values[CONTROL_CONTAINER_TYPE],
3635                         &main_control_data->element_values[CONTROL_CONTAINER_TYPE]);
3636       SwapElementValue (&subpanel_control_data->element_values[CONTROL_POSITION_HINTS],
3637                         &main_control_data->element_values[CONTROL_POSITION_HINTS]);
3638
3639       WriteControlComponentFile (subpanel_control_data);
3640
3641       
3642       /*  Delete the main panel control.  Null out the icon field   */
3643       /*  since it is being used within the subpanel_control_data.  */
3644       
3645       subpanel_control_data->icon = main_control_data->icon;
3646       main_control_data->icon = NULL;
3647       DeleteControl (main_control_data);
3648
3649
3650       /*  Set the main control to the subpanel control values  */
3651
3652       main_control_data->element_values = subpanel_control_data->element_values;
3653       main_control_data->icon = subpanel_control_data->icon;
3654       main_control_data->indicator = subpanel_control_data->indicator;
3655       main_control_data->actions = subpanel_control_data->actions;
3656
3657
3658       /*  Remove and readd the callbacks from the main control and  */
3659       /*  the main panel icon copy.                                 */
3660       
3661       XtRemoveCallback (main_control_data->icon, XmNcallback, 
3662                         (XtCallbackProc) PushCB, subpanel_control_data);
3663
3664       XtRemoveCallback (main_control_data->icon, XmNhelpCallback,
3665                         (XtCallbackProc) ControlTopicHelpCB, subpanel_control_data);
3666       
3667       XtAddCallback (main_control_data->icon, XmNcallback, 
3668                      (XtCallbackProc) PushCB, main_control_data);
3669
3670       XtAddCallback (main_control_data->icon, XmNhelpCallback,
3671                      (XtCallbackProc) ControlTopicHelpCB, main_control_data);
3672
3673       
3674       XtRemoveCallback (subpanel_data->main_panel_icon_copy, XmNcallback, 
3675                         (XtCallbackProc) PushCB, subpanel_control_data);
3676
3677       XtRemoveCallback (subpanel_data->main_panel_icon_copy, XmNhelpCallback,
3678                         (XtCallbackProc) ControlTopicHelpCB, subpanel_control_data);
3679       
3680       XtAddCallback (subpanel_data->main_panel_icon_copy, XmNcallback, 
3681                      (XtCallbackProc) PushCB, main_control_data);
3682
3683       XtAddCallback (subpanel_data->main_panel_icon_copy, XmNhelpCallback,
3684                      (XtCallbackProc) ControlTopicHelpCB, main_control_data);
3685
3686
3687
3688       /*  Move the subpanel control data's up one position within the    */
3689       /*  subpanel's list to denote the removal of the subpanel control  */
3690       /*  and free up the remaining subpanel data.                       */
3691
3692       for (i = subpanel_control_position; i < subpanel_data->control_data_count - 1; i++)
3693          subpanel_data->control_data[i] = subpanel_data->control_data[i + 1];
3694
3695       subpanel_data->control_data_count--;
3696
3697       XtFree ((char *) subpanel_control_data);
3698
3699
3700       if (subpanel_data->control_data_count == 0)
3701       {
3702          XtFree ((char *) subpanel_data->control_data);
3703          subpanel_data->control_data = NULL;
3704       }
3705    }
3706    else
3707    {
3708       /*  Call a function which either unlinks the dynamic .fp file or  */
3709       /*  writes a Delete = True dynamic .fp file.  The function also   */
3710       /*  updates the session tables.                                   */
3711    
3712       RemoveControlComponentFile (control_data);
3713
3714
3715       for (i = 0; i < subpanel_data->control_data_count; i++)
3716       {
3717           if (control_data == subpanel_data->control_data[i]) break;
3718       }
3719
3720       if (subpanel_data->default_control == control_data)
3721       {
3722          if (i < subpanel_data->control_data_count - 1)
3723          {
3724             ToggleDefaultControl (main_control_data, subpanel_data,
3725                                   subpanel_data->control_data[i + 1]);
3726          }
3727          else
3728          {
3729             if (i > 0)
3730                ToggleDefaultControl (main_control_data, subpanel_data,
3731                                      subpanel_data->control_data[i - 1]);
3732             else if (subpanel_data->main_panel_icon_copy != NULL)
3733                ToggleDefaultControl (main_control_data, subpanel_data,
3734                                      main_control_data);
3735          }
3736       }
3737
3738       DeleteControl (control_data);
3739
3740       /*  Loop through the control list and move the controls down  */
3741       /*  one position.                                             */
3742       
3743       for (j = i + 1 ; j < subpanel_data->control_data_count; j++)
3744       {
3745          subpanel_data->control_data[j - 1] = subpanel_data->control_data[j];
3746       }
3747
3748       subpanel_data->control_data_count--;
3749    }
3750
3751
3752    /*  If the subpanel is empty, delete it.  */
3753    
3754    if (subpanel_data->main_panel_icon_copy == NULL &&
3755        subpanel_data->control_data_count == 0)
3756    {
3757       DeleteSubpanel (subpanel_data->parent_control_data);
3758       return;
3759    }
3760
3761
3762    /*  Get the control positioning constraints reset  */
3763    
3764    if (attach_widget != NULL && target_widget != NULL)
3765    {
3766       XtSetArg (al[0], XmNtopWidget, target_widget);
3767       XtSetValues (attach_widget, al, 1);
3768    }
3769
3770    if (last)
3771    {
3772       XtSetArg (al[0], XmNbottomAttachment, XmATTACH_FORM);
3773       XtSetArg (al[1], XmNbottomOffset, 5);
3774       XtSetValues (target_widget, al, 2);
3775
3776       XtSetArg (al[0], XmNheight, XtHeight (subpanel_data->form) -
3777                                   (XtHeight (target_widget) - height));
3778       XtSetValues (subpanel_data->form, al, 1);
3779    }
3780
3781
3782    /*  Loop through the remaining controls and see if any left are  */
3783    /*  monitors.  If not, adjust the left pad of the controls       */
3784    
3785    control_monitor = False;
3786
3787    for (j = 0; j < subpanel_data->control_data_count; j++)
3788    {
3789       if ((int) subpanel_data->control_data[j]->
3790           element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
3791       {
3792          control_monitor = True;
3793          break;
3794       }
3795    }
3796
3797    if ((int) main_control_data->
3798        element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
3799    {
3800       control_monitor = True;
3801    }
3802
3803    if (control_monitor == False)
3804    {
3805       XtSetArg (al[0], XmNleftOffset, 5);
3806
3807       for (j = 0; j < subpanel_data->control_data_count; j++)
3808          XtSetValues (subpanel_data->control_data[j]->icon, al, 1);
3809
3810       if (subpanel_data->main_panel_icon_copy != NULL)
3811          XtSetValues (subpanel_data->main_panel_icon_copy, al, 1);
3812    }
3813
3814
3815    /*  Pop the subpanel back up and resume processing  */
3816
3817    if (subpanel_data->torn == False)
3818        ArrowCB (main_control_data->arrow,
3819                 (XtPointer)main_control_data, (XtPointer)NULL);
3820
3821    /*  Set the XmNcancelButton resource to the default control  */
3822    /*  within the subpanel.                                     */
3823
3824    if (subpanel_data->control_data)
3825       XtSetArg (al[0], XmNcancelButton, subpanel_data->control_data[0]->icon);
3826    else
3827       XtSetArg (al[0], XmNcancelButton, subpanel_data->main_panel_icon_copy);
3828
3829    XtSetValues (subpanel_data->form, al, 1);
3830
3831 }
3832
3833
3834
3835
3836 /************************************************************************
3837  *
3838  *  ToggleDefaultControl
3839  *      This is used to switch the main panel control to the control
3840  *      attached to the selected toggle.
3841  *
3842  *  Inputs:
3843  *      main_control_data - a pointer to the main panel's control data.
3844  *      subpanel_data - a pointer to the subpanel where the control to
3845  *                      be put in the main panel is coming from.
3846  *      control_data - a pointer to the control in the subpanel to be 
3847  *                     toggled into the main panel.
3848  *
3849  ************************************************************************/
3850
3851
3852 void
3853 ToggleDefaultControl (ControlData  * main_control_data,
3854                       SubpanelData * subpanel_data,
3855                       ControlData  * control_data)
3856
3857
3858 {
3859    BoxData * box_data;
3860
3861    Widget prev_icon = NULL;
3862    Widget next_icon = NULL;
3863    Widget old_main_icon = main_control_data->icon;
3864    Widget main_subpanel_icon;
3865    Widget parent = XtParent (old_main_icon);
3866    Widget control_icon;
3867
3868    char * icon_name = NULL;
3869    char * alt_icon_name = NULL;
3870    String exp_file_name = NULL;
3871
3872
3873    XmString icon_label = NULL;
3874
3875    Dimension width;
3876    Dimension new_width;
3877
3878    Arg al[40];
3879    int ac;
3880    int i;
3881
3882
3883    /*  If the selection occured on the currently selected toggle   */
3884    /*  do nothing.                                                 */
3885
3886    if (subpanel_data->default_control == control_data)
3887       return;
3888
3889
3890    /*  Update the main panel control's push recall and embedded client  */
3891    /*  lists, and reparent the embedded client if necessary.            */
3892
3893    if (main_control_data == subpanel_data->default_control)
3894    {
3895       control_icon = main_control_data->icon;
3896       main_control_data->icon = subpanel_data->main_panel_icon_copy;
3897
3898       if ((Boolean) main_control_data->element_values[CONTROL_PUSH_RECALL].parsed_value)
3899          PushRecallRegister (main_control_data, True);
3900
3901       if ((char) main_control_data->element_values[CONTROL_TYPE].parsed_value == CONTROL_CLIENT)
3902          EmbeddedClientRegister (main_control_data, True);
3903
3904       main_control_data->icon = control_icon;
3905
3906       if ((char) main_control_data->
3907           element_values[CONTROL_TYPE].parsed_value == CONTROL_CLIENT)
3908       {
3909          EmbeddedClientReparent ((char *) main_control_data->
3910                       element_values[CONTROL_CLIENT_NAME].parsed_value,
3911                       subpanel_data->main_panel_icon_copy);
3912       }
3913    }
3914    else
3915    {
3916       if ((Boolean) subpanel_data->default_control->element_values[CONTROL_PUSH_RECALL].parsed_value)
3917          PushRecallRegister (subpanel_data->default_control, True);
3918
3919       if ((char) subpanel_data->default_control->element_values[CONTROL_TYPE].parsed_value == CONTROL_CLIENT)
3920          EmbeddedClientRegister (subpanel_data->default_control, True);
3921
3922       if ((char) subpanel_data->default_control->
3923           element_values[CONTROL_TYPE].parsed_value == CONTROL_CLIENT)
3924       {
3925          EmbeddedClientReparent ((char *) subpanel_data->default_control->
3926                      element_values[CONTROL_CLIENT_NAME].parsed_value,
3927                      subpanel_data->default_control->icon);
3928       }
3929    }
3930
3931
3932    subpanel_data->default_control = control_data;
3933    control_data->subpanel_data = subpanel_data;
3934    main_control_data->is_action = control_data->is_action;
3935
3936
3937    /*  Get the width of the current main control to be used to  */
3938    /*  possible adjust the new control when it is created.      */
3939
3940    width = XtWidth (main_control_data->icon);
3941
3942
3943    /*  Disallow geometry changes of the main control's parent until  */
3944    /*  after the controls have been destroyed and created            */
3945
3946    XtSetArg (al[0], XmNresizePolicy, XmRESIZE_NONE);
3947    XtSetValues (parent, al, 1);
3948
3949
3950    /*  Create the new control using the control data from the  */
3951    /*  control within the subpanel                             */
3952
3953    /*  Loop through the main controls parent data (box_data) to  */
3954    /*  find its position relative to controls around it          */
3955    
3956    box_data = (BoxData *) main_control_data->parent_data;
3957    
3958    for (i = 0; i < box_data->control_data_count; i++)
3959    {
3960       if (box_data->control_data[i] == main_control_data)
3961       {
3962          if (i != 0)
3963             prev_icon = box_data->control_data[i - 1]->icon;
3964
3965          if (i != box_data->control_data_count - 1)
3966             next_icon = box_data->control_data[i + 1]->icon;
3967
3968          break;
3969       }
3970    }
3971
3972
3973    /*  Call the function used to set the control's pixel and font data  */
3974
3975    ac = 0;
3976    ControlSetVisualData (control_data, al, &ac);
3977
3978    XtSetArg (al[ac], XmNpixmapPosition, XmPIXMAP_TOP);  ac++;
3979
3980
3981    /*  Set up the attachment constraints for the control  */
3982
3983    XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);          ac++;
3984    XtSetArg (al[ac], XmNtopOffset, 1);                          ac++;
3985    XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);       ac++;
3986    XtSetArg (al[ac], XmNbottomOffset, 1);                       ac++;
3987
3988    if (prev_icon == NULL)
3989    {
3990       XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);      ac++;
3991       XtSetArg (al[ac], XmNleftOffset, 1);                      ac++;
3992    }
3993    else
3994    {
3995       XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET);    ac++;    
3996       XtSetArg (al[ac], XmNleftWidget, prev_icon);              ac++;    
3997    }
3998
3999    if (next_icon == NULL)
4000    {
4001       XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);     ac++;
4002       XtSetArg (al[ac], XmNrightOffset, 1);                     ac++;
4003    }
4004      
4005
4006    /*  Call the function used to set the control's icon and label data  */
4007       
4008    ControlSetIconData (parent, control_data, &icon_label, BOX, al, &ac,
4009                        &icon_name, &alt_icon_name);
4010
4011
4012    /*  Call the function used to set the control's behavioral aspects  */
4013
4014    ControlSetBehavior (control_data, al, &ac, False, &exp_file_name);
4015
4016
4017    /*  Call the function used to create and register the control  */
4018
4019    control_icon = control_data->icon;
4020
4021    main_control_data->icon = 
4022       ControlCreateAndRegister (parent, control_data, False, al, ac);
4023
4024
4025    /*  If this in not the main control copy then restore the subpanel icon  */
4026
4027    if (main_control_data != control_data)
4028       control_data->icon = control_icon;
4029
4030
4031    /*  If this is a toggle of a client control from the subpanel to  */
4032    /*  the main panel, call the reparenting function.                */
4033
4034    if ((char) control_data->
4035        element_values[CONTROL_TYPE].parsed_value == CONTROL_CLIENT)
4036    {
4037       EmbeddedClientReparent ((char *) control_data->
4038                               element_values[CONTROL_CLIENT_NAME].parsed_value,
4039                               main_control_data->icon);
4040    }
4041
4042
4043    if (icon_label != NULL)
4044       XmStringFree (icon_label);
4045
4046    if (icon_name != NULL)
4047       XtFree(icon_name);
4048
4049    if (alt_icon_name != NULL)
4050       XtFree(alt_icon_name);
4051
4052    if (exp_file_name != NULL)
4053       XtFree(exp_file_name);
4054
4055    /*  If this is not the right most control within its parent,  */
4056    /*  reset the poistioning constraints of the control to the  */
4057    /*  right of this one.                                        */
4058    
4059    if (next_icon != NULL)
4060    {
4061       ac = 0;
4062       XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET);            ac++;
4063       XtSetArg (al[ac], XmNleftWidget, main_control_data->icon);        ac++;
4064       XtSetValues (next_icon, al, ac);
4065    }
4066
4067
4068    /*  Now destroy the original main panel icon  */
4069
4070    XtDestroyWidget (old_main_icon);
4071
4072    
4073    /*  Get the width of the new icon and increase its size to minimize  */
4074    /*  the degree of resizing of the main panel.                        */
4075    
4076    new_width = XtWidth (main_control_data->icon);
4077
4078    if (new_width < width)
4079    {
4080       Dimension normal_size;
4081       Dimension margin_width;
4082       
4083       if (panel.resolution == HIGH)
4084          normal_size = ICON_HIGH_WIDTH;
4085       else if (panel.resolution == MEDIUM)
4086          normal_size = ICON_MEDIUM_WIDTH;
4087       else
4088          normal_size = ICON_LOW_WIDTH;
4089
4090       if (new_width < normal_size)
4091       {
4092          XtSetArg (al[0], XmNwidth, normal_size);
4093          XtSetArg (al[1], XmNmarginWidth, (Dimension)(normal_size-new_width)/2);
4094          XtSetValues (main_control_data->icon, al, 2);
4095       }
4096    }
4097
4098
4099    /*  Get the width of the icon again for arrow and embedded client  */
4100    /*  processing.                                                    */
4101
4102    new_width = XtWidth (main_control_data->icon);
4103
4104
4105    /*  Call a function to reposition embedded clients to the right  */
4106    /*  of the main panel control.                                   */
4107    
4108    if (new_width != width)
4109       EmbeddedClientReposition (main_control_data->icon,
4110                                 XtX (main_control_data->icon) + 3, 
4111                                 new_width - width);
4112
4113
4114    /*  Reset the geometry policy for the main control parent  */
4115
4116    XtSetArg (al[0], XmNresizePolicy, XmRESIZE_ANY);
4117    XtSetValues (parent, al, 1);
4118
4119
4120    /*  Set the width of the arrow  */
4121
4122    new_width += 2;
4123    if (prev_icon != NULL) new_width -= 2;
4124    if (next_icon != NULL) new_width -= 2;
4125
4126    XtSetArg (al[0], XmNwidth, new_width);
4127    XtSetValues (main_control_data->arrow, al, 1);
4128 }
4129
4130
4131
4132
4133 /************************************************************************
4134  *
4135  *  SetupPushAnimation
4136  *      Add the sequence of images that make up a push animation for a
4137  *      control.
4138  *
4139  *      Inputs: control_data - a pointer to the control to which to add
4140  *              the animation.
4141  *
4142  ************************************************************************/
4143  
4144
4145 static void
4146 SetupPushAnimation (ControlData * control_data)
4147
4148
4149 {
4150    char * animation_name = control_data->
4151                            element_values[CONTROL_PUSH_ANIMATION].parsed_value;
4152    int    count;
4153    int    delay;
4154    String image_name;
4155
4156    int i, j; 
4157
4158
4159    count = panel.animation_count;
4160    
4161    if (animation_name == NULL) return;
4162
4163    for (i = 0; i < count; i++)
4164    {
4165        if (!strcmp (panel.animation_data[i].name, animation_name))
4166           break;
4167    }
4168
4169    if (i < count)
4170    {
4171       for (j = 0; j < panel.animation_data[i].item_count; j++)
4172       {
4173          image_name = GetIconName (panel.animation_data[i].items[j].image_name,
4174                                    panel.main_icon_size);
4175
4176          delay = panel.animation_data[i].items[j].delay;
4177
4178          _DtControlAddPushAnimationImage (control_data->icon, image_name, delay);
4179          XtFree(image_name);
4180       }
4181    }
4182 }
4183
4184
4185
4186
4187 /************************************************************************
4188  *
4189  *  SetupDropAnimation
4190  *      Add the sequence of images that make up a drop animation for a
4191  *      control.
4192  *
4193  *      Inputs: control_data - a pointer to the control to which to add
4194  *              the animation.
4195  *
4196  ************************************************************************/
4197  
4198
4199 static void
4200 SetupDropAnimation (ControlData * control_data)
4201
4202
4203 {
4204    char * animation_name = control_data->
4205                             element_values[CONTROL_DROP_ANIMATION].parsed_value;
4206    int    count;
4207    int    delay;
4208    String image_name;
4209
4210    int i, j; 
4211
4212
4213    count = panel.animation_count;
4214    
4215    if (animation_name == NULL) return;
4216
4217    for (i = 0; i < count; i++)
4218    {
4219        if (!strcmp (panel.animation_data[i].name, animation_name))
4220           break;
4221    }
4222
4223    if (i < count)
4224    {
4225       for (j = 0; j < panel.animation_data[i].item_count; j++)
4226       {
4227          image_name = GetIconName (panel.animation_data[i].items[j].image_name,
4228                                    panel.main_icon_size);
4229
4230          delay = panel.animation_data[i].items[j].delay;
4231
4232          _DtControlAddDropAnimationImage (control_data->icon, image_name, delay);
4233          XtFree(image_name);
4234       }
4235    }
4236 }
4237
4238
4239
4240
4241
4242 /************************************************************************
4243  *
4244  *  GetIconName
4245  *      Get the file name for an icon by extracting the panel resolution
4246  *      and then looking up the image name.
4247  *
4248  *      Inputs: image_name - the base name of the image to be found
4249  *              icon_size - the size requested (t, s, m, l) for the
4250  *              icon.
4251  *
4252  ************************************************************************/
4253
4254
4255 String
4256 GetIconName (String       image_name, 
4257              unsigned int icon_size)  
4258              
4259
4260
4261 {
4262    String       return_name = NULL;
4263    Screen     * screen = XtScreen (panel.shell);
4264    unsigned int next_size;
4265
4266
4267    /*  Get name.  */
4268
4269    next_size = icon_size;
4270
4271
4272    /*  Loop through until all sizes are exhausted  */
4273
4274    while (return_name == NULL)
4275    {
4276      return_name = 
4277         _DtGetIconFileName (screen, image_name, NULL, NULL, next_size);
4278
4279      if (next_size == DtLARGE)
4280         next_size = DtMEDIUM;
4281      else if (next_size == DtMEDIUM)
4282         next_size = DtSMALL;
4283      else if (next_size == DtSMALL)
4284         next_size = DtTINY;
4285      else
4286         break; /* tried all sizes, exit loop */
4287    }
4288
4289
4290    if (return_name == NULL)
4291       return_name = 
4292          _DtGetIconFileName (screen, image_name, NULL, NULL, DtUNSPECIFIED);
4293
4294    if (return_name == NULL)
4295       return_name = 
4296          _DtGetIconFileName (screen, DEFAULT_IMAGE_NAME, NULL, NULL, icon_size);
4297
4298    if (return_name == NULL)
4299       return_name = XtNewString (image_name);
4300
4301
4302    /*  Return value to be freed by caller.  */
4303
4304    return (return_name);
4305 }