dtwm: Resolve coverity warnings related to uninitialised variables and missing return...
[oweals/cde.git] / cde / programs / dtwm / PopupMenu.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 /* $XConsortium: PopupMenu.c /main/5 1995/11/01 11:28:50 rswiston $ */
24 /*****************************************************************************
25  *****************************************************************************
26  **
27  **   File:         PopupMenu.c
28  **
29  **   Project:      CDE
30  **
31  **   Description:  This file contains the functions for creating and managing
32  **                 the main panel and subpanel popup menus.
33  **
34  **
35  ****************************************************************************
36  *****************************************************************************/
37
38
39 #include <Xm/XmP.h>
40 #include <Xm/ManagerP.h>
41 #include <Xm/RowColumn.h>
42 #include <Xm/LabelG.h>
43 #include <Xm/PushBG.h>
44 #include <Xm/SeparatoG.h>
45
46 #include <Dt/SharedProcs.h>
47
48 #include "DataBaseLoad.h"
49 #include "WmGlobal.h"
50 #include "UI.h"
51
52 #define POPUP_CHILDREN 7
53
54
55 extern void ToggleDefaultControl (ControlData *, SubpanelData *, ControlData *);
56 extern void SwitchRenameLabel (Widget, BoxData *);
57 extern Boolean CheckControlTypeFile (ControlData *);
58
59
60
61
62
63
64
65 /************************************************************************
66  *
67  *  ActionCB
68  *
69  ************************************************************************/
70  
71 void
72 ActionCB (Widget    w,
73           XtPointer client_data,
74           XtPointer call_data)
75
76
77 {
78    ControlData * control_data;
79    long           control_type;
80
81    long indx = (long) client_data;
82    Arg args[1];
83
84
85    XtSetArg (args[0], XmNuserData, &control_data);
86    XtGetValues(w, args, 1);
87
88    if (CheckControlTypeFile (control_data) == False)
89       return;
90
91    control_type = (long) (control_data->element_values[CONTROL_TYPE].parsed_value);
92
93    if (control_type == CONTROL_FILE && !control_data->is_action)
94    {
95       DtActionArg * aap;
96
97       aap = (DtActionArg *) XtCalloc(1,sizeof(DtActionArg));
98
99       aap->argClass = DtACTION_FILE;
100
101       aap->u.file.name = (char *)
102                control_data->element_values[CONTROL_FILE_NAME].parsed_value;
103
104       DtActionInvoke (control_data->icon,
105                       control_data->actions[indx]->action_name,
106                       aap, 1, NULL, NULL, NULL, 1, NULL, NULL);
107
108       XtFree ((char *) aap);
109    }
110    else
111    {
112       DtActionInvoke (control_data->icon,
113                       control_data->actions[indx]->action_name,
114                       control_data->actions[indx]->aap,
115                       control_data->actions[indx]->count,
116                       NULL, NULL, NULL, 1, NULL, NULL);
117    }
118 }
119
120
121 /************************************************************************
122  *
123  *  DeleteWorkspaceCB
124  *      The callback function is called off of a menu pick to delete
125  *      a specific workspace.  The function identifies the index of the
126  *      workspace and calls the workspace manager API to perform the delete.
127  *      All frontpanel UI processing is performed through a notification 
128  *      callback issued by the workspace manager after a successful delete.
129  *
130  ************************************************************************/
131
132 void
133 DeleteWorkspaceCB (Widget    w,
134                    XtPointer client_data,
135                    XtPointer call_data)
136
137
138 {
139    long delete_workspace = (long) client_data;
140    SwitchData * switch_data = NULL;
141    int i;
142    
143
144    /*  Look up the switch data to get the atom name of the workspace  */
145    /*  to delete.                                                     */
146    
147    for (i = 0; i < panel.box_data_count; i++)
148    {
149       if (panel.box_data[i]->switch_data != NULL)
150       {
151          switch_data = panel.box_data[i]->switch_data;
152          break;
153       }
154    }
155
156    if(switch_data)
157    {
158       _DtWsmDeleteWorkspace (panel.shell, 
159                              switch_data->atom_names[delete_workspace]);
160    }
161 }
162
163
164
165
166 /************************************************************************
167  *
168  *  RenameWorkspaceCB
169  *      The callback function is called off of a menu pick to rename
170  *      a specific workspace.  The function identifies the index of the
171  *      workspace and calls SwitchRenameLabel() function to change the switch.
172  *      button to a text widget for typing the new workspace name and setting.
173  *      up the callback to accept the new name upon activation.
174  *
175  ************************************************************************/
176
177 void
178 RenameWorkspaceCB (Widget    w,
179                    XtPointer client_data,
180                    XtPointer call_data)
181
182
183 {
184    long rename_ws = (long) client_data;
185    SwitchData * switch_data = NULL;
186    int i;
187    
188
189    /*  Look up the switch data to get the atom name of the workspace  */
190    /*  to delete.                                                     */
191    
192    for (i = 0; i < panel.box_data_count; i++)
193    {
194       if (panel.box_data[i]->switch_data != NULL)
195       {
196          switch_data = panel.box_data[i]->switch_data;
197          break;
198       }
199    }
200    
201    if(switch_data) {
202       SwitchRenameLabel (switch_data->buttons[rename_ws], panel.box_data[i]);
203    }
204 }
205
206
207
208
209
210 /************************************************************************
211  *
212  *  AddWorkspaceCB
213  *      The callback function is called off of a menu pick.  It generates
214  *      a new workspace name and calls the workspace manager API to 
215  *      create the new workspace.  All frontpanel UI processing is 
216  *      performed through a notification callback issued by the workspace
217  *      manager after a successful add.
218  *
219  ************************************************************************/
220  
221 void
222 AddWorkspaceCB (Widget    w,
223                 XtPointer client_data,
224                 XtPointer call_data)
225
226
227 {
228    SwitchData * switch_data = NULL;
229    char * switch_name;
230    char * temp_name;
231
232    int append;
233    int i;
234    int slen;
235
236    /*  Get the beginning part of the new name  */
237    
238    temp_name = FPGETMESSAGE (82, 35, "New");
239    slen = strlen (temp_name) + 5 + 1;
240    switch_name = XtCalloc(1, slen);
241    strcpy (switch_name, temp_name);
242
243
244    /*  Look up the switch data to get the atom name of the workspace  */
245    /*  to delete.                                                     */
246    
247    for (i = 0; i < panel.box_data_count; i++)
248    {
249       if (panel.box_data[i]->switch_data != NULL)
250       {
251          switch_data = panel.box_data[i]->switch_data;
252          break;
253       }
254    }
255    
256
257    /*  Generate a new title for the workspace.  It should be unique  */
258    /*  from the existing title.                                      */
259
260    append = 0;
261
262    while (1)
263    {
264       Boolean good_name;
265       
266       good_name = True;
267       append++;      
268
269       for (i = 0; i < switch_data->switch_count; i++)
270       {
271          if (strcmp (switch_name, switch_data->switch_names[i]) == 0)
272          {
273             good_name = False;
274             snprintf (switch_name, slen - 1, "%s_%d", temp_name, append);
275             continue;
276          }
277       }
278
279       if (good_name)
280       {
281          _DtWsmCreateWorkspace (panel.shell, switch_name);
282          break;
283       }
284    }
285
286    XtFree(switch_name);
287 }
288
289
290 /************************************************************************
291  *
292  *  DeleteCancelCB
293  *
294  ************************************************************************/
295
296 static void
297 DeleteCancelCB(
298         Widget w,
299         XtPointer client_data,
300         XtPointer call_data )
301 {
302    XtUnmanageChild((Widget)client_data);
303    XmUpdateDisplay((Widget)client_data);
304    XtDestroyWidget((Widget)client_data);
305 }
306
307
308
309
310 /************************************************************************
311  *
312  *  DeleteControlOkCB
313  *      Called from the Ok button on the confimation dialog when a 
314  *      control deletion is seleted from the popup menu.
315  *
316  ************************************************************************/
317
318
319 static void
320 DeleteControlOkCB (Widget    w,
321                    XtPointer client_data,
322                    XtPointer call_data)
323
324
325 {
326    ControlData  * control_data;
327    SubpanelData * subpanel_data;
328    Arg args[1];
329
330
331    /*  Extract the control data from the user data field of the  */
332    /*  widget pointed to by client data.                         */
333    
334    XtSetArg (args[0], XmNuserData, &control_data);
335    XtGetValues((Widget) client_data, args, 1);
336
337
338    /*  Get the subpanel data for the control.  Check to see if the  */
339    /*  control is a real subpanel control or the main panel copy.   */
340    
341    if (control_data->parent_type == SUBPANEL)
342       subpanel_data = (SubpanelData *) control_data->parent_data;
343    else
344       subpanel_data = (SubpanelData *) control_data->subpanel_data;
345
346
347    /*  Get rid of the dialog and call the funtion to delete the control  */
348
349    XtUnmanageChild ((Widget) client_data);
350    XmUpdateDisplay ((Widget) client_data);
351
352    DeleteSubpanelControl (subpanel_data, control_data);
353
354    XtDestroyWidget ((Widget) client_data);
355 }
356
357
358
359
360 /************************************************************************
361  *
362  *  DeleteSubpanelOkCB
363  *
364  ************************************************************************/
365
366 static void
367 DeleteSubpanelOkCB(
368         Widget w,
369         XtPointer client_data,
370         XtPointer call_data )
371 {
372    ControlData * control_data;
373    Arg args[1];
374
375    XtSetArg (args[0], XmNuserData, &control_data);
376    XtGetValues((Widget)client_data, args, 1);
377
378    XtUnmanageChild((Widget)client_data);
379    XmUpdateDisplay((Widget)client_data);
380
381    DeleteSubpanel(control_data);
382
383    XtDestroyWidget((Widget)client_data);
384 }
385
386
387 /************************************************************************
388  *
389  *  DeleteControlCB
390  *
391  ************************************************************************/
392
393 void
394 DeleteControlCB (Widget    w,
395                  XtPointer client_data,
396                  XtPointer call_data)
397
398
399 {
400     ControlData * control_data;
401 #ifndef IBM_163763
402     SubpanelData *subpanel_data;
403 #endif
404     Widget dialog;
405     String title, del_ctrl, ctrl_name, ctrl_label, del_msg, message;
406     long indx = (long) client_data;
407     Arg args[2];
408
409     XtSetArg (args[0], XmNuserData, &control_data);
410     XtGetValues (w, args, 1);
411
412     del_ctrl = FPGETMESSAGE(82, 31, "Delete Control:");
413     del_ctrl = XtNewString (del_ctrl);
414
415     ctrl_label = (char *)
416                 control_data->element_values[CONTROL_LABEL].parsed_value;
417     ctrl_name = (char *)
418                    control_data->element_values[CONTROL_NAME].parsed_value;
419
420     if (ctrl_label == NULL)
421        ctrl_label = ctrl_name;
422
423     if (control_data->element_values[CONTROL_LOCKED].parsed_value)
424     {
425        title = FPGETMESSAGE(82,1, "Workspace Manager - Delete Locked Control Error");
426        title = XtNewString (title);
427
428        del_msg = FPGETMESSAGE(82,5, "This control cannot be deleted because it is locked.");
429        del_msg = XtNewString (del_msg);
430
431        message = XtMalloc (sizeof(char) *
432                            (strlen(del_ctrl) + strlen(ctrl_label) +
433                             strlen(del_msg) + 4));
434
435        sprintf(message, "%s %s\n\n%s", del_ctrl, ctrl_label, del_msg);
436
437        _DtMessage (XtParent(w), title, message, NULL, NULL);
438
439        XtFree (title);
440        XtFree (del_ctrl);
441        XtFree (del_msg);
442        XtFree (message);
443     }
444     else
445     {
446        title = FPGETMESSAGE(82,2, "Workspace Manager - Delete Control");
447        title = XtNewString (title);
448
449        if (SessionFileNameLookup (ctrl_name, CONTROL, (char *) control_data->element_values[CONTROL_CONTAINER_NAME].parsed_value, SUBPANEL) == NULL)
450           del_msg = FPGETMESSAGE(82,32, "If you delete this control, you cannot restore it using\nthe \"Install Icon\" drop zone.\n\nYou can use \"RestorePanel\" in the Application Manager\nto put back this control at a later time.\n\nAre you sure you want to delete this control?");
451        else
452           del_msg = FPGETMESSAGE(82,6, "Are you sure you want to delete this control?");
453
454        del_msg = XtNewString (del_msg);
455
456        message = XtMalloc (sizeof(char) *
457                            (strlen(del_ctrl) + strlen(ctrl_label) +
458                             strlen(del_msg) + 4));
459
460        sprintf(message, "%s %s\n\n%s", del_ctrl, ctrl_label, del_msg);
461
462 #ifndef IBM_163763
463        /*  Get the subpanel data for the control.  Check to see if the  */
464        /*  control is a real subpanel control or the main panel copy.   */
465
466        if (control_data->parent_type == SUBPANEL)
467           subpanel_data = (SubpanelData *) control_data->parent_data;
468        else
469           subpanel_data = (SubpanelData *) control_data->subpanel_data;
470
471        dialog = _DtMessageDialog(subpanel_data->shell,title,message,NULL,TRUE,
472 #else
473        dialog = _DtMessageDialog(panel.shell, title, message, NULL, TRUE,
474 #endif
475                            DeleteCancelCB, DeleteControlOkCB, NULL, NULL, False,
476                            QUESTION_DIALOG);
477
478        XtSetArg (args[0], XmNuserData, control_data);
479        XtSetArg (args[1], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
480        XtSetValues (dialog, args, 2);
481
482        XtFree (title);
483        XtFree (del_ctrl);
484        XtFree (del_msg);
485        XtFree (message);
486     }
487
488 }
489
490
491
492
493 /************************************************************************
494  *
495  *  ToggleControlCB
496  *      This callback initiates a subpanel control being toggled into
497  *      the main panel.
498  *
499  ************************************************************************/
500
501 void
502 ToggleControlCB (Widget    w,
503                  XtPointer client_data,
504                  XtPointer call_data)
505
506
507 {
508     SubpanelData * subpanel_data = (SubpanelData *) client_data;
509     ControlData * control_data;
510     long indx = (long) client_data;
511     Arg args[1];
512
513     XtSetArg (args[0], XmNuserData, &control_data);
514     XtGetValues(w, args, 1);
515
516     ToggleDefaultControl (subpanel_data->parent_control_data,
517                           subpanel_data, control_data);
518 }
519
520
521
522
523 /************************************************************************
524  *
525  *  AddSubpanelCB
526  *
527  ************************************************************************/
528
529 void
530 AddSubpanelCB (Widget w,
531                XtPointer client_data,
532                XtPointer call_data)
533
534
535 {
536     ControlData * control_data;
537     long indx = (long) client_data;
538     Arg args[1];
539
540     XtSetArg (args[0], XmNuserData, &control_data);
541     XtGetValues(w, args, 1);
542
543     AddSubpanel(control_data);
544 }
545
546
547
548
549 /************************************************************************
550  *
551  *  DeleteSubpanelCB
552  *
553  ************************************************************************/
554  
555 void
556 DeleteSubpanelCB (Widget    w,
557                   XtPointer client_data,
558                   XtPointer call_data)
559
560
561 {
562     ControlData * control_data;
563     SubpanelData * subpanel_data;
564     Widget dialog;
565     String title, message, del_spanel, spanel_name, del_msg;
566     Arg args[2];
567
568     XtSetArg (args[0], XmNuserData, &control_data);
569     XtGetValues(w, args, 1);
570
571     subpanel_data = (SubpanelData *) control_data->subpanel_data;
572     if (!subpanel_data)
573         subpanel_data = (SubpanelData *) control_data->parent_data;
574
575     del_spanel = FPGETMESSAGE(82, 33, "Delete Subpanel:");
576     del_spanel = XtNewString (del_spanel);
577
578     spanel_name = (char *)
579                   subpanel_data->element_values[SUBPANEL_NAME].parsed_value;
580
581     if (subpanel_data->element_values[SUBPANEL_LOCKED].parsed_value)
582     {
583        title = FPGETMESSAGE(82,3, "Workspace Manager - Delete Locked Subpanel Error");
584        title = XtNewString (title);
585
586        del_msg = FPGETMESSAGE(82,7, "This subpanel cannot be deleted because it is locked.");
587        del_msg = XtNewString (del_msg);
588
589        message = XtMalloc (sizeof(char) *
590                            (strlen(del_spanel) + strlen(spanel_name) +
591                             strlen(del_msg) + 4));
592
593        sprintf(message, "%s %s\n\n%s", del_spanel, spanel_name, del_msg);
594
595        _DtMessage (XtParent(w), title, message, NULL, NULL);
596
597        XtFree (title);
598        XtFree (del_spanel);
599        XtFree (del_msg);
600        XtFree (message);
601     }
602     else
603     {
604        title = FPGETMESSAGE(82,4, "Workspace Manager - Delete Subpanel");
605        title = XtNewString (title);
606
607        if (subpanel_data->control_data_count > 0)
608        {
609          if (SessionFileNameLookup (spanel_name, SUBPANEL, (char *)
610             subpanel_data->element_values[SUBPANEL_CONTAINER_NAME].parsed_value,
611             CONTROL) == NULL)
612              del_msg = FPGETMESSAGE(82,34,
613 "If you delete this subpanel, you cannot restore all\nof the controls contained in the subpanel using the\n\"Install Icon\" drop zone.\n\nYou can use \"RestorePanel\" in the Application Manager\nto put back this subpanel and its controls at a later time.\n\nAre you sure you want to delete this subpanel?");
614          else
615              del_msg = FPGETMESSAGE(82,8, "This subpanel contains more than one control.\n\nAre you sure you want to delete this subpanel?");
616        }
617        else
618           del_msg = FPGETMESSAGE(82,9, "Are you sure you want to delete this subpanel?");
619
620        del_msg = XtNewString (del_msg);
621
622        message = XtMalloc (sizeof(char) *
623                            (strlen(del_spanel) + strlen(spanel_name) +
624                             strlen(del_msg) + 4));
625
626        sprintf(message, "%s %s\n\n%s", del_spanel, spanel_name, del_msg);
627
628 #ifndef IBM_163763
629        dialog = _DtMessageDialog(subpanel_data->shell,title,message,NULL,TRUE,
630 #else
631        dialog = _DtMessageDialog(panel.shell, title, message, NULL, TRUE,
632 #endif
633                           DeleteCancelCB, DeleteSubpanelOkCB, NULL, NULL, False,
634                           QUESTION_DIALOG);
635
636        XtSetArg (args[0], XmNuserData, control_data);
637        XtSetArg (args[1], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
638        XtSetValues(dialog, args, 2);
639
640        XtFree (title);
641        XtFree (del_spanel);
642        XtFree (del_msg);
643        XtFree (message);
644     }
645 }
646
647
648
649
650
651 /************************************************************************
652  *
653  *  PostWorkspacePopupMenu
654  *
655  ************************************************************************/
656  
657
658 void
659 PostWorkspacePopupMenu (Widget      w,
660                         XtPointer   client_data,
661                         XEvent    * event)
662
663
664 {
665    int i;
666    BoxData * box_data;
667    SwitchData * switch_data = NULL;
668    XButtonEvent * b_event = (XButtonEvent *) event;
669
670    /* only use BMENU press events */
671
672    if (b_event->button != wmGD.bMenuButton) return;
673
674    for (i = 0; i < panel.box_data_count; i++)
675    {
676       box_data = panel.box_data[i];
677
678       if (box_data->switch_data != NULL)
679          switch_data = box_data->switch_data;
680    }
681
682    if (switch_data != NULL)
683       XtManageChild(switch_data->popup_data->popup);
684 }
685
686
687
688
689 /************************************************************************
690  *
691  *  PostPopupMenu
692  *
693  ************************************************************************/
694  
695 void
696 PostPopupMenu (Widget      w,
697                XtPointer   client_data,
698                XEvent    * event)
699
700
701 {
702    XButtonEvent * b_event = (XButtonEvent *) event;
703
704    /* only use BMENU press events */
705
706    if (b_event->button != wmGD.bMenuButton) return;
707
708    XtManageChild(panel.popup_data->popup);
709 }
710
711
712
713
714 /************************************************************************
715  *
716  *  GetBoxDataFromForm
717  *
718  ************************************************************************/
719  
720 static void
721 GetBoxDataFromForm (Widget     form,
722                     BoxData ** box_data_rtn)
723
724
725 {
726    BoxData * box_data;
727    int i;
728
729    for (i = 0; i < panel.box_data_count; i++)
730    {
731       box_data = panel.box_data[i];
732
733       if (box_data == *box_data_rtn) continue;
734
735       if (box_data->left_control_form == form ||
736          box_data->right_control_form == form)
737       {
738          *box_data_rtn = box_data;
739          break;
740       }
741    }
742 }
743
744
745
746
747 /************************************************************************
748  *
749  *  GetSubpanelDataFromForm
750  *
751  ************************************************************************/
752  
753 static void
754 GetSubpanelDataFromForm (Widget          form,
755                          SubpanelData ** subpanel_data_rtn)
756
757
758 {
759    BoxData * box_data;
760    ControlData * control_data;
761    SubpanelData * subpanel_data;
762    int i, j;
763
764    for (i = 0; i < panel.box_data_count; i++)
765    {
766       box_data = panel.box_data[i];
767
768       for (j = 0; j < box_data->control_data_count; j++)
769       {
770          control_data = box_data->control_data[j];
771
772          if (control_data->subpanel_data != NULL)
773          {
774             subpanel_data = control_data->subpanel_data;
775
776             if (subpanel_data == *subpanel_data_rtn) continue;
777
778             if (subpanel_data->form == form)
779             {
780                *subpanel_data_rtn = subpanel_data;
781                break;
782             }
783          }
784       }
785    }
786 }
787
788
789
790
791
792 /************************************************************************
793  *
794  *  KeyMenuPosition
795  *
796  ************************************************************************/
797  
798 static void
799 KeyMenuPosition (Widget popup, Widget focus_widget)
800
801
802 {
803    XButtonPressedEvent bevent;  /* synthetic button press event */
804    Widget parent;
805    Position root_x, root_y;
806    Position x, y;
807    Arg args[2];
808
809
810    /* get the gadget's x and y */
811
812    XtSetArg (args[0], XmNx, &x);
813    XtSetArg (args[1], XmNy, &y);
814    XtGetValues (focus_widget, args, 2);
815
816
817    /* get the focus widget's parent since the focus widget is a gadget */
818
819    parent = XtParent (focus_widget);
820
821
822    /* get the root coordinates of the gadget */
823
824    XtTranslateCoords (parent, x, y, &root_x, &root_y);
825
826
827    /*  XmMenuPosition() only uses the root_x and root_y  */
828    /*  of the event for positioning                      */
829
830    bevent.x_root = root_x;
831    bevent.y_root = root_y;
832
833
834    /* set the menu positioning */
835
836    XmMenuPosition (popup, &bevent);
837 }
838
839
840
841
842
843 /************************************************************************
844  *
845  *  GetMainControlData
846  *
847  ************************************************************************/
848  
849 static ControlData *
850 GetMainControlData (BoxData * box_data,
851                     Widget    focus_widget)
852
853
854 {
855    int i;
856    ControlData * control_data;
857    Boolean found = False;
858
859    for (i = 0; i < box_data->control_data_count; i++)
860    {
861       control_data = box_data->control_data[i];
862
863       if (control_data->icon == focus_widget)
864       {
865          found = True;
866          break;
867       }
868    }
869
870    if (!found) return NULL;
871
872    return (control_data);
873 }
874
875
876
877
878 /************************************************************************
879  *
880  *  GetSubpanelControlData
881  *
882  ************************************************************************/
883  
884 static ControlData *
885 GetSubpanelControlData (SubpanelData * subpanel_data,
886                         Widget         focus_widget)
887
888
889 {
890    int i;
891    ControlData * control_data;
892    Boolean found = False;
893
894    if ( subpanel_data->dropzone == focus_widget )
895       return NULL;
896
897    if (subpanel_data->main_panel_icon_copy == focus_widget ||
898        subpanel_data->parent_control_data->indicator == focus_widget)
899    {
900       return (subpanel_data->parent_control_data);
901    }
902
903
904    for (i = 0; i < subpanel_data->control_data_count; i++)
905    {
906       control_data = subpanel_data->control_data[i];
907       if (control_data->icon == focus_widget ||
908           control_data->indicator == focus_widget)
909       {
910          found = True;
911          break;
912       }
913    }
914
915    if (!found) return NULL;
916
917    return (control_data);
918 }
919
920
921
922
923 /************************************************************************
924  *
925  *  SetupActionMenuItems
926  *      Set up the action list for display in the popup menu for a 
927  *      control.  This may require creating additional menu items is
928  *      the action list for this control is greater that previously
929  *      encountered or it may require umanaging menu item is there are
930  *      less actions.
931  *
932  *      Inputs:
933  *         w: The parent of the menu items.
934  *         control_data: The control the menu is being set up for.
935  *         action_item: A pointer to the array of menu items for the actions.
936  *         action_count: A pointer to the total number of action items.
937  *
938  ************************************************************************/
939
940
941 static void
942 SetupActionMenuItems (Widget        w,
943                       ControlData * control_data,
944                       PopupData  * popup_data,
945                       Widget      * action_item,
946                       long        * action_count)
947
948
949 {
950    XmString label_string;
951    long i;
952    long num_actions = 0;
953    long action_index = *action_count;
954    Arg args[5];
955    
956
957    /*  Count the action list for the control in order to adjust  */
958    /*  the number of action menu items within the menu.          */
959
960    if (control_data != NULL)
961       while (control_data->actions[num_actions] != NULL)
962          num_actions++;
963
964    if (num_actions > *action_count )
965    {
966       action_item = (Widget *) XtRealloc((char *) action_item,
967                                          sizeof(Widget) * num_actions);
968
969       for (i = 0; i < num_actions - *action_count; i++)
970       {    
971           action_item[action_index] = 
972              XmCreatePushButtonGadget (w, "action_button", args, 0);
973
974           (*action_count)++;
975
976           XtManageChild (action_item[action_index]);
977           XtAddCallback (action_item[action_index], XmNactivateCallback,
978                          ActionCB, (XtPointer)action_index);
979           action_index++;
980       }
981       
982    }
983    else
984    {
985       for (i = 0; i < *action_count; i++)
986          XtUnmanageChild (action_item[i]);
987    }
988
989    for (i = 0; i < num_actions ; i++)
990    {
991       XtSetArg (args[0], XmNuserData, control_data);
992       XtSetValues (action_item[i], args, 1);
993    }
994
995    for (i = 0; i < num_actions; i++)
996    {
997       if (control_data->actions[i]->action_label != NULL)
998          label_string = 
999                XmStringCreateLocalized (control_data->actions[i]->action_label);
1000       else
1001          label_string = 
1002                XmStringCreateLocalized (control_data->actions[i]->action_name);
1003
1004       XtSetArg (args[0], XmNlabelString, label_string);
1005       XtSetArg (args[1], XmNuserData, control_data);
1006       XtSetValues (action_item[i], args, 2);
1007       XmStringFree (label_string);
1008    }
1009
1010    for (i = 0; i < num_actions; i++)
1011    {
1012       if (!XtIsManaged (action_item[i]))
1013          XtManageChild (action_item[i]);
1014    }
1015
1016    if (num_actions > 0)
1017       XtManageChild(popup_data->separator1);
1018    else
1019       XtUnmanageChild(popup_data->separator1);
1020 }
1021
1022
1023
1024
1025
1026 /************************************************************************
1027  *
1028  *  UpdateMainControlMenu
1029  *      Set up the label and the add/delete subpanel menu item for the
1030  *      popup menu.
1031  *
1032  *      Inputs:
1033  *         control_data: The control overwhich the menu is being posted.
1034  *
1035  ************************************************************************/
1036  
1037
1038 static void
1039 UpdateMainControlMenu (ControlData * control_data)
1040
1041
1042 {
1043    XmString   label_string;
1044    char     * mnemonic;
1045    char     * control_label;
1046
1047    long control_type;
1048    Arg args[5];
1049
1050    ElementValue * old_element_values;
1051
1052    /*  Save element values of control then load values of default control */
1053
1054    if (control_data->subpanel_data != NULL && 
1055         control_data != control_data->subpanel_data->default_control)
1056    {
1057         old_element_values = control_data->element_values;
1058         control_data->element_values = 
1059                 control_data->subpanel_data->default_control->element_values;
1060    }
1061
1062    /*  Set the title of the menu  */
1063    
1064    control_label =
1065          (char *) control_data->element_values[CONTROL_LABEL].parsed_value;
1066
1067    if (control_label == NULL)
1068       control_label = 
1069                (char *) control_data->element_values[CONTROL_NAME].parsed_value;
1070
1071    label_string = XmStringCreateLocalized (control_label);
1072    XtSetArg (args[0], XmNlabelString, label_string);
1073    XtSetValues (panel.popup_data->popup_title, args, 1);
1074    XmStringFree (label_string);
1075
1076
1077    /*  If the control is blank, remove the add/delete subpanel item.    */
1078    /*  Otherwise, if there is a subpanel, activate the delete subpanel  */
1079    /*  item.  Else activate the add subpanel item.                      */
1080
1081    control_type = (long)control_data->element_values[CONTROL_TYPE].parsed_value;
1082
1083    if (control_type != CONTROL_BLANK)
1084    {
1085       XtManageChild (panel.popup_data->modify_subpanel_item);
1086
1087       if (control_data->subpanel_data == NULL)
1088       {
1089          if (panel.popup_data->subpanel_add_state != True)
1090          {
1091             label_string = 
1092                XmStringCreateLocalized ((FPGETMESSAGE(82, 10, "Add Subpanel")));
1093             XtSetArg (args[0], XmNlabelString, label_string);
1094             mnemonic = ((char *)FPGETMESSAGE(82, 11, "A"));
1095             XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
1096             XtSetArg (args[2], XmNuserData, control_data);
1097             XtSetValues (panel.popup_data->modify_subpanel_item, args, 3);
1098
1099             XmStringFree (label_string);
1100
1101             XtRemoveCallback (panel.popup_data->modify_subpanel_item,
1102                               XmNactivateCallback, DeleteSubpanelCB, NULL);
1103             XtAddCallback (panel.popup_data->modify_subpanel_item,
1104                            XmNactivateCallback, AddSubpanelCB, NULL);
1105
1106             panel.popup_data->subpanel_add_state = True;
1107          }
1108          else
1109          {
1110             XtSetArg (args[0], XmNuserData, control_data);
1111             XtSetValues (panel.popup_data->modify_subpanel_item, args, 1);
1112          }
1113       }
1114       else
1115       {
1116          if (panel.popup_data->subpanel_add_state == True)
1117          {
1118             label_string = 
1119               XmStringCreateLocalized ((FPGETMESSAGE(82, 12, "Delete Subpanel")));
1120             XtSetArg (args[0], XmNlabelString, label_string);
1121             mnemonic = ((char *)FPGETMESSAGE(82, 13, "D"));
1122             XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
1123             XtSetArg (args[2], XmNuserData, control_data);
1124             XtSetValues (panel.popup_data->modify_subpanel_item, args, 3);
1125
1126             XmStringFree (label_string);
1127
1128             XtRemoveCallback (panel.popup_data->modify_subpanel_item,
1129                               XmNactivateCallback, AddSubpanelCB, NULL);
1130             XtAddCallback (panel.popup_data->modify_subpanel_item,
1131                            XmNactivateCallback, DeleteSubpanelCB, NULL);
1132
1133             panel.popup_data->subpanel_add_state = False;
1134          }
1135          else
1136          {
1137             XtSetArg (args[0], XmNuserData, control_data);
1138             XtSetValues (panel.popup_data->modify_subpanel_item, args, 1);
1139          }
1140       }
1141    }
1142    else
1143    {
1144       XtUnmanageChild (panel.popup_data->modify_subpanel_item);
1145    }
1146
1147    XtRemoveAllCallbacks (panel.popup_data->help_item, XmNactivateCallback);
1148
1149    XtAddCallback(panel.popup_data->help_item, XmNactivateCallback,
1150                  ControlTopicHelpCB, (XtPointer)control_data);
1151
1152    XtUnmanageChild (panel.popup_data->deinstall_item);
1153    XtUnmanageChild (panel.popup_data->toggle_item);
1154
1155    /* Restore element values to control. */
1156
1157    if (control_data->subpanel_data != NULL && 
1158         control_data != control_data->subpanel_data->default_control)
1159    {
1160         control_data->element_values = old_element_values;
1161    }
1162 }
1163
1164
1165
1166
1167
1168 /************************************************************************
1169  *
1170  *  UpdateSubpanelControlMenu
1171  *      Set the elements of the popup menu for a subpanel control
1172  *      item to its proper values before it is made visible.
1173  *
1174  *      Inputs: 
1175  *        subpanel_data:  The subpanel in which the menu is to be
1176  *                        posted.
1177  *
1178  *        control_data:  The control that the menu is being brought up for.
1179  *
1180  ************************************************************************/
1181  
1182
1183 static void
1184 UpdateSubpanelControlMenu (SubpanelData * subpanel_data,
1185                            ControlData  * control_data)
1186
1187
1188 {
1189    XmString label_string;
1190    Arg args[5];
1191    char     * control_label = NULL;
1192
1193    /*  Set the title of the menu  */
1194    
1195    if (control_data)
1196    {
1197       control_label =
1198          (char *) control_data->element_values[CONTROL_LABEL].parsed_value;
1199
1200       if (control_label == NULL)
1201          control_label = 
1202                (char *) control_data->element_values[CONTROL_NAME].parsed_value;
1203    } 
1204    else
1205    {
1206       control_label = FPGETMESSAGE(82, 36, "Install Icon");
1207    }
1208
1209    label_string = XmStringCreateLocalized (control_label);
1210    XtSetArg (args[0], XmNlabelString, label_string);
1211    XtSetValues (panel.popup_data->popup_title, args, 1);
1212    XmStringFree (label_string);
1213
1214
1215    /*  Set the sensitivity of the control deinstall and toggle menu item  */
1216    
1217    if (control_data == NULL)
1218    {
1219       XtSetSensitive (panel.popup_data->deinstall_item, False);
1220       XtSetSensitive (panel.popup_data->toggle_item, False);
1221
1222       XtRemoveAllCallbacks (panel.popup_data->help_item, XmNactivateCallback);
1223
1224       XtAddCallback(panel.popup_data->help_item, XmNactivateCallback,
1225                     GeneralTopicHelpCB, (XtPointer)INSTALL_ZONE);
1226    }
1227    else
1228    {
1229       XtSetSensitive (panel.popup_data->deinstall_item, True);
1230       XtSetArg (args[0], XmNuserData, control_data);
1231       XtSetValues(panel.popup_data->deinstall_item, args, 1);
1232
1233       XtRemoveAllCallbacks (panel.popup_data->deinstall_item, 
1234                             XmNactivateCallback);
1235
1236       XtAddCallback (panel.popup_data->deinstall_item, XmNactivateCallback,
1237                      DeleteControlCB, (XtPointer) NULL);
1238
1239       if ( control_data ==  subpanel_data->default_control)
1240          XtSetSensitive (panel.popup_data->toggle_item, False);
1241       else
1242          XtSetSensitive (panel.popup_data->toggle_item, True);
1243
1244       XtSetArg (args[0], XmNuserData, control_data);
1245       XtSetValues(panel.popup_data->toggle_item, args, 1);
1246
1247       XtRemoveAllCallbacks (panel.popup_data->toggle_item,
1248                             XmNactivateCallback);
1249
1250       XtAddCallback (panel.popup_data->toggle_item, XmNactivateCallback,
1251                      ToggleControlCB, (XtPointer) subpanel_data);
1252
1253       XtRemoveAllCallbacks (panel.popup_data->help_item, XmNactivateCallback);
1254
1255       XtAddCallback(panel.popup_data->help_item, XmNactivateCallback,
1256                     ControlTopicHelpCB, (XtPointer)control_data);
1257    }
1258
1259    XtManageChild (panel.popup_data->deinstall_item);
1260
1261    if (! (subpanel_data->parent_control_data->
1262                   element_values[CONTROL_LOCKED].parsed_value))
1263       XtManageChild (panel.popup_data->toggle_item);
1264    else
1265       XtUnmanageChild (panel.popup_data->toggle_item);
1266    
1267    XtUnmanageChild (panel.popup_data->modify_subpanel_item);
1268 }
1269
1270
1271
1272
1273 /************************************************************************
1274  *
1275  *  PopupMenu
1276  *      Callback function which updates the popup menu for main panel
1277  *      and subpanel controls before the menu is posted.
1278  *
1279  ************************************************************************/
1280
1281
1282 static void
1283 PopupMenu (Widget    w,
1284            XtPointer client_data,
1285            XtPointer call_data)
1286
1287
1288 {
1289    XmAnyCallbackStruct * callback;
1290    XEvent * event;
1291    Widget form, focus_widget;
1292    XmManagerWidget mgr;
1293    SubpanelData * subpanel_data = NULL;
1294    ControlData * control_data;
1295    BoxData * box_data = NULL;
1296    XmString label_string;
1297    Arg args[5];
1298    long control_type, action_count = panel.popup_data->action_count;
1299
1300    callback = (XmAnyCallbackStruct *) call_data;
1301    event = (XEvent *) callback->event;
1302
1303
1304    /*  Get the form where the menu was posted from.  */
1305
1306    form = XmGetPostedFromWidget(w);
1307
1308    XtSetArg (args[0], XmNuserData, &control_type);
1309    XtGetValues (form, args, 1);
1310
1311    if (control_type == CONTROL)
1312    {
1313       GetBoxDataFromForm (form, &box_data);
1314       subpanel_data = NULL;
1315    }
1316    else if (control_type == SUBPANEL)
1317    {
1318       GetSubpanelDataFromForm (form, &subpanel_data);
1319       box_data = NULL;
1320    }
1321
1322    if (event->type == ButtonPress)
1323    {
1324       /* Change to use new Xme function when porting to Motif 2.0 */
1325       /* Get gadget at x, y position */
1326
1327       focus_widget = (Widget) XmObjectAtPoint (form, event->xbutton.x,
1328                                                event->xbutton.y);
1329       if (focus_widget == NULL)
1330          return;
1331
1332       /* set the menu positioning */
1333
1334       XmMenuPosition (panel.popup_data->popup, (XButtonPressedEvent *)event);
1335    }
1336    else
1337    {
1338       /* get the widget that has the traversal focus */
1339
1340       focus_widget = XmGetFocusWidget (form);
1341
1342
1343       /* set the menu positioning for non button events */
1344
1345       KeyMenuPosition (panel.popup_data->popup, focus_widget);
1346    }
1347
1348    if (control_type == CONTROL)
1349    {
1350       control_data = GetMainControlData (box_data, focus_widget);
1351
1352       /* Find the right subpanel data if main control is not default */
1353       /* control.                                                    */
1354
1355       UpdateMainControlMenu (control_data);
1356
1357       if (control_data->subpanel_data != NULL &&                        
1358           control_data != control_data->subpanel_data->default_control)
1359       {
1360          subpanel_data = control_data->subpanel_data;
1361          control_data = control_data->subpanel_data->default_control;
1362          control_data->subpanel_data = subpanel_data;
1363          UpdateMainControlMenu (control_data);
1364       }
1365
1366       SetupActionMenuItems (w, control_data, panel.popup_data,
1367                             panel.popup_data->action_item, &action_count);
1368
1369    }
1370    else if (control_type == SUBPANEL)
1371    {
1372       control_data = GetSubpanelControlData (subpanel_data, focus_widget);
1373
1374       UpdateSubpanelControlMenu (subpanel_data, control_data);
1375
1376       SetupActionMenuItems (w, control_data, panel.popup_data,
1377                             panel.popup_data->action_item, &action_count);
1378    }
1379
1380    panel.popup_data->action_count = action_count;
1381 }
1382
1383
1384
1385
1386 /************************************************************************
1387  *
1388  *  CreatePopupMenu
1389  *
1390  ************************************************************************/
1391
1392
1393 void
1394 CreatePopupMenu (Widget w)
1395
1396
1397 {
1398    Widget children[20];
1399    char * mnemonic;
1400    Arg args[5];
1401    PopupData * popup_data;
1402    long i, child_num = 0;
1403    XmString label_string;
1404
1405    popup_data = panel.popup_data = (PopupData *) XtMalloc(sizeof(PopupData));
1406
1407    i = 0;
1408    XtSetArg (args[i], XmNwhichButton, wmGD.bMenuButton); i++;
1409
1410    popup_data->popup = XmCreatePopupMenu(w, "FPPopup", args, i);
1411
1412    popup_data->add_ws_item = NULL;
1413
1414    XtAddCallback (popup_data->popup, XmNmapCallback, PopupMenu,
1415                   (XtPointer) NULL);
1416
1417    popup_data->popup_title = children[child_num++] =
1418                  XmCreateLabelGadget(popup_data->popup, "title", NULL, 0);
1419
1420    children[child_num++] = XmCreateSeparatorGadget(popup_data->popup,
1421                                                    "sep1", NULL, 0);
1422    children[child_num++] = XmCreateSeparatorGadget(popup_data->popup,
1423                                                    "sep2", NULL, 0);
1424
1425    popup_data->action_item = (Widget *) XtMalloc(sizeof(Widget) * 5);
1426    popup_data->action_count = 0;
1427
1428    for (i = 0; i < 5; i++)
1429    {    
1430       children[child_num] = popup_data->action_item[i] =
1431          XmCreatePushButtonGadget(popup_data->popup, "action_button", args, 0);
1432       popup_data->action_count++;
1433
1434       XtManageChild (popup_data->action_item[i]);
1435       XtAddCallback (children[child_num++], XmNactivateCallback,
1436                      ActionCB, (XtPointer) i);
1437    }
1438
1439    popup_data->separator1 = children[child_num++] =
1440                 XmCreateSeparatorGadget (popup_data->popup, "sep3", NULL, 0);
1441
1442    label_string =
1443            XmStringCreateLocalized((FPGETMESSAGE(82, 14, "Copy To Main Panel")));
1444    XtSetArg (args[0], XmNlabelString, label_string);
1445    mnemonic = ((char *)FPGETMESSAGE(82, 15, "C"));
1446    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
1447    popup_data->toggle_item = children[child_num] =
1448       XmCreatePushButtonGadget (popup_data->popup, "Toggle_Control", args, 2);
1449    XmStringFree (label_string);
1450
1451    label_string = XmStringCreateLocalized((FPGETMESSAGE(82, 16, "Delete")));
1452    XtSetArg (args[0], XmNlabelString, label_string);
1453    mnemonic = ((char *)FPGETMESSAGE(82, 17, "D"));
1454    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
1455    popup_data->deinstall_item = children[child_num] =
1456          XmCreatePushButtonGadget(popup_data->popup, "Delete_Control",
1457                                   args, 2);
1458    XmStringFree (label_string);
1459
1460    label_string =
1461               XmStringCreateLocalized ((FPGETMESSAGE(82, 10, "Add Subpanel")));
1462    XtSetArg (args[0], XmNlabelString, label_string);
1463    mnemonic = ((char *)FPGETMESSAGE(82, 11, "A"));
1464    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
1465    popup_data->modify_subpanel_item = children[child_num] =
1466          XmCreatePushButtonGadget (popup_data->popup, "Add_Subpanel", args, 2);
1467    XmStringFree (label_string);
1468
1469    XtAddCallback(children[child_num++], XmNactivateCallback, AddSubpanelCB,
1470                         (XtPointer)NULL);
1471    popup_data->subpanel_add_state = True;
1472
1473    popup_data->separator2 = children[child_num++] =
1474                 XmCreateSeparatorGadget(popup_data->popup, "sep4", NULL, 0);
1475
1476    label_string = XmStringCreateLocalized ((FPGETMESSAGE(82, 18, "Help")));
1477    XtSetArg (args[0], XmNlabelString, label_string);
1478    mnemonic = ((char *)FPGETMESSAGE(82, 19, "H"));
1479    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
1480    popup_data->help_item = children[child_num++] =
1481                 XmCreatePushButtonGadget (popup_data->popup, "Help", args, 2);
1482    XmStringFree (label_string);
1483
1484    XtManageChildren(children, child_num);
1485 }
1486
1487
1488
1489
1490 /************************************************************************
1491  *
1492  *  CreateActionButtons
1493  *     Show the the action menu items and hide workspace menu items since
1494  *     we are over a control.
1495  *
1496  *
1497  ************************************************************************/
1498  
1499
1500 static void
1501 CreateActionButtons (Widget        w,
1502                      SwitchData  * switch_data,
1503                      ControlData * control_data)
1504
1505
1506 {
1507     PopupData * popup_data = switch_data->popup_data;
1508     long action_count = popup_data->action_count;
1509     Arg args[1];
1510     XmString label_string;
1511     char     * control_label;
1512
1513    /*  Set the title of the menu  */
1514    
1515     control_label =
1516           (char *) control_data->element_values[CONTROL_LABEL].parsed_value;
1517
1518     if (control_label == NULL)
1519        control_label = 
1520                (char *) control_data->element_values[CONTROL_NAME].parsed_value;
1521
1522     label_string = XmStringCreateLocalized (control_label);
1523     XtSetArg (args[0], XmNlabelString, label_string);
1524     XtSetValues (popup_data->popup_title, args, 1);
1525     XmStringFree (label_string);
1526
1527    /* show actions items */
1528     SetupActionMenuItems(w, control_data, popup_data,
1529                          popup_data->action_item, &action_count);
1530     popup_data->action_count = action_count;
1531
1532    /* hide add and delete workspace items */
1533     XtUnmanageChild(popup_data->add_ws_item);
1534     XtUnmanageChild(popup_data->delete_ws_item);
1535     XtUnmanageChild(popup_data->rename_ws_item);
1536
1537    /* reset the help callback to reflect switch control help */
1538     XtRemoveAllCallbacks (popup_data->help_item, XmNactivateCallback);
1539     XtAddCallback(popup_data->help_item, XmNactivateCallback,
1540                   ControlTopicHelpCB, control_data);
1541 }
1542
1543
1544
1545
1546
1547 /************************************************************************
1548  *
1549  *  ShowWorkspaceItems
1550  *     Don't show the the action menu items since we are not over a control.
1551  *     Reset the activate callbacks with the latest data.
1552  *
1553  ************************************************************************/
1554  
1555
1556 static void
1557 ShowWorkspaceItems (SwitchData * switch_data,
1558                            Widget       focus_widget)
1559
1560
1561 {
1562    PopupData * popup_data = switch_data->popup_data;
1563    long i;
1564    Arg args[1];
1565    XmString label_string;
1566    char     * control_label;
1567    char     * ws;
1568    char     * ws_name;
1569    char     * format;
1570
1571
1572    /* hide actions items */
1573
1574    for (i = 0; i < popup_data->action_count; i++)
1575        XtUnmanageChild (popup_data->action_item[i]);
1576
1577
1578    /* show add and delete workspace items */
1579
1580    XtManageChild (popup_data->add_ws_item);
1581    XtManageChild (popup_data->delete_ws_item);
1582    XtManageChild (popup_data->rename_ws_item);
1583
1584
1585    /* reset the activate callback to reflect current button index */
1586
1587    XtRemoveAllCallbacks (popup_data->delete_ws_item, XmNactivateCallback);
1588    for (i = 0; i < switch_data->switch_count &&
1589                switch_data->buttons[i] != NULL; i++)
1590    {
1591       if (switch_data->buttons[i] == focus_widget) break;
1592    }
1593
1594
1595    /*  If we didn't find the switch button to post the menu for, it   */
1596    /*  must be in edit mode so the correct menu is the active switch  */
1597
1598    if (i >= switch_data->switch_count)
1599       i = switch_data->active_switch;
1600
1601
1602    /*  Set the title of the menu  */
1603    
1604    format = strdup (FPGETMESSAGE(82, 20, "%1$s %2$s"));
1605    ws = strdup (FPGETMESSAGE(82, 21, "Workspace"));
1606    ws_name = switch_data->switch_names[i];
1607
1608    control_label = XtMalloc (sizeof(char) * (strlen(ws) + strlen(ws_name) + 4));
1609
1610    sprintf (control_label, format, ws, ws_name);
1611    free (format);
1612    free (ws);
1613
1614    label_string = XmStringCreateLocalized (control_label);
1615    XtSetArg (args[0], XmNlabelString, label_string);
1616    XtSetValues (popup_data->popup_title, args, 1);
1617    XmStringFree (label_string);
1618    XtFree(control_label);
1619
1620    XtAddCallback (popup_data->delete_ws_item, XmNactivateCallback,
1621                   DeleteWorkspaceCB, (XtPointer) i);
1622
1623    /* reset the activate callback to reflect current button index */
1624    XtRemoveAllCallbacks (popup_data->rename_ws_item, XmNactivateCallback);
1625    XtAddCallback (popup_data->rename_ws_item, XmNactivateCallback,
1626                   RenameWorkspaceCB, (XtPointer) i);
1627
1628    /* reset the help callback to reflect switch button help */
1629    XtRemoveAllCallbacks (popup_data->help_item, XmNactivateCallback);
1630    XtAddCallback(popup_data->help_item, XmNactivateCallback,
1631                  GeneralTopicHelpCB, (XtPointer) SWITCH_BUTTON);
1632
1633    XtManageChild(popup_data->separator1);
1634 }
1635
1636
1637
1638
1639 /************************************************************************
1640  *
1641  *  ShowPartialWorkspaceItems
1642  *     Don't show the delete workspace item since we are not over
1643  *     a workspace button and don't show the action menu items since we are
1644  *     not over a control.  Reset the activate callback with the latest data.
1645  *
1646  ************************************************************************/
1647  
1648 static void
1649 ShowPartialWorkspaceItems(SwitchData * switch_data)
1650
1651
1652 {
1653    PopupData * popup_data = switch_data->popup_data;
1654    int i;
1655    Arg args[1];
1656    XmString label_string;
1657
1658    label_string = XmStringCreateLocalized((FPGETMESSAGE(82, 22, "Switch Area")));
1659    XtSetArg (args[0], XmNlabelString, label_string);
1660    XtSetValues (popup_data->popup_title, args, 1);
1661    XmStringFree (label_string);
1662
1663    /* hide actions items */
1664    for (i = 0; i < popup_data->action_count; i++)
1665        XtUnmanageChild (popup_data->action_item[i]);
1666
1667    /* show add workspace item */
1668    XtManageChild (popup_data->add_ws_item);
1669
1670    /* hide delete and rename workspace items */
1671    XtUnmanageChild (popup_data->delete_ws_item);
1672    XtUnmanageChild (popup_data->rename_ws_item);
1673
1674    /* reset the help callback to reflect switch area help */
1675    XtRemoveAllCallbacks (popup_data->help_item, XmNactivateCallback);
1676    XtAddCallback(popup_data->help_item, XmNactivateCallback,
1677                  SwitchTopicHelpCB, (XtPointer)switch_data);
1678
1679    XtManageChild(popup_data->separator1);
1680 }
1681
1682
1683
1684
1685
1686 /************************************************************************
1687  *
1688  *  GetSwitchDataFromForm
1689  *
1690  ************************************************************************/
1691  
1692
1693
1694 static void
1695 GetSwitchDataFromForm (Widget        form,
1696                        SwitchData ** switch_data_rtn)
1697
1698
1699 {
1700    BoxData * box_data;
1701    int i;
1702
1703    for (i = 0; i < panel.box_data_count; i++)
1704    {
1705       box_data = panel.box_data[i];
1706
1707       if (box_data->switch_form == form)
1708       {
1709          *switch_data_rtn = box_data->switch_data;
1710          break;
1711       }
1712    }
1713 }
1714
1715
1716
1717
1718 /************************************************************************
1719  *
1720  *  GetSwtichControlData
1721  *
1722  ************************************************************************/
1723  
1724
1725 static ControlData *
1726 GetSwitchControlData (SwitchData * switch_data,
1727                       Widget       focus_widget)
1728
1729
1730 {
1731    int i;
1732    ControlData * control_data;
1733    Boolean found = False;
1734
1735    for (i = 0; i < switch_data->control_data_count; i++)
1736    {
1737       control_data = switch_data->control_data[i];
1738
1739       if (control_data->icon == focus_widget)
1740       {
1741          found = True;
1742          break;
1743       }
1744    }
1745
1746    if (!found) return NULL;
1747
1748    return (control_data);
1749 }
1750
1751
1752
1753
1754
1755 /************************************************************************
1756  *
1757  *  WSPopupMenu
1758  *
1759  ************************************************************************/
1760  
1761 static void
1762 WSPopupMenu (Widget     w,
1763              XtPointer client_data,
1764              XtPointer call_data)
1765
1766
1767 {
1768    XmManagerWidget mgr = (XmManagerWidget) w;
1769    int num_children = mgr->composite.num_children;
1770    XmAnyCallbackStruct * callback;
1771    XEvent * event;
1772    Widget form, focus_widget;
1773    SwitchData * switch_data;
1774    ControlData * control_data = NULL;
1775    Boolean is_button = False;
1776    Position x, y;
1777    Arg args[2];
1778    long control_type;
1779
1780    callback = (XmAnyCallbackStruct *) call_data;
1781    event = (XEvent *) callback->event;
1782
1783
1784    /* get the form where the menu was posted from */
1785
1786    form = XmGetPostedFromWidget (w);
1787
1788    GetSwitchDataFromForm (form, &switch_data);
1789
1790
1791    if (event->type == ButtonPress)
1792    {
1793
1794      /*  Change to use new Xme function when porting to Motif 2.0  */
1795      /*  Get gadget at x, y position                               */
1796
1797      focus_widget = (Widget) XmObjectAtPoint (form, event->xbutton.x,
1798                                               event->xbutton.y);
1799
1800      if (focus_widget == NULL)
1801      {
1802         XtSetArg (args[0], XmNx, &x);
1803         XtSetArg (args[1], XmNy, &y);
1804         XtGetValues(switch_data->rc, args, 2);
1805
1806         focus_widget = (Widget) XmObjectAtPoint (switch_data->rc,
1807                                                  event->xbutton.x - x,
1808                                                  event->xbutton.y - y);
1809         is_button = True;
1810      }
1811      else
1812         control_data = GetSwitchControlData (switch_data, focus_widget);
1813
1814
1815      /* set the menu positioning */
1816
1817      XmMenuPosition (switch_data->popup_data->popup,
1818                      (XButtonPressedEvent *) event);
1819    }
1820    else
1821    {
1822  
1823       /* get the widget that has the traversal focus */
1824   
1825       focus_widget = XmGetFocusWidget (form);
1826
1827       control_data = GetSwitchControlData (switch_data, focus_widget);
1828
1829       if (control_data == NULL)
1830          is_button = True;
1831
1832       /* set the menu positioning for non button events */
1833
1834       KeyMenuPosition (switch_data->popup_data->popup, focus_widget);
1835    }
1836
1837    if (focus_widget != NULL)
1838    {
1839       if (is_button)
1840         /* The mouse is over a button in the switch area */
1841          ShowWorkspaceItems (switch_data, focus_widget);
1842       else
1843       {
1844          if (control_data != NULL)
1845          {
1846             control_type =
1847                  (long) control_data->element_values[CONTROL_TYPE].parsed_value;
1848
1849             if (control_type != CONTROL_BLANK)
1850               /* The mouse is over a control in the switch area */
1851                CreateActionButtons (w, switch_data, control_data);
1852             else
1853               /* The mouse is over a blank control in the switch area */
1854                ShowPartialWorkspaceItems (switch_data);
1855          }
1856          else
1857          {
1858               /*
1859                * The mouse is over area other than the buttons and control
1860                * in the switch area
1861                */
1862                ShowPartialWorkspaceItems (switch_data);
1863          }
1864       }
1865    } 
1866    else
1867       /*
1868        * The mouse is over area other than the buttons and control
1869        * in the switch area
1870        */
1871       ShowPartialWorkspaceItems (switch_data);
1872 }
1873
1874
1875
1876
1877 /************************************************************************
1878  *
1879  *  CreateWorkspacePopupMenu
1880  *
1881  ************************************************************************/
1882  
1883  
1884 void
1885 CreateWorkspacePopupMenu (Widget       w,
1886                           SwitchData * switch_data)
1887
1888
1889 {
1890    Widget children[20];
1891    XmString label_string;
1892    char * mnemonic;
1893    Arg args[5];
1894    long i, child_num = 0;
1895    PopupData * popup_data;
1896
1897    popup_data = (PopupData *) XtMalloc(sizeof(PopupData));
1898
1899    i = 0;
1900    XtSetArg (args[i], XmNwhichButton, wmGD.bMenuButton); i++;
1901
1902    popup_data->popup = XmCreatePopupMenu(w, "WSPopup", args, i);
1903
1904    popup_data->deinstall_item = NULL;
1905    popup_data->toggle_item = NULL;
1906    popup_data->modify_subpanel_item = NULL;
1907    popup_data->subpanel_add_state = True;
1908
1909    XtAddCallback(popup_data->popup, XmNmapCallback, WSPopupMenu,
1910                  (XtPointer) switch_data);
1911
1912    label_string = XmStringCreateLocalized((FPGETMESSAGE(82, 22, "Switch Area")));
1913    XtSetArg (args[0], XmNlabelString, label_string);
1914    popup_data->popup_title = children[child_num++] =
1915                 XmCreateLabelGadget (popup_data->popup, "title", args, 1);
1916    XmStringFree (label_string);
1917
1918    children[child_num++] = XmCreateSeparatorGadget (popup_data->popup, "sep1",
1919                                                     NULL, 0);
1920    children[child_num++] = XmCreateSeparatorGadget (popup_data->popup, "sep2",
1921                                                     NULL, 0);
1922
1923    popup_data->action_item = (Widget *) XtMalloc(sizeof(Widget) * 5);
1924    popup_data->action_count = 0;
1925
1926    for (i = 0; i < 5; i++)
1927    {    
1928       children[child_num] = popup_data->action_item[i] =
1929          XmCreatePushButtonGadget (popup_data->popup, "action_button", args, 0);
1930       popup_data->action_count++;
1931
1932       XtManageChild (popup_data->action_item[i]);
1933       XtAddCallback (children[child_num++], XmNactivateCallback,
1934                      ActionCB, (XtPointer) i);
1935    }
1936
1937    label_string =
1938           XmStringCreateLocalized ((FPGETMESSAGE(82, 23, "Add Workspace")));
1939    XtSetArg (args[0], XmNlabelString, label_string);
1940    mnemonic = ((char *)FPGETMESSAGE(82, 24, "A"));
1941    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
1942    popup_data->add_ws_item = children[child_num] =
1943          XmCreatePushButtonGadget (popup_data->popup, "Add_Workspace", args, 2);
1944    XmStringFree (label_string);
1945
1946    XtAddCallback(children[child_num++], XmNactivateCallback, AddWorkspaceCB,
1947                         (XtPointer)NULL);
1948
1949    label_string = XmStringCreateLocalized((FPGETMESSAGE(82, 25, "Delete")));
1950    XtSetArg (args[0], XmNlabelString, label_string);
1951    mnemonic = ((char *)FPGETMESSAGE(82, 26, "D"));
1952    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
1953    popup_data->delete_ws_item = children[child_num] = 
1954                         XmCreatePushButtonGadget (popup_data->popup,
1955                                                   "Delete_Workspace", args, 2);
1956    XmStringFree (label_string);
1957
1958    XtAddCallback(children[child_num++], XmNactivateCallback,
1959                  DeleteWorkspaceCB, (XtPointer) 0);
1960
1961    label_string = XmStringCreateLocalized((FPGETMESSAGE(82, 27, "Rename")));
1962    XtSetArg (args[0], XmNlabelString, label_string);
1963    mnemonic = ((char *)FPGETMESSAGE(82, 28, "R"));
1964    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
1965    popup_data->rename_ws_item = children[child_num] = 
1966                         XmCreatePushButtonGadget (popup_data->popup,
1967                                                   "Rename_Workspace", args, 2);
1968    XmStringFree (label_string);
1969
1970    XtAddCallback(children[child_num++], XmNactivateCallback,
1971                  RenameWorkspaceCB, (XtPointer) 0);
1972
1973    popup_data->separator1 = children[child_num++] =
1974       XmCreateSeparatorGadget (popup_data->popup, "sep3", NULL, 0);
1975
1976    popup_data->separator2 = NULL;
1977
1978    label_string = XmStringCreateLocalized((FPGETMESSAGE(82, 29, "Help")));
1979    XtSetArg (args[0], XmNlabelString, label_string);
1980    mnemonic = ((char *)FPGETMESSAGE(82, 30, "H"));
1981    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
1982    popup_data->help_item = children[child_num++] =
1983                 XmCreatePushButtonGadget (popup_data->popup, "Help", args, 2);
1984    XmStringFree (label_string);
1985
1986    XtManageChildren(children, child_num);
1987
1988    switch_data->popup_data = popup_data;
1989 }
1990
1991
1992