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>
62 #include <X11/Xatom.h>
63 #include <X11/keysym.h>
65 #include "DataBaseLoad.h"
69 #include "WmResNames.h"
70 #include "WmFunction.h"
73 /************************************************************************
75 * External and static function declarations.
77 ************************************************************************/
79 extern XtPointer _XmStringUngenerate(XmString, XmStringTag,
80 XmTextType, XmTextType);
82 extern void SubpanelControlCreate (SubpanelData *, ControlData *, ControlData *,
83 Widget, Boolean, Boolean);
84 extern void WmSubpanelPosted (Display *, Window);
85 extern int PushRecallGetData (char *);
86 extern void SwitchButtonCreate (SwitchData *, Boolean);
87 extern void AddControlActionList (ControlData *);
89 void ArrowCB (Widget, XtPointer, XtPointer);
90 void HandleInputCB (Widget, XtPointer, XtPointer);
91 void MinimizeInputCB (Widget, XtPointer, XtPointer);
92 void MenuInputCB (Widget, XtPointer, XtPointer);
93 void SwitchButtonCB (Widget, XtPointer, XtPointer);
94 void PushCB (Widget, XtPointer, XtPointer);
95 void SubpanelUnmapCB (Widget, XtPointer, XtPointer);
96 void SubpanelTornEventHandler (Widget, XtPointer, XEvent *, Boolean *);
97 Boolean CheckControlTypeFile (ControlData *);
100 static void SwitchRenameCancel (Widget, XEvent *, String *, Cardinal *);
101 static void SwitchRenameCB (Widget, XtPointer, XtPointer);
102 static void GetValuesFromDataType(char *, char *, SubpanelData *,
105 void SwitchRenameLabel (Widget, BoxData *);
106 void DropCB (Widget, XtPointer, XtPointer);
107 void TransferDropCB (Widget, XtPointer, XtPointer);
108 void CustomizeDropCB (Widget, XtPointer, XtPointer);
109 void CustomizeTransferDropCB (Widget, XtPointer, XtPointer);
115 /* Translations and action definitions */
116 /* These are used specifically for the text field overlay */
117 /* on the switch button for renaming the workspace. They */
118 /* are necessary for handling escape key processing. */
120 static char translations_escape[] = "<Key>osfCancel:Escape()";
122 static XtActionsRec action_table[] = {
123 {"Escape", SwitchRenameCancel},
128 /************************************************************************
130 * File local globals.
132 ************************************************************************/
134 extern String post_arrow_image;
135 extern String unpost_arrow_image;
136 extern String post_monitor_arrow_image;
137 extern String unpost_monitor_arrow_image;
138 extern String blank_arrow_image;
139 extern String dropzone_image;
140 extern String indicator_on_image;
141 extern String indicator_off_image;
145 /************************************************************************
148 * Call the specified WmFunction function with appropriate args
150 ************************************************************************/
154 CallWmFunction (WmFunction wm_function,
161 WmGlobalData * wm_global_data = (WmGlobalData *) panel.global_data;
162 ClientData * wm_client_data = NULL;
163 Display * display = wm_global_data->display;
164 Window client_window = XtWindow(client);
167 * Find the window manager client data for this client
170 XFindContext (display, client_window, wm_global_data->windowContextType,
171 (XtPointer) &wm_client_data);
173 if (wm_client_data == NULL)
177 * Execute the window manager function
180 wm_function (args, wm_client_data, event);
183 /************************************************************************
186 * Process the callback on the subpanel posting/unposting arrow
188 ************************************************************************/
193 XtPointer client_data,
198 ControlData * control_data = (ControlData *) client_data;
199 SubpanelData * subpanel_data = control_data->subpanel_data;
205 /* If the subpanel's shell is not managed, this is a request to post */
206 /* the subpanel. Otherwise it is an unpost request. */
207 /* Reset the arrow image after the post or unpost. */
209 if (!XtIsManaged (subpanel_data->shell))
211 Position x = XtX (control_data->arrow);
212 Position y = XtY (control_data->arrow);
215 XtSetMappedWhenManaged (subpanel_data->shell, False);
216 XtManageChild (subpanel_data->form);
218 XtTranslateCoords (w, 0, 0, &x, &y);
220 XtSetArg (al[0], XmNx, x);
221 XtSetValues (subpanel_data->form, al, 1);
223 XtManageChild (subpanel_data->shell);
224 XtSetMappedWhenManaged (subpanel_data->shell, True);
227 XtSetArg (al[ac], XmNimageName, unpost_arrow_image); ac++;
228 XtSetValues (w, al, ac);
232 /* Execute the window manager function to unpost the subpanel */
234 CallWmFunction (F_Kill, NULL, subpanel_data->shell, NULL);
241 /************************************************************************
243 * HandleInputTranslations
244 * Return translation table suitable for HandleInputCB
246 ************************************************************************/
250 HandleInputTranslations(void)
253 static XtTranslations handle_translations;
255 if (handle_translations == NULL)
257 handle_translations = XtParseTranslationTable(
258 "<BtnDown>: DrawingAreaInput() ManagerGadgetArm()\n\
259 <BtnUp>: DrawingAreaInput() ManagerGadgetActivate()\n\
260 <Btn1Motion>: DrawingAreaInput() ManagerGadgetButtonMotion()\n\
261 <Btn2Motion>: DrawingAreaInput() ManagerGadgetButtonMotion()");
263 return handle_translations;
266 /************************************************************************
269 * Process button events on the frontpanel handles.
271 ************************************************************************/
275 HandleInputCB (Widget w,
276 XtPointer client_data,
281 XmAnyCallbackStruct * callback;
284 XButtonEvent * buttonEvent;
285 XMotionEvent * motionEvent;
287 callback = (XmAnyCallbackStruct *) call_data;
288 event = (XEvent *) callback->event;
289 buttonEvent = (XButtonEvent *) event;
290 motionEvent = (XMotionEvent *) event;
292 if (event->type == ButtonPress)
294 if (buttonEvent->button == wmGD.bMenuButton)
296 XUngrabPointer (XtDisplay (w), buttonEvent->time);
297 XSync (XtDisplay (w), FALSE);
298 CallWmFunction (F_Post_FpMenu, NULL, panel.shell, event);
303 wmGD.preMoveX = buttonEvent->x_root;
304 wmGD.preMoveY = buttonEvent->y_root;
306 if (buttonEvent->button == Button1)
308 CallWmFunction (F_Raise, NULL, panel.shell, event);
309 XSync (DISPLAY, FALSE);
310 XmUpdateDisplay (panel.shell);
314 else if (event->type == ButtonRelease)
316 wmGD.preMove = False;
318 else if (event->type == MotionNotify && wmGD.preMove)
322 diffX = motionEvent->x_root - wmGD.preMoveX;
323 if (diffX < 0) diffX = -diffX;
324 diffY = motionEvent->y_root - wmGD.preMoveY;
325 if (diffY < 0) diffY = -diffY;
327 if (diffX >= wmGD.moveThreshold || diffY >= wmGD.moveThreshold)
329 XUngrabPointer (XtDisplay (w), motionEvent->time);
330 XSync (XtDisplay (w), FALSE);
331 CallWmFunction (F_Move, NULL, panel.shell, event);
332 wmGD.preMove = False;
340 /************************************************************************
343 * Process button events on the frontpanel minimize button.
345 ************************************************************************/
349 MinimizeInputCB (Widget w,
350 XtPointer client_data,
355 XmAnyCallbackStruct * callback;
358 XButtonEvent * bevent;
360 extern Pixmap minimize_normal_pixmap;
361 extern Pixmap minimize_selected_pixmap;
366 callback = (XmAnyCallbackStruct *) call_data;
367 event = (XEvent *) callback->event;
368 bevent = (XButtonEvent *) event;
370 /* On the BSelect button press, change the image to the selected
371 * minimize image. On the release, check to see if the release
372 * occured within the minimize button before minimizing.
373 * On BMenu button press, post the front panel menu.
376 if (event->type == ButtonPress)
378 if (bevent->button == Button1)
380 XtSetArg (al[0], XmNbackgroundPixmap, minimize_selected_pixmap);
381 XtSetValues (w, al, 1);
383 else if (bevent->button == wmGD.bMenuButton)
385 XUngrabPointer (XtDisplay (w), bevent->time);
386 XSync (XtDisplay (w), FALSE);
387 CallWmFunction (F_Post_FpMenu, NULL, panel.shell, event);
390 else if (event->type == ButtonRelease && bevent->button == Button1)
392 if (bevent->x >= 0 && bevent->x <= (Position) XtWidth(w) &&
393 bevent->y >= 0 && bevent->y <= (Position) XtHeight(w))
395 CallWmFunction (F_Minimize, NULL, panel.shell, event);
398 XtSetArg (al[0], XmNbackgroundPixmap, minimize_normal_pixmap);
399 XtSetValues (w, al, 1);
406 /************************************************************************
409 * Process button events on the front panel menu button.
411 ************************************************************************/
415 MenuInputCB (Widget w,
416 XtPointer client_data,
421 XmAnyCallbackStruct * callback;
424 XButtonEvent * bevent;
426 callback = (XmAnyCallbackStruct *) call_data;
427 event = (XEvent *) callback->event;
428 bevent = (XButtonEvent *) event;
432 * On BSelect or BMenu button press post the front panel system menu
435 if (event->type == ButtonPress &&
436 (bevent->button == Button1 || bevent->button == wmGD.bMenuButton))
438 XUngrabPointer (XtDisplay (w), bevent->time);
439 XSync (XtDisplay (w), FALSE);
440 CallWmFunction (F_Post_FpMenu, NULL, panel.shell, event);
446 /************************************************************************
447 ************************************************************************
449 The next block of functions are used for the switch button switching,
450 renaming functionality, and add and delete of workspaces.
452 ************************************************************************
453 ************************************************************************/
457 /************************************************************************
459 * WorkspaceAdjustPanelPosition
460 * After a workspace button has been added or deleted, if the panel
461 * has changed sizes, reposition the panel to keep the same relative
464 * Inputs: x - the original x coordinate of the panel
465 * y - the original y coordinate of the panel
466 * width - the original width of the panel
467 * height - the original height of the panel
469 ************************************************************************/
473 WorkspaceAdjustPanelPosition (Position x,
480 Dimension screen_width;
481 Dimension screen_height;
484 Dimension new_height;
491 screen_width = WidthOfScreen (XtScreen (panel.shell));
492 screen_height = HeightOfScreen (XtScreen (panel.shell));
495 /* Reposition the panel to keep it centered relative to where */
496 /* it was positioned before the deletion of the button. */
500 new_width = XtWidth (panel.shell);
502 if (new_width != width || x + (Position) new_width > (Position) screen_width)
504 panel_center = x + width / 2 - 1;
505 new_x = panel_center - new_width / 2 - 4;
509 else if (new_x + (Position) new_width > (Position) screen_width)
510 new_x = screen_width - new_width - 4;
512 XtSetArg (al[ac], XmNx, new_x); ac++;
516 /* Keep the panel to the bottom of the screen, if it was there. */
517 /* But make sure that it does not go below the bottom. */
519 new_height = XtHeight (panel.shell);
521 if (new_height != height || (Dimension)(new_height + y - 1) > screen_height)
523 if (new_height < height && y > (Position)(screen_height / 2))
525 new_y = y + (Position)(height - new_height - 4);
526 XtSetArg (al[ac], XmNy, new_y); ac++;
528 else if ((Dimension)(new_height + y - 1) > screen_height)
530 new_y = (Position)(screen_height - new_height - 4);
531 XtSetArg (al[ac], XmNy, new_y); ac++;
536 XtSetValues (panel.shell, al, ac);
542 /************************************************************************
545 * Called by the workspace manager API to send notification of
546 * configuration changes to the workspace. The types of changes
547 * processed by this function are workspace add, delete, and rename.
549 ************************************************************************/
553 WorkspaceModifyCB (Widget w,
556 XtPointer client_data)
560 SwitchData * switch_data = (SwitchData *) client_data;
561 BoxData * box_data = switch_data->box_data;
562 DtWsmWorkspaceInfo * workspace_info;
568 Dimension screen_width;
571 x = XtX (panel.shell);
572 y = XtY (panel.shell);
573 width = XtWidth (panel.shell);
574 height = XtHeight (panel.shell);
575 screen_width = WidthOfScreen (XtScreen (panel.shell));
577 DtWsmGetWorkspaceInfo (XtDisplay (w), RootWindowOfScreen (XtScreen (w)),
578 atom_name, &workspace_info);
583 /* Increase the size of the switch names and button and call */
584 /* the function to create the new workspace switch button */
586 case DtWSM_REASON_ADD:
592 /* Cancel workspace renaming */
594 if (XtIsManaged (box_data->switch_edit))
595 SwitchRenameCancel (box_data->switch_edit, NULL, NULL, NULL);
598 DtWsmGetWorkspaceList (XtDisplay (switch_data->rc),
599 RootWindowOfScreen (XtScreen (switch_data->rc)),
600 &atom_names, &switch_count);
602 XFree (switch_data->atom_names);
603 switch_data->atom_names = atom_names;
605 switch_data->switch_count = switch_count;
607 switch_data->switch_names =
608 (char **) XtRealloc ((char *) switch_data->switch_names,
609 sizeof (char *) * switch_data->switch_count);
611 switch_data->switch_names[switch_data->switch_count - 1] =
612 XtNewString (workspace_info->pchTitle);
614 switch_data->buttons =
615 (Widget *) XtRealloc ((char *) switch_data->buttons,
616 sizeof (Widget *) * switch_data->switch_count);
618 SwitchButtonCreate (switch_data, True);
621 /* When adding a switch buttons, keep the row columns row count */
622 /* equal to the requested value with small number of buttons */
624 if (switch_data->switch_count <= (int)
625 (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value))
629 panel.switch_row_count = (int)
630 (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value);
632 XtSetArg (al[0], XmNnumColumns, panel.switch_row_count);
633 XtSetValues (switch_data->rc, al, 1);
637 /* If the fp width is greater than the screen, increase the */
640 if (XtWidth (panel.shell) > screen_width)
644 panel.switch_row_count++;
646 XtSetArg (al[0], XmNnumColumns, panel.switch_row_count);
647 XtSetValues (switch_data->rc, al, 1);
650 WorkspaceAdjustPanelPosition (x, y, width, height);
655 /* Loop through the current set of atom names, comparing */
656 /* them with the atom of the workspace to be deleted. When */
657 /* free up the associated data and readjust the name, button */
658 /* and atom lists. */
660 case DtWSM_REASON_DELETE:
668 Dimension button_spacing;
669 Dimension button_width;
672 /* Cancel workspace renaming */
674 if (XtIsManaged (box_data->switch_edit))
675 SwitchRenameCancel (box_data->switch_edit, NULL, NULL, NULL);
678 DtWsmGetWorkspaceList (XtDisplay (switch_data->rc),
679 RootWindowOfScreen (XtScreen (switch_data->rc)),
680 &atom_names, &switch_count);
682 for (i = 0; i < switch_data->switch_count; i++)
684 if (atom_name == switch_data->atom_names[i])
686 if (switch_data->active_switch > i)
687 switch_data->active_switch--;
689 XtFree (switch_data->switch_names[i]);
690 XtDestroyWidget (switch_data->buttons[i]);
691 XFree (switch_data->atom_names);
692 switch_data->atom_names = atom_names;
693 switch_data->switch_count = switch_count;
695 for (j = i; j < switch_data->switch_count; j++)
697 switch_data->switch_names[j] = switch_data->switch_names[j+1];
698 switch_data->buttons[j] = switch_data->buttons[j + 1];
706 /* When deleting a switch button, keep trying to decrease the */
707 /* row count to the requested value. */
709 if (panel.switch_row_count > (int)
710 (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value))
712 button_width = XtWidth (switch_data->buttons[0]);
713 XtSetArg (al[0], XmNspacing, &button_spacing);
714 XtGetValues (switch_data->rc, al, 1);
716 if ((int)(screen_width - (width + button_width + button_spacing)) >
719 panel.switch_row_count--;
720 XtSetArg (al[0], XmNnumColumns, panel.switch_row_count);
721 XtSetValues (switch_data->rc, al, 1);
725 WorkspaceAdjustPanelPosition (x, y, width, height);
731 /* Loop through the current set of atom names, comparing */
732 /* them with the new atom. When a match is found, reset the */
733 /* the switch name to the new one and update the button label. */
735 case DtWSM_REASON_TITLE:
737 XmString toggle_string;
742 for (i = 0; i < switch_data->switch_count; i++)
744 if (atom_name == switch_data->atom_names[i])
746 switch_data->switch_names[i] =
747 XtNewString (workspace_info->pchTitle);
750 XmStringCreateLocalized (workspace_info->pchTitle);
752 XtSetArg (al[0], XmNstring, toggle_string);
753 XtSetValues (switch_data->buttons[i], al, 1);
754 XmStringFree (toggle_string);
756 XtSetArg (al[0], XmNiconName, workspace_info->pchTitle);
757 XtSetArg (al[1], XmNtitle, workspace_info->pchTitle);
758 XtSetValues (panel.shell, al, 2);
767 /* Loop through the set of switch atom names to find the one */
768 /* that is now active. Unset the old workspace button and */
769 /* set the new one referenced by the atom. */
771 case DtWSM_REASON_CURRENT:
776 for (i = 0; i < switch_data->switch_count; i++)
778 if (switch_data->atom_names[i] == atom_name)
780 XtSetArg (al[0], XmNiconName, switch_data->switch_names[i]);
781 XtSetArg (al[1], XmNtitle, switch_data->switch_names[i]);
782 XtSetValues (panel.shell, al, 2);
784 _DtIconSetState (switch_data->buttons[switch_data->active_switch], False, False);
785 switch_data->active_switch = i;
786 _DtIconSetState (switch_data->buttons[switch_data->active_switch], True, False);
794 DtWsmFreeWorkspaceInfo (workspace_info);
800 /************************************************************************
803 * Process callbacks on the switch buttons. This function cause
804 * either the workspace switch to occur or for the switch button
805 * label to become editable.
807 ************************************************************************/
811 SwitchButtonCB (Widget w,
812 XtPointer client_data,
817 DtControlCallbackStruct * callback = (DtControlCallbackStruct *) call_data;
818 XEvent * event = callback->event;
820 Widget switch_button = w;
821 Widget old_switch_button;
823 SwitchData * switch_data;
830 if (callback->reason != XmCR_VALUE_CHANGED) return;
832 XtSetArg (al[ac], XmNuserData, &box_data); ac++;
833 XtGetValues (switch_button, al, ac);
835 switch_data = box_data->switch_data;
836 old_switch_button = switch_data->buttons[switch_data->active_switch];
839 /* If the selection occured on a non-selected button, find the atom */
840 /* representing the workspace name of the button that was selected */
841 /* and use it to call the workspace manager API to switch the */
842 /* workspace. The indication on the buttons occurs out of the */
843 /* called from the workspace manager API. */
845 /* If the selection occured on the current button, set up the name */
846 /* change editing functions. */
848 if (switch_button != old_switch_button)
851 /* See if the workspace name is being edited. If so, call the */
852 /* callback function to accept the changes. */
854 if (XtIsManaged (box_data->switch_edit))
856 Widget edit_switch_button;
858 XtSetArg (al[0], XmNuserData, &edit_switch_button);
859 XtGetValues (box_data->switch_edit, al, 1);
860 SwitchRenameCB (box_data->switch_edit,
861 (XtPointer) edit_switch_button, (XtPointer) NULL);
863 XmProcessTraversal (w, XmTRAVERSE_CURRENT);
867 if (event->xany.type == ButtonRelease)
868 switch_data->time_stamp = event->xbutton.time;
870 for (i = 0; i < switch_data->switch_count; i++)
872 if (switch_button == switch_data->buttons[i])
874 XtSetArg (al[0], XmNiconName, switch_data->switch_names[i]);
875 XtSetArg (al[1], XmNtitle, switch_data->switch_names[i]);
876 XtSetValues (panel.shell, al, 2);
878 DtWsmSetCurrentWorkspace (XtParent (switch_button),
879 switch_data->atom_names[i]);
884 _DtIconSetState (old_switch_button, False, False);
888 /* Don't do anything on double click */
890 if (event->xany.type == ButtonRelease)
892 if ((event->xbutton.time - switch_data->time_stamp) >
893 XtGetMultiClickTime(XtDisplay(panel.shell)))
895 switch_data->time_stamp = event->xbutton.time;
896 SwitchRenameLabel (w, box_data);
900 _DtIconSetState (w, True, False);
907 /************************************************************************
910 * This is the XtActionProc that gets called when a user types
911 * escape in a text widget which has this translation tied to it.
913 ***********************************************************************/
917 SwitchRenameCancel (Widget w,
920 Cardinal * num_params)
924 Widget switch_button;
928 /* Extract the toggle button from the text field's user data */
930 XtSetArg (al[0], XmNuserData, &switch_button);
931 XtGetValues (w, al, 1);
934 /* Remove the callbacks to eliminate double processing */
936 XtRemoveAllCallbacks (w, XmNactivateCallback);
939 /* Unmanage the text widget, set the traversal to the button and exit */
942 XmProcessTraversal (switch_button, XmTRAVERSE_CURRENT);
948 /************************************************************************
951 * Process callbacks on the text field when a switch name is
954 ************************************************************************/
958 SwitchRenameCB (Widget w,
959 XtPointer client_data,
964 Widget switch_button = (Widget) client_data;
968 SwitchData * switch_data;
977 /* Remove the callbacks to eliminate double processing */
979 XtRemoveCallback (w, XmNactivateCallback,
980 SwitchRenameCB, (XtPointer) client_data);
983 /* If this callback has been called and the text widget is already */
984 /* unmanaged, it means that the escape key was pressed, so return */
986 if (XtIsManaged(w) == False) return;
989 /* Process the two reasons this callback is invoked. A <Return> */
990 /* key has been pressed or the focus is being moved. Accept the */
991 /* new name for both conditions. */
994 XtSetArg (al[ac], XmNuserData, &box_data); ac++;
995 XtGetValues (switch_button, al, ac);
997 switch_data = box_data->switch_data;
999 for (i = 0; i < switch_data->switch_count; i++)
1000 if (switch_data->buttons[i] == switch_button)
1004 /* Get the new name from the text field */
1006 edit_string = (char *) XmTextFieldGetString (w);
1009 /* Verify that title is valid and unique and if so, validate */
1010 /* uniqueness and then change the toggle and workspace internal */
1015 _DtStripSpaces (edit_string);
1017 if (strlen (edit_string) == 0)
1021 for (i = 0; i < switch_data->switch_count; i++)
1023 if (strcmp (switch_data->switch_names[i], edit_string) == 0)
1025 if (i == current_switch)
1027 XtUnmanageChild (w);
1028 XmProcessTraversal (switch_button, XmTRAVERSE_CURRENT);
1029 XtFree (edit_string);
1042 /* If the title is not valid, post and error dialog and */
1043 /* then leave the text field active to allow reediting. */
1044 /* Otherwise, change the title. */
1051 s1 = FPGETMESSAGE (86, 1, "Workspace Manager - Rename Error");
1052 s1 = XtNewString (s1);
1053 s2 = FPGETMESSAGE (86, 2, "Invalid or duplicate workspace name"),
1054 s2 = XtNewString (s2);
1056 _DtMessage (XtParent (w), s1, s2, NULL, NULL);
1062 _DtWsmSetWorkspaceTitle (panel.shell,
1063 switch_data->atom_names[current_switch],
1067 /* Unmanage the text field and exit */
1069 XtFree (edit_string);
1070 XtUnmanageChild (w);
1076 /************************************************************************
1079 * Set up the text field and callbacks needed for renaming a
1082 ************************************************************************/
1086 SwitchRenameLabel (Widget switch_button,
1091 Widget switch_edit = box_data->switch_edit;
1093 static Boolean first = True;
1095 XmString toggle_string;
1098 Dimension toggle_width;
1099 Dimension toggle_height;
1100 XmFontList toggle_font_list;
1101 Pixel toggle_background;
1103 Position switch_rc_x;
1104 Position switch_rc_y;
1108 XtTranslations trans_table;
1114 /* Add the additional actions needed by the panel and */
1115 /* set up translations in main edit widget */
1121 XtAppAddActions(XtWidgetToApplicationContext(panel.shell),action_table,1);
1122 trans_table = XtParseTranslationTable (translations_escape);
1123 XtOverrideTranslations (switch_edit, trans_table);
1127 /* Extract the label and toggle position */
1130 XtSetArg (al[ac], XmNx, &toggle_x); ac++;
1131 XtSetArg (al[ac], XmNy, &toggle_y); ac++;
1132 XtSetArg (al[ac], XmNwidth, &toggle_width); ac++;
1133 XtSetArg (al[ac], XmNheight, &toggle_height); ac++;
1134 XtSetArg (al[ac], XmNstring, &toggle_string); ac++;
1135 XtSetArg (al[ac], XmNfontList, &toggle_font_list); ac++;
1136 XtGetValues (switch_button, al, ac);
1139 /* Extract the switch_rc's position */
1141 switch_rc_x = XtX (XtParent (switch_button));
1142 switch_rc_y = XtY (XtParent (switch_button));
1145 /* Convert the xm string into a char string for editing and */
1146 /* then create the text widget to perform the name editing. */
1149 (char *)_XmStringUngenerate(toggle_string, NULL,
1150 XmCHARSET_TEXT, XmCHARSET_TEXT))
1154 /* Set the switch editing field to the new resource set */
1157 XtSetArg (al[ac], XmNleftOffset, toggle_x + switch_rc_x); ac++;
1158 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1159 XtSetArg (al[ac], XmNtopOffset, toggle_y + switch_rc_y); ac++;
1160 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1161 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
1162 XtSetArg (al[ac], XmNmarginHeight, 0); ac++;
1163 XtSetArg (al[ac], XmNfontList, toggle_font_list); ac++;
1164 XtSetArg (al[ac], XmNhighlightThickness, 1); ac++;
1165 XtSetArg (al[ac], XmNvalue, edit_string); ac++;
1166 XtSetArg (al[ac], XmNuserData, switch_button); ac++;
1168 XtSetValues (switch_edit, al, ac);
1170 XtFree(edit_string);
1173 XtSetArg (al[ac], XmNcursorPosition,
1174 XmTextFieldGetLastPosition (switch_edit)); ac++;
1175 XtSetArg (al[ac], XmNwidth, toggle_width); ac++;
1176 XtSetArg (al[ac], XmNheight, toggle_height); ac++;
1177 XtSetValues (switch_edit, al, ac);
1180 /* Add the callbacks for the text input processing */
1182 XtAddCallback (switch_edit, XmNactivateCallback,
1183 SwitchRenameCB, (XtPointer) switch_button);
1185 XtManageChild (switch_edit);
1187 XRaiseWindow (XtDisplay (switch_edit), XtWindow (switch_edit));
1188 XSetInputFocus (XtDisplay (switch_edit), XtWindow (panel.shell),
1189 RevertToParent, CurrentTime);
1191 XmProcessTraversal (switch_edit, XmTRAVERSE_CURRENT);
1194 XmStringFree (toggle_string);
1200 /************************************************************************
1201 ************************************************************************
1203 The next block of functions are used for the push and drop callbacks
1204 on all of the panel controls.
1206 ************************************************************************
1207 ************************************************************************/
1212 /************************************************************************
1214 * CheckControlTypeFile
1215 * Check the control if it is of type "file" that the file exists
1216 * before performing a push or drop action.
1218 * Inputs: control_data - the control whose file type and status are
1221 ************************************************************************/
1225 CheckControlTypeFile (ControlData * control_data)
1229 struct stat stat_info;
1236 if ((int) control_data->element_values[CONTROL_TYPE].parsed_value != CONTROL_FILE)
1240 (char *) control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1242 if (lstat (file_name, &stat_info) == 0)
1246 /* Display an error dialog because the file cannot be found */
1248 title = FPGETMESSAGE (86, 9, "Workspace Manager - Icon Action Error");
1249 title = XtNewString (title);
1251 msg = FPGETMESSAGE (86, 7, "Cannot find the file");
1252 message = XtMalloc (strlen (msg) + strlen (file_name) + 2);
1253 sprintf (message, "%s %s", msg, file_name);
1255 _DtMessage (panel.shell, title, message, NULL, NULL);
1265 /************************************************************************
1268 * Free the function argument
1270 ************************************************************************/
1279 if (wmFunc == F_Action)
1281 WmActionArg *pAP = (WmActionArg *) pArg;
1283 if (pAP->aap != NULL)
1287 for (i=0; i < pAP->numArgs; i++)
1289 if (pAP->aap[i].u.file.name != NULL)
1290 XtFree ((char *) pAP->aap[i].u.file.name);
1292 XtFree ((char *) pAP->aap);
1295 if (pAP->actionName != NULL)
1296 XtFree ((char *) pAP->actionName);
1298 if (pAP->szExecParms != NULL)
1299 XtFree ((char *) pAP->szExecParms);
1303 XtFree ((char *) pArg);
1308 CheckOtherMonitorsOn(SubpanelData * subpanel_data)
1311 ControlData * control_data;
1314 for (i = -1; i < subpanel_data->control_data_count; i++)
1318 m_state = _DtControlGetMonitorState(subpanel_data->main_panel_icon_copy);
1322 control_data = subpanel_data->control_data[i];
1323 m_state = _DtControlGetMonitorState(control_data->icon);
1326 if (m_state == DtMONITOR_ON) return True;
1333 /************************************************************************
1336 * Process the callback on a control.
1338 ************************************************************************/
1342 XtPointer client_data,
1343 XtPointer call_data)
1346 int control_behavior;
1348 DtControlCallbackStruct * callback = (DtControlCallbackStruct *) call_data;
1349 XEvent * event = callback->event;
1350 ControlData * control_data = (ControlData *) client_data;
1353 PanelActionData * push_action;
1354 Boolean push_recall;
1355 Boolean unpost_subpanel = True;
1358 SubpanelData * subpanel_data;
1359 ControlData * main_control_data;
1365 Widget monitor_icon;
1371 control_behavior = (int) (panel.element_values[PANEL_CONTROL_BEHAVIOR].parsed_value);
1374 /* See if the workspace name is being edited. If so, call the */
1375 /* callback function to accept the changes. */
1377 for (i = 0; i < panel.box_data_count; i++)
1379 if (panel.box_data[i]->switch_edit != NULL)
1381 if (XtIsManaged (panel.box_data[i]->switch_edit))
1383 Widget switch_button;
1385 XtSetArg (al[0], XmNuserData, &switch_button);
1386 XtGetValues (panel.box_data[i]->switch_edit, al, 1);
1387 SwitchRenameCB (panel.box_data[i]->switch_edit,
1388 (XtPointer) switch_button, (XtPointer) NULL);
1389 XmProcessTraversal (w, XmTRAVERSE_CURRENT);
1396 /* See if the control action occurred out of a subpanel. If so, */
1397 /* get the subpanel and set the main control data. */
1399 if (control_data->parent_type == SUBPANEL)
1401 subpanel_data = (SubpanelData *) control_data->parent_data;
1402 main_control_data = subpanel_data->parent_control_data;
1404 /* This control may have been toggled from the subpanel. If */
1405 /* so, make sure the subpanel is not reposted. */
1408 if (XtParent (w) != subpanel_data->form)
1409 unpost_subpanel = False;
1413 /* The control may be the main panel icon copy. If so, find */
1414 /* the subpanel that contains it a set the subpanel data */
1416 subpanel_data = NULL;
1418 for (i = 0; i < panel.box_data_count; i++)
1420 for (j = 0; j < panel.box_data[i]->control_data_count; j++)
1422 ControlData * box_control;
1424 box_control = panel.box_data[i]->control_data[j];
1426 if (box_control->subpanel_data != NULL &&
1427 box_control->subpanel_data->main_panel_icon_copy == w)
1429 subpanel_data = box_control->subpanel_data;
1430 main_control_data = subpanel_data->parent_control_data;
1434 if (subpanel_data != NULL)
1440 /* If the input occurred out of a subpanel, check to see if */
1441 /* the input was an escape key. If so, unpost the subpanel */
1444 if (subpanel_data != NULL && event != NULL)
1446 if (event->xany.type == KeyPress)
1452 XComposeStatus compose;
1453 static Boolean first = True;
1455 count = XLookupString ((XKeyEvent *)event, buffer, bufsize,
1458 if (keysym == XK_Escape)
1462 ArrowCB (main_control_data->arrow,
1463 (XtPointer)main_control_data, (XtPointer)NULL);
1475 /* This function handles four callback reasons. Two of them, */
1476 /* START and STOP show and remove an hour glass cursor. */
1477 /* MONITOR modifies subpanel visuals when a file change is */
1478 /* detected. ACTIVATE/DEFAULT_ACTION handle the activation */
1481 if (callback->reason == XmCR_BUSY_START)
1484 XDefineCursor (XtDisplay (panel.shell), XtWindow (panel.shell),
1487 for (i = 0, pWid = M_PopupList (panel.shell);
1488 i < M_NumPopups (panel.shell); i++)
1489 XDefineCursor (XtDisplay (panel.shell), XtWindow (pWid[i]),
1493 else if (callback->reason == XmCR_BUSY_STOP)
1495 XUndefineCursor (XtDisplay (panel.shell), XtWindow (panel.shell));
1497 for (i = 0, pWid = M_PopupList (panel.shell);
1498 i < M_NumPopups (panel.shell); i++)
1499 XUndefineCursor (XtDisplay (panel.shell), XtWindow (pWid[i]));
1502 else if (callback->reason == XmCR_MONITOR)
1504 /* For a monitor file, turn on the monitor indicator for */
1505 /* the subpanel control and turn on the arrow to the */
1506 /* highlighted arrow of the subpanel. */
1508 if (subpanel_data != NULL)
1510 monitor_icon = control_data->indicator;
1512 m_state = _DtControlGetMonitorState(w);
1514 if (m_state == DtMONITOR_ON)
1515 XtSetArg (al[0], XmNimageName, indicator_on_image);
1516 else /* DtMONITOR_OFF */
1517 XtSetArg (al[0], XmNimageName, indicator_off_image);
1519 XtSetValues (monitor_icon, al, 1);
1521 if (XtIsManaged (subpanel_data->shell))
1523 if (m_state == DtMONITOR_ON)
1525 XtSetArg (al[0], XmNimageName, unpost_monitor_arrow_image);
1526 XtSetValues (main_control_data->arrow, al, 1);
1530 if (!CheckOtherMonitorsOn(subpanel_data))
1532 XtSetArg (al[0], XmNimageName, unpost_arrow_image);
1533 XtSetValues (main_control_data->arrow, al, 1);
1539 if (m_state == DtMONITOR_ON)
1541 XtSetArg (al[0], XmNimageName, post_monitor_arrow_image);
1542 XtSetValues (main_control_data->arrow, al, 1);
1546 if (!CheckOtherMonitorsOn(subpanel_data))
1548 XtSetArg (al[0], XmNimageName, post_arrow_image);
1549 XtSetValues (main_control_data->arrow, al, 1);
1556 else if ((control_behavior == DOUBLE_CLICK &&
1557 callback->reason == XmCR_DEFAULT_ACTION) ||
1558 (control_behavior == SINGLE_CLICK &&
1559 (callback->reason == XmCR_DEFAULT_ACTION ||
1560 callback->reason == XmCR_SINGLE_SELECT)))
1562 control_type = (int) (control_data->element_values[CONTROL_TYPE].parsed_value);
1563 push_action = (PanelActionData *) (control_data->element_values[CONTROL_PUSH_ACTION].parsed_value);
1564 push_recall = (Boolean) (control_data->element_values[CONTROL_PUSH_RECALL].parsed_value);
1566 switch (control_type)
1568 case CONTROL_CLIENT:
1574 /* Turn off the subpanel control monitor indicator */
1576 if ((char) control_data->element_values[CONTROL_MONITOR_TYPE].
1577 parsed_value != MONITOR_NONE)
1579 if (subpanel_data != NULL)
1581 monitor_icon = control_data->indicator;
1582 XtSetArg (al[0], XmNimageName, indicator_off_image);
1583 XtSetValues (monitor_icon, al, 1);
1588 if (CheckControlTypeFile (control_data) && push_action != NULL)
1590 _DtControlDoPushAnimation (w);
1592 if (push_recall == False)
1594 /* If the control is of type file, build and object */
1595 /* list that contains the host and file name to */
1596 /* pass to the invokation. */
1598 if (control_type == CONTROL_FILE && !control_data->is_action)
1602 aap = (DtActionArg *) XtCalloc(1,sizeof(DtActionArg));
1604 aap->argClass = DtACTION_FILE;
1606 aap->u.file.name = (char *) control_data->
1607 element_values[CONTROL_FILE_NAME].parsed_value;
1609 DtActionInvoke (panel.shell,
1610 push_action->action_name,
1611 aap, 1, NULL, NULL, NULL,
1614 XtFree ((char *) aap);
1618 if (strcmp (push_action->action_name, "FPOnItemHelp") == 0)
1621 unpost_subpanel = False;
1625 DtActionInvoke (panel.shell,
1626 push_action->action_name,
1627 NULL, 0, NULL, NULL, NULL,
1636 String func_arg = NULL;
1639 char * client_title;
1641 WmGlobalData * wm_global_data = (WmGlobalData *) panel.global_data;
1642 ClientData * wm_client_data = NULL;
1643 WmPushRecallArg push_argument;
1646 /* Parse out the function and arguments used by the */
1647 /* window manager to invoke the client. */
1649 s1save = s1 = XtNewString ("f.action");
1652 ParseWmFunction ((unsigned char **) &s1, CRS_ANY, &wm_func);
1657 (char *) control_data->element_values[CONTROL_CLIENT_NAME].parsed_value;
1659 if (client_name == NULL)
1661 (char *) control_data->element_values[CONTROL_LABEL].parsed_value;
1664 (char *) control_data->element_values[CONTROL_LABEL].parsed_value;
1666 if (control_type == CONTROL_FILE && ! control_data->is_action)
1670 file_name = (char *) control_data->
1671 element_values[CONTROL_FILE_NAME].parsed_value;
1673 s1 = XtMalloc (strlen (push_action->action_name) + strlen (file_name) + 2);
1674 strcpy (s1, push_action->action_name);
1676 strcat (s1, file_name);
1679 s1 = XtNewString (push_action->action_name);
1681 ParseWmFunctionArg ((unsigned char **) &s1, function_index,
1682 wm_func, (void **) &func_arg,
1683 client_name, client_name);
1686 /* Set the push argument to the parsed data */
1688 push_argument.ixReg = PushRecallGetData (client_name);
1689 push_argument.wmFunc = wm_func;
1690 push_argument.pArgs = func_arg;
1693 /* Get the window manager client data for the panel and */
1694 /* call the push recall function to get the client run. */
1696 if (subpanel_data != NULL)
1697 XFindContext (wm_global_data->display,
1698 XtWindow (subpanel_data->shell),
1699 wm_global_data->windowContextType,
1700 (XtPointer) &wm_client_data);
1702 XFindContext (wm_global_data->display,
1703 XtWindow (panel.shell),
1704 wm_global_data->windowContextType,
1705 (XtPointer) &wm_client_data);
1707 F_Push_Recall ((String) &push_argument,
1708 wm_client_data, callback->event);
1710 FreeFunctionArg (wm_func, func_arg);
1726 /* Call the unposting function and reset the arrow behavior if the */
1727 /* action occured out of a subpanel. */
1729 if (subpanel_data != NULL && unpost_subpanel &&
1730 (Boolean) panel.element_values[PANEL_SUBPANEL_UNPOST].parsed_value &&
1731 subpanel_data->torn == False)
1732 ArrowCB (main_control_data->arrow,
1733 (XtPointer)main_control_data, (XtPointer)NULL);
1740 /************************************************************************
1743 * Process the callback for drops on a control
1745 ************************************************************************/
1750 XtPointer client_data,
1751 XtPointer call_data)
1755 PanelActionData * drop_action = (PanelActionData *) client_data;
1756 DtDndDropAnimateCallback animate_data =
1757 (DtDndDropAnimateCallback) call_data;
1759 ControlData * control_data;
1763 char * save_name = NULL;
1765 XtSetArg (al[0], XmNuserData, &control_data);
1766 XtGetValues (w, al, 1);
1768 if (CheckControlTypeFile (control_data) &&
1769 (animate_data->dropData->protocol == DtDND_FILENAME_TRANSFER ||
1770 animate_data->dropData->protocol == DtDND_BUFFER_TRANSFER))
1774 (int)control_data->element_values[CONTROL_TYPE].parsed_value;
1775 char * control_name =
1776 (char *)control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1777 Boolean send_control_name = False;
1779 _DtControlDoDropAnimation (w);
1781 drop_action = (PanelActionData *)
1782 control_data->element_values[CONTROL_DROP_ACTION].parsed_value;
1784 if (control_data->operation == XmDROP_MOVE)
1786 if (control_data->move_action)
1788 save_name = drop_action->action_name;
1789 drop_action->action_name = control_data->move_action;
1792 else if (control_data->operation == XmDROP_COPY)
1794 if (control_data->copy_action)
1796 save_name = drop_action->action_name;
1797 drop_action->action_name = control_data->copy_action;
1800 else if (control_data->operation == XmDROP_LINK)
1802 if (control_data->link_action)
1804 save_name = drop_action->action_name;
1805 drop_action->action_name = control_data->link_action;
1810 numItems = animate_data->dropData->numItems;
1812 if ((control_type == CONTROL_FILE) &&
1813 (!control_data->is_action) &&
1814 (strcmp(control_name, drop_action->action_name) != 0))
1817 send_control_name = True;
1820 if (animate_data->dropData->protocol == DtDND_FILENAME_TRANSFER)
1822 char ** file_list = animate_data->dropData->data.files;
1825 aap = (DtActionArg *) XtCalloc (numItems, sizeof (DtActionArg));
1827 if (send_control_name)
1829 aap[m].argClass = DtACTION_FILE;
1830 aap[m++].u.file.name =
1831 (char *)control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1834 for (l = 0; m < numItems; l++, m++)
1836 aap[m].argClass = DtACTION_FILE;
1837 aap[m].u.file.name = file_list[l];
1840 else if (animate_data->dropData->protocol == DtDND_BUFFER_TRANSFER)
1842 DtDndBuffer * buf_list = animate_data->dropData->data.buffers;
1845 aap = (DtActionArg *) XtCalloc (numItems, sizeof (DtActionArg));
1847 if (send_control_name)
1849 aap[m].argClass = DtACTION_FILE;
1850 aap[m++].u.file.name =
1851 (char *)control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1854 for (l = 0; m < numItems; l++, m++)
1856 aap[m].argClass = DtACTION_BUFFER;
1857 aap[m].u.buffer.bp = buf_list[l].bp;
1858 aap[m].u.buffer.size = buf_list[l].size;
1859 aap[m].u.buffer.name = buf_list[l].name;
1864 if (save_name != NULL)
1865 drop_action->action_name = save_name;
1867 control_data->operation = NULL;
1872 DtActionInvoke (w, drop_action->action_name, aap, numItems,
1873 NULL, NULL, NULL, 1, NULL, NULL);
1875 XtFree((char *) aap);
1877 if (save_name != NULL)
1878 drop_action->action_name = save_name;
1880 control_data->operation = NULL;
1887 /************************************************************************
1890 * Process the callback for drops on a control
1892 ************************************************************************/
1896 TransferDropCB (Widget w,
1897 XtPointer client_data,
1898 XtPointer call_data)
1902 DtDndTransferCallbackStruct * transfer_data =
1903 (DtDndTransferCallbackStruct *) call_data;
1904 ControlData * control_data;
1908 /* Currently only accepts FILE drops */
1910 if (transfer_data->dropData->protocol == DtDND_FILENAME_TRANSFER ||
1911 transfer_data->dropData->protocol == DtDND_BUFFER_TRANSFER)
1913 transfer_data->status = DtDND_SUCCESS;
1915 XtSetArg (al[0], XmNuserData, &control_data);
1916 XtGetValues (w, al, 1);
1918 control_data->operation = transfer_data->operation;
1922 transfer_data->status = DtDND_FAILURE;
1924 transfer_data->completeMove = False;
1929 /************************************************************************
1930 ************************************************************************
1932 This block of functions handle the processing of subpanel torn-off
1933 behavior. Default behavior for a subpanel is to unpost when a
1934 control is selected. This changes to sticky when the subpanel is torn.
1936 ************************************************************************
1937 ************************************************************************/
1940 /************************************************************************
1943 * Process the callback on the subpanel unposting initiated through
1944 * the window manager close menu item.
1946 ************************************************************************/
1950 SubpanelUnmapCB (Widget w,
1951 XtPointer client_data,
1952 XtPointer call_data)
1956 ControlData * main_control_data = (ControlData *) client_data;
1957 SubpanelData * subpanel_data = main_control_data->subpanel_data;
1964 XtSetArg (al[ac], XmNimageName, post_arrow_image); ac++;
1965 XtSetValues (main_control_data->arrow, al, ac);
1967 XtUnmanageChild (subpanel_data->shell);
1968 subpanel_data->torn = False;
1971 /* Remove the event handler from the subpanel */
1973 XtRemoveEventHandler (subpanel_data->shell, StructureNotifyMask, False,
1974 (XtEventHandler) SubpanelTornEventHandler,
1975 (XtPointer) main_control_data);
1978 /* Reset the active traversal control for the front panel */
1979 /* We should not have to do this but for unknown reasons, */
1980 /* the traversal highlight is getting lost. */
1982 XmProcessTraversal (panel.shell, XmTRAVERSE_NEXT);
1983 XmProcessTraversal (panel.shell, XmTRAVERSE_PREV);
1989 /************************************************************************
1991 * SubpanelTornEventHandler
1992 * Set a subpanel flag to change its posting behavior when it is
1995 ************************************************************************/
1998 SubpanelTornEventHandler (Widget subpanel_shell,
1999 XtPointer client_data,
2001 Boolean * continue_dispatch)
2004 ControlData * main_control_data = (ControlData *) client_data;
2005 SubpanelData * subpanel_data = main_control_data->subpanel_data;
2008 if (subpanel_data->posted_x != 0 &&
2009 subpanel_data->posted_x != XtX (subpanel_data->shell))
2011 subpanel_data->torn = True;
2013 subpanel_data->torn = False;
2015 *continue_dispatch = True;
2022 /************************************************************************
2025 * Start up the help manager to show the help topic
2027 * Inputs: widget - the widget for which help was requested
2028 * help_volume - the help volume that contains the information
2029 * help_topic - the specific help topic.
2031 ************************************************************************/
2034 void StartHelpClient (Widget widget,
2040 /***** TEMPORARY - Add code to actually invoke the Help Client ****/
2042 WmDtDisplayTopicHelp (widget, help_volume, help_topic);
2045 /************************************************************************
2048 * Invoke topic help if available otherwise invoke help string if
2051 ************************************************************************/
2054 void InvokeHelp (Widget widget,
2060 if (help_volume == NULL)
2061 help_volume = FP_HELP_VOLUME;
2063 if (help_topic != NULL)
2065 if (strcmp (help_volume, FP_HELP_VOLUME) == 0)
2066 WmDtDisplayTopicHelp (widget, help_volume, help_topic);
2068 StartHelpClient (widget, help_volume, help_topic);
2072 if (help_string != NULL)
2073 WmDtDisplayStringHelp (widget, help_string);
2078 /************************************************************************
2080 * SubpanelTopicHelpCB
2081 * Process the callback for help on the subpanel
2083 ************************************************************************/
2086 void SubpanelTopicHelpCB (Widget widget,
2087 XtPointer client_data,
2088 XtPointer call_data)
2091 SubpanelData * subpanel_data = (SubpanelData *) client_data;
2097 (char *) subpanel_data->element_values[SUBPANEL_HELP_VOLUME].parsed_value;
2099 (char *) subpanel_data->element_values[SUBPANEL_HELP_TOPIC].parsed_value;
2101 (char *) subpanel_data->element_values[SUBPANEL_HELP_STRING].parsed_value;
2103 InvokeHelp(widget, help_topic, help_volume, help_string);
2105 } /* END OF FUNCTION SubpanelTopicHelpCB */
2110 /************************************************************************
2113 * Process the callback for help on the switch
2115 ************************************************************************/
2118 void SwitchTopicHelpCB (Widget widget,
2119 XtPointer client_data,
2120 XtPointer call_data)
2123 SwitchData * switch_data = (SwitchData *) client_data;
2129 (char *) switch_data->element_values[SWITCH_HELP_VOLUME].parsed_value;
2131 (char *) switch_data->element_values[SWITCH_HELP_TOPIC].parsed_value;
2133 (char *) switch_data->element_values[SWITCH_HELP_STRING].parsed_value;
2135 InvokeHelp(widget, help_topic, help_volume, help_string);
2137 } /* END OF FUNCTION SwitchTopicHelpCB */
2142 /************************************************************************
2144 * ControlTopicHelpCB
2145 * Process the callback for help on the control
2147 *************************************************************************/
2150 void ControlTopicHelpCB (Widget widget,
2151 XtPointer client_data,
2152 XtPointer call_data)
2156 ControlData * control_data = (ControlData *) client_data;
2162 (char *) control_data->element_values[CONTROL_HELP_VOLUME].parsed_value;
2164 (char *) control_data->element_values[CONTROL_HELP_TOPIC].parsed_value;
2166 (char *) control_data->element_values[CONTROL_HELP_STRING].parsed_value;
2168 InvokeHelp(widget, help_topic, help_volume, help_string);
2170 } /* END OF FUNCTION ControlTopicHelpCB */
2175 /************************************************************************
2177 * GeneralTopicHelpCB
2178 * Process the callback for help on the control
2180 ************************************************************************/
2183 void GeneralTopicHelpCB (Widget widget,
2184 XtPointer client_data,
2185 XtPointer call_data)
2192 help_volume = FP_HELP_VOLUME;
2193 help_topic = (char *) client_data;
2195 WmDtDisplayTopicHelp (widget, help_volume, help_topic);
2197 } /* END OF FUNCTION GeneralTopicHelpCB */
2202 /************************************************************************
2203 ************************************************************************
2205 This block of functions handle the initialization and dynamic
2206 processing for the subpanel installation area.
2208 ************************************************************************
2209 ************************************************************************/
2211 /************************************************************************
2213 * GetValuesFromDataType
2214 * Given and file type index and subpanel data, construct an element
2215 * values array for a new control that is initialized to the attributes
2218 ************************************************************************/
2222 GetValuesFromDataType (char * data_type,
2224 SubpanelData * subpanel_data,
2225 ElementValue ** element_values)
2232 *element_values = (ElementValue *) XtMalloc (sizeof(ElementValue) *
2233 CONTROL_KEYWORD_COUNT);
2235 for (i = 0; i < CONTROL_KEYWORD_COUNT; i++)
2237 (*element_values)[i].use_default = True;
2238 (*element_values)[i].string_value = NULL;
2239 (*element_values)[i].parsed_value = NULL;
2242 (*element_values)[CONTROL_FILE_NAME].string_value = XtNewString (file_name);
2244 ptr = (char *)strrchr(file_name, '/');
2247 (*element_values)[CONTROL_NAME].string_value = XtNewString(ptr);
2248 (*element_values)[CONTROL_TYPE].string_value = XtNewString("file");
2249 (*element_values)[CONTROL_CONTAINER_TYPE].string_value =
2250 XtNewString("SUBPANEL");
2251 (*element_values)[CONTROL_CONTAINER_NAME].string_value =
2252 XtNewString(subpanel_data->element_values[0].string_value);
2253 (*element_values)[CONTROL_POSITION_HINTS].string_value =
2254 XtNewString("last");
2256 InitializeControlFields (*element_values, data_type);
2262 /************************************************************************
2265 * Process the callback for the drop on the subpanel drop zone for
2266 * dynamic customization
2268 ************************************************************************/
2272 CustomizeDropCB (Widget w,
2273 XtPointer client_data,
2274 XtPointer call_data)
2278 ControlData * main_control_data;
2279 SubpanelData * subpanel_data;
2280 DtDndDropAnimateCallbackStruct * animate_data =
2281 (DtDndDropAnimateCallbackStruct *) call_data;
2283 ControlData * control_data;
2284 ElementValue * element_values;
2288 Boolean bad_control;
2289 Boolean control_monitor;
2293 char * new_control_name;
2294 char * control_name;
2295 Widget attach_widget;
2306 /* If this is not a transfer drop, return */
2308 if (animate_data->dropData->protocol != DtDND_FILENAME_TRANSFER)
2312 /* Get the subpanel, box, and main control data */
2314 XtSetArg (al[0], XmNuserData, &subpanel_data);
2315 XtGetValues (w, al, 1);
2317 main_control_data = subpanel_data->parent_control_data;
2318 box_data = (BoxData *) main_control_data->parent_data;
2320 file_count = animate_data->dropData->numItems;
2321 file_list = animate_data->dropData->data.files;
2324 /* Pop down the subpanel before creating the new control or */
2325 /* mucking with any of the old controls. */
2327 if (subpanel_data->torn == False)
2328 XtUnmanageChild (subpanel_data->shell);
2331 /* Loop through the set of files (possibly more than one) that */
2332 /* have been dropped. */
2334 for (i = 0; i < file_count; i++)
2337 /* Get the file type of the file and process as either */
2338 /* a "FrontPanel" file or a normal file type. */
2340 data_type = DtDtsFileToDataType (file_list[i]);
2342 if (!strcmp (data_type, "FP"))
2345 InitParse (file_list[i], &element_values);
2348 /* Reset the values of the container name and type to this one */
2350 if (element_values[CONTROL_CONTAINER_NAME].use_default == False)
2352 if (element_values[CONTROL_CONTAINER_NAME].parsed_value != NULL)
2353 XtFree (element_values[CONTROL_CONTAINER_NAME].parsed_value);
2354 if (element_values[CONTROL_CONTAINER_NAME].string_value != NULL)
2355 XtFree (element_values[CONTROL_CONTAINER_NAME].string_value);
2358 if (element_values[CONTROL_CONTAINER_TYPE].use_default == False)
2360 if (element_values[CONTROL_CONTAINER_TYPE].string_value != NULL)
2361 XtFree (element_values[CONTROL_CONTAINER_TYPE].string_value);
2364 if (element_values[CONTROL_POSITION_HINTS].use_default == False)
2366 if (element_values[CONTROL_POSITION_HINTS].string_value != NULL)
2367 XtFree (element_values[CONTROL_POSITION_HINTS].string_value);
2370 element_values[CONTROL_CONTAINER_NAME].use_default = False;
2371 element_values[CONTROL_CONTAINER_NAME].string_value =
2372 XtNewString (subpanel_data->element_values[SUBPANEL_NAME].parsed_value);
2373 element_values[CONTROL_CONTAINER_NAME].parsed_value =
2374 XtNewString (subpanel_data->element_values[SUBPANEL_NAME].parsed_value);
2376 element_values[CONTROL_CONTAINER_TYPE].use_default = False;
2377 element_values[CONTROL_CONTAINER_TYPE].string_value =
2378 XtNewString ("SUBPANEL");
2379 element_values[CONTROL_CONTAINER_TYPE].parsed_value =
2382 element_values[CONTROL_POSITION_HINTS].use_default = False;
2383 element_values[CONTROL_POSITION_HINTS].string_value =
2384 XtNewString ("last");
2385 element_values[CONTROL_POSITION_HINTS].parsed_value =
2391 GetValuesFromDataType (data_type, file_list[i],
2392 subpanel_data, &element_values);
2395 DtDtsFreeDataType (data_type);
2399 /* Check for naming conflicts and if found, issue an error and */
2400 /* clean up. Continue processing subsequent files even if this */
2401 /* one is not valid. */
2403 new_control_name = (char *) element_values[CONTROL_NAME].parsed_value;
2404 bad_control = False;
2406 for (j = 0; j < subpanel_data->control_data_count; j++)
2408 control_name = (char *) subpanel_data->control_data[j]->
2409 element_values[CONTROL_NAME].parsed_value;
2411 if (strcmp (control_name, new_control_name) == 0)
2413 ControlData control_data;
2414 String title, del_ctrl, ctrl_name, del_msg, message;
2417 /* Display an error dialog for the unusable drop data */
2419 title = FPGETMESSAGE (86, 3, "Workspace Manager - Install Icon Error");
2420 title = XtNewString (title);
2422 del_ctrl = FPGETMESSAGE (86, 4, "Install Icon:");
2423 del_ctrl = XtNewString (del_ctrl);
2425 del_msg = FPGETMESSAGE (86, 8, "There is already an icon of this name.");
2426 del_msg = XtNewString (del_msg);
2428 message = XtMalloc ((strlen(del_ctrl) + strlen(new_control_name) +
2429 strlen(del_msg) + 4));
2430 sprintf(message, "%s %s\n\n%s", del_ctrl, new_control_name, del_msg);
2432 _DtMessage (panel.shell, title, message, NULL, NULL);
2440 /* Set up a temporary control data structure so that the */
2441 /* appropriate function can be used to free the allocated */
2442 /* element values. */
2444 control_data.element_values = element_values;
2445 RemoveEntry (&control_data, CONTROL);
2452 if (bad_control) continue;
2455 if ((int) element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
2456 control_monitor = True;
2458 control_monitor = False;
2461 position_hints = (int)element_values[CONTROL_POSITION_HINTS].parsed_value;
2464 /* Initialize the subpanel layout and processing attributes. */
2466 if ((int) main_control_data->
2467 element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
2469 control_monitor = True;
2473 for (j = 0; j < subpanel_data->control_data_count; j++)
2475 if ((int) subpanel_data->control_data[j]->
2476 element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
2478 control_monitor = True;
2484 /* If the new control is a montior, loop through the existing */
2485 /* control set a adjust the left offset resource to ensure */
2486 /* that they are all aligned properly. */
2488 if (control_monitor)
2490 XtSetArg (al[0], XmNleftOffset, 20);
2492 for (j = 0; j < subpanel_data->control_data_count; j++)
2493 XtSetValues (subpanel_data->control_data[j]->icon, al, 1);
2495 if (subpanel_data->main_panel_icon_copy != NULL)
2496 XtSetValues (subpanel_data->main_panel_icon_copy, al, 1);
2500 /* Get the subpanel control data and position the element */
2501 /* values into the postion hints location. */
2502 /* The remainder of the positioning code is set up to allow */
2503 /* placement in non-last positions even though position is */
2504 /* forced to last. This is here for future use. */
2506 subpanel_data->control_data_count++;
2507 count = subpanel_data->control_data_count;
2509 subpanel_data->control_data =
2510 (ControlData **) XtRealloc ((char *) subpanel_data->control_data,
2511 sizeof (ControlData *) * count);
2513 for (j = count - 2; j >= 0; j--)
2515 if (position_hints >=
2516 (int) subpanel_data->control_data[j]->element_values[CONTROL_POSITION_HINTS].parsed_value)
2522 for (k = count - 1; k > j; k--)
2523 subpanel_data->control_data[k] = subpanel_data->control_data[k - 1];
2525 subpanel_data->control_data[j] = control_data =
2526 (ControlData *) XtMalloc (sizeof (ControlData));
2528 control_data->element_values = element_values;
2529 control_data->parent_data = (XtPointer) subpanel_data;
2530 control_data->parent_type = SUBPANEL;
2531 control_data->subpanel_data = NULL;
2532 control_data->icon = NULL;
2533 control_data->arrow = NULL;
2534 control_data->arrow_separator = NULL;
2535 control_data->indicator = NULL;
2536 control_data->is_action = False;
2537 control_data->move_action = NULL;
2538 control_data->copy_action = NULL;
2539 control_data->link_action = NULL;
2540 control_data->operation = NULL;
2542 AddControlActionList (control_data);
2545 if (j == 0 && subpanel_data->main_panel_icon_copy != NULL)
2546 attach_widget = subpanel_data->main_panel_icon_copy;
2548 attach_widget = subpanel_data->control_data[j - 1]->icon;
2551 /* Reattach the bottom control so the new bottom will appear */
2556 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
2557 XtSetArg (al[ac], XmNbottomOffset, 0); ac++;
2558 XtSetValues (attach_widget, al, ac);
2562 SubpanelControlCreate (subpanel_data, main_control_data,
2563 control_data, attach_widget, False,
2567 /* Pad the bottom control */
2572 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
2573 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
2574 XtSetValues (control_data->icon, al, ac);
2577 WriteControlComponentFile (control_data);
2582 /* Pop the subpanel back up and return */
2584 if (subpanel_data->torn == False)
2585 ArrowCB (main_control_data->arrow,
2586 (XtPointer)main_control_data, (XtPointer)NULL);
2592 /************************************************************************
2594 * CustomizeTransferDropCB
2595 * Process the callback for drops on an install zone
2597 ************************************************************************/
2601 CustomizeTransferDropCB (Widget w,
2602 XtPointer client_data,
2603 XtPointer call_data)
2607 DtDndTransferCallbackStruct * transfer_data =
2608 (DtDndTransferCallbackStruct *) call_data;
2610 /* Currently only accepts FILE drops */
2612 if (transfer_data->dropData->protocol == DtDND_FILENAME_TRANSFER)
2613 transfer_data->status = DtDND_SUCCESS;
2615 transfer_data->status = DtDND_FAILURE;
2617 transfer_data->completeMove = False;