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 libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /*****************************************************************************
29 * Description: This file contains the user interface behavior processing
30 * functions for the CDE front panel
32 * (c) Copyright 1993, 1994 Hewlett-Packard Company
33 * (c) Copyright 1993, 1994 International Business Machines Corp.
34 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
35 * (c) Copyright 1993, 1994 Novell, Inc.
37 ****************************************************************************/
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>
57 #include <Dt/SharedProcs.h>
60 #include <Xm/ToggleBG.h>
61 #include <Xm/AtomMgr.h>
64 #include <X11/Xatom.h>
65 #include <X11/keysym.h>
67 #include "DataBaseLoad.h"
72 #include "WmResNames.h"
73 #include "WmResParse.h"
74 #include "WmFunction.h"
77 /************************************************************************
79 * External and static function declarations.
81 ************************************************************************/
83 extern XtPointer _XmStringUngenerate(XmString, XmStringTag,
84 XmTextType, XmTextType);
86 extern void SubpanelControlCreate (SubpanelData *, ControlData *, ControlData *,
87 Widget, Boolean, Boolean);
88 extern void WmSubpanelPosted (Display *, Window);
89 extern int PushRecallGetData (char *);
90 extern void SwitchButtonCreate (SwitchData *, Boolean);
91 extern void AddControlActionList (ControlData *);
93 void ArrowCB (Widget, XtPointer, XtPointer);
94 void HandleInputCB (Widget, XtPointer, XtPointer);
95 void MinimizeInputCB (Widget, XtPointer, XtPointer);
96 void MenuInputCB (Widget, XtPointer, XtPointer);
97 void SwitchButtonCB (Widget, XtPointer, XtPointer);
98 void PushCB (Widget, XtPointer, XtPointer);
99 void SubpanelUnmapCB (Widget, XtPointer, XtPointer);
100 void SubpanelTornEventHandler (Widget, XtPointer, XEvent *, Boolean *);
101 Boolean CheckControlTypeFile (ControlData *);
104 static void SwitchRenameCancel (Widget, XEvent *, String *, Cardinal *);
105 static void SwitchRenameCB (Widget, XtPointer, XtPointer);
106 static void GetValuesFromDataType(char *, char *, SubpanelData *,
109 void SwitchRenameLabel (Widget, BoxData *);
110 void DropCB (Widget, XtPointer, XtPointer);
111 void TransferDropCB (Widget, XtPointer, XtPointer);
112 void CustomizeDropCB (Widget, XtPointer, XtPointer);
113 void CustomizeTransferDropCB (Widget, XtPointer, XtPointer);
119 /* Translations and action definitions */
120 /* These are used specifically for the text field overlay */
121 /* on the switch button for renaming the workspace. They */
122 /* are necessary for handling escape key processing. */
124 static char translations_escape[] = "<Key>osfCancel:Escape()";
126 static XtActionsRec action_table[] = {
127 {"Escape", SwitchRenameCancel},
132 /************************************************************************
134 * File local globals.
136 ************************************************************************/
138 extern String post_arrow_image;
139 extern String unpost_arrow_image;
140 extern String post_monitor_arrow_image;
141 extern String unpost_monitor_arrow_image;
142 extern String blank_arrow_image;
143 extern String dropzone_image;
144 extern String indicator_on_image;
145 extern String indicator_off_image;
149 /************************************************************************
152 * Call the specified WmFunction function with appropriate args
154 ************************************************************************/
158 CallWmFunction (WmFunction wm_function,
165 WmGlobalData * wm_global_data = (WmGlobalData *) panel.global_data;
166 ClientData * wm_client_data = NULL;
167 Display * display = wm_global_data->display;
168 Window client_window = XtWindow(client);
171 * Find the window manager client data for this client
174 XFindContext (display, client_window, wm_global_data->windowContextType,
175 (XtPointer) &wm_client_data);
177 if (wm_client_data == NULL)
181 * Execute the window manager function
184 wm_function (args, wm_client_data, event);
187 /************************************************************************
190 * Process the callback on the subpanel posting/unposting arrow
192 ************************************************************************/
197 XtPointer client_data,
202 ControlData * control_data = (ControlData *) client_data;
203 SubpanelData * subpanel_data = control_data->subpanel_data;
209 /* If the subpanel's shell is not managed, this is a request to post */
210 /* the subpanel. Otherwise it is an unpost request. */
211 /* Reset the arrow image after the post or unpost. */
213 if (!XtIsManaged (subpanel_data->shell))
215 Position x = XtX (control_data->arrow);
216 Position y = XtY (control_data->arrow);
219 XtSetMappedWhenManaged (subpanel_data->shell, False);
220 XtManageChild (subpanel_data->form);
222 XtTranslateCoords (w, 0, 0, &x, &y);
224 XtSetArg (al[0], XmNx, x);
225 XtSetValues (subpanel_data->form, al, 1);
227 XtManageChild (subpanel_data->shell);
228 XtSetMappedWhenManaged (subpanel_data->shell, True);
231 XtSetArg (al[ac], XmNimageName, unpost_arrow_image); ac++;
232 XtSetValues (w, al, ac);
236 /* Execute the window manager function to unpost the subpanel */
238 CallWmFunction (F_Kill, NULL, subpanel_data->shell, NULL);
245 /************************************************************************
247 * HandleInputTranslations
248 * Return translation table suitable for HandleInputCB
250 ************************************************************************/
254 HandleInputTranslations(void)
257 static XtTranslations handle_translations;
259 if (handle_translations == NULL)
261 handle_translations = XtParseTranslationTable(
262 "<BtnDown>: DrawingAreaInput() ManagerGadgetArm()\n\
263 <BtnUp>: DrawingAreaInput() ManagerGadgetActivate()\n\
264 <Btn1Motion>: DrawingAreaInput() ManagerGadgetButtonMotion()\n\
265 <Btn2Motion>: DrawingAreaInput() ManagerGadgetButtonMotion()");
267 return handle_translations;
270 /************************************************************************
273 * Process button events on the frontpanel handles.
275 ************************************************************************/
279 HandleInputCB (Widget w,
280 XtPointer client_data,
285 XmAnyCallbackStruct * callback;
288 XButtonEvent * buttonEvent;
289 XMotionEvent * motionEvent;
291 callback = (XmAnyCallbackStruct *) call_data;
292 event = (XEvent *) callback->event;
293 buttonEvent = (XButtonEvent *) event;
294 motionEvent = (XMotionEvent *) event;
296 if (event->type == ButtonPress)
298 if (buttonEvent->button == wmGD.bMenuButton)
300 XUngrabPointer (XtDisplay (w), buttonEvent->time);
301 XSync (XtDisplay (w), FALSE);
302 CallWmFunction (F_Post_FpMenu, NULL, panel.shell, event);
307 wmGD.preMoveX = buttonEvent->x_root;
308 wmGD.preMoveY = buttonEvent->y_root;
310 if (buttonEvent->button == Button1)
312 CallWmFunction (F_Raise, NULL, panel.shell, event);
313 XSync (DISPLAY, FALSE);
314 XmUpdateDisplay (panel.shell);
318 else if (event->type == ButtonRelease)
320 wmGD.preMove = False;
322 else if (event->type == MotionNotify && wmGD.preMove)
326 diffX = motionEvent->x_root - wmGD.preMoveX;
327 if (diffX < 0) diffX = -diffX;
328 diffY = motionEvent->y_root - wmGD.preMoveY;
329 if (diffY < 0) diffY = -diffY;
331 if (diffX >= wmGD.moveThreshold || diffY >= wmGD.moveThreshold)
333 XUngrabPointer (XtDisplay (w), motionEvent->time);
334 XSync (XtDisplay (w), FALSE);
335 CallWmFunction (F_Move, NULL, panel.shell, event);
336 wmGD.preMove = False;
344 /************************************************************************
347 * Process button events on the frontpanel minimize button.
349 ************************************************************************/
353 MinimizeInputCB (Widget w,
354 XtPointer client_data,
359 XmAnyCallbackStruct * callback;
362 XButtonEvent * bevent;
364 extern Pixmap minimize_normal_pixmap;
365 extern Pixmap minimize_selected_pixmap;
370 callback = (XmAnyCallbackStruct *) call_data;
371 event = (XEvent *) callback->event;
372 bevent = (XButtonEvent *) event;
374 /* On the BSelect button press, change the image to the selected
375 * minimize image. On the release, check to see if the release
376 * occurred within the minimize button before minimizing.
377 * On BMenu button press, post the front panel menu.
380 if (event->type == ButtonPress)
382 if (bevent->button == Button1)
384 XtSetArg (al[0], XmNbackgroundPixmap, minimize_selected_pixmap);
385 XtSetValues (w, al, 1);
387 else if (bevent->button == wmGD.bMenuButton)
389 XUngrabPointer (XtDisplay (w), bevent->time);
390 XSync (XtDisplay (w), FALSE);
391 CallWmFunction (F_Post_FpMenu, NULL, panel.shell, event);
394 else if (event->type == ButtonRelease && bevent->button == Button1)
396 if (bevent->x >= 0 && bevent->x <= (Position) XtWidth(w) &&
397 bevent->y >= 0 && bevent->y <= (Position) XtHeight(w))
399 CallWmFunction (F_Minimize, NULL, panel.shell, event);
402 XtSetArg (al[0], XmNbackgroundPixmap, minimize_normal_pixmap);
403 XtSetValues (w, al, 1);
410 /************************************************************************
413 * Process button events on the front panel menu button.
415 ************************************************************************/
419 MenuInputCB (Widget w,
420 XtPointer client_data,
425 XmAnyCallbackStruct * callback;
428 XButtonEvent * bevent;
430 callback = (XmAnyCallbackStruct *) call_data;
431 event = (XEvent *) callback->event;
432 bevent = (XButtonEvent *) event;
436 * On BSelect or BMenu button press post the front panel system menu
439 if (event->type == ButtonPress &&
440 (bevent->button == Button1 || bevent->button == wmGD.bMenuButton))
442 XUngrabPointer (XtDisplay (w), bevent->time);
443 XSync (XtDisplay (w), FALSE);
444 CallWmFunction (F_Post_FpMenu, NULL, panel.shell, event);
450 /************************************************************************
451 ************************************************************************
453 The next block of functions are used for the switch button switching,
454 renaming functionality, and add and delete of workspaces.
456 ************************************************************************
457 ************************************************************************/
461 /************************************************************************
463 * WorkspaceAdjustPanelPosition
464 * After a workspace button has been added or deleted, if the panel
465 * has changed sizes, reposition the panel to keep the same relative
468 * Inputs: x - the original x coordinate of the panel
469 * y - the original y coordinate of the panel
470 * width - the original width of the panel
471 * height - the original height of the panel
473 ************************************************************************/
477 WorkspaceAdjustPanelPosition (Position x,
484 Dimension screen_width;
485 Dimension screen_height;
488 Dimension new_height;
495 screen_width = WidthOfScreen (XtScreen (panel.shell));
496 screen_height = HeightOfScreen (XtScreen (panel.shell));
499 /* Reposition the panel to keep it centered relative to where */
500 /* it was positioned before the deletion of the button. */
504 new_width = XtWidth (panel.shell);
506 if (new_width != width || x + (Position) new_width > (Position) screen_width)
508 panel_center = x + width / 2 - 1;
509 new_x = panel_center - new_width / 2 - 4;
513 else if (new_x + (Position) new_width > (Position) screen_width)
514 new_x = screen_width - new_width - 4;
516 XtSetArg (al[ac], XmNx, new_x); ac++;
520 /* Keep the panel to the bottom of the screen, if it was there. */
521 /* But make sure that it does not go below the bottom. */
523 new_height = XtHeight (panel.shell);
525 if (new_height != height || (Dimension)(new_height + y - 1) > screen_height)
527 if (new_height < height && y > (Position)(screen_height / 2))
529 new_y = y + (Position)(height - new_height - 4);
530 XtSetArg (al[ac], XmNy, new_y); ac++;
532 else if ((Dimension)(new_height + y - 1) > screen_height)
534 new_y = (Position)(screen_height - new_height - 4);
535 XtSetArg (al[ac], XmNy, new_y); ac++;
540 XtSetValues (panel.shell, al, ac);
546 /************************************************************************
549 * Called by the workspace manager API to send notification of
550 * configuration changes to the workspace. The types of changes
551 * processed by this function are workspace add, delete, and rename.
553 ************************************************************************/
557 WorkspaceModifyCB (Widget w,
560 XtPointer client_data)
564 SwitchData * switch_data = (SwitchData *) client_data;
565 BoxData * box_data = switch_data->box_data;
566 DtWsmWorkspaceInfo * workspace_info;
572 Dimension screen_width;
575 x = XtX (panel.shell);
576 y = XtY (panel.shell);
577 width = XtWidth (panel.shell);
578 height = XtHeight (panel.shell);
579 screen_width = WidthOfScreen (XtScreen (panel.shell));
581 DtWsmGetWorkspaceInfo (XtDisplay (w), RootWindowOfScreen (XtScreen (w)),
582 atom_name, &workspace_info);
587 /* Increase the size of the switch names and button and call */
588 /* the function to create the new workspace switch button */
590 case DtWSM_REASON_ADD:
596 /* Cancel workspace renaming */
598 if (XtIsManaged (box_data->switch_edit))
599 SwitchRenameCancel (box_data->switch_edit, NULL, NULL, NULL);
602 DtWsmGetWorkspaceList (XtDisplay (switch_data->rc),
603 RootWindowOfScreen (XtScreen (switch_data->rc)),
604 &atom_names, &switch_count);
606 XFree (switch_data->atom_names);
607 switch_data->atom_names = atom_names;
609 switch_data->switch_count = switch_count;
611 switch_data->switch_names =
612 (char **) XtRealloc ((char *) switch_data->switch_names,
613 sizeof (char *) * switch_data->switch_count);
615 switch_data->switch_names[switch_data->switch_count - 1] =
616 XtNewString (workspace_info->pchTitle);
618 switch_data->buttons =
619 (Widget *) XtRealloc ((char *) switch_data->buttons,
620 sizeof (Widget *) * switch_data->switch_count);
622 SwitchButtonCreate (switch_data, True);
625 /* When adding a switch buttons, keep the row columns row count */
626 /* equal to the requested value with small number of buttons */
628 if (switch_data->switch_count <= (intptr_t)
629 (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value))
633 panel.switch_row_count = (intptr_t)
634 (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value);
636 XtSetArg (al[0], XmNnumColumns, panel.switch_row_count);
637 XtSetValues (switch_data->rc, al, 1);
641 /* If the fp width is greater than the screen, increase the */
644 if (XtWidth (panel.shell) > screen_width)
648 panel.switch_row_count++;
650 XtSetArg (al[0], XmNnumColumns, panel.switch_row_count);
651 XtSetValues (switch_data->rc, al, 1);
654 WorkspaceAdjustPanelPosition (x, y, width, height);
659 /* Loop through the current set of atom names, comparing */
660 /* them with the atom of the workspace to be deleted. When */
661 /* free up the associated data and readjust the name, button */
662 /* and atom lists. */
664 case DtWSM_REASON_DELETE:
672 Dimension button_spacing;
673 Dimension button_width;
676 /* Cancel workspace renaming */
678 if (XtIsManaged (box_data->switch_edit))
679 SwitchRenameCancel (box_data->switch_edit, NULL, NULL, NULL);
682 DtWsmGetWorkspaceList (XtDisplay (switch_data->rc),
683 RootWindowOfScreen (XtScreen (switch_data->rc)),
684 &atom_names, &switch_count);
686 for (i = 0; i < switch_data->switch_count; i++)
688 if (atom_name == switch_data->atom_names[i])
690 if (switch_data->active_switch > i)
691 switch_data->active_switch--;
693 XtFree (switch_data->switch_names[i]);
694 XtDestroyWidget (switch_data->buttons[i]);
695 XFree (switch_data->atom_names);
696 switch_data->atom_names = atom_names;
697 switch_data->switch_count = switch_count;
699 for (j = i; j < switch_data->switch_count; j++)
701 switch_data->switch_names[j] = switch_data->switch_names[j+1];
702 switch_data->buttons[j] = switch_data->buttons[j + 1];
710 /* When deleting a switch button, keep trying to decrease the */
711 /* row count to the requested value. */
713 if (panel.switch_row_count > (intptr_t)
714 (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value))
716 button_width = XtWidth (switch_data->buttons[0]);
717 XtSetArg (al[0], XmNspacing, &button_spacing);
718 XtGetValues (switch_data->rc, al, 1);
720 if ((int)(screen_width - (width + button_width + button_spacing)) >
723 panel.switch_row_count--;
724 XtSetArg (al[0], XmNnumColumns, panel.switch_row_count);
725 XtSetValues (switch_data->rc, al, 1);
729 WorkspaceAdjustPanelPosition (x, y, width, height);
735 /* Loop through the current set of atom names, comparing */
736 /* them with the new atom. When a match is found, reset the */
737 /* the switch name to the new one and update the button label. */
739 case DtWSM_REASON_TITLE:
741 XmString toggle_string;
746 for (i = 0; i < switch_data->switch_count; i++)
748 if (atom_name == switch_data->atom_names[i])
750 switch_data->switch_names[i] =
751 XtNewString (workspace_info->pchTitle);
754 XmStringCreateLocalized (workspace_info->pchTitle);
756 XtSetArg (al[0], XmNstring, toggle_string);
757 XtSetValues (switch_data->buttons[i], al, 1);
758 XmStringFree (toggle_string);
760 XtSetArg (al[0], XmNiconName, workspace_info->pchTitle);
761 XtSetArg (al[1], XmNtitle, workspace_info->pchTitle);
762 XtSetValues (panel.shell, al, 2);
771 /* Loop through the set of switch atom names to find the one */
772 /* that is now active. Unset the old workspace button and */
773 /* set the new one referenced by the atom. */
775 case DtWSM_REASON_CURRENT:
780 for (i = 0; i < switch_data->switch_count; i++)
782 if (switch_data->atom_names[i] == atom_name)
784 XtSetArg (al[0], XmNiconName, switch_data->switch_names[i]);
785 XtSetArg (al[1], XmNtitle, switch_data->switch_names[i]);
786 XtSetValues (panel.shell, al, 2);
788 _DtIconSetState (switch_data->buttons[switch_data->active_switch], False, False);
789 switch_data->active_switch = i;
790 _DtIconSetState (switch_data->buttons[switch_data->active_switch], True, False);
798 DtWsmFreeWorkspaceInfo (workspace_info);
804 /************************************************************************
807 * Process callbacks on the switch buttons. This function cause
808 * either the workspace switch to occur or for the switch button
809 * label to become editable.
811 ************************************************************************/
815 SwitchButtonCB (Widget w,
816 XtPointer client_data,
821 DtControlCallbackStruct * callback = (DtControlCallbackStruct *) call_data;
822 XEvent * event = callback->event;
824 Widget switch_button = w;
825 Widget old_switch_button;
827 SwitchData * switch_data;
834 if (callback->reason != XmCR_VALUE_CHANGED) return;
836 XtSetArg (al[ac], XmNuserData, &box_data); ac++;
837 XtGetValues (switch_button, al, ac);
839 switch_data = box_data->switch_data;
840 old_switch_button = switch_data->buttons[switch_data->active_switch];
843 /* If the selection occurred on a non-selected button, find the atom */
844 /* representing the workspace name of the button that was selected */
845 /* and use it to call the workspace manager API to switch the */
846 /* workspace. The indication on the buttons occurs out of the */
847 /* called from the workspace manager API. */
849 /* If the selection occurred on the current button, set up the name */
850 /* change editing functions. */
852 if (switch_button != old_switch_button)
855 /* See if the workspace name is being edited. If so, call the */
856 /* callback function to accept the changes. */
858 if (XtIsManaged (box_data->switch_edit))
860 Widget edit_switch_button;
862 XtSetArg (al[0], XmNuserData, &edit_switch_button);
863 XtGetValues (box_data->switch_edit, al, 1);
864 SwitchRenameCB (box_data->switch_edit,
865 (XtPointer) edit_switch_button, (XtPointer) NULL);
867 XmProcessTraversal (w, XmTRAVERSE_CURRENT);
871 if (event->xany.type == ButtonRelease)
872 switch_data->time_stamp = event->xbutton.time;
874 for (i = 0; i < switch_data->switch_count; i++)
876 if (switch_button == switch_data->buttons[i])
878 XtSetArg (al[0], XmNiconName, switch_data->switch_names[i]);
879 XtSetArg (al[1], XmNtitle, switch_data->switch_names[i]);
880 XtSetValues (panel.shell, al, 2);
882 DtWsmSetCurrentWorkspace (XtParent (switch_button),
883 switch_data->atom_names[i]);
888 _DtIconSetState (old_switch_button, False, False);
892 /* Don't do anything on double click */
894 if (event->xany.type == ButtonRelease)
896 if ((event->xbutton.time - switch_data->time_stamp) >
897 XtGetMultiClickTime(XtDisplay(panel.shell)))
899 switch_data->time_stamp = event->xbutton.time;
900 SwitchRenameLabel (w, box_data);
904 _DtIconSetState (w, True, False);
911 /************************************************************************
914 * This is the XtActionProc that gets called when a user types
915 * escape in a text widget which has this translation tied to it.
917 ***********************************************************************/
921 SwitchRenameCancel (Widget w,
924 Cardinal * num_params)
928 Widget switch_button;
932 /* Extract the toggle button from the text field's user data */
934 XtSetArg (al[0], XmNuserData, &switch_button);
935 XtGetValues (w, al, 1);
938 /* Remove the callbacks to eliminate double processing */
940 XtRemoveAllCallbacks (w, XmNactivateCallback);
943 /* Unmanage the text widget, set the traversal to the button and exit */
946 XmProcessTraversal (switch_button, XmTRAVERSE_CURRENT);
952 /************************************************************************
955 * Process callbacks on the text field when a switch name is
958 ************************************************************************/
962 SwitchRenameCB (Widget w,
963 XtPointer client_data,
968 Widget switch_button = (Widget) client_data;
972 SwitchData * switch_data;
975 int current_switch = 0;
981 /* Remove the callbacks to eliminate double processing */
983 XtRemoveCallback (w, XmNactivateCallback,
984 SwitchRenameCB, (XtPointer) client_data);
987 /* If this callback has been called and the text widget is already */
988 /* unmanaged, it means that the escape key was pressed, so return */
990 if (XtIsManaged(w) == False) return;
993 /* Process the two reasons this callback is invoked. A <Return> */
994 /* key has been pressed or the focus is being moved. Accept the */
995 /* new name for both conditions. */
998 XtSetArg (al[ac], XmNuserData, &box_data); ac++;
999 XtGetValues (switch_button, al, ac);
1001 switch_data = box_data->switch_data;
1003 for (i = 0; i < switch_data->switch_count; i++)
1004 if (switch_data->buttons[i] == switch_button)
1008 /* Get the new name from the text field */
1010 edit_string = (char *) XmTextFieldGetString (w);
1013 /* Verify that title is valid and unique and if so, validate */
1014 /* uniqueness and then change the toggle and workspace internal */
1019 _DtStripSpaces (edit_string);
1021 if (strlen (edit_string) == 0)
1025 for (i = 0; i < switch_data->switch_count; i++)
1027 if (strcmp (switch_data->switch_names[i], edit_string) == 0)
1029 if (i == current_switch)
1031 XtUnmanageChild (w);
1032 XmProcessTraversal (switch_button, XmTRAVERSE_CURRENT);
1033 XtFree (edit_string);
1046 /* If the title is not valid, post and error dialog and */
1047 /* then leave the text field active to allow reediting. */
1048 /* Otherwise, change the title. */
1055 s1 = FPGETMESSAGE (86, 1, "Workspace Manager - Rename Error");
1056 s1 = XtNewString (s1);
1057 s2 = FPGETMESSAGE (86, 2, "Invalid or duplicate workspace name"),
1058 s2 = XtNewString (s2);
1060 _DtMessage (XtParent (w), s1, s2, NULL, NULL);
1066 _DtWsmSetWorkspaceTitle (panel.shell,
1067 switch_data->atom_names[current_switch],
1071 /* Unmanage the text field and exit */
1073 XtFree (edit_string);
1074 XtUnmanageChild (w);
1080 /************************************************************************
1083 * Set up the text field and callbacks needed for renaming a
1086 ************************************************************************/
1090 SwitchRenameLabel (Widget switch_button,
1095 Widget switch_edit = box_data->switch_edit;
1097 static Boolean first = True;
1099 XmString toggle_string;
1102 Dimension toggle_width;
1103 Dimension toggle_height;
1104 XmFontList toggle_font_list;
1105 Pixel toggle_background;
1107 Position switch_rc_x;
1108 Position switch_rc_y;
1112 XtTranslations trans_table;
1118 /* Add the additional actions needed by the panel and */
1119 /* set up translations in main edit widget */
1125 XtAppAddActions(XtWidgetToApplicationContext(panel.shell),action_table,1);
1126 trans_table = XtParseTranslationTable (translations_escape);
1127 XtOverrideTranslations (switch_edit, trans_table);
1131 /* Extract the label and toggle position */
1134 XtSetArg (al[ac], XmNx, &toggle_x); ac++;
1135 XtSetArg (al[ac], XmNy, &toggle_y); ac++;
1136 XtSetArg (al[ac], XmNwidth, &toggle_width); ac++;
1137 XtSetArg (al[ac], XmNheight, &toggle_height); ac++;
1138 XtSetArg (al[ac], XmNstring, &toggle_string); ac++;
1139 XtSetArg (al[ac], XmNfontList, &toggle_font_list); ac++;
1140 XtGetValues (switch_button, al, ac);
1143 /* Extract the switch_rc's position */
1145 switch_rc_x = XtX (XtParent (switch_button));
1146 switch_rc_y = XtY (XtParent (switch_button));
1149 /* Convert the xm string into a char string for editing and */
1150 /* then create the text widget to perform the name editing. */
1153 (char *)_XmStringUngenerate(toggle_string, NULL,
1154 XmCHARSET_TEXT, XmCHARSET_TEXT))
1158 /* Set the switch editing field to the new resource set */
1161 XtSetArg (al[ac], XmNleftOffset, toggle_x + switch_rc_x); ac++;
1162 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1163 XtSetArg (al[ac], XmNtopOffset, toggle_y + switch_rc_y); ac++;
1164 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1165 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
1166 XtSetArg (al[ac], XmNmarginHeight, 0); ac++;
1167 XtSetArg (al[ac], XmNfontList, toggle_font_list); ac++;
1168 XtSetArg (al[ac], XmNhighlightThickness, 1); ac++;
1169 XtSetArg (al[ac], XmNvalue, edit_string); ac++;
1170 XtSetArg (al[ac], XmNuserData, switch_button); ac++;
1172 XtSetValues (switch_edit, al, ac);
1174 XtFree(edit_string);
1177 XtSetArg (al[ac], XmNcursorPosition,
1178 XmTextFieldGetLastPosition (switch_edit)); ac++;
1179 XtSetArg (al[ac], XmNwidth, toggle_width); ac++;
1180 XtSetArg (al[ac], XmNheight, toggle_height); ac++;
1181 XtSetValues (switch_edit, al, ac);
1184 /* Add the callbacks for the text input processing */
1186 XtAddCallback (switch_edit, XmNactivateCallback,
1187 SwitchRenameCB, (XtPointer) switch_button);
1189 XtManageChild (switch_edit);
1191 XRaiseWindow (XtDisplay (switch_edit), XtWindow (switch_edit));
1192 XSetInputFocus (XtDisplay (switch_edit), XtWindow (panel.shell),
1193 RevertToParent, CurrentTime);
1195 XmProcessTraversal (switch_edit, XmTRAVERSE_CURRENT);
1198 XmStringFree (toggle_string);
1204 /************************************************************************
1205 ************************************************************************
1207 The next block of functions are used for the push and drop callbacks
1208 on all of the panel controls.
1210 ************************************************************************
1211 ************************************************************************/
1216 /************************************************************************
1218 * CheckControlTypeFile
1219 * Check the control if it is of type "file" that the file exists
1220 * before performing a push or drop action.
1222 * Inputs: control_data - the control whose file type and status are
1225 ************************************************************************/
1229 CheckControlTypeFile (ControlData * control_data)
1233 struct stat stat_info;
1240 if ((intptr_t) control_data->element_values[CONTROL_TYPE].parsed_value != CONTROL_FILE)
1244 (char *) control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1246 if (lstat (file_name, &stat_info) == 0)
1250 /* Display an error dialog because the file cannot be found */
1252 title = FPGETMESSAGE (86, 9, "Workspace Manager - Icon Action Error");
1253 title = XtNewString (title);
1255 msg = FPGETMESSAGE (86, 7, "Cannot find the file");
1256 message = XtMalloc (strlen (msg) + strlen (file_name) + 2);
1257 sprintf (message, "%s %s", msg, file_name);
1259 _DtMessage (panel.shell, title, message, NULL, NULL);
1269 /************************************************************************
1272 * Free the function argument
1274 ************************************************************************/
1283 if (wmFunc == F_Action)
1285 WmActionArg *pAP = (WmActionArg *) pArg;
1287 if (pAP->aap != NULL)
1291 for (i=0; i < pAP->numArgs; i++)
1293 if (pAP->aap[i].u.file.name != NULL)
1294 XtFree ((char *) pAP->aap[i].u.file.name);
1296 XtFree ((char *) pAP->aap);
1299 if (pAP->actionName != NULL)
1300 XtFree ((char *) pAP->actionName);
1302 if (pAP->szExecParms != NULL)
1303 XtFree ((char *) pAP->szExecParms);
1307 XtFree ((char *) pArg);
1312 CheckOtherMonitorsOn(SubpanelData * subpanel_data)
1315 ControlData * control_data;
1318 for (i = -1; i < subpanel_data->control_data_count; i++)
1322 m_state = _DtControlGetMonitorState(subpanel_data->main_panel_icon_copy);
1326 control_data = subpanel_data->control_data[i];
1327 m_state = _DtControlGetMonitorState(control_data->icon);
1330 if (m_state == DtMONITOR_ON) return True;
1337 /************************************************************************
1340 * Process the callback on a control.
1342 ************************************************************************/
1346 XtPointer client_data,
1347 XtPointer call_data)
1350 int control_behavior;
1352 DtControlCallbackStruct * callback = (DtControlCallbackStruct *) call_data;
1353 XEvent * event = callback->event;
1354 ControlData * control_data = (ControlData *) client_data;
1357 PanelActionData * push_action;
1358 Boolean push_recall;
1359 Boolean unpost_subpanel = True;
1362 SubpanelData * subpanel_data;
1363 ControlData * main_control_data;
1369 Widget monitor_icon;
1375 control_behavior = (intptr_t) (panel.element_values[PANEL_CONTROL_BEHAVIOR].parsed_value);
1378 /* See if the workspace name is being edited. If so, call the */
1379 /* callback function to accept the changes. */
1381 for (i = 0; i < panel.box_data_count; i++)
1383 if (panel.box_data[i]->switch_edit != NULL)
1385 if (XtIsManaged (panel.box_data[i]->switch_edit))
1387 Widget switch_button;
1389 XtSetArg (al[0], XmNuserData, &switch_button);
1390 XtGetValues (panel.box_data[i]->switch_edit, al, 1);
1391 SwitchRenameCB (panel.box_data[i]->switch_edit,
1392 (XtPointer) switch_button, (XtPointer) NULL);
1393 XmProcessTraversal (w, XmTRAVERSE_CURRENT);
1400 /* See if the control action occurred out of a subpanel. If so, */
1401 /* get the subpanel and set the main control data. */
1403 if (control_data->parent_type == SUBPANEL)
1405 subpanel_data = (SubpanelData *) control_data->parent_data;
1406 main_control_data = subpanel_data->parent_control_data;
1408 /* This control may have been toggled from the subpanel. If */
1409 /* so, make sure the subpanel is not reposted. */
1412 if (XtParent (w) != subpanel_data->form)
1413 unpost_subpanel = False;
1417 /* The control may be the main panel icon copy. If so, find */
1418 /* the subpanel that contains it a set the subpanel data */
1420 subpanel_data = NULL;
1422 for (i = 0; i < panel.box_data_count; i++)
1424 for (j = 0; j < panel.box_data[i]->control_data_count; j++)
1426 ControlData * box_control;
1428 box_control = panel.box_data[i]->control_data[j];
1430 if (box_control->subpanel_data != NULL &&
1431 box_control->subpanel_data->main_panel_icon_copy == w)
1433 subpanel_data = box_control->subpanel_data;
1434 main_control_data = subpanel_data->parent_control_data;
1438 if (subpanel_data != NULL)
1444 /* If the input occurred out of a subpanel, check to see if */
1445 /* the input was an escape key. If so, unpost the subpanel */
1448 if (subpanel_data != NULL && event != NULL)
1450 if (event->xany.type == KeyPress)
1456 XComposeStatus compose;
1457 static Boolean first = True;
1459 count = XLookupString ((XKeyEvent *)event, buffer, bufsize,
1462 if (keysym == XK_Escape)
1466 ArrowCB (main_control_data->arrow,
1467 (XtPointer)main_control_data, (XtPointer)NULL);
1479 /* This function handles four callback reasons. Two of them, */
1480 /* START and STOP show and remove an hour glass cursor. */
1481 /* MONITOR modifies subpanel visuals when a file change is */
1482 /* detected. ACTIVATE/DEFAULT_ACTION handle the activation */
1485 if (callback->reason == XmCR_BUSY_START)
1488 XDefineCursor (XtDisplay (panel.shell), XtWindow (panel.shell),
1491 for (i = 0, pWid = M_PopupList (panel.shell);
1492 i < M_NumPopups (panel.shell); i++)
1493 XDefineCursor (XtDisplay (panel.shell), XtWindow (pWid[i]),
1497 else if (callback->reason == XmCR_BUSY_STOP)
1499 XUndefineCursor (XtDisplay (panel.shell), XtWindow (panel.shell));
1501 for (i = 0, pWid = M_PopupList (panel.shell);
1502 i < M_NumPopups (panel.shell); i++)
1503 XUndefineCursor (XtDisplay (panel.shell), XtWindow (pWid[i]));
1506 else if (callback->reason == XmCR_MONITOR)
1508 /* For a monitor file, turn on the monitor indicator for */
1509 /* the subpanel control and turn on the arrow to the */
1510 /* highlighted arrow of the subpanel. */
1512 if (subpanel_data != NULL)
1514 monitor_icon = control_data->indicator;
1516 m_state = _DtControlGetMonitorState(w);
1518 if (m_state == DtMONITOR_ON)
1519 XtSetArg (al[0], XmNimageName, indicator_on_image);
1520 else /* DtMONITOR_OFF */
1521 XtSetArg (al[0], XmNimageName, indicator_off_image);
1523 XtSetValues (monitor_icon, al, 1);
1525 if (XtIsManaged (subpanel_data->shell))
1527 if (m_state == DtMONITOR_ON)
1529 XtSetArg (al[0], XmNimageName, unpost_monitor_arrow_image);
1530 XtSetValues (main_control_data->arrow, al, 1);
1534 if (!CheckOtherMonitorsOn(subpanel_data))
1536 XtSetArg (al[0], XmNimageName, unpost_arrow_image);
1537 XtSetValues (main_control_data->arrow, al, 1);
1543 if (m_state == DtMONITOR_ON)
1545 XtSetArg (al[0], XmNimageName, post_monitor_arrow_image);
1546 XtSetValues (main_control_data->arrow, al, 1);
1550 if (!CheckOtherMonitorsOn(subpanel_data))
1552 XtSetArg (al[0], XmNimageName, post_arrow_image);
1553 XtSetValues (main_control_data->arrow, al, 1);
1560 else if ((control_behavior == DOUBLE_CLICK &&
1561 callback->reason == XmCR_DEFAULT_ACTION) ||
1562 (control_behavior == SINGLE_CLICK &&
1563 (callback->reason == XmCR_DEFAULT_ACTION ||
1564 callback->reason == XmCR_SINGLE_SELECT)))
1566 control_type = (intptr_t) (control_data->element_values[CONTROL_TYPE].parsed_value);
1567 push_action = (PanelActionData *) (control_data->element_values[CONTROL_PUSH_ACTION].parsed_value);
1568 push_recall = (Boolean) (intptr_t) (control_data->element_values[CONTROL_PUSH_RECALL].parsed_value);
1570 switch (control_type)
1572 case CONTROL_CLIENT:
1578 /* Turn off the subpanel control monitor indicator */
1580 if ((char) (intptr_t) control_data->element_values[CONTROL_MONITOR_TYPE].
1581 parsed_value != MONITOR_NONE)
1583 if (subpanel_data != NULL)
1585 monitor_icon = control_data->indicator;
1586 XtSetArg (al[0], XmNimageName, indicator_off_image);
1587 XtSetValues (monitor_icon, al, 1);
1592 if (CheckControlTypeFile (control_data) && push_action != NULL)
1594 _DtControlDoPushAnimation (w);
1596 if (push_recall == False)
1598 /* If the control is of type file, build and object */
1599 /* list that contains the host and file name to */
1600 /* pass to the invokation. */
1602 if (control_type == CONTROL_FILE && !control_data->is_action)
1606 aap = (DtActionArg *) XtCalloc(1,sizeof(DtActionArg));
1608 aap->argClass = DtACTION_FILE;
1610 aap->u.file.name = (char *) control_data->
1611 element_values[CONTROL_FILE_NAME].parsed_value;
1613 DtActionInvoke (panel.shell,
1614 push_action->action_name,
1615 aap, 1, NULL, NULL, NULL,
1618 XtFree ((char *) aap);
1622 if (strcmp (push_action->action_name, "FPOnItemHelp") == 0)
1625 unpost_subpanel = False;
1629 DtActionInvoke (panel.shell,
1630 push_action->action_name,
1631 NULL, 0, NULL, NULL, NULL,
1640 String func_arg = NULL;
1643 char * client_title;
1645 WmGlobalData * wm_global_data = (WmGlobalData *) panel.global_data;
1646 ClientData * wm_client_data = NULL;
1647 WmPushRecallArg push_argument;
1650 /* Parse out the function and arguments used by the */
1651 /* window manager to invoke the client. */
1653 s1save = s1 = XtNewString ("f.action");
1656 ParseWmFunction ((unsigned char **) &s1, CRS_ANY, &wm_func);
1661 (char *) control_data->element_values[CONTROL_CLIENT_NAME].parsed_value;
1663 if (client_name == NULL)
1665 (char *) control_data->element_values[CONTROL_LABEL].parsed_value;
1668 (char *) control_data->element_values[CONTROL_LABEL].parsed_value;
1670 if (control_type == CONTROL_FILE && ! control_data->is_action)
1674 file_name = (char *) control_data->
1675 element_values[CONTROL_FILE_NAME].parsed_value;
1677 s1 = XtMalloc (strlen (push_action->action_name) + strlen (file_name) + 2);
1678 strcpy (s1, push_action->action_name);
1680 strcat (s1, file_name);
1683 s1 = XtNewString (push_action->action_name);
1685 ParseWmFunctionArg ((unsigned char **) &s1, function_index,
1686 wm_func, (void **) &func_arg,
1687 client_name, client_name);
1690 /* Set the push argument to the parsed data */
1692 push_argument.ixReg = PushRecallGetData (client_name);
1693 push_argument.wmFunc = wm_func;
1694 push_argument.pArgs = func_arg;
1697 /* Get the window manager client data for the panel and */
1698 /* call the push recall function to get the client run. */
1700 if (subpanel_data != NULL)
1701 XFindContext (wm_global_data->display,
1702 XtWindow (subpanel_data->shell),
1703 wm_global_data->windowContextType,
1704 (XtPointer) &wm_client_data);
1706 XFindContext (wm_global_data->display,
1707 XtWindow (panel.shell),
1708 wm_global_data->windowContextType,
1709 (XtPointer) &wm_client_data);
1711 F_Push_Recall ((String) &push_argument,
1712 wm_client_data, callback->event);
1714 FreeFunctionArg (wm_func, func_arg);
1730 /* Call the unposting function and reset the arrow behavior if the */
1731 /* action occurred out of a subpanel. */
1733 if (subpanel_data != NULL && unpost_subpanel &&
1734 (Boolean) (intptr_t) panel.element_values[PANEL_SUBPANEL_UNPOST].parsed_value &&
1735 subpanel_data->torn == False)
1736 ArrowCB (main_control_data->arrow,
1737 (XtPointer)main_control_data, (XtPointer)NULL);
1744 /************************************************************************
1747 * Process the callback for drops on a control
1749 ************************************************************************/
1754 XtPointer client_data,
1755 XtPointer call_data)
1759 PanelActionData * drop_action = (PanelActionData *) client_data;
1760 DtDndDropAnimateCallback animate_data =
1761 (DtDndDropAnimateCallback) call_data;
1763 ControlData * control_data;
1767 char * save_name = NULL;
1769 XtSetArg (al[0], XmNuserData, &control_data);
1770 XtGetValues (w, al, 1);
1772 if (CheckControlTypeFile (control_data) &&
1773 (animate_data->dropData->protocol == DtDND_FILENAME_TRANSFER ||
1774 animate_data->dropData->protocol == DtDND_BUFFER_TRANSFER))
1777 intptr_t control_type =
1778 (intptr_t)control_data->element_values[CONTROL_TYPE].parsed_value;
1779 char * control_name =
1780 (char *)control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1781 Boolean send_control_name = False;
1783 _DtControlDoDropAnimation (w);
1785 drop_action = (PanelActionData *)
1786 control_data->element_values[CONTROL_DROP_ACTION].parsed_value;
1788 if (control_data->operation == XmDROP_MOVE)
1790 if (control_data->move_action)
1792 save_name = drop_action->action_name;
1793 drop_action->action_name = control_data->move_action;
1796 else if (control_data->operation == XmDROP_COPY)
1798 if (control_data->copy_action)
1800 save_name = drop_action->action_name;
1801 drop_action->action_name = control_data->copy_action;
1804 else if (control_data->operation == XmDROP_LINK)
1806 if (control_data->link_action)
1808 save_name = drop_action->action_name;
1809 drop_action->action_name = control_data->link_action;
1814 numItems = animate_data->dropData->numItems;
1816 if ((control_type == CONTROL_FILE) &&
1817 (!control_data->is_action) &&
1818 (strcmp(control_name, drop_action->action_name) != 0))
1821 send_control_name = True;
1824 if (animate_data->dropData->protocol == DtDND_FILENAME_TRANSFER)
1826 char ** file_list = animate_data->dropData->data.files;
1829 aap = (DtActionArg *) XtCalloc (numItems, sizeof (DtActionArg));
1831 if (send_control_name)
1833 aap[m].argClass = DtACTION_FILE;
1834 aap[m++].u.file.name =
1835 (char *)control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1838 for (l = 0; m < numItems; l++, m++)
1840 aap[m].argClass = DtACTION_FILE;
1841 aap[m].u.file.name = file_list[l];
1844 else if (animate_data->dropData->protocol == DtDND_BUFFER_TRANSFER)
1846 DtDndBuffer * buf_list = animate_data->dropData->data.buffers;
1849 aap = (DtActionArg *) XtCalloc (numItems, sizeof (DtActionArg));
1851 if (send_control_name)
1853 aap[m].argClass = DtACTION_FILE;
1854 aap[m++].u.file.name =
1855 (char *)control_data->element_values[CONTROL_FILE_NAME].parsed_value;
1858 for (l = 0; m < numItems; l++, m++)
1860 aap[m].argClass = DtACTION_BUFFER;
1861 aap[m].u.buffer.bp = buf_list[l].bp;
1862 aap[m].u.buffer.size = buf_list[l].size;
1863 aap[m].u.buffer.name = buf_list[l].name;
1868 if (save_name != NULL)
1869 drop_action->action_name = save_name;
1871 control_data->operation = 0;
1876 DtActionInvoke (w, drop_action->action_name, aap, numItems,
1877 NULL, NULL, NULL, 1, NULL, NULL);
1879 XtFree((char *) aap);
1881 if (save_name != NULL)
1882 drop_action->action_name = save_name;
1884 control_data->operation = 0;
1891 /************************************************************************
1894 * Process the callback for drops on a control
1896 ************************************************************************/
1900 TransferDropCB (Widget w,
1901 XtPointer client_data,
1902 XtPointer call_data)
1906 DtDndTransferCallbackStruct * transfer_data =
1907 (DtDndTransferCallbackStruct *) call_data;
1908 ControlData * control_data;
1912 /* Currently only accepts FILE drops */
1914 if (transfer_data->dropData->protocol == DtDND_FILENAME_TRANSFER ||
1915 transfer_data->dropData->protocol == DtDND_BUFFER_TRANSFER)
1917 transfer_data->status = DtDND_SUCCESS;
1919 XtSetArg (al[0], XmNuserData, &control_data);
1920 XtGetValues (w, al, 1);
1922 control_data->operation = transfer_data->operation;
1926 transfer_data->status = DtDND_FAILURE;
1928 transfer_data->completeMove = False;
1933 /************************************************************************
1934 ************************************************************************
1936 This block of functions handle the processing of subpanel torn-off
1937 behavior. Default behavior for a subpanel is to unpost when a
1938 control is selected. This changes to sticky when the subpanel is torn.
1940 ************************************************************************
1941 ************************************************************************/
1944 /************************************************************************
1947 * Process the callback on the subpanel unposting initiated through
1948 * the window manager close menu item.
1950 ************************************************************************/
1954 SubpanelUnmapCB (Widget w,
1955 XtPointer client_data,
1956 XtPointer call_data)
1960 ControlData * main_control_data = (ControlData *) client_data;
1961 SubpanelData * subpanel_data = main_control_data->subpanel_data;
1968 XtSetArg (al[ac], XmNimageName, post_arrow_image); ac++;
1969 XtSetValues (main_control_data->arrow, al, ac);
1971 XtUnmanageChild (subpanel_data->shell);
1972 subpanel_data->torn = False;
1975 /* Remove the event handler from the subpanel */
1977 XtRemoveEventHandler (subpanel_data->shell, StructureNotifyMask, False,
1978 (XtEventHandler) SubpanelTornEventHandler,
1979 (XtPointer) main_control_data);
1982 /* Reset the active traversal control for the front panel */
1983 /* We should not have to do this but for unknown reasons, */
1984 /* the traversal highlight is getting lost. */
1986 XmProcessTraversal (panel.shell, XmTRAVERSE_NEXT);
1987 XmProcessTraversal (panel.shell, XmTRAVERSE_PREV);
1993 /************************************************************************
1995 * SubpanelTornEventHandler
1996 * Set a subpanel flag to change its posting behavior when it is
1999 ************************************************************************/
2002 SubpanelTornEventHandler (Widget subpanel_shell,
2003 XtPointer client_data,
2005 Boolean * continue_dispatch)
2008 ControlData * main_control_data = (ControlData *) client_data;
2009 SubpanelData * subpanel_data = main_control_data->subpanel_data;
2012 if (subpanel_data->posted_x != 0 &&
2013 subpanel_data->posted_x != XtX (subpanel_data->shell))
2015 subpanel_data->torn = True;
2017 subpanel_data->torn = False;
2019 *continue_dispatch = True;
2026 /************************************************************************
2029 * Start up the help manager to show the help topic
2031 * Inputs: widget - the widget for which help was requested
2032 * help_volume - the help volume that contains the information
2033 * help_topic - the specific help topic.
2035 ************************************************************************/
2038 void StartHelpClient (Widget widget,
2044 /***** TEMPORARY - Add code to actually invoke the Help Client ****/
2046 WmDtDisplayTopicHelp (widget, help_volume, help_topic);
2049 /************************************************************************
2052 * Invoke topic help if available otherwise invoke help string if
2055 ************************************************************************/
2058 void InvokeHelp (Widget widget,
2064 if (help_volume == NULL)
2065 help_volume = FP_HELP_VOLUME;
2067 if (help_topic != NULL)
2069 if (strcmp (help_volume, FP_HELP_VOLUME) == 0)
2070 WmDtDisplayTopicHelp (widget, help_volume, help_topic);
2072 StartHelpClient (widget, help_volume, help_topic);
2076 if (help_string != NULL)
2077 WmDtDisplayStringHelp (widget, help_string);
2082 /************************************************************************
2084 * SubpanelTopicHelpCB
2085 * Process the callback for help on the subpanel
2087 ************************************************************************/
2090 void SubpanelTopicHelpCB (Widget widget,
2091 XtPointer client_data,
2092 XtPointer call_data)
2095 SubpanelData * subpanel_data = (SubpanelData *) client_data;
2101 (char *) subpanel_data->element_values[SUBPANEL_HELP_VOLUME].parsed_value;
2103 (char *) subpanel_data->element_values[SUBPANEL_HELP_TOPIC].parsed_value;
2105 (char *) subpanel_data->element_values[SUBPANEL_HELP_STRING].parsed_value;
2107 InvokeHelp(widget, help_topic, help_volume, help_string);
2109 } /* END OF FUNCTION SubpanelTopicHelpCB */
2114 /************************************************************************
2117 * Process the callback for help on the switch
2119 ************************************************************************/
2122 void SwitchTopicHelpCB (Widget widget,
2123 XtPointer client_data,
2124 XtPointer call_data)
2127 SwitchData * switch_data = (SwitchData *) client_data;
2133 (char *) switch_data->element_values[SWITCH_HELP_VOLUME].parsed_value;
2135 (char *) switch_data->element_values[SWITCH_HELP_TOPIC].parsed_value;
2137 (char *) switch_data->element_values[SWITCH_HELP_STRING].parsed_value;
2139 InvokeHelp(widget, help_topic, help_volume, help_string);
2141 } /* END OF FUNCTION SwitchTopicHelpCB */
2146 /************************************************************************
2148 * ControlTopicHelpCB
2149 * Process the callback for help on the control
2151 *************************************************************************/
2154 void ControlTopicHelpCB (Widget widget,
2155 XtPointer client_data,
2156 XtPointer call_data)
2160 ControlData * control_data = (ControlData *) client_data;
2166 (char *) control_data->element_values[CONTROL_HELP_VOLUME].parsed_value;
2168 (char *) control_data->element_values[CONTROL_HELP_TOPIC].parsed_value;
2170 (char *) control_data->element_values[CONTROL_HELP_STRING].parsed_value;
2172 InvokeHelp(widget, help_topic, help_volume, help_string);
2174 } /* END OF FUNCTION ControlTopicHelpCB */
2179 /************************************************************************
2181 * GeneralTopicHelpCB
2182 * Process the callback for help on the control
2184 ************************************************************************/
2187 void GeneralTopicHelpCB (Widget widget,
2188 XtPointer client_data,
2189 XtPointer call_data)
2196 help_volume = FP_HELP_VOLUME;
2197 help_topic = (char *) client_data;
2199 WmDtDisplayTopicHelp (widget, help_volume, help_topic);
2201 } /* END OF FUNCTION GeneralTopicHelpCB */
2206 /************************************************************************
2207 ************************************************************************
2209 This block of functions handle the initialization and dynamic
2210 processing for the subpanel installation area.
2212 ************************************************************************
2213 ************************************************************************/
2215 /************************************************************************
2217 * GetValuesFromDataType
2218 * Given and file type index and subpanel data, construct an element
2219 * values array for a new control that is initialized to the attributes
2222 ************************************************************************/
2226 GetValuesFromDataType (char * data_type,
2228 SubpanelData * subpanel_data,
2229 ElementValue ** element_values)
2236 *element_values = (ElementValue *) XtMalloc (sizeof(ElementValue) *
2237 CONTROL_KEYWORD_COUNT);
2239 for (i = 0; i < CONTROL_KEYWORD_COUNT; i++)
2241 (*element_values)[i].use_default = True;
2242 (*element_values)[i].string_value = NULL;
2243 (*element_values)[i].parsed_value = NULL;
2246 (*element_values)[CONTROL_FILE_NAME].string_value = XtNewString (file_name);
2248 ptr = (char *)strrchr(file_name, '/');
2251 (*element_values)[CONTROL_NAME].string_value = XtNewString(ptr);
2252 (*element_values)[CONTROL_TYPE].string_value = XtNewString("file");
2253 (*element_values)[CONTROL_CONTAINER_TYPE].string_value =
2254 XtNewString("SUBPANEL");
2255 (*element_values)[CONTROL_CONTAINER_NAME].string_value =
2256 XtNewString(subpanel_data->element_values[0].string_value);
2257 (*element_values)[CONTROL_POSITION_HINTS].string_value =
2258 XtNewString("last");
2260 InitializeControlFields (*element_values, data_type);
2266 /************************************************************************
2269 * Process the callback for the drop on the subpanel drop zone for
2270 * dynamic customization
2272 ************************************************************************/
2276 CustomizeDropCB (Widget w,
2277 XtPointer client_data,
2278 XtPointer call_data)
2282 ControlData * main_control_data;
2283 SubpanelData * subpanel_data;
2284 DtDndDropAnimateCallbackStruct * animate_data =
2285 (DtDndDropAnimateCallbackStruct *) call_data;
2287 ControlData * control_data;
2288 ElementValue * element_values;
2292 Boolean bad_control;
2293 Boolean control_monitor;
2294 intptr_t position_hints;
2297 char * new_control_name;
2298 char * control_name;
2299 Widget attach_widget;
2310 /* If this is not a transfer drop, return */
2312 if (animate_data->dropData->protocol != DtDND_FILENAME_TRANSFER)
2316 /* Get the subpanel, box, and main control data */
2318 XtSetArg (al[0], XmNuserData, &subpanel_data);
2319 XtGetValues (w, al, 1);
2321 main_control_data = subpanel_data->parent_control_data;
2322 box_data = (BoxData *) main_control_data->parent_data;
2324 file_count = animate_data->dropData->numItems;
2325 file_list = animate_data->dropData->data.files;
2328 /* Pop down the subpanel before creating the new control or */
2329 /* mucking with any of the old controls. */
2331 if (subpanel_data->torn == False)
2332 XtUnmanageChild (subpanel_data->shell);
2335 /* Loop through the set of files (possibly more than one) that */
2336 /* have been dropped. */
2338 for (i = 0; i < file_count; i++)
2341 /* Get the file type of the file and process as either */
2342 /* a "FrontPanel" file or a normal file type. */
2344 data_type = DtDtsFileToDataType (file_list[i]);
2346 if (!strcmp (data_type, "FP"))
2349 InitParse (file_list[i], &element_values);
2352 /* Reset the values of the container name and type to this one */
2354 if (element_values[CONTROL_CONTAINER_NAME].use_default == False)
2356 if (element_values[CONTROL_CONTAINER_NAME].parsed_value != NULL)
2357 XtFree (element_values[CONTROL_CONTAINER_NAME].parsed_value);
2358 if (element_values[CONTROL_CONTAINER_NAME].string_value != NULL)
2359 XtFree (element_values[CONTROL_CONTAINER_NAME].string_value);
2362 if (element_values[CONTROL_CONTAINER_TYPE].use_default == False)
2364 if (element_values[CONTROL_CONTAINER_TYPE].string_value != NULL)
2365 XtFree (element_values[CONTROL_CONTAINER_TYPE].string_value);
2368 if (element_values[CONTROL_POSITION_HINTS].use_default == False)
2370 if (element_values[CONTROL_POSITION_HINTS].string_value != NULL)
2371 XtFree (element_values[CONTROL_POSITION_HINTS].string_value);
2374 element_values[CONTROL_CONTAINER_NAME].use_default = False;
2375 element_values[CONTROL_CONTAINER_NAME].string_value =
2376 XtNewString (subpanel_data->element_values[SUBPANEL_NAME].parsed_value);
2377 element_values[CONTROL_CONTAINER_NAME].parsed_value =
2378 XtNewString (subpanel_data->element_values[SUBPANEL_NAME].parsed_value);
2380 element_values[CONTROL_CONTAINER_TYPE].use_default = False;
2381 element_values[CONTROL_CONTAINER_TYPE].string_value =
2382 XtNewString ("SUBPANEL");
2383 element_values[CONTROL_CONTAINER_TYPE].parsed_value =
2386 element_values[CONTROL_POSITION_HINTS].use_default = False;
2387 element_values[CONTROL_POSITION_HINTS].string_value =
2388 XtNewString ("last");
2389 element_values[CONTROL_POSITION_HINTS].parsed_value =
2395 GetValuesFromDataType (data_type, file_list[i],
2396 subpanel_data, &element_values);
2399 DtDtsFreeDataType (data_type);
2403 /* Check for naming conflicts and if found, issue an error and */
2404 /* clean up. Continue processing subsequent files even if this */
2405 /* one is not valid. */
2407 new_control_name = (char *) element_values[CONTROL_NAME].parsed_value;
2408 bad_control = False;
2410 for (j = 0; j < subpanel_data->control_data_count; j++)
2412 control_name = (char *) subpanel_data->control_data[j]->
2413 element_values[CONTROL_NAME].parsed_value;
2415 if (strcmp (control_name, new_control_name) == 0)
2417 ControlData control_data;
2418 String title, del_ctrl, ctrl_name, del_msg, message;
2421 /* Display an error dialog for the unusable drop data */
2423 title = FPGETMESSAGE (86, 3, "Workspace Manager - Install Icon Error");
2424 title = XtNewString (title);
2426 del_ctrl = FPGETMESSAGE (86, 4, "Install Icon:");
2427 del_ctrl = XtNewString (del_ctrl);
2429 del_msg = FPGETMESSAGE (86, 8, "There is already an icon of this name.");
2430 del_msg = XtNewString (del_msg);
2432 message = XtMalloc ((strlen(del_ctrl) + strlen(new_control_name) +
2433 strlen(del_msg) + 4));
2434 sprintf(message, "%s %s\n\n%s", del_ctrl, new_control_name, del_msg);
2436 _DtMessage (panel.shell, title, message, NULL, NULL);
2444 /* Set up a temporary control data structure so that the */
2445 /* appropriate function can be used to free the allocated */
2446 /* element values. */
2448 control_data.element_values = element_values;
2449 RemoveEntry ((RecordData *)&control_data, CONTROL);
2456 if (bad_control) continue;
2459 if ((intptr_t) element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
2460 control_monitor = True;
2462 control_monitor = False;
2465 position_hints = (intptr_t) element_values[CONTROL_POSITION_HINTS].parsed_value;
2468 /* Initialize the subpanel layout and processing attributes. */
2470 if ((intptr_t) main_control_data->
2471 element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
2473 control_monitor = True;
2477 for (j = 0; j < subpanel_data->control_data_count; j++)
2479 if ((intptr_t) subpanel_data->control_data[j]->
2480 element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
2482 control_monitor = True;
2488 /* If the new control is a montior, loop through the existing */
2489 /* control set a adjust the left offset resource to ensure */
2490 /* that they are all aligned properly. */
2492 if (control_monitor)
2494 XtSetArg (al[0], XmNleftOffset, 20);
2496 for (j = 0; j < subpanel_data->control_data_count; j++)
2497 XtSetValues (subpanel_data->control_data[j]->icon, al, 1);
2499 if (subpanel_data->main_panel_icon_copy != NULL)
2500 XtSetValues (subpanel_data->main_panel_icon_copy, al, 1);
2504 /* Get the subpanel control data and position the element */
2505 /* values into the postion hints location. */
2506 /* The remainder of the positioning code is set up to allow */
2507 /* placement in non-last positions even though position is */
2508 /* forced to last. This is here for future use. */
2510 subpanel_data->control_data_count++;
2511 count = subpanel_data->control_data_count;
2513 subpanel_data->control_data =
2514 (ControlData **) XtRealloc ((char *) subpanel_data->control_data,
2515 sizeof (ControlData *) * count);
2517 for (j = count - 2; j >= 0; j--)
2519 if (position_hints >=
2520 (intptr_t) subpanel_data->control_data[j]->element_values[CONTROL_POSITION_HINTS].parsed_value)
2526 for (k = count - 1; k > j; k--)
2527 subpanel_data->control_data[k] = subpanel_data->control_data[k - 1];
2529 subpanel_data->control_data[j] = control_data =
2530 (ControlData *) XtMalloc (sizeof (ControlData));
2532 control_data->element_values = element_values;
2533 control_data->parent_data = (XtPointer) subpanel_data;
2534 control_data->parent_type = SUBPANEL;
2535 control_data->subpanel_data = NULL;
2536 control_data->icon = NULL;
2537 control_data->arrow = NULL;
2538 control_data->arrow_separator = NULL;
2539 control_data->indicator = NULL;
2540 control_data->is_action = False;
2541 control_data->move_action = NULL;
2542 control_data->copy_action = NULL;
2543 control_data->link_action = NULL;
2544 control_data->operation = 0;
2546 AddControlActionList (control_data);
2549 if (j == 0 && subpanel_data->main_panel_icon_copy != NULL)
2550 attach_widget = subpanel_data->main_panel_icon_copy;
2552 attach_widget = subpanel_data->control_data[j - 1]->icon;
2555 /* Reattach the bottom control so the new bottom will appear */
2560 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
2561 XtSetArg (al[ac], XmNbottomOffset, 0); ac++;
2562 XtSetValues (attach_widget, al, ac);
2566 SubpanelControlCreate (subpanel_data, main_control_data,
2567 control_data, attach_widget, False,
2571 /* Pad the bottom control */
2576 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
2577 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
2578 XtSetValues (control_data->icon, al, ac);
2581 WriteControlComponentFile (control_data);
2586 /* Pop the subpanel back up and return */
2588 if (subpanel_data->torn == False)
2589 ArrowCB (main_control_data->arrow,
2590 (XtPointer)main_control_data, (XtPointer)NULL);
2596 /************************************************************************
2598 * CustomizeTransferDropCB
2599 * Process the callback for drops on an install zone
2601 ************************************************************************/
2605 CustomizeTransferDropCB (Widget w,
2606 XtPointer client_data,
2607 XtPointer call_data)
2611 DtDndTransferCallbackStruct * transfer_data =
2612 (DtDndTransferCallbackStruct *) call_data;
2614 /* Currently only accepts FILE drops */
2616 if (transfer_data->dropData->protocol == DtDND_FILENAME_TRANSFER)
2617 transfer_data->status = DtDND_SUCCESS;
2619 transfer_data->status = DtDND_FAILURE;
2621 transfer_data->completeMove = False;