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