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