2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $XConsortium: Callback.c /main/10 1996/10/30 11:14:26 drk $ */
24 /*****************************************************************************
30 * Description: This file contains the user interface behavior processing
31 * functions for the CDE front panel
33 * (c) Copyright 1993, 1994 Hewlett-Packard Company
34 * (c) Copyright 1993, 1994 International Business Machines Corp.
35 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
36 * (c) Copyright 1993, 1994 Novell, Inc.
38 ****************************************************************************/
40 #include <sys/param.h>
44 #include <Dt/DbReader.h>
46 #include <Dt/Control.h>
47 #include <Dt/ControlP.h>
48 #include <Dt/IconFile.h>
52 #include <Dt/Action.h>
53 #include <Dt/DtNlUtils.h>
56 #include <Dt/MacrosP.h>
59 #include <Xm/ToggleBG.h>
60 #include <Xm/AtomMgr.h>
63 #include <X11/Xatom.h>
64 #include <X11/keysym.h>
66 #include "DataBaseLoad.h"
70 #include "WmResNames.h"
71 #include "WmFunction.h"
74 /************************************************************************
76 * External and static function declarations.
78 ************************************************************************/
80 extern XtPointer _XmStringUngenerate(XmString, XmStringTag,
81 XmTextType, XmTextType);
83 extern void SubpanelControlCreate (SubpanelData *, ControlData *, ControlData *,
84 Widget, Boolean, Boolean);
85 extern void WmSubpanelPosted (Display *, Window);
86 extern int PushRecallGetData (char *);
87 extern void SwitchButtonCreate (SwitchData *, Boolean);
88 extern void AddControlActionList (ControlData *);
90 void ArrowCB (Widget, XtPointer, XtPointer);
91 void HandleInputCB (Widget, XtPointer, XtPointer);
92 void MinimizeInputCB (Widget, XtPointer, XtPointer);
93 void MenuInputCB (Widget, XtPointer, XtPointer);
94 void SwitchButtonCB (Widget, XtPointer, XtPointer);
95 void PushCB (Widget, XtPointer, XtPointer);
96 void SubpanelUnmapCB (Widget, XtPointer, XtPointer);
97 void SubpanelTornEventHandler (Widget, XtPointer, XEvent *, Boolean *);
98 Boolean CheckControlTypeFile (ControlData *);
101 static void SwitchRenameCancel (Widget, XEvent *, String *, Cardinal *);
102 static void SwitchRenameCB (Widget, XtPointer, XtPointer);
103 static void GetValuesFromDataType(char *, char *, SubpanelData *,
106 void SwitchRenameLabel (Widget, BoxData *);
107 void DropCB (Widget, XtPointer, XtPointer);
108 void TransferDropCB (Widget, XtPointer, XtPointer);
109 void CustomizeDropCB (Widget, XtPointer, XtPointer);
110 void CustomizeTransferDropCB (Widget, XtPointer, XtPointer);
116 /* Translations and action definitions */
117 /* These are used specifically for the text field overlay */
118 /* on the switch button for renaming the workspace. They */
119 /* are necessary for handling escape key processing. */
121 static char translations_escape[] = "<Key>osfCancel:Escape()";
123 static XtActionsRec action_table[] = {
124 {"Escape", SwitchRenameCancel},
129 /************************************************************************
131 * File local globals.
133 ************************************************************************/
135 extern String post_arrow_image;
136 extern String unpost_arrow_image;
137 extern String post_monitor_arrow_image;
138 extern String unpost_monitor_arrow_image;
139 extern String blank_arrow_image;
140 extern String dropzone_image;
141 extern String indicator_on_image;
142 extern String indicator_off_image;
146 /************************************************************************
149 * Call the specified WmFunction function with appropriate args
151 ************************************************************************/
155 CallWmFunction (WmFunction wm_function,
162 WmGlobalData * wm_global_data = (WmGlobalData *) panel.global_data;
163 ClientData * wm_client_data = NULL;
164 Display * display = wm_global_data->display;
165 Window client_window = XtWindow(client);
168 * Find the window manager client data for this client
171 XFindContext (display, client_window, wm_global_data->windowContextType,
172 (XtPointer) &wm_client_data);
174 if (wm_client_data == NULL)
178 * Execute the window manager function
181 wm_function (args, wm_client_data, event);
184 /************************************************************************
187 * Process the callback on the subpanel posting/unposting arrow
189 ************************************************************************/
194 XtPointer client_data,
199 ControlData * control_data = (ControlData *) client_data;
200 SubpanelData * subpanel_data = control_data->subpanel_data;
206 /* If the subpanel's shell is not managed, this is a request to post */
207 /* the subpanel. Otherwise it is an unpost request. */
208 /* Reset the arrow image after the post or unpost. */
210 if (!XtIsManaged (subpanel_data->shell))
212 Position x = XtX (control_data->arrow);
213 Position y = XtY (control_data->arrow);
216 XtSetMappedWhenManaged (subpanel_data->shell, False);
217 XtManageChild (subpanel_data->form);
219 XtTranslateCoords (w, 0, 0, &x, &y);
221 XtSetArg (al[0], XmNx, x);
222 XtSetValues (subpanel_data->form, al, 1);
224 XtManageChild (subpanel_data->shell);
225 XtSetMappedWhenManaged (subpanel_data->shell, True);
228 XtSetArg (al[ac], XmNimageName, unpost_arrow_image); ac++;
229 XtSetValues (w, al, ac);
233 /* Execute the window manager function to unpost the subpanel */
235 CallWmFunction (F_Kill, NULL, subpanel_data->shell, NULL);
242 /************************************************************************
244 * HandleInputTranslations
245 * Return translation table suitable for HandleInputCB
247 ************************************************************************/
251 HandleInputTranslations(void)
254 static XtTranslations handle_translations;
256 if (handle_translations == NULL)
258 handle_translations = XtParseTranslationTable(
259 "<BtnDown>: DrawingAreaInput() ManagerGadgetArm()\n\
260 <BtnUp>: DrawingAreaInput() ManagerGadgetActivate()\n\
261 <Btn1Motion>: DrawingAreaInput() ManagerGadgetButtonMotion()\n\
262 <Btn2Motion>: DrawingAreaInput() ManagerGadgetButtonMotion()");
264 return handle_translations;
267 /************************************************************************
270 * Process button events on the frontpanel handles.
272 ************************************************************************/
276 HandleInputCB (Widget w,
277 XtPointer client_data,
282 XmAnyCallbackStruct * callback;
285 XButtonEvent * buttonEvent;
286 XMotionEvent * motionEvent;
288 callback = (XmAnyCallbackStruct *) call_data;
289 event = (XEvent *) callback->event;
290 buttonEvent = (XButtonEvent *) event;
291 motionEvent = (XMotionEvent *) event;
293 if (event->type == ButtonPress)
295 if (buttonEvent->button == wmGD.bMenuButton)
297 XUngrabPointer (XtDisplay (w), buttonEvent->time);
298 XSync (XtDisplay (w), FALSE);
299 CallWmFunction (F_Post_FpMenu, NULL, panel.shell, event);
304 wmGD.preMoveX = buttonEvent->x_root;
305 wmGD.preMoveY = buttonEvent->y_root;
307 if (buttonEvent->button == Button1)
309 CallWmFunction (F_Raise, NULL, panel.shell, event);
310 XSync (DISPLAY, FALSE);
311 XmUpdateDisplay (panel.shell);
315 else if (event->type == ButtonRelease)
317 wmGD.preMove = False;
319 else if (event->type == MotionNotify && wmGD.preMove)
323 diffX = motionEvent->x_root - wmGD.preMoveX;
324 if (diffX < 0) diffX = -diffX;
325 diffY = motionEvent->y_root - wmGD.preMoveY;
326 if (diffY < 0) diffY = -diffY;
328 if (diffX >= wmGD.moveThreshold || diffY >= wmGD.moveThreshold)
330 XUngrabPointer (XtDisplay (w), motionEvent->time);
331 XSync (XtDisplay (w), FALSE);
332 CallWmFunction (F_Move, NULL, panel.shell, event);
333 wmGD.preMove = False;
341 /************************************************************************
344 * Process button events on the frontpanel minimize button.
346 ************************************************************************/
350 MinimizeInputCB (Widget w,
351 XtPointer client_data,
356 XmAnyCallbackStruct * callback;
359 XButtonEvent * bevent;
361 extern Pixmap minimize_normal_pixmap;
362 extern Pixmap minimize_selected_pixmap;
367 callback = (XmAnyCallbackStruct *) call_data;
368 event = (XEvent *) callback->event;
369 bevent = (XButtonEvent *) event;
371 /* On the BSelect button press, change the image to the selected
372 * minimize image. On the release, check to see if the release
373 * occured within the minimize button before minimizing.
374 * On BMenu button press, post the front panel menu.
377 if (event->type == ButtonPress)
379 if (bevent->button == Button1)
381 XtSetArg (al[0], XmNbackgroundPixmap, minimize_selected_pixmap);
382 XtSetValues (w, al, 1);
384 else if (bevent->button == wmGD.bMenuButton)
386 XUngrabPointer (XtDisplay (w), bevent->time);
387 XSync (XtDisplay (w), FALSE);
388 CallWmFunction (F_Post_FpMenu, NULL, panel.shell, event);
391 else if (event->type == ButtonRelease && bevent->button == Button1)
393 if (bevent->x >= 0 && bevent->x <= (Position) XtWidth(w) &&
394 bevent->y >= 0 && bevent->y <= (Position) XtHeight(w))
396 CallWmFunction (F_Minimize, NULL, panel.shell, event);
399 XtSetArg (al[0], XmNbackgroundPixmap, minimize_normal_pixmap);
400 XtSetValues (w, al, 1);
407 /************************************************************************
410 * Process button events on the front panel menu button.
412 ************************************************************************/
416 MenuInputCB (Widget w,
417 XtPointer client_data,
422 XmAnyCallbackStruct * callback;
425 XButtonEvent * bevent;
427 callback = (XmAnyCallbackStruct *) call_data;
428 event = (XEvent *) callback->event;
429 bevent = (XButtonEvent *) event;
433 * On BSelect or BMenu button press post the front panel system menu
436 if (event->type == ButtonPress &&
437 (bevent->button == Button1 || bevent->button == wmGD.bMenuButton))
439 XUngrabPointer (XtDisplay (w), bevent->time);
440 XSync (XtDisplay (w), FALSE);
441 CallWmFunction (F_Post_FpMenu, NULL, panel.shell, event);
447 /************************************************************************
448 ************************************************************************
450 The next block of functions are used for the switch button switching,
451 renaming functionality, and add and delete of workspaces.
453 ************************************************************************
454 ************************************************************************/
458 /************************************************************************
460 * WorkspaceAdjustPanelPosition
461 * After a workspace button has been added or deleted, if the panel
462 * has changed sizes, reposition the panel to keep the same relative
465 * Inputs: x - the original x coordinate of the panel
466 * y - the original y coordinate of the panel
467 * width - the original width of the panel
468 * height - the original height of the panel
470 ************************************************************************/
474 WorkspaceAdjustPanelPosition (Position x,
481 Dimension screen_width;
482 Dimension screen_height;
485 Dimension new_height;
492 screen_width = WidthOfScreen (XtScreen (panel.shell));
493 screen_height = HeightOfScreen (XtScreen (panel.shell));
496 /* Reposition the panel to keep it centered relative to where */
497 /* it was positioned before the deletion of the button. */
501 new_width = XtWidth (panel.shell);
503 if (new_width != width || x + (Position) new_width > (Position) screen_width)
505 panel_center = x + width / 2 - 1;
506 new_x = panel_center - new_width / 2 - 4;
510 else if (new_x + (Position) new_width > (Position) screen_width)
511 new_x = screen_width - new_width - 4;
513 XtSetArg (al[ac], XmNx, new_x); ac++;
517 /* Keep the panel to the bottom of the screen, if it was there. */
518 /* But make sure that it does not go below the bottom. */
520 new_height = XtHeight (panel.shell);
522 if (new_height != height || (Dimension)(new_height + y - 1) > screen_height)
524 if (new_height < height && y > (Position)(screen_height / 2))
526 new_y = y + (Position)(height - new_height - 4);
527 XtSetArg (al[ac], XmNy, new_y); ac++;
529 else if ((Dimension)(new_height + y - 1) > screen_height)
531 new_y = (Position)(screen_height - new_height - 4);
532 XtSetArg (al[ac], XmNy, new_y); ac++;
537 XtSetValues (panel.shell, al, ac);
543 /************************************************************************
546 * Called by the workspace manager API to send notification of
547 * configuration changes to the workspace. The types of changes
548 * processed by this function are workspace add, delete, and rename.
550 ************************************************************************/
554 WorkspaceModifyCB (Widget w,
557 XtPointer client_data)
561 SwitchData * switch_data = (SwitchData *) client_data;
562 BoxData * box_data = switch_data->box_data;
563 DtWsmWorkspaceInfo * workspace_info;
569 Dimension screen_width;
572 x = XtX (panel.shell);
573 y = XtY (panel.shell);
574 width = XtWidth (panel.shell);
575 height = XtHeight (panel.shell);
576 screen_width = WidthOfScreen (XtScreen (panel.shell));
578 DtWsmGetWorkspaceInfo (XtDisplay (w), RootWindowOfScreen (XtScreen (w)),
579 atom_name, &workspace_info);
584 /* Increase the size of the switch names and button and call */
585 /* the function to create the new workspace switch button */
587 case DtWSM_REASON_ADD:
593 /* Cancel workspace renaming */
595 if (XtIsManaged (box_data->switch_edit))
596 SwitchRenameCancel (box_data->switch_edit, NULL, NULL, NULL);
599 DtWsmGetWorkspaceList (XtDisplay (switch_data->rc),
600 RootWindowOfScreen (XtScreen (switch_data->rc)),
601 &atom_names, &switch_count);
603 XFree (switch_data->atom_names);
604 switch_data->atom_names = atom_names;
606 switch_data->switch_count = switch_count;
608 switch_data->switch_names =
609 (char **) XtRealloc ((char *) switch_data->switch_names,
610 sizeof (char *) * switch_data->switch_count);
612 switch_data->switch_names[switch_data->switch_count - 1] =
613 XtNewString (workspace_info->pchTitle);
615 switch_data->buttons =
616 (Widget *) XtRealloc ((char *) switch_data->buttons,
617 sizeof (Widget *) * switch_data->switch_count);
619 SwitchButtonCreate (switch_data, True);
622 /* When adding a switch buttons, keep the row columns row count */
623 /* equal to the requested value with small number of buttons */
625 if (switch_data->switch_count <= (int)
626 (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value))
630 panel.switch_row_count = (int)
631 (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value);
633 XtSetArg (al[0], XmNnumColumns, panel.switch_row_count);
634 XtSetValues (switch_data->rc, al, 1);
638 /* If the fp width is greater than the screen, increase the */
641 if (XtWidth (panel.shell) > screen_width)
645 panel.switch_row_count++;
647 XtSetArg (al[0], XmNnumColumns, panel.switch_row_count);
648 XtSetValues (switch_data->rc, al, 1);
651 WorkspaceAdjustPanelPosition (x, y, width, height);
656 /* Loop through the current set of atom names, comparing */
657 /* them with the atom of the workspace to be deleted. When */
658 /* free up the associated data and readjust the name, button */
659 /* and atom lists. */
661 case DtWSM_REASON_DELETE:
669 Dimension button_spacing;
670 Dimension button_width;
673 /* Cancel workspace renaming */
675 if (XtIsManaged (box_data->switch_edit))
676 SwitchRenameCancel (box_data->switch_edit, NULL, NULL, NULL);
679 DtWsmGetWorkspaceList (XtDisplay (switch_data->rc),
680 RootWindowOfScreen (XtScreen (switch_data->rc)),
681 &atom_names, &switch_count);
683 for (i = 0; i < switch_data->switch_count; i++)
685 if (atom_name == switch_data->atom_names[i])
687 if (switch_data->active_switch > i)
688 switch_data->active_switch--;
690 XtFree (switch_data->switch_names[i]);
691 XtDestroyWidget (switch_data->buttons[i]);
692 XFree (switch_data->atom_names);
693 switch_data->atom_names = atom_names;
694 switch_data->switch_count = switch_count;
696 for (j = i; j < switch_data->switch_count; j++)
698 switch_data->switch_names[j] = switch_data->switch_names[j+1];
699 switch_data->buttons[j] = switch_data->buttons[j + 1];
707 /* When deleting a switch button, keep trying to decrease the */
708 /* row count to the requested value. */
710 if (panel.switch_row_count > (int)
711 (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value))
713 button_width = XtWidth (switch_data->buttons[0]);
714 XtSetArg (al[0], XmNspacing, &button_spacing);
715 XtGetValues (switch_data->rc, al, 1);
717 if ((int)(screen_width - (width + button_width + button_spacing)) >
720 panel.switch_row_count--;
721 XtSetArg (al[0], XmNnumColumns, panel.switch_row_count);
722 XtSetValues (switch_data->rc, al, 1);
726 WorkspaceAdjustPanelPosition (x, y, width, height);
732 /* Loop through the current set of atom names, comparing */
733 /* them with the new atom. When a match is found, reset the */
734 /* the switch name to the new one and update the button label. */
736 case DtWSM_REASON_TITLE:
738 XmString toggle_string;
743 for (i = 0; i < switch_data->switch_count; i++)
745 if (atom_name == switch_data->atom_names[i])
747 switch_data->switch_names[i] =
748 XtNewString (workspace_info->pchTitle);
751 XmStringCreateLocalized (workspace_info->pchTitle);
753 XtSetArg (al[0], XmNstring, toggle_string);
754 XtSetValues (switch_data->buttons[i], al, 1);
755 XmStringFree (toggle_string);
757 XtSetArg (al[0], XmNiconName, workspace_info->pchTitle);
758 XtSetArg (al[1], XmNtitle, workspace_info->pchTitle);
759 XtSetValues (panel.shell, al, 2);
768 /* Loop through the set of switch atom names to find the one */
769 /* that is now active. Unset the old workspace button and */
770 /* set the new one referenced by the atom. */
772 case DtWSM_REASON_CURRENT:
777 for (i = 0; i < switch_data->switch_count; i++)
779 if (switch_data->atom_names[i] == atom_name)
781 XtSetArg (al[0], XmNiconName, switch_data->switch_names[i]);
782 XtSetArg (al[1], XmNtitle, switch_data->switch_names[i]);
783 XtSetValues (panel.shell, al, 2);
785 _DtIconSetState (switch_data->buttons[switch_data->active_switch], False, False);
786 switch_data->active_switch = i;
787 _DtIconSetState (switch_data->buttons[switch_data->active_switch], True, False);
795 DtWsmFreeWorkspaceInfo (workspace_info);
801 /************************************************************************
804 * Process callbacks on the switch buttons. This function cause
805 * either the workspace switch to occur or for the switch button
806 * label to become editable.
808 ************************************************************************/
812 SwitchButtonCB (Widget w,
813 XtPointer client_data,
818 DtControlCallbackStruct * callback = (DtControlCallbackStruct *) call_data;
819 XEvent * event = callback->event;
821 Widget switch_button = w;
822 Widget old_switch_button;
824 SwitchData * switch_data;
831 if (callback->reason != XmCR_VALUE_CHANGED) return;
833 XtSetArg (al[ac], XmNuserData, &box_data); ac++;
834 XtGetValues (switch_button, al, ac);
836 switch_data = box_data->switch_data;
837 old_switch_button = switch_data->buttons[switch_data->active_switch];
840 /* If the selection occured on a non-selected button, find the atom */
841 /* representing the workspace name of the button that was selected */
842 /* and use it to call the workspace manager API to switch the */
843 /* workspace. The indication on the buttons occurs out of the */
844 /* called from the workspace manager API. */
846 /* If the selection occured on the current button, set up the name */
847 /* change editing functions. */
849 if (switch_button != old_switch_button)
852 /* See if the workspace name is being edited. If so, call the */
853 /* callback function to accept the changes. */
855 if (XtIsManaged (box_data->switch_edit))
857 Widget edit_switch_button;
859 XtSetArg (al[0], XmNuserData, &edit_switch_button);
860 XtGetValues (box_data->switch_edit, al, 1);
861 SwitchRenameCB (box_data->switch_edit,
862 (XtPointer) edit_switch_button, (XtPointer) NULL);
864 XmProcessTraversal (w, XmTRAVERSE_CURRENT);
868 if (event->xany.type == ButtonRelease)
869 switch_data->time_stamp = event->xbutton.time;
871 for (i = 0; i < switch_data->switch_count; i++)
873 if (switch_button == switch_data->buttons[i])
875 XtSetArg (al[0], XmNiconName, switch_data->switch_names[i]);
876 XtSetArg (al[1], XmNtitle, switch_data->switch_names[i]);
877 XtSetValues (panel.shell, al, 2);
879 DtWsmSetCurrentWorkspace (XtParent (switch_button),
880 switch_data->atom_names[i]);
885 _DtIconSetState (old_switch_button, False, False);
889 /* Don't do anything on double click */
891 if (event->xany.type == ButtonRelease)
893 if ((event->xbutton.time - switch_data->time_stamp) >
894 XtGetMultiClickTime(XtDisplay(panel.shell)))
896 switch_data->time_stamp = event->xbutton.time;
897 SwitchRenameLabel (w, box_data);
901 _DtIconSetState (w, True, False);
908 /************************************************************************
911 * This is the XtActionProc that gets called when a user types
912 * escape in a text widget which has this translation tied to it.
914 ***********************************************************************/
918 SwitchRenameCancel (Widget w,
921 Cardinal * num_params)
925 Widget switch_button;
929 /* Extract the toggle button from the text field's user data */
931 XtSetArg (al[0], XmNuserData, &switch_button);
932 XtGetValues (w, al, 1);
935 /* Remove the callbacks to eliminate double processing */
937 XtRemoveAllCallbacks (w, XmNactivateCallback);
940 /* Unmanage the text widget, set the traversal to the button and exit */
943 XmProcessTraversal (switch_button, XmTRAVERSE_CURRENT);
949 /************************************************************************
952 * Process callbacks on the text field when a switch name is
955 ************************************************************************/
959 SwitchRenameCB (Widget w,
960 XtPointer client_data,
965 Widget switch_button = (Widget) client_data;
969 SwitchData * switch_data;
978 /* Remove the callbacks to eliminate double processing */
980 XtRemoveCallback (w, XmNactivateCallback,
981 SwitchRenameCB, (XtPointer) client_data);
984 /* If this callback has been called and the text widget is already */
985 /* unmanaged, it means that the escape key was pressed, so return */
987 if (XtIsManaged(w) == False) return;
990 /* Process the two reasons this callback is invoked. A <Return> */
991 /* key has been pressed or the focus is being moved. Accept the */
992 /* new name for both conditions. */
995 XtSetArg (al[ac], XmNuserData, &box_data); ac++;
996 XtGetValues (switch_button, al, ac);
998 switch_data = box_data->switch_data;
1000 for (i = 0; i < switch_data->switch_count; i++)
1001 if (switch_data->buttons[i] == switch_button)
1005 /* Get the new name from the text field */
1007 edit_string = (char *) XmTextFieldGetString (w);
1010 /* Verify that title is valid and unique and if so, validate */
1011 /* uniqueness and then change the toggle and workspace internal */
1016 _DtStripSpaces (edit_string);
1018 if (strlen (edit_string) == 0)
1022 for (i = 0; i < switch_data->switch_count; i++)
1024 if (strcmp (switch_data->switch_names[i], edit_string) == 0)
1026 if (i == current_switch)
1028 XtUnmanageChild (w);
1029 XmProcessTraversal (switch_button, XmTRAVERSE_CURRENT);
1030 XtFree (edit_string);
1043 /* If the title is not valid, post and error dialog and */
1044 /* then leave the text field active to allow reediting. */
1045 /* Otherwise, change the title. */
1052 s1 = FPGETMESSAGE (86, 1, "Workspace Manager - Rename Error");
1053 s1 = XtNewString (s1);
1054 s2 = FPGETMESSAGE (86, 2, "Invalid or duplicate workspace name"),
1055 s2 = XtNewString (s2);
1057 _DtMessage (XtParent (w), s1, s2, NULL, NULL);
1063 _DtWsmSetWorkspaceTitle (panel.shell,
1064 switch_data->atom_names[current_switch],
1068 /* Unmanage the text field and exit */
1070 XtFree (edit_string);
1071 XtUnmanageChild (w);
1077 /************************************************************************
1080 * Set up the text field and callbacks needed for renaming a
1083 ************************************************************************/
1087 SwitchRenameLabel (Widget switch_button,
1092 Widget switch_edit = box_data->switch_edit;
1094 static Boolean first = True;
1096 XmString toggle_string;
1099 Dimension toggle_width;
1100 Dimension toggle_height;
1101 XmFontList toggle_font_list;
1102 Pixel toggle_background;
1104 Position switch_rc_x;
1105 Position switch_rc_y;
1109 XtTranslations trans_table;
1115 /* Add the additional actions needed by the panel and */
1116 /* set up translations in main edit widget */
1122 XtAppAddActions(XtWidgetToApplicationContext(panel.shell),action_table,1);
1123 trans_table = XtParseTranslationTable (translations_escape);
1124 XtOverrideTranslations (switch_edit, trans_table);
1128 /* Extract the label and toggle position */
1131 XtSetArg (al[ac], XmNx, &toggle_x); ac++;
1132 XtSetArg (al[ac], XmNy, &toggle_y); ac++;
1133 XtSetArg (al[ac], XmNwidth, &toggle_width); ac++;
1134 XtSetArg (al[ac], XmNheight, &toggle_height); ac++;
1135 XtSetArg (al[ac], XmNstring, &toggle_string); ac++;
1136 XtSetArg (al[ac], XmNfontList, &toggle_font_list); ac++;
1137 XtGetValues (switch_button, al, ac);
1140 /* Extract the switch_rc's position */
1142 switch_rc_x = XtX (XtParent (switch_button));
1143 switch_rc_y = XtY (XtParent (switch_button));
1146 /* Convert the xm string into a char string for editing and */
1147 /* then create the text widget to perform the name editing. */
1150 (char *)_XmStringUngenerate(toggle_string, NULL,
1151 XmCHARSET_TEXT, XmCHARSET_TEXT))
1155 /* Set the switch editing field to the new resource set */
1158 XtSetArg (al[ac], XmNleftOffset, toggle_x + switch_rc_x); ac++;
1159 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1160 XtSetArg (al[ac], XmNtopOffset, toggle_y + switch_rc_y); ac++;
1161 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1162 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
1163 XtSetArg (al[ac], XmNmarginHeight, 0); ac++;
1164 XtSetArg (al[ac], XmNfontList, toggle_font_list); ac++;
1165 XtSetArg (al[ac], XmNhighlightThickness, 1); ac++;
1166 XtSetArg (al[ac], XmNvalue, edit_string); ac++;
1167 XtSetArg (al[ac], XmNuserData, switch_button); ac++;
1169 XtSetValues (switch_edit, al, ac);
1171 XtFree(edit_string);
1174 XtSetArg (al[ac], XmNcursorPosition,
1175 XmTextFieldGetLastPosition (switch_edit)); ac++;
1176 XtSetArg (al[ac], XmNwidth, toggle_width); ac++;
1177 XtSetArg (al[ac], XmNheight, toggle_height); ac++;
1178 XtSetValues (switch_edit, al, ac);
1181 /* Add the callbacks for the text input processing */
1183 XtAddCallback (switch_edit, XmNactivateCallback,
1184 SwitchRenameCB, (XtPointer) switch_button);
1186 XtManageChild (switch_edit);
1188 XRaiseWindow (XtDisplay (switch_edit), XtWindow (switch_edit));
1189 XSetInputFocus (XtDisplay (switch_edit), XtWindow (panel.shell),
1190 RevertToParent, CurrentTime);
1192 XmProcessTraversal (switch_edit, XmTRAVERSE_CURRENT);
1195 XmStringFree (toggle_string);
1201 /************************************************************************
1202 ************************************************************************
1204 The next block of functions are used for the push and drop callbacks
1205 on all of the panel controls.
1207 ************************************************************************
1208 ************************************************************************/
1213 /************************************************************************
1215 * CheckControlTypeFile
1216 * Check the control if it is of type "file" that the file exists
1217 * before performing a push or drop action.
1219 * Inputs: control_data - the control whose file type and status are
1222 ************************************************************************/
1226 CheckControlTypeFile (ControlData * control_data)
1230 struct stat stat_info;
1237 if ((int) control_data->element_values[CONTROL_TYPE].parsed_value != CONTROL_FILE)
1241 (char *) control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1243 if (lstat (file_name, &stat_info) == 0)
1247 /* Display an error dialog because the file cannot be found */
1249 title = FPGETMESSAGE (86, 9, "Workspace Manager - Icon Action Error");
1250 title = XtNewString (title);
1252 msg = FPGETMESSAGE (86, 7, "Cannot find the file");
1253 message = XtMalloc (strlen (msg) + strlen (file_name) + 2);
1254 sprintf (message, "%s %s", msg, file_name);
1256 _DtMessage (panel.shell, title, message, NULL, NULL);
1266 /************************************************************************
1269 * Free the function argument
1271 ************************************************************************/
1280 if (wmFunc == F_Action)
1282 WmActionArg *pAP = (WmActionArg *) pArg;
1284 if (pAP->aap != NULL)
1288 for (i=0; i < pAP->numArgs; i++)
1290 if (pAP->aap[i].u.file.name != NULL)
1291 XtFree ((char *) pAP->aap[i].u.file.name);
1293 XtFree ((char *) pAP->aap);
1296 if (pAP->actionName != NULL)
1297 XtFree ((char *) pAP->actionName);
1299 if (pAP->szExecParms != NULL)
1300 XtFree ((char *) pAP->szExecParms);
1304 XtFree ((char *) pArg);
1309 CheckOtherMonitorsOn(SubpanelData * subpanel_data)
1312 ControlData * control_data;
1315 for (i = -1; i < subpanel_data->control_data_count; i++)
1319 m_state = _DtControlGetMonitorState(subpanel_data->main_panel_icon_copy);
1323 control_data = subpanel_data->control_data[i];
1324 m_state = _DtControlGetMonitorState(control_data->icon);
1327 if (m_state == DtMONITOR_ON) return True;
1334 /************************************************************************
1337 * Process the callback on a control.
1339 ************************************************************************/
1343 XtPointer client_data,
1344 XtPointer call_data)
1347 int control_behavior;
1349 DtControlCallbackStruct * callback = (DtControlCallbackStruct *) call_data;
1350 XEvent * event = callback->event;
1351 ControlData * control_data = (ControlData *) client_data;
1354 PanelActionData * push_action;
1355 Boolean push_recall;
1356 Boolean unpost_subpanel = True;
1359 SubpanelData * subpanel_data;
1360 ControlData * main_control_data;
1366 Widget monitor_icon;
1372 control_behavior = (int) (panel.element_values[PANEL_CONTROL_BEHAVIOR].parsed_value);
1375 /* See if the workspace name is being edited. If so, call the */
1376 /* callback function to accept the changes. */
1378 for (i = 0; i < panel.box_data_count; i++)
1380 if (panel.box_data[i]->switch_edit != NULL)
1382 if (XtIsManaged (panel.box_data[i]->switch_edit))
1384 Widget switch_button;
1386 XtSetArg (al[0], XmNuserData, &switch_button);
1387 XtGetValues (panel.box_data[i]->switch_edit, al, 1);
1388 SwitchRenameCB (panel.box_data[i]->switch_edit,
1389 (XtPointer) switch_button, (XtPointer) NULL);
1390 XmProcessTraversal (w, XmTRAVERSE_CURRENT);
1397 /* See if the control action occurred out of a subpanel. If so, */
1398 /* get the subpanel and set the main control data. */
1400 if (control_data->parent_type == SUBPANEL)
1402 subpanel_data = (SubpanelData *) control_data->parent_data;
1403 main_control_data = subpanel_data->parent_control_data;
1405 /* This control may have been toggled from the subpanel. If */
1406 /* so, make sure the subpanel is not reposted. */
1409 if (XtParent (w) != subpanel_data->form)
1410 unpost_subpanel = False;
1414 /* The control may be the main panel icon copy. If so, find */
1415 /* the subpanel that contains it a set the subpanel data */
1417 subpanel_data = NULL;
1419 for (i = 0; i < panel.box_data_count; i++)
1421 for (j = 0; j < panel.box_data[i]->control_data_count; j++)
1423 ControlData * box_control;
1425 box_control = panel.box_data[i]->control_data[j];
1427 if (box_control->subpanel_data != NULL &&
1428 box_control->subpanel_data->main_panel_icon_copy == w)
1430 subpanel_data = box_control->subpanel_data;
1431 main_control_data = subpanel_data->parent_control_data;
1435 if (subpanel_data != NULL)
1441 /* If the input occurred out of a subpanel, check to see if */
1442 /* the input was an escape key. If so, unpost the subpanel */
1445 if (subpanel_data != NULL && event != NULL)
1447 if (event->xany.type == KeyPress)
1453 XComposeStatus compose;
1454 static Boolean first = True;
1456 count = XLookupString ((XKeyEvent *)event, buffer, bufsize,
1459 if (keysym == XK_Escape)
1463 ArrowCB (main_control_data->arrow,
1464 (XtPointer)main_control_data, (XtPointer)NULL);
1476 /* This function handles four callback reasons. Two of them, */
1477 /* START and STOP show and remove an hour glass cursor. */
1478 /* MONITOR modifies subpanel visuals when a file change is */
1479 /* detected. ACTIVATE/DEFAULT_ACTION handle the activation */
1482 if (callback->reason == XmCR_BUSY_START)
1485 XDefineCursor (XtDisplay (panel.shell), XtWindow (panel.shell),
1488 for (i = 0, pWid = M_PopupList (panel.shell);
1489 i < M_NumPopups (panel.shell); i++)
1490 XDefineCursor (XtDisplay (panel.shell), XtWindow (pWid[i]),
1494 else if (callback->reason == XmCR_BUSY_STOP)
1496 XUndefineCursor (XtDisplay (panel.shell), XtWindow (panel.shell));
1498 for (i = 0, pWid = M_PopupList (panel.shell);
1499 i < M_NumPopups (panel.shell); i++)
1500 XUndefineCursor (XtDisplay (panel.shell), XtWindow (pWid[i]));
1503 else if (callback->reason == XmCR_MONITOR)
1505 /* For a monitor file, turn on the monitor indicator for */
1506 /* the subpanel control and turn on the arrow to the */
1507 /* highlighted arrow of the subpanel. */
1509 if (subpanel_data != NULL)
1511 monitor_icon = control_data->indicator;
1513 m_state = _DtControlGetMonitorState(w);
1515 if (m_state == DtMONITOR_ON)
1516 XtSetArg (al[0], XmNimageName, indicator_on_image);
1517 else /* DtMONITOR_OFF */
1518 XtSetArg (al[0], XmNimageName, indicator_off_image);
1520 XtSetValues (monitor_icon, al, 1);
1522 if (XtIsManaged (subpanel_data->shell))
1524 if (m_state == DtMONITOR_ON)
1526 XtSetArg (al[0], XmNimageName, unpost_monitor_arrow_image);
1527 XtSetValues (main_control_data->arrow, al, 1);
1531 if (!CheckOtherMonitorsOn(subpanel_data))
1533 XtSetArg (al[0], XmNimageName, unpost_arrow_image);
1534 XtSetValues (main_control_data->arrow, al, 1);
1540 if (m_state == DtMONITOR_ON)
1542 XtSetArg (al[0], XmNimageName, post_monitor_arrow_image);
1543 XtSetValues (main_control_data->arrow, al, 1);
1547 if (!CheckOtherMonitorsOn(subpanel_data))
1549 XtSetArg (al[0], XmNimageName, post_arrow_image);
1550 XtSetValues (main_control_data->arrow, al, 1);
1557 else if ((control_behavior == DOUBLE_CLICK &&
1558 callback->reason == XmCR_DEFAULT_ACTION) ||
1559 (control_behavior == SINGLE_CLICK &&
1560 (callback->reason == XmCR_DEFAULT_ACTION ||
1561 callback->reason == XmCR_SINGLE_SELECT)))
1563 control_type = (int) (control_data->element_values[CONTROL_TYPE].parsed_value);
1564 push_action = (PanelActionData *) (control_data->element_values[CONTROL_PUSH_ACTION].parsed_value);
1565 push_recall = (Boolean) (control_data->element_values[CONTROL_PUSH_RECALL].parsed_value);
1567 switch (control_type)
1569 case CONTROL_CLIENT:
1575 /* Turn off the subpanel control monitor indicator */
1577 if ((char) control_data->element_values[CONTROL_MONITOR_TYPE].
1578 parsed_value != MONITOR_NONE)
1580 if (subpanel_data != NULL)
1582 monitor_icon = control_data->indicator;
1583 XtSetArg (al[0], XmNimageName, indicator_off_image);
1584 XtSetValues (monitor_icon, al, 1);
1589 if (CheckControlTypeFile (control_data) && push_action != NULL)
1591 _DtControlDoPushAnimation (w);
1593 if (push_recall == False)
1595 /* If the control is of type file, build and object */
1596 /* list that contains the host and file name to */
1597 /* pass to the invokation. */
1599 if (control_type == CONTROL_FILE && !control_data->is_action)
1603 aap = (DtActionArg *) XtCalloc(1,sizeof(DtActionArg));
1605 aap->argClass = DtACTION_FILE;
1607 aap->u.file.name = (char *) control_data->
1608 element_values[CONTROL_FILE_NAME].parsed_value;
1610 DtActionInvoke (panel.shell,
1611 push_action->action_name,
1612 aap, 1, NULL, NULL, NULL,
1615 XtFree ((char *) aap);
1619 if (strcmp (push_action->action_name, "FPOnItemHelp") == 0)
1622 unpost_subpanel = False;
1626 DtActionInvoke (panel.shell,
1627 push_action->action_name,
1628 NULL, 0, NULL, NULL, NULL,
1637 String func_arg = NULL;
1640 char * client_title;
1642 WmGlobalData * wm_global_data = (WmGlobalData *) panel.global_data;
1643 ClientData * wm_client_data = NULL;
1644 WmPushRecallArg push_argument;
1647 /* Parse out the function and arguments used by the */
1648 /* window manager to invoke the client. */
1650 s1save = s1 = XtNewString ("f.action");
1653 ParseWmFunction ((unsigned char **) &s1, CRS_ANY, &wm_func);
1658 (char *) control_data->element_values[CONTROL_CLIENT_NAME].parsed_value;
1660 if (client_name == NULL)
1662 (char *) control_data->element_values[CONTROL_LABEL].parsed_value;
1665 (char *) control_data->element_values[CONTROL_LABEL].parsed_value;
1667 if (control_type == CONTROL_FILE && ! control_data->is_action)
1671 file_name = (char *) control_data->
1672 element_values[CONTROL_FILE_NAME].parsed_value;
1674 s1 = XtMalloc (strlen (push_action->action_name) + strlen (file_name) + 2);
1675 strcpy (s1, push_action->action_name);
1677 strcat (s1, file_name);
1680 s1 = XtNewString (push_action->action_name);
1682 ParseWmFunctionArg ((unsigned char **) &s1, function_index,
1683 wm_func, (void **) &func_arg,
1684 client_name, client_name);
1687 /* Set the push argument to the parsed data */
1689 push_argument.ixReg = PushRecallGetData (client_name);
1690 push_argument.wmFunc = wm_func;
1691 push_argument.pArgs = func_arg;
1694 /* Get the window manager client data for the panel and */
1695 /* call the push recall function to get the client run. */
1697 if (subpanel_data != NULL)
1698 XFindContext (wm_global_data->display,
1699 XtWindow (subpanel_data->shell),
1700 wm_global_data->windowContextType,
1701 (XtPointer) &wm_client_data);
1703 XFindContext (wm_global_data->display,
1704 XtWindow (panel.shell),
1705 wm_global_data->windowContextType,
1706 (XtPointer) &wm_client_data);
1708 F_Push_Recall ((String) &push_argument,
1709 wm_client_data, callback->event);
1711 FreeFunctionArg (wm_func, func_arg);
1727 /* Call the unposting function and reset the arrow behavior if the */
1728 /* action occured out of a subpanel. */
1730 if (subpanel_data != NULL && unpost_subpanel &&
1731 (Boolean) panel.element_values[PANEL_SUBPANEL_UNPOST].parsed_value &&
1732 subpanel_data->torn == False)
1733 ArrowCB (main_control_data->arrow,
1734 (XtPointer)main_control_data, (XtPointer)NULL);
1741 /************************************************************************
1744 * Process the callback for drops on a control
1746 ************************************************************************/
1751 XtPointer client_data,
1752 XtPointer call_data)
1756 PanelActionData * drop_action = (PanelActionData *) client_data;
1757 DtDndDropAnimateCallback animate_data =
1758 (DtDndDropAnimateCallback) call_data;
1760 ControlData * control_data;
1764 char * save_name = NULL;
1766 XtSetArg (al[0], XmNuserData, &control_data);
1767 XtGetValues (w, al, 1);
1769 if (CheckControlTypeFile (control_data) &&
1770 (animate_data->dropData->protocol == DtDND_FILENAME_TRANSFER ||
1771 animate_data->dropData->protocol == DtDND_BUFFER_TRANSFER))
1775 (int)control_data->element_values[CONTROL_TYPE].parsed_value;
1776 char * control_name =
1777 (char *)control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1778 Boolean send_control_name = False;
1780 _DtControlDoDropAnimation (w);
1782 drop_action = (PanelActionData *)
1783 control_data->element_values[CONTROL_DROP_ACTION].parsed_value;
1785 if (control_data->operation == XmDROP_MOVE)
1787 if (control_data->move_action)
1789 save_name = drop_action->action_name;
1790 drop_action->action_name = control_data->move_action;
1793 else if (control_data->operation == XmDROP_COPY)
1795 if (control_data->copy_action)
1797 save_name = drop_action->action_name;
1798 drop_action->action_name = control_data->copy_action;
1801 else if (control_data->operation == XmDROP_LINK)
1803 if (control_data->link_action)
1805 save_name = drop_action->action_name;
1806 drop_action->action_name = control_data->link_action;
1811 numItems = animate_data->dropData->numItems;
1813 if ((control_type == CONTROL_FILE) &&
1814 (!control_data->is_action) &&
1815 (strcmp(control_name, drop_action->action_name) != 0))
1818 send_control_name = True;
1821 if (animate_data->dropData->protocol == DtDND_FILENAME_TRANSFER)
1823 char ** file_list = animate_data->dropData->data.files;
1826 aap = (DtActionArg *) XtCalloc (numItems, sizeof (DtActionArg));
1828 if (send_control_name)
1830 aap[m].argClass = DtACTION_FILE;
1831 aap[m++].u.file.name =
1832 (char *)control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1835 for (l = 0; m < numItems; l++, m++)
1837 aap[m].argClass = DtACTION_FILE;
1838 aap[m].u.file.name = file_list[l];
1841 else if (animate_data->dropData->protocol == DtDND_BUFFER_TRANSFER)
1843 DtDndBuffer * buf_list = animate_data->dropData->data.buffers;
1846 aap = (DtActionArg *) XtCalloc (numItems, sizeof (DtActionArg));
1848 if (send_control_name)
1850 aap[m].argClass = DtACTION_FILE;
1851 aap[m++].u.file.name =
1852 (char *)control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1855 for (l = 0; m < numItems; l++, m++)
1857 aap[m].argClass = DtACTION_BUFFER;
1858 aap[m].u.buffer.bp = buf_list[l].bp;
1859 aap[m].u.buffer.size = buf_list[l].size;
1860 aap[m].u.buffer.name = buf_list[l].name;
1865 if (save_name != NULL)
1866 drop_action->action_name = save_name;
1868 control_data->operation = NULL;
1873 DtActionInvoke (w, drop_action->action_name, aap, numItems,
1874 NULL, NULL, NULL, 1, NULL, NULL);
1876 XtFree((char *) aap);
1878 if (save_name != NULL)
1879 drop_action->action_name = save_name;
1881 control_data->operation = NULL;
1888 /************************************************************************
1891 * Process the callback for drops on a control
1893 ************************************************************************/
1897 TransferDropCB (Widget w,
1898 XtPointer client_data,
1899 XtPointer call_data)
1903 DtDndTransferCallbackStruct * transfer_data =
1904 (DtDndTransferCallbackStruct *) call_data;
1905 ControlData * control_data;
1909 /* Currently only accepts FILE drops */
1911 if (transfer_data->dropData->protocol == DtDND_FILENAME_TRANSFER ||
1912 transfer_data->dropData->protocol == DtDND_BUFFER_TRANSFER)
1914 transfer_data->status = DtDND_SUCCESS;
1916 XtSetArg (al[0], XmNuserData, &control_data);
1917 XtGetValues (w, al, 1);
1919 control_data->operation = transfer_data->operation;
1923 transfer_data->status = DtDND_FAILURE;
1925 transfer_data->completeMove = False;
1930 /************************************************************************
1931 ************************************************************************
1933 This block of functions handle the processing of subpanel torn-off
1934 behavior. Default behavior for a subpanel is to unpost when a
1935 control is selected. This changes to sticky when the subpanel is torn.
1937 ************************************************************************
1938 ************************************************************************/
1941 /************************************************************************
1944 * Process the callback on the subpanel unposting initiated through
1945 * the window manager close menu item.
1947 ************************************************************************/
1951 SubpanelUnmapCB (Widget w,
1952 XtPointer client_data,
1953 XtPointer call_data)
1957 ControlData * main_control_data = (ControlData *) client_data;
1958 SubpanelData * subpanel_data = main_control_data->subpanel_data;
1965 XtSetArg (al[ac], XmNimageName, post_arrow_image); ac++;
1966 XtSetValues (main_control_data->arrow, al, ac);
1968 XtUnmanageChild (subpanel_data->shell);
1969 subpanel_data->torn = False;
1972 /* Remove the event handler from the subpanel */
1974 XtRemoveEventHandler (subpanel_data->shell, StructureNotifyMask, False,
1975 (XtEventHandler) SubpanelTornEventHandler,
1976 (XtPointer) main_control_data);
1979 /* Reset the active traversal control for the front panel */
1980 /* We should not have to do this but for unknown reasons, */
1981 /* the traversal highlight is getting lost. */
1983 XmProcessTraversal (panel.shell, XmTRAVERSE_NEXT);
1984 XmProcessTraversal (panel.shell, XmTRAVERSE_PREV);
1990 /************************************************************************
1992 * SubpanelTornEventHandler
1993 * Set a subpanel flag to change its posting behavior when it is
1996 ************************************************************************/
1999 SubpanelTornEventHandler (Widget subpanel_shell,
2000 XtPointer client_data,
2002 Boolean * continue_dispatch)
2005 ControlData * main_control_data = (ControlData *) client_data;
2006 SubpanelData * subpanel_data = main_control_data->subpanel_data;
2009 if (subpanel_data->posted_x != 0 &&
2010 subpanel_data->posted_x != XtX (subpanel_data->shell))
2012 subpanel_data->torn = True;
2014 subpanel_data->torn = False;
2016 *continue_dispatch = True;
2023 /************************************************************************
2026 * Start up the help manager to show the help topic
2028 * Inputs: widget - the widget for which help was requested
2029 * help_volume - the help volume that contains the information
2030 * help_topic - the specific help topic.
2032 ************************************************************************/
2035 void StartHelpClient (Widget widget,
2041 /***** TEMPORARY - Add code to actually invoke the Help Client ****/
2043 WmDtDisplayTopicHelp (widget, help_volume, help_topic);
2046 /************************************************************************
2049 * Invoke topic help if available otherwise invoke help string if
2052 ************************************************************************/
2055 void InvokeHelp (Widget widget,
2061 if (help_volume == NULL)
2062 help_volume = FP_HELP_VOLUME;
2064 if (help_topic != NULL)
2066 if (strcmp (help_volume, FP_HELP_VOLUME) == 0)
2067 WmDtDisplayTopicHelp (widget, help_volume, help_topic);
2069 StartHelpClient (widget, help_volume, help_topic);
2073 if (help_string != NULL)
2074 WmDtDisplayStringHelp (widget, help_string);
2079 /************************************************************************
2081 * SubpanelTopicHelpCB
2082 * Process the callback for help on the subpanel
2084 ************************************************************************/
2087 void SubpanelTopicHelpCB (Widget widget,
2088 XtPointer client_data,
2089 XtPointer call_data)
2092 SubpanelData * subpanel_data = (SubpanelData *) client_data;
2098 (char *) subpanel_data->element_values[SUBPANEL_HELP_VOLUME].parsed_value;
2100 (char *) subpanel_data->element_values[SUBPANEL_HELP_TOPIC].parsed_value;
2102 (char *) subpanel_data->element_values[SUBPANEL_HELP_STRING].parsed_value;
2104 InvokeHelp(widget, help_topic, help_volume, help_string);
2106 } /* END OF FUNCTION SubpanelTopicHelpCB */
2111 /************************************************************************
2114 * Process the callback for help on the switch
2116 ************************************************************************/
2119 void SwitchTopicHelpCB (Widget widget,
2120 XtPointer client_data,
2121 XtPointer call_data)
2124 SwitchData * switch_data = (SwitchData *) client_data;
2130 (char *) switch_data->element_values[SWITCH_HELP_VOLUME].parsed_value;
2132 (char *) switch_data->element_values[SWITCH_HELP_TOPIC].parsed_value;
2134 (char *) switch_data->element_values[SWITCH_HELP_STRING].parsed_value;
2136 InvokeHelp(widget, help_topic, help_volume, help_string);
2138 } /* END OF FUNCTION SwitchTopicHelpCB */
2143 /************************************************************************
2145 * ControlTopicHelpCB
2146 * Process the callback for help on the control
2148 *************************************************************************/
2151 void ControlTopicHelpCB (Widget widget,
2152 XtPointer client_data,
2153 XtPointer call_data)
2157 ControlData * control_data = (ControlData *) client_data;
2163 (char *) control_data->element_values[CONTROL_HELP_VOLUME].parsed_value;
2165 (char *) control_data->element_values[CONTROL_HELP_TOPIC].parsed_value;
2167 (char *) control_data->element_values[CONTROL_HELP_STRING].parsed_value;
2169 InvokeHelp(widget, help_topic, help_volume, help_string);
2171 } /* END OF FUNCTION ControlTopicHelpCB */
2176 /************************************************************************
2178 * GeneralTopicHelpCB
2179 * Process the callback for help on the control
2181 ************************************************************************/
2184 void GeneralTopicHelpCB (Widget widget,
2185 XtPointer client_data,
2186 XtPointer call_data)
2193 help_volume = FP_HELP_VOLUME;
2194 help_topic = (char *) client_data;
2196 WmDtDisplayTopicHelp (widget, help_volume, help_topic);
2198 } /* END OF FUNCTION GeneralTopicHelpCB */
2203 /************************************************************************
2204 ************************************************************************
2206 This block of functions handle the initialization and dynamic
2207 processing for the subpanel installation area.
2209 ************************************************************************
2210 ************************************************************************/
2212 /************************************************************************
2214 * GetValuesFromDataType
2215 * Given and file type index and subpanel data, construct an element
2216 * values array for a new control that is initialized to the attributes
2219 ************************************************************************/
2223 GetValuesFromDataType (char * data_type,
2225 SubpanelData * subpanel_data,
2226 ElementValue ** element_values)
2233 *element_values = (ElementValue *) XtMalloc (sizeof(ElementValue) *
2234 CONTROL_KEYWORD_COUNT);
2236 for (i = 0; i < CONTROL_KEYWORD_COUNT; i++)
2238 (*element_values)[i].use_default = True;
2239 (*element_values)[i].string_value = NULL;
2240 (*element_values)[i].parsed_value = NULL;
2243 (*element_values)[CONTROL_FILE_NAME].string_value = XtNewString (file_name);
2245 ptr = (char *)strrchr(file_name, '/');
2248 (*element_values)[CONTROL_NAME].string_value = XtNewString(ptr);
2249 (*element_values)[CONTROL_TYPE].string_value = XtNewString("file");
2250 (*element_values)[CONTROL_CONTAINER_TYPE].string_value =
2251 XtNewString("SUBPANEL");
2252 (*element_values)[CONTROL_CONTAINER_NAME].string_value =
2253 XtNewString(subpanel_data->element_values[0].string_value);
2254 (*element_values)[CONTROL_POSITION_HINTS].string_value =
2255 XtNewString("last");
2257 InitializeControlFields (*element_values, data_type);
2263 /************************************************************************
2266 * Process the callback for the drop on the subpanel drop zone for
2267 * dynamic customization
2269 ************************************************************************/
2273 CustomizeDropCB (Widget w,
2274 XtPointer client_data,
2275 XtPointer call_data)
2279 ControlData * main_control_data;
2280 SubpanelData * subpanel_data;
2281 DtDndDropAnimateCallbackStruct * animate_data =
2282 (DtDndDropAnimateCallbackStruct *) call_data;
2284 ControlData * control_data;
2285 ElementValue * element_values;
2289 Boolean bad_control;
2290 Boolean control_monitor;
2294 char * new_control_name;
2295 char * control_name;
2296 Widget attach_widget;
2307 /* If this is not a transfer drop, return */
2309 if (animate_data->dropData->protocol != DtDND_FILENAME_TRANSFER)
2313 /* Get the subpanel, box, and main control data */
2315 XtSetArg (al[0], XmNuserData, &subpanel_data);
2316 XtGetValues (w, al, 1);
2318 main_control_data = subpanel_data->parent_control_data;
2319 box_data = (BoxData *) main_control_data->parent_data;
2321 file_count = animate_data->dropData->numItems;
2322 file_list = animate_data->dropData->data.files;
2325 /* Pop down the subpanel before creating the new control or */
2326 /* mucking with any of the old controls. */
2328 if (subpanel_data->torn == False)
2329 XtUnmanageChild (subpanel_data->shell);
2332 /* Loop through the set of files (possibly more than one) that */
2333 /* have been dropped. */
2335 for (i = 0; i < file_count; i++)
2338 /* Get the file type of the file and process as either */
2339 /* a "FrontPanel" file or a normal file type. */
2341 data_type = DtDtsFileToDataType (file_list[i]);
2343 if (!strcmp (data_type, "FP"))
2346 InitParse (file_list[i], &element_values);
2349 /* Reset the values of the container name and type to this one */
2351 if (element_values[CONTROL_CONTAINER_NAME].use_default == False)
2353 if (element_values[CONTROL_CONTAINER_NAME].parsed_value != NULL)
2354 XtFree (element_values[CONTROL_CONTAINER_NAME].parsed_value);
2355 if (element_values[CONTROL_CONTAINER_NAME].string_value != NULL)
2356 XtFree (element_values[CONTROL_CONTAINER_NAME].string_value);
2359 if (element_values[CONTROL_CONTAINER_TYPE].use_default == False)
2361 if (element_values[CONTROL_CONTAINER_TYPE].string_value != NULL)
2362 XtFree (element_values[CONTROL_CONTAINER_TYPE].string_value);
2365 if (element_values[CONTROL_POSITION_HINTS].use_default == False)
2367 if (element_values[CONTROL_POSITION_HINTS].string_value != NULL)
2368 XtFree (element_values[CONTROL_POSITION_HINTS].string_value);
2371 element_values[CONTROL_CONTAINER_NAME].use_default = False;
2372 element_values[CONTROL_CONTAINER_NAME].string_value =
2373 XtNewString (subpanel_data->element_values[SUBPANEL_NAME].parsed_value);
2374 element_values[CONTROL_CONTAINER_NAME].parsed_value =
2375 XtNewString (subpanel_data->element_values[SUBPANEL_NAME].parsed_value);
2377 element_values[CONTROL_CONTAINER_TYPE].use_default = False;
2378 element_values[CONTROL_CONTAINER_TYPE].string_value =
2379 XtNewString ("SUBPANEL");
2380 element_values[CONTROL_CONTAINER_TYPE].parsed_value =
2383 element_values[CONTROL_POSITION_HINTS].use_default = False;
2384 element_values[CONTROL_POSITION_HINTS].string_value =
2385 XtNewString ("last");
2386 element_values[CONTROL_POSITION_HINTS].parsed_value =
2392 GetValuesFromDataType (data_type, file_list[i],
2393 subpanel_data, &element_values);
2396 DtDtsFreeDataType (data_type);
2400 /* Check for naming conflicts and if found, issue an error and */
2401 /* clean up. Continue processing subsequent files even if this */
2402 /* one is not valid. */
2404 new_control_name = (char *) element_values[CONTROL_NAME].parsed_value;
2405 bad_control = False;
2407 for (j = 0; j < subpanel_data->control_data_count; j++)
2409 control_name = (char *) subpanel_data->control_data[j]->
2410 element_values[CONTROL_NAME].parsed_value;
2412 if (strcmp (control_name, new_control_name) == 0)
2414 ControlData control_data;
2415 String title, del_ctrl, ctrl_name, del_msg, message;
2418 /* Display an error dialog for the unusable drop data */
2420 title = FPGETMESSAGE (86, 3, "Workspace Manager - Install Icon Error");
2421 title = XtNewString (title);
2423 del_ctrl = FPGETMESSAGE (86, 4, "Install Icon:");
2424 del_ctrl = XtNewString (del_ctrl);
2426 del_msg = FPGETMESSAGE (86, 8, "There is already an icon of this name.");
2427 del_msg = XtNewString (del_msg);
2429 message = XtMalloc ((strlen(del_ctrl) + strlen(new_control_name) +
2430 strlen(del_msg) + 4));
2431 sprintf(message, "%s %s\n\n%s", del_ctrl, new_control_name, del_msg);
2433 _DtMessage (panel.shell, title, message, NULL, NULL);
2441 /* Set up a temporary control data structure so that the */
2442 /* appropriate function can be used to free the allocated */
2443 /* element values. */
2445 control_data.element_values = element_values;
2446 RemoveEntry (&control_data, CONTROL);
2453 if (bad_control) continue;
2456 if ((int) element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
2457 control_monitor = True;
2459 control_monitor = False;
2462 position_hints = (int)element_values[CONTROL_POSITION_HINTS].parsed_value;
2465 /* Initialize the subpanel layout and processing attributes. */
2467 if ((int) main_control_data->
2468 element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
2470 control_monitor = True;
2474 for (j = 0; j < subpanel_data->control_data_count; j++)
2476 if ((int) subpanel_data->control_data[j]->
2477 element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
2479 control_monitor = True;
2485 /* If the new control is a montior, loop through the existing */
2486 /* control set a adjust the left offset resource to ensure */
2487 /* that they are all aligned properly. */
2489 if (control_monitor)
2491 XtSetArg (al[0], XmNleftOffset, 20);
2493 for (j = 0; j < subpanel_data->control_data_count; j++)
2494 XtSetValues (subpanel_data->control_data[j]->icon, al, 1);
2496 if (subpanel_data->main_panel_icon_copy != NULL)
2497 XtSetValues (subpanel_data->main_panel_icon_copy, al, 1);
2501 /* Get the subpanel control data and position the element */
2502 /* values into the postion hints location. */
2503 /* The remainder of the positioning code is set up to allow */
2504 /* placement in non-last positions even though position is */
2505 /* forced to last. This is here for future use. */
2507 subpanel_data->control_data_count++;
2508 count = subpanel_data->control_data_count;
2510 subpanel_data->control_data =
2511 (ControlData **) XtRealloc ((char *) subpanel_data->control_data,
2512 sizeof (ControlData *) * count);
2514 for (j = count - 2; j >= 0; j--)
2516 if (position_hints >=
2517 (int) subpanel_data->control_data[j]->element_values[CONTROL_POSITION_HINTS].parsed_value)
2523 for (k = count - 1; k > j; k--)
2524 subpanel_data->control_data[k] = subpanel_data->control_data[k - 1];
2526 subpanel_data->control_data[j] = control_data =
2527 (ControlData *) XtMalloc (sizeof (ControlData));
2529 control_data->element_values = element_values;
2530 control_data->parent_data = (XtPointer) subpanel_data;
2531 control_data->parent_type = SUBPANEL;
2532 control_data->subpanel_data = NULL;
2533 control_data->icon = NULL;
2534 control_data->arrow = NULL;
2535 control_data->arrow_separator = NULL;
2536 control_data->indicator = NULL;
2537 control_data->is_action = False;
2538 control_data->move_action = NULL;
2539 control_data->copy_action = NULL;
2540 control_data->link_action = NULL;
2541 control_data->operation = NULL;
2543 AddControlActionList (control_data);
2546 if (j == 0 && subpanel_data->main_panel_icon_copy != NULL)
2547 attach_widget = subpanel_data->main_panel_icon_copy;
2549 attach_widget = subpanel_data->control_data[j - 1]->icon;
2552 /* Reattach the bottom control so the new bottom will appear */
2557 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
2558 XtSetArg (al[ac], XmNbottomOffset, 0); ac++;
2559 XtSetValues (attach_widget, al, ac);
2563 SubpanelControlCreate (subpanel_data, main_control_data,
2564 control_data, attach_widget, False,
2568 /* Pad the bottom control */
2573 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
2574 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
2575 XtSetValues (control_data->icon, al, ac);
2578 WriteControlComponentFile (control_data);
2583 /* Pop the subpanel back up and return */
2585 if (subpanel_data->torn == False)
2586 ArrowCB (main_control_data->arrow,
2587 (XtPointer)main_control_data, (XtPointer)NULL);
2593 /************************************************************************
2595 * CustomizeTransferDropCB
2596 * Process the callback for drops on an install zone
2598 ************************************************************************/
2602 CustomizeTransferDropCB (Widget w,
2603 XtPointer client_data,
2604 XtPointer call_data)
2608 DtDndTransferCallbackStruct * transfer_data =
2609 (DtDndTransferCallbackStruct *) call_data;
2611 /* Currently only accepts FILE drops */
2613 if (transfer_data->dropData->protocol == DtDND_FILENAME_TRANSFER)
2614 transfer_data->status = DtDND_SUCCESS;
2616 transfer_data->status = DtDND_FAILURE;
2618 transfer_data->completeMove = False;