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