Link with C++ linker
[oweals/cde.git] / cde / programs / dtfile / MultiView.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: MultiView.c /main/5 1996/10/15 10:08:30 mustafa $ */
24 /************************************<+>*************************************
25  ****************************************************************************
26  *
27  *   FILE:           MultiView.c
28  *
29  *   COMPONENT_NAME: Desktop File Manager (dtfile)
30  *
31  *   Description:    Contains the shared code for managing multiple toplevel
32  *                   main application window.
33  *
34  *   FUNCTIONS: CreateMenuBtn
35  *              _DtCreateMenuSystem
36  *              _DtGlobalRestoreMenuSensitivity
37  *              _DtGlobalSetMenuSensitivity
38  *              _DtGlobalUpdateMenuItemState
39  *
40  *   (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
41  *   (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
42  *   (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
43  *   (c) Copyright 1993, 1994, 1995 Novell, Inc.
44  *
45  ****************************************************************************
46  ************************************<+>*************************************/
47
48  
49
50 #include <stdio.h>
51 #include <signal.h>
52 #include <pwd.h>
53 #include <time.h>
54
55 #include <Xm/XmP.h>
56 #include <Xm/CascadeBG.h>
57 #include <Xm/PushBG.h>
58 #include <Xm/RowColumn.h>
59 #include <Xm/SeparatoG.h>
60 #include <Xm/ToggleBG.h>
61 #include <Xm/MenuShellP.h>
62
63 #include <X11/ShellP.h>
64
65 #include <Dt/DtP.h>
66 #include <Dt/DtNlUtils.h>
67 #include <Dt/Connect.h>
68
69 #include "Encaps.h"
70 #include "MultiView.h"
71
72
73 /********    Static Function Declarations    ********/
74
75 extern void _DtGlobalUpdateMenuItemState(
76                         Widget btn,
77                         unsigned int mask,
78                         unsigned int on,
79                         unsigned int * globalMenuStates) ;
80 extern void _DtGlobalSetMenuSensitivity(
81                         Widget w,
82                         XtPointer client_data,
83                         XtPointer call_data) ;
84 extern void _DtGlobalRestoreMenuSensitivity(
85                         Widget w,
86                         XtPointer client_data,
87                         XtPointer call_data) ;
88 static Widget CreateMenuBtn(
89                         Widget parent,
90                         Boolean isPushButton,
91                         MenuDesc * menuDesc,
92                         int btnIndex) ;
93
94 /********    End Static Function Declarations    ********/
95
96 extern Widget * findBtn;
97 extern Widget * change_directoryBtn;
98 extern Widget * preferencesBtn;
99 extern Widget * defaultEnvBtn;
100 extern Widget * filterBtn;
101
102 Widget
103 _DtCreateMenuSystem(
104         Widget parent,
105         char * menuBarName,
106         XtCallbackProc helpCallback,
107         XtPointer helpData,
108         Boolean createSharedComponents,
109         MenuDesc * menuDesc,
110         int numMenuComponents,
111         void (*getMenuDataProc)(),
112         void (*setMenuSensitivity)(),
113         void (*restoreMenuSensitivity)() )
114
115 {
116    int n;
117    int i;
118    Arg args[20];
119    Widget menubar;
120    Widget lastCascadeBtn = NULL;
121    Widget lastMenuPane = NULL;
122    char lastMenuPaneType = MENU_PANE;
123    Boolean firstMenuPane = True;
124    Widget child;
125    XmString labelString;
126    int pulldownIndex = 1;
127    int menuPaneIndex = 1;
128    int menuBtnIndex = 1;
129
130    /* Use our own menu control functions, if none specified */
131    if (setMenuSensitivity == NULL)
132       setMenuSensitivity = _DtGlobalSetMenuSensitivity;
133    if (restoreMenuSensitivity == NULL)
134       restoreMenuSensitivity = _DtGlobalRestoreMenuSensitivity;
135
136    /*  Create the pulldown menu  */
137    n = 0;
138    XtSetArg(args[n], XmNorientation, XmHORIZONTAL);     n++;
139    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
140    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM);        n++;
141    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM);  n++;
142    menubar = XmCreateMenuBar(parent, menuBarName, args, n);
143    XtManageChild(menubar);
144    if (helpCallback)
145       XtAddCallback(menubar, XmNhelpCallback, helpCallback, helpData);
146
147    for (i = 0; i < numMenuComponents; i++)
148    {
149       n = 0;
150
151       switch (menuDesc[i].type)
152       {
153          case MENU_PULLDOWN_BUTTON:
154          {
155             labelString = XmStringCreateLocalized(menuDesc[i].label);
156             XtSetArg(args[n], XmNlabelString, labelString);   n++;
157             if (menuDesc[i].mnemonic)
158             {
159                XtSetArg(args[n], XmNmnemonic, menuDesc[i].mnemonic[0]);   n++;
160             }
161             XtSetArg(args[n], XmNmarginWidth, 6);   n++;
162             child = XmCreateCascadeButtonGadget(menubar, menuDesc[i].name, 
163                                                 args, n);
164             if (menuDesc[i].helpCallback)
165             {
166                XtAddCallback(child, XmNhelpCallback, 
167                              menuDesc[i].helpCallback, menuDesc[i].helpData);
168             }
169             if (menuDesc[i].isHelpBtn)
170             {
171                XtSetArg(args[0], XmNmenuHelpWidget, child);
172                XtSetValues(menubar, args, 1);
173             }
174             XtManageChild(child);
175             XmStringFree(labelString);
176             lastCascadeBtn = menuDesc[i].widget = child;
177             pulldownIndex++;
178             break;
179          }
180
181          case SHARED_MENU_PANE:
182          case MENU_PANE:
183          {
184             if (createSharedComponents || (menuDesc[i].type == MENU_PANE))
185             {
186                child = XmCreatePulldownMenu(menubar, menuDesc[i].name, NULL, 0);
187
188                if (firstMenuPane)
189                {
190                   XtAddCallback(XtParent(child), XmNpopupCallback, 
191                                 setMenuSensitivity, 
192                                 (XtPointer)getMenuDataProc);
193                   XtAddCallback(XtParent(child), XmNpopdownCallback, 
194                                 restoreMenuSensitivity, 
195                                 (XtPointer)getMenuDataProc);
196                   firstMenuPane = False;
197                }
198
199                if (menuDesc[i].helpCallback)
200                {
201                   XtAddCallback(child, XmNhelpCallback, 
202                              menuDesc[i].helpCallback, menuDesc[i].helpData);
203                }
204
205                menuDesc[i].widget = child;
206             }
207
208             lastMenuPane = menuDesc[i].widget;
209             lastMenuPaneType = menuDesc[i].type;
210             XtSetArg(args[0], XmNsubMenuId, lastMenuPane);
211             XtSetValues(lastCascadeBtn, args, 1);
212             menuBtnIndex = 1;
213             menuPaneIndex++;
214             break;
215          }
216
217          case MENU_TOGGLE_BUTTON:
218          case MENU_BUTTON:
219          {
220             /* Need to always make btns for non-shared menupanes */
221             if ((createSharedComponents) || (lastMenuPaneType == MENU_PANE))
222             {
223                child = CreateMenuBtn (lastMenuPane, 
224                                       (menuDesc[i].type == MENU_BUTTON),
225                                       menuDesc + i, menuBtnIndex);
226                XtManageChild(child);
227                menuDesc[i].widget = child;
228             }
229             menuBtnIndex++;
230             break;
231          }
232
233          case MENU_SEPARATOR:
234          {
235             /* Need to always make components for non-shared menupanes */
236             if ((createSharedComponents) || (lastMenuPaneType == MENU_PANE))
237             {
238                child = XmCreateSeparatorGadget(lastMenuPane, menuDesc[i].name, 
239                                                NULL, 0);
240                XtManageChild(child);
241                menuDesc[i].widget = child;
242             }
243             break;
244          }
245       }
246    }
247
248
249    return(menubar);
250 }
251
252
253
254 /* ARGSUSED */
255 void
256 _DtGlobalSetMenuSensitivity(
257         Widget w,
258         XtPointer client_data,
259         XtPointer call_data )
260
261 {
262    Arg menuPaneArgs[1];
263    Widget mbar;
264    XmMenuShellWidget mshell = (XmMenuShellWidget) w;
265    void (*getMenuData)() = (void(*)())client_data;
266    XtPointer mainRecord;
267    MenuDesc * menuDesc;
268    int menuItemCount;
269    unsigned int * globalMenuStates;
270    unsigned int * viewMenuStates;
271    int i;
272
273    _XmGetActiveTopLevelMenu(mshell->composite.children[0], &mbar);
274    (*getMenuData)(mbar, &mainRecord, &menuDesc, &menuItemCount,
275                   &globalMenuStates, &viewMenuStates);
276    XtSetArg(menuPaneArgs[0], XmNuserData, mainRecord);
277
278    for (i = 0; i < menuItemCount; i++)
279    {
280       switch (menuDesc[i].type)
281       {
282          case SHARED_MENU_PANE:
283          case MENU_PANE:
284          {
285             /* Need to do this to get help working */
286             XtSetValues(menuDesc[i].widget, menuPaneArgs, 1);
287             break;
288          }
289
290          case MENU_BUTTON:
291          {
292             if ((menuDesc[i].maskBit) &&
293                ((*globalMenuStates & menuDesc[i].maskBit) != 
294                 (*viewMenuStates & menuDesc[i].maskBit)))
295             {
296                _DtGlobalUpdateMenuItemState(menuDesc[i].widget, 
297                                          menuDesc[i].maskBit, 
298                                          *viewMenuStates & menuDesc[i].maskBit,
299                                          globalMenuStates);
300             }
301             break;
302          }
303       }
304    }
305 }
306
307
308 /* ARGSUSED */
309 void
310 _DtGlobalRestoreMenuSensitivity(
311         Widget w,
312         XtPointer client_data,
313         XtPointer call_data )
314
315 {
316    Widget mbar;
317    XmMenuShellWidget mshell = (XmMenuShellWidget) w;
318    void (*getMenuData)() = (void (*)())client_data;
319    XtPointer mainRecord;
320    MenuDesc * menuDesc;
321    int menuItemCount;
322    unsigned int * globalMenuStates;
323    unsigned int * viewMenuStates;
324    int i;
325
326    _XmGetActiveTopLevelMenu(mshell->composite.children[0], &mbar);
327    (*getMenuData)(mbar, &mainRecord, &menuDesc, &menuItemCount,
328                   &globalMenuStates, &viewMenuStates);
329
330    for (i = 0; i < menuItemCount; i++)
331    {
332       if (menuDesc[i].type == MENU_BUTTON)
333       {
334          if ((menuDesc[i].maskBit) && 
335              ((*globalMenuStates & menuDesc[i].maskBit) == 0))
336          {
337             _DtGlobalUpdateMenuItemState(menuDesc[i].widget, 
338                                       menuDesc[i].maskBit, 
339                                       True,
340                                       globalMenuStates);
341          }
342       }
343    }
344 }
345
346
347 void
348 _DtGlobalUpdateMenuItemState(
349         Widget btn,
350         unsigned int mask,
351         unsigned int on,
352         unsigned int * globalMenuStates )
353
354 {
355    if (on != 0)
356    {
357       XtSetSensitive(btn, True);
358       *globalMenuStates |= mask;
359    }
360    else
361    {
362       if(btn != *findBtn             &&
363          btn != *change_directoryBtn && 
364          btn != *preferencesBtn      && 
365          btn != *defaultEnvBtn       && 
366          btn != *filterBtn               ) 
367       {
368         XtSetSensitive(btn, False);
369         *globalMenuStates &= ~mask;
370       }
371    }
372 }
373
374
375 static Widget
376 CreateMenuBtn (
377    Widget parent,
378    Boolean isPushButton,
379    MenuDesc * menuDesc,
380    int btnIndex )
381 {
382    int n;
383    Arg args[10];
384    Widget child;
385    XmString labelString;
386
387    n = 0;
388    labelString = XmStringCreateLocalized(menuDesc->label);
389    XtSetArg(args[n], XmNlabelString, labelString);              n++;
390    XtSetArg(args[n], XmNmnemonic, menuDesc->mnemonic[0]);       n++;
391    if (isPushButton)
392       child = XmCreatePushButtonGadget(parent, menuDesc->name, args, n);
393    else
394    {
395       XtSetArg(args[n], XmNvisibleWhenOff,TRUE);n++;
396       child = XmCreateToggleButtonGadget(parent, menuDesc->name, args, n);
397    }
398    if (menuDesc->helpCallback)
399    {
400       XtAddCallback(child, XmNhelpCallback, menuDesc->helpCallback, 
401                     menuDesc->helpData);
402    }
403    if (menuDesc->activateCallback)
404    {
405       if (isPushButton)
406       {
407          XtAddCallback(child, XmNactivateCallback, menuDesc->activateCallback, 
408                        menuDesc->activateData);
409       }
410       else
411       {
412          XtAddCallback(child, XmNvalueChangedCallback, 
413                        menuDesc->activateCallback, menuDesc->activateData);
414       }
415    }
416    XmStringFree(labelString);
417    return (child);
418 }