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 /* $TOG: dtb_utils.C /main/8 1998/10/26 17:19:11 mgreess $ */
25 * $TOG: dtb_utils.C /main/8 1998/10/26 17:19:11 mgreess $
28 * CDE Application Builder General Utility Functions
30 * This file was generated by dtcodegen, from project dtmailopts
32 * ** DO NOT MODIFY BY HAND - ALL MODIFICATIONS WILL BE LOST **
38 #include <sys/param.h>
43 #include <Xm/MessageB.h>
47 #include <Dt/HelpDialog.h>
48 #include <Dt/HelpQuickD.h>
49 #include <Dt/Session.h>
50 #include "dtb_utils.h"
53 #define min(a,b) ((a) < (b)? (a):(b))
57 #define max(a,b) ((a) > (b)? (a):(b))
61 * Private functions used for dynamic centering of objects
63 static void center_widget(
65 DTB_CENTERING_TYPES type
67 static void uncenter_widget(
69 DTB_CENTERING_TYPES type
71 static void centering_handler(
73 XtPointer client_data,
75 Boolean *cont_dispatch
78 * Static functions used for dynamic aligning of group objects
80 static Widget get_label_widget(
83 static Position get_offset_from_ancestor(
87 static Dimension get_label_width(
90 static void get_widest_label(
94 Dimension *label_width
96 static void get_widest_value(
100 Dimension *value_width
102 static void get_widget_rect(
106 static void get_greatest_size(
114 static void get_group_cell_size(
116 DtbGroupInfo *group_info,
120 static void get_group_row_col(
122 DtbGroupInfo *group_info,
126 static Widget get_group_child(
128 DtbGroupInfo *group_info,
132 static void align_children(
134 DtbGroupInfo *group_info,
137 static void align_handler(
139 XtPointer client_data,
141 Boolean *cont_dispatch
143 static void free_group_info(
145 XtPointer client_data,
148 static void align_rows(
150 DtbGroupInfo *group_info,
153 static void align_cols(
155 DtbGroupInfo *group_info,
158 static void align_left(
160 DtbGroupInfo *group_info
162 static void align_right(
164 DtbGroupInfo *group_info
166 static void align_labels(
168 DtbGroupInfo *group_info
170 static void align_vcenter(
172 DtbGroupInfo *group_info,
175 static void align_top(
177 DtbGroupInfo *group_info
179 static void align_bottom(
181 DtbGroupInfo *group_info
183 static void align_hcenter(
185 DtbGroupInfo *group_info,
190 * Private functions used for finding paths
192 static int determine_exe_dir(
197 static int determine_exe_dir_from_argv(
202 static int determine_exe_dir_from_path (
207 static Boolean path_is_executable(
214 * Variable for storing client session save callback
216 static DtbClientSessionSaveCB dtb_client_session_saveCB = NULL;
219 * Variable for storing top level widget
221 static Widget dtb_project_toplevel_widget = (Widget)NULL;
224 * Variable for storing command used to invoke application
226 static char *dtb_save_command_str = (char *)NULL;
229 * Directory where the binary for this process whate loaded from
231 static char *dtb_exe_dir = (char *)NULL;
234 * Application Builder utility funcs
237 * Create/load a Pixmap given an XPM or Bitmap files
238 * NOTE: this allocates a server Pixmap; it is the responsibility
239 * of the caller to free the Pixmap
242 dtb_cvt_file_to_pixmap(
245 Pixmap *pixmapReturnPtr
248 #define pixmapReturn (*pixmapReturnPtr)
250 Screen *screen = NULL;
253 char *image_path = new char[MAXPATHLEN+1];
254 Boolean pixmap_found = FALSE;
259 screen = XtScreen(widget);
260 fgPixel = WhitePixelOfScreen(screen);
261 bgPixel = BlackPixelOfScreen(screen);
264 * Get proper colors for widget
266 XtVaGetValues(widget,
267 XmNforeground, &fgPixel,
268 XmNbackground, &bgPixel,
272 * In CDE, XmGetPixmap handles .xpm files, as well.
276 pixmap = XmGetPixmap(screen, fileName, fgPixel, bgPixel);
278 pixmap_found = ((pixmap != 0) && (pixmap != XmUNSPECIFIED_PIXMAP));
282 sprintf(image_path, "%s/%s", dtb_get_exe_dir(), fileName);
283 pixmap = XmGetPixmap(screen, image_path, fgPixel, bgPixel);
285 pixmap_found = ((pixmap != 0) && (pixmap != XmUNSPECIFIED_PIXMAP));
289 sprintf(image_path, "%s/bitmaps/%s", dtb_get_exe_dir(), fileName);
290 pixmap = XmGetPixmap(screen, image_path, fgPixel, bgPixel);
292 pixmap_found = ((pixmap != 0) && (pixmap != XmUNSPECIFIED_PIXMAP));
296 delete [] image_path;
300 pixmapReturn = pixmap;
301 pixmapReturn = pixmap;
302 delete [] image_path;
309 * Sets both the sensitive and insensitive pixmaps
312 dtb_set_label_from_bitmap_data(
316 unsigned char *bitmapData
319 Display *display = NULL;
320 Screen *screen = NULL;
324 unsigned int depth = 0;
325 Pixmap labelPixmap = 0;
327 if ( (widget == NULL)
330 || (bitmapData == NULL) )
336 * Get a whole slew of information X needs
343 display = XtDisplay(widget);
344 screen = XtScreen(widget);
345 window = XtWindow(widget);
348 /* Widget has not been realized, yet */
349 window = RootWindowOfScreen(screen);
352 XtVaGetValues(widget,
353 XmNbackground, &widgetBg,
354 XmNforeground, &widgetFg,
355 XmNdepth, &widgetDepth,
365 labelPixmap = XCreatePixmapFromBitmapData(
372 if (labelPixmap == 0)
377 dtb_set_label_pixmaps(widget, labelPixmap, 0);
384 * Sets the label and insensitive label pixmaps of the widget.
386 * If either (or both) pixmap is NULL, it is ignored.
389 dtb_set_label_pixmaps(
392 Pixmap labelInsensitivePixmap
395 if ( (widget == NULL)
396 || ((labelPixmap == 0) && (labelInsensitivePixmap == 0)) )
402 * Set the appropriate resources.
404 XtVaSetValues(widget, XmNlabelType, XmPIXMAP, NULL);
405 if (labelPixmap != 0)
407 XtVaSetValues(widget, XmNlabelPixmap, labelPixmap, NULL);
409 if (labelInsensitivePixmap != 0)
411 XtVaSetValues(widget, XmNlabelInsensitivePixmap,
412 labelInsensitivePixmap, NULL);
420 * Returns TRUE if the fileName has the extension
423 dtb_file_has_extension(
428 Boolean hasExt = FALSE;
430 if (extension == NULL)
432 hasExt = ( (fileName == NULL) || (strlen(fileName) == 0) );
436 if (fileName == NULL)
440 char *dotPtr= strrchr(fileName, '.');
443 else if (strcmp(dotPtr+1, extension) == 0)
452 * Appends the extension to fileBase and attempts to load in
456 dtb_cvt_filebase_to_pixmap(
463 char *fileName = new char[512];
466 strcpy(fileName, fileBase);
467 strcat(fileName, extension);
468 rc = dtb_cvt_file_to_pixmap(fileName, widget, pixmap_ptr);
475 dtb_cvt_image_file_to_pixmap(
481 int rc = 0; /* return code */
482 Pixmap tmpPixmap = 0;
485 if (dtb_file_has_extension(fileName, "pm") ||
486 dtb_file_has_extension(fileName, "xpm") ||
487 dtb_file_has_extension(fileName, "bm") ||
488 dtb_file_has_extension(fileName, "xbm"))
490 /* If explicit filename requested, use it directly */
491 rc = dtb_cvt_file_to_pixmap(fileName, widget, &tmpPixmap);
493 else /* Append extensions to locate best graphic match */
495 XtVaGetValues(widget, XmNdepth, &depth, NULL);
497 if (depth > 1) /* Look for Color Graphics First */
499 rc = dtb_cvt_filebase_to_pixmap(widget, fileName, ".pm", &tmpPixmap);
501 rc = dtb_cvt_filebase_to_pixmap(widget, fileName, ".xpm", &tmpPixmap);
503 rc = dtb_cvt_filebase_to_pixmap(widget, fileName, ".bm", &tmpPixmap);
505 rc = dtb_cvt_filebase_to_pixmap(widget, fileName, ".xbm", &tmpPixmap);
507 else /* Look for Monochrome First */
509 rc = dtb_cvt_filebase_to_pixmap(widget, fileName, ".bm", &tmpPixmap);
511 rc = dtb_cvt_filebase_to_pixmap(widget, fileName, ".xbm", &tmpPixmap);
513 rc = dtb_cvt_filebase_to_pixmap(widget, fileName, ".pm", &tmpPixmap);
515 rc = dtb_cvt_filebase_to_pixmap(widget, fileName, ".xpm", &tmpPixmap);
521 fprintf(stderr,"dtb_cvt_image_file_to_pixmap: %s :unable to load %s\n",
522 XtName(widget), fileName);
533 * Sets the XmNlabel from the image file (either xbitmap or xpixmap format).
535 * returns negative on error.
538 dtb_set_label_from_image_file(
543 int rc = 0; /* return code */
544 Pixmap labelPixmap = 0;
545 Pixmap insensitivePixmap = 0;
547 rc = dtb_cvt_image_file_to_pixmap(widget, fileName, &labelPixmap);
551 fprintf(stderr,"dtb_set_label_from_image_file: %s :unable to load %s\n",
552 XtName(widget), fileName);
555 insensitivePixmap = dtb_create_greyed_pixmap(widget,labelPixmap);
556 rc = dtb_set_label_pixmaps(widget, labelPixmap, insensitivePixmap);
563 dtb_cvt_resource_from_string(
566 unsigned int size_of_type,
567 String res_str_value,
568 unsigned long error_value
571 unsigned long cvt_value_return = error_value;
572 unsigned char cvt_value1 = 0;
573 unsigned short cvt_value2 = 0;
574 unsigned int cvt_value3 = 0;
575 unsigned long cvt_value4 = 0;
576 XtPointer cvt_value_ptr = NULL;
577 int which_cvt_value = -1;
581 if (size_of_type > sizeof(cvt_value_return))
583 /* Type we are converting to is too large */
584 return cvt_value_return;
588 * Get a data object of the appropriate size
590 if (size_of_type == sizeof(cvt_value1))
593 cvt_value_ptr = (XtPointer)&cvt_value1;
595 else if (size_of_type == sizeof(cvt_value2))
598 cvt_value_ptr = (XtPointer)&cvt_value2;
600 else if (size_of_type == sizeof(cvt_value3))
603 cvt_value_ptr = (XtPointer)&cvt_value3;
605 else if (size_of_type == sizeof(cvt_value4))
608 cvt_value_ptr = (XtPointer)&cvt_value4;
612 return cvt_value_return;
616 * Actually do the conversion
618 source.size = strlen(res_str_value) + 1;
619 source.addr = res_str_value;
621 dest.size = size_of_type;
622 dest.addr = (char *)cvt_value_ptr;
624 if (XtConvertAndStore(parent, XtRString, &source,
625 res_type, &dest) != 0)
627 switch (which_cvt_value)
630 cvt_value_return = (unsigned long)cvt_value1;
634 cvt_value_return = (unsigned long)cvt_value2;
638 cvt_value_return = (unsigned long)cvt_value3;
642 cvt_value_return = (unsigned long)cvt_value4;
647 return cvt_value_return;
652 * For a given pixmap, create a 50% greyed version. Most likely this will
653 * be used where the source pixmap is the labelPixmap for a widget and an
654 * insensitivePixmap is needed so the widget will look right when it is
655 * "not sensitive" ("greyed out" or "inactive").
657 * NOTE: This routine creates a Pixmap, which is an X server resource. The
658 * created pixmap must be freed by the caller when it is no longer
662 dtb_create_greyed_pixmap(
669 Pixmap insensitive_pixmap;
671 unsigned int width, height, depth, bw;
678 dpy = XtDisplay(widget);
680 if(pixmap == XmUNSPECIFIED_PIXMAP || pixmap == (Pixmap)NULL) {
681 fprintf(stderr,"dtb_create_greyed_pixmap: Invalid source pixmap\n");
682 return((Pixmap)NULL);
685 XtVaGetValues(widget,
686 XmNbackground, &background,
689 /* Get width/height of source pixmap */
690 if (!XGetGeometry(dpy,pixmap,&root,&x,&y,&width,&height,&bw,&depth)) {
691 fprintf(stderr,"dtb_create_greyed_pixmap: Invalid source pixmap\n");
692 return((Pixmap)NULL);
694 gcv.foreground = background;
695 gcv.fill_style = FillStippled;
696 gcv.stipple = XmGetPixmapByDepth(XtScreen(widget),
697 "50_foreground", 1, 0, 1);
698 gcm = GCForeground | GCFillStyle | GCStipple;
699 gc = XtGetGC(widget, gcm, &gcv);
701 /* Create insensitive pixmap */
702 insensitive_pixmap = XCreatePixmap(dpy, pixmap, width, height, depth);
703 XCopyArea(dpy, pixmap, insensitive_pixmap, gc, 0, 0, width, height, 0, 0);
704 XFillRectangle(dpy, insensitive_pixmap, gc, 0, 0, width, height);
706 XtReleaseGC(widget, gc);
707 return(insensitive_pixmap);
712 ** Routines to save and access the toplevel widget for an application.
713 ** This is useful in dtb_ convenience functions, and also probably by
714 ** developers in routines they provide in their _stubs.c files.
715 ** static Widget dtb_project_toplevel_widget = (Widget) NULL;
718 dtb_save_toplevel_widget(
722 dtb_project_toplevel_widget = toplevel;
727 dtb_get_toplevel_widget()
729 return(dtb_project_toplevel_widget);
734 ** Routines to save and access the command used to invoke the application.
741 char exe_dir[MAXPATHLEN+1];
742 dtb_save_command_str = argv0;
745 * Save the path to the executable
747 if (determine_exe_dir(argv0, exe_dir, MAXPATHLEN+1) >= 0)
749 dtb_exe_dir = (char *)malloc(strlen(exe_dir)+1);
750 if (dtb_exe_dir != NULL)
752 strcpy(dtb_exe_dir, exe_dir);
761 return(dtb_save_command_str);
767 ** Generic callback function to be attached as XmNhelpCallback and
768 ** provide support for on-object and Help-key help. The help text to
769 ** be displayed is provided via a specialized data structure passed in
776 XtPointer clientData,
780 DtbObjectHelpData help_data = (DtbObjectHelpData)clientData;
783 char *buffer = new char[100];
785 static Widget Quick_help_dialog = (Widget)NULL;
786 static Widget MoreButton;
789 ** In order to save the more-help info (help volume & location ID) as part
790 ** of the quick help dialog's backtrack mechanism, we have to splice the
791 ** volume & ID strings together and save them as the help volume field.
792 ** If there isn't supplemental help information, we save a null string.
794 ** Checking the status of the more-help info also lets us decide whether
795 ** the "More..." button should be enabled on the dialog.
797 if( help_data->help_volume ==0 || *(help_data->help_volume) == NULL ||
798 help_data->help_locationID ==0 || *(help_data->help_locationID)== NULL){
802 sprintf(buffer,"%s/%s",help_data->help_volume,help_data->help_locationID);
806 ** If this is our first time to post help, create the proper dialog and
807 ** set its attributes to suit the current object. If not, then just
808 ** update the attributes.
810 ** (You have to be careful about gratuitous SetValues on the dialog because
811 ** its internal stack mechanism takes repeated settings as separate items
812 ** and updates the stack for each.)
814 if(Quick_help_dialog == (Widget)NULL) {
815 /* Create shared help dialog */
817 XtSetArg(wargs[i],XmNtitle, "Application Help"); i++;
818 XtSetArg(wargs[i],DtNhelpType, DtHELP_TYPE_DYNAMIC_STRING); i++;
819 XtSetArg(wargs[i],DtNstringData,help_data->help_text); i++;
820 XtSetArg(wargs[i],DtNhelpVolume,buffer); i++;
821 Quick_help_dialog = DtCreateHelpQuickDialog(dtb_get_toplevel_widget(),
825 ** Fetch out the Dialog's More button child and hook the 'more help'
826 ** handler to its activateCallback. Set it's current status to
827 ** indicate whether this object has supplemental help data.
829 MoreButton = DtHelpQuickDialogGetChild(Quick_help_dialog,
830 DtHELP_QUICK_MORE_BUTTON);
831 XtManageChild(MoreButton);
832 XtAddCallback(MoreButton,XmNactivateCallback,dtb_more_help_dispatch,
833 (XtPointer)Quick_help_dialog);
834 if(buffer[0] == '\0') XtSetSensitive(MoreButton,False);
837 ** Fetch out the Dialog's Backtrack button child & hook a callback
838 ** that will control button sensitivity based on the presence of more
841 back_button = DtHelpQuickDialogGetChild(Quick_help_dialog,
842 DtHELP_QUICK_BACK_BUTTON);
843 XtAddCallback(back_button,XmNactivateCallback,dtb_help_back_hdlr,
844 (XtPointer)Quick_help_dialog);
846 /* Otherwise the dialog already exists so we just set the attributes. */
849 ** If we have supplemental help info, enable the more button.
850 ** Also save this info for later use in the backtrack handler.
852 if(buffer[0] == '\0') {
853 XtSetSensitive(MoreButton,False);
856 XtSetSensitive(MoreButton,True);
859 XtVaSetValues(Quick_help_dialog,
860 DtNhelpType, DtHELP_TYPE_DYNAMIC_STRING,
861 DtNhelpVolume,buffer,
862 DtNstringData,help_data->help_text,
866 /* Now display the help dialog */
867 XtManageChild(Quick_help_dialog);
870 #endif /* DEAD_WOOD */
874 ** This callback is invoked when the user presses "More..." on the
875 ** QuickHelpDialog. It figures out whether a help volume entry is associated
876 ** with the displayed help text, and if so it brings up a GeneralHelpDialog
877 ** to display the appropriate help volume information.
880 dtb_more_help_dispatch(
882 XtPointer clientData,
888 String buffer, vol, loc;
890 static Widget GeneralHelpDialog = (Widget) NULL;
891 Widget help_dialog = (Widget)clientData;
893 /* Fetch the saved volume/locationID information from the dialog widget */
894 XtVaGetValues(help_dialog,
895 DtNhelpVolume,&buffer,
899 ** Parse the combined volume/locationID string. If that fails there
900 ** must be no data, so don't bother displaying the GeneralHelpDialog.
901 ** (We shouldn't be in this callback routine if that happens, though...)
903 if( (cp=strrchr(buffer,'/')) != (char *)NULL) {
909 if(GeneralHelpDialog == (Widget)NULL) {
910 /* Create General Help Dialog */
912 XtSetArg(wargs[i],XmNtitle, "Application Help"); i++;
913 XtSetArg(wargs[i],DtNhelpType, DtHELP_TYPE_TOPIC); i++;
914 XtSetArg(wargs[i],DtNhelpVolume, vol); i++;
915 XtSetArg(wargs[i],DtNlocationId,loc); i++;
917 GeneralHelpDialog = DtCreateHelpDialog(dtb_get_toplevel_widget(),
918 "GeneralHelp",wargs,i);
922 XtSetArg(wargs[i],DtNhelpType, DtHELP_TYPE_TOPIC); i++;
923 XtSetArg(wargs[i],DtNhelpVolume,vol); i++;
924 XtSetArg(wargs[i],DtNlocationId,loc); i++;
925 XtSetValues(GeneralHelpDialog,wargs,i);
928 /* Now take down the quick help dialog and display the full help one */
929 XtManageChild(GeneralHelpDialog);
930 XtUnmanageChild(help_dialog);
935 ** Callback that is added to the QuickHelpDialog widget's "Backtrack" button
936 ** and is used to control the "More.." button. At each step in the backtrack,
937 ** this routine checks to see if there is help volume & location info stored
938 ** in the dialog's helpVolume resource. If so, then the "More..." button is
939 ** enabled. If not, then it is disabled.
944 XtPointer clientData,
951 Widget help_dialog = (Widget)clientData;
953 /* Fetch the saved volume/locationID information from the dialog widget */
954 XtVaGetValues(help_dialog,
955 DtNhelpVolume,&buffer,
959 /* Get a handle to the "More..." button */
960 more_button = DtHelpQuickDialogGetChild(help_dialog,
961 DtHELP_QUICK_MORE_BUTTON);
963 ** Parse the combined volume/locationID string. Disable the "More..."
964 ** button if there isn't any help info, and enable it if there is.
966 if( buffer == 0 || (*buffer == '\0') ||
967 (cp=strrchr(buffer,'/')) == (char *)NULL) {
968 XtSetSensitive(more_button,False);
971 XtSetSensitive(more_button,True);
978 ** Utility function used to provide support for on-item help.
979 ** It is typically invoked via a callback on the "On Item" item in the
980 ** main menubar's "Help" menu.
987 /* Call the DtHelp routine that supports interactive on-item help. */
988 if(DtHelpReturnSelectedWidgetId(dtb_get_toplevel_widget(),
989 (Cursor)NULL,&target) != DtHELP_SELECT_VALID) return;
992 ** Starting at the target widget, wander up the widget tree looking
993 ** for one that has an XmNhelpCallback, and call the first one we
996 while(target != (Widget)NULL) {
997 if( XtHasCallbacks(target,XmNhelpCallback) == XtCallbackHasSome) {
998 XtCallCallbacks(target,XmNhelpCallback,(XtPointer)NULL);
1002 target = XtParent(target);
1007 #endif /* DEAD_WOOD */
1011 ** Utility function called to display help volume information.
1012 ** It needs the name of the help volume and the location ID (both as
1013 ** strings) so it can configure the full help dialog widget properly.
1016 dtb_show_help_volume_info(
1023 static Widget GeneralHelpDialog = (Widget) NULL;
1025 if(GeneralHelpDialog == (Widget)NULL) {
1026 /* Create General Help Dialog */
1028 XtSetArg(wargs[i],XmNtitle, "Application Help"); i++;
1029 XtSetArg(wargs[i],DtNhelpType, DtHELP_TYPE_TOPIC); i++;
1030 XtSetArg(wargs[i],DtNhelpVolume, volume_name); i++;
1031 XtSetArg(wargs[i],DtNlocationId,location_id); i++;
1033 GeneralHelpDialog = DtCreateHelpDialog(dtb_get_toplevel_widget(),
1034 "GeneralHelp",wargs,i);
1038 XtSetArg(wargs[i],DtNhelpType, DtHELP_TYPE_TOPIC); i++;
1039 XtSetArg(wargs[i],DtNhelpVolume,volume_name); i++;
1040 XtSetArg(wargs[i],DtNlocationId,location_id); i++;
1041 XtSetValues(GeneralHelpDialog,wargs,i);
1044 /* Now display the full help dialog */
1045 XtManageChild(GeneralHelpDialog);
1053 ** dtb_call_help_callback()
1054 ** Utility routine to call the help callbacks on a target widget. This
1055 ** is predominantly used to display help data on a dialog by having this
1056 ** function as the activate callback on the dialog's help button.
1059 dtb_call_help_callback(
1061 XtPointer clientData,
1065 Widget target = (Widget)clientData;
1067 XtCallCallbacks(target,XmNhelpCallback,(XtPointer)NULL);
1069 #endif /* DEAD_WOOD */
1073 * dtb_session_save()
1074 * Callback that is called when the application (top level
1075 * widget of application) gets a WM_SAVE_YOURSELF ClientMessage
1076 * This callback will call the client/application's session
1091 **client_argv = NULL,
1095 Boolean status = False;
1096 DtbClientSessionSaveCB session_saveCB;
1099 * Return if no widget passed in.
1105 * Get session file path/name to store application's state
1107 if (DtSessionSavePath(widget, &session_file_path, &session_file_name) == False)
1111 * Get client session save callback
1113 session_saveCB = dtb_get_client_session_saveCB();
1116 * Call client session save callback
1120 * client_argv and client_argc are the variables that
1121 * will contain any extra command line options
1122 * that need to be used when invoking the application
1123 * to bring it to the current state.
1125 status = session_saveCB(widget, session_file_path,
1126 &client_argv, &client_argc);
1129 * Generate the reinvoking command and add it as the property value
1133 * Fetch command used to invoke application
1135 app_name = dtb_get_command();
1138 * new_argc and new_argc are the variables used to reconstruct
1139 * the command to re-invoke the application
1143 * Start new_argc with:
1144 * 1 for argv[0], normally the application
1145 * client_argc any extra command line options as
1146 * returned from client session save
1149 new_argc = 1 + client_argc;
1152 * If the status returned from session save callback is 'True',
1153 * the session file was actually used. This means we need to
1155 * -session <session file name>
1156 * to the command saved, which is 2 more strings.
1164 new_argv = (char **)XtMalloc((sizeof(char **) * new_argc));
1167 * Set new_argv[0] to be the application name
1169 new_argc_counter = 0;
1170 new_argv[new_argc_counter] = app_name;
1174 * Proceed to copy every command line option from
1175 * client_argv. Skip -session, if found.
1177 for (i=0; i < client_argc;)
1179 if (strcmp(client_argv[i], "-session"))
1181 new_argv[new_argc_counter] = client_argv[i];
1188 * The next increment below will skip the session file.
1198 * If session file used, add
1199 * -session <session file name>
1203 new_argv[new_argc_counter] = "-session";
1205 new_argv[new_argc_counter] = session_file_name;
1210 * otherwise, destroy session file
1212 (void)unlink(session_file_path);
1216 * Set WM_COMMAND property with vector constructed
1218 XSetCommand(XtDisplay(widget), XtWindow(widget),
1219 new_argv, new_argc);
1222 * Free argument vector
1224 XtFree ((char *)new_argv);
1227 * CDE Sessioning API states that the path/name
1228 * strings have to be free'd by the application.
1230 XtFree ((char *)session_file_path);
1231 XtFree ((char *)session_file_name);
1236 * dtb_get_client_session_saveCB()
1238 DtbClientSessionSaveCB
1239 dtb_get_client_session_saveCB()
1241 return(dtb_client_session_saveCB);
1248 * This function will center all the passed form's children.
1249 * The type of centering depends on what 'type' is.
1252 dtb_children_center(
1254 DTB_CENTERING_TYPES type
1257 WidgetList children_list;
1261 if (!form || (type == DTB_CENTER_NONE))
1268 XmNnumChildren, &num_children,
1269 XmNchildren, &children_list,
1273 * Center all children
1275 for (i=0; i < num_children; ++i)
1277 dtb_center(children_list[i], type);
1283 * This function 'uncenters' the children of the passed
1287 dtb_children_uncenter(
1289 DTB_CENTERING_TYPES type
1292 WidgetList children_list;
1296 if (!form || (type == DTB_CENTER_NONE))
1303 XmNnumChildren, &num_children,
1304 XmNchildren, &children_list,
1308 * Center all children
1310 for (i=0; i < num_children; ++i)
1312 dtb_uncenter(children_list[i], type);
1315 #endif /* DEAD_WOOD */
1319 * This function centers the passed widget.
1320 * This is done by setting the proper offsets.
1321 * Dynamic centering is accomplished by attaching an event handler
1322 * which detect resizes and recomputes and sets the appropriate offset.
1327 DTB_CENTERING_TYPES type
1330 if (!form_child || (type == DTB_CENTER_NONE))
1333 center_widget(form_child, type);
1335 XtAddEventHandler(form_child,
1336 StructureNotifyMask, False,
1337 centering_handler, (XtPointer)type);
1342 * This function 'uncenters' the passed widget.
1343 * This involves resetting the attachment offsets
1344 * and removing the resize event handler.
1349 DTB_CENTERING_TYPES type
1352 if (!form_child || (type == DTB_CENTER_NONE))
1355 uncenter_widget(form_child, type);
1357 XtRemoveEventHandler(form_child,
1358 StructureNotifyMask, False,
1359 centering_handler, (XtPointer)type);
1364 * This function centers the passed widget.
1365 * This is done by making the appropriate offset equal
1366 * to the negative half of it's width/height (depending
1367 * on whether horizontal or vertical centering was chosen.
1372 DTB_CENTERING_TYPES type
1376 Dimension width = 0,
1379 unsigned char left_attach = XmATTACH_NONE,
1380 top_attach = XmATTACH_NONE;
1382 if (!form_child || !XtIsManaged(form_child) || !XtIsRealized(form_child))
1385 parent = XtParent(form_child);
1387 if (!parent || !XtIsSubclass(parent, xmFormWidgetClass))
1390 XtVaGetValues(form_child,
1393 XmNleftAttachment, &left_attach,
1394 XmNtopAttachment, &top_attach,
1398 case DTB_CENTER_POSITION_VERT:
1400 if (left_attach != XmATTACH_POSITION)
1403 center_offset = -(width/2);
1405 XtVaSetValues(form_child,
1406 XmNleftOffset, center_offset,
1411 case DTB_CENTER_POSITION_HORIZ:
1413 if (top_attach != XmATTACH_POSITION)
1416 center_offset = -(height/2);
1418 XtVaSetValues(form_child,
1419 XmNtopOffset, center_offset,
1423 case DTB_CENTER_POSITION_BOTH:
1428 if ((left_attach != XmATTACH_POSITION) &&
1429 (top_attach != XmATTACH_POSITION))
1432 left_offset = -(width/2);
1433 top_offset = -(height/2);
1435 XtVaSetValues(form_child,
1436 XmNleftOffset, left_offset,
1437 XmNtopOffset, top_offset,
1449 * This function 'uncenters' the passed widget.
1450 * It merely resets the offsets of the top/left attachments to 0.
1455 DTB_CENTERING_TYPES type
1459 unsigned char left_attach = XmATTACH_NONE,
1460 top_attach = XmATTACH_NONE;
1462 if (!form_child || !XtIsManaged(form_child) || !XtIsRealized(form_child))
1465 parent = XtParent(form_child);
1467 if (!parent || !XtIsSubclass(parent, xmFormWidgetClass))
1470 XtVaGetValues(form_child,
1471 XmNleftAttachment, &left_attach,
1472 XmNtopAttachment, &top_attach,
1476 case DTB_CENTER_POSITION_VERT:
1478 if (left_attach != XmATTACH_POSITION)
1481 XtVaSetValues(form_child,
1487 case DTB_CENTER_POSITION_HORIZ:
1489 if (top_attach != XmATTACH_POSITION)
1492 XtVaSetValues(form_child,
1497 case DTB_CENTER_POSITION_BOTH:
1499 if ((left_attach != XmATTACH_POSITION) &&
1500 (top_attach != XmATTACH_POSITION))
1503 XtVaSetValues(form_child,
1516 * Event handler to center a widget
1517 * The type of centering needed is passed in as client_data
1522 XtPointer client_data,
1527 XConfigureEvent *xcon = &event->xconfigure;
1528 Widget resized_child;
1529 DTB_CENTERING_TYPES type = (DTB_CENTERING_TYPES)((long)client_data);
1532 if ((event->type != ConfigureNotify) && (event->type != MapNotify))
1535 resized_child = XtWindowToWidget(XtDisplay(widget), xcon->window);
1540 center_widget(resized_child, type);
1545 * Given a widget, return it's label widget.
1552 WidgetList children_list;
1553 Widget label_widget = NULL;
1554 int num_children = 0;
1555 char *subobj_name = NULL,
1558 if (XtIsSubclass(widget, xmLabelWidgetClass)) {
1562 subobj_name = XtName(widget);
1563 label_name = (char *)XtMalloc(1 + strlen(subobj_name) + strlen("_label") + 1);
1564 sprintf(label_name, "*%s_label", subobj_name);
1566 label_widget = XtNameToWidget(widget, label_name);
1568 XtFree((char *)label_name);
1571 return(label_widget);
1574 * How to look for 1st child of group object ??
1575 * How do we know if 'widget' is a group object ??
1576 * For now, just check if it is a form
1578 if (XtIsSubclass(widget, xmFormWidgetClass) ||
1579 XtIsSubclass(widget, xmFrameWidgetClass))
1580 XtVaGetValues(widget,
1581 XmNnumChildren, &num_children,
1582 XmNchildren, &children_list,
1585 if (num_children > 0)
1586 return(get_label_widget(children_list[0]));
1593 get_offset_from_ancestor(
1599 Widget cur_parent = NULL;
1600 Position offset = 0;
1602 if (!ancestor || !w || (w == ancestor))
1605 XtVaGetValues(cur, XmNx, &offset, NULL);
1607 cur_parent = XtParent(cur);
1609 while (cur_parent != ancestor)
1611 Position tmp_offset = 0;
1614 XtVaGetValues(cur, XmNx, &tmp_offset, NULL);
1616 offset += tmp_offset;
1617 cur_parent = XtParent(cur);
1629 Widget lbl_widget = NULL;
1630 Dimension lbl_width = 0;
1632 lbl_widget = get_label_widget(widget);
1636 Position offset = 0;
1638 XtVaGetValues(lbl_widget,
1639 XmNwidth, &lbl_width,
1642 offset = get_offset_from_ancestor(widget, lbl_widget);
1644 lbl_width += (Dimension)offset;
1655 Widget *child_widget,
1656 Dimension *label_width
1659 Widget cur_widest = NULL;
1660 Dimension cur_width = 0;
1663 for (i = 0; i < count; ++i)
1667 tmp = get_label_width(list[i]);
1669 if (tmp > cur_width)
1672 cur_widest = list[i];
1676 *child_widget = cur_widest;
1677 *label_width = cur_width;
1685 Widget *child_widget,
1686 Dimension *value_width
1689 Widget cur_widest = NULL;
1690 Dimension cur_width = 0;
1693 for (i = 0; i < count; ++i)
1695 Dimension tmp, label_width, obj_width = 0;
1697 label_width = get_label_width(list[i]);
1698 XtVaGetValues(list[i], XmNwidth, &obj_width, NULL);
1700 tmp = obj_width - label_width;
1702 if (tmp > cur_width)
1705 cur_widest = list[i];
1709 *child_widget = cur_widest;
1710 *value_width = cur_width;
1723 XtVaGetValues(widget,
1724 XtNwidth, (XtArgVal)&(rect->width),
1725 XtNheight, (XtArgVal)&(rect->height),
1726 XtNx, (XtArgVal)&(rect->x),
1727 XtNy, (XtArgVal)&(rect->y),
1744 int previous_width, previous_height;
1746 if (!list || (count < 0))
1749 get_widget_rect(list[0], &w_rect);
1751 *width = w_rect.width;
1752 previous_width = *width;
1754 *height = w_rect.height;
1755 previous_height = *height;
1757 if (tallest != NULL)
1763 for (i=0; i < count; i++)
1765 get_widget_rect(list[i], &w_rect);
1767 *width = max((int) w_rect.width, (int) *width);
1768 if (widest != NULL && *width > previous_width)
1771 *height = max((int) w_rect.height, (int)*height);
1772 if (tallest != NULL && *height > previous_height)
1779 get_group_cell_size(
1786 WidgetList children_list = NULL;
1787 int num_children = 0;
1792 XtVaGetValues(parent,
1793 XmNnumChildren, &num_children,
1794 XmNchildren, &children_list,
1797 get_greatest_size(children_list, num_children,
1798 cell_width, cell_height,
1799 (Widget *)NULL, (Widget *)NULL);
1806 DtbGroupInfo *group_info,
1811 WidgetList children_list = NULL;
1816 if (!parent || !group_info)
1826 XtVaGetValues(parent,
1827 XmNnumChildren, &num_children,
1828 XmNchildren, &children_list,
1831 num_rows = group_info->num_rows;
1832 num_cols = group_info->num_cols;
1834 if ((num_rows <= 0) && (num_cols <= 0))
1842 num_cols = (num_children/num_rows) + ((num_children % num_rows) ? 1 : 0);
1845 num_rows = (num_children/num_cols) + ((num_children % num_cols) ? 1 : 0);
1855 DtbGroupInfo *group_info,
1860 DTB_GROUP_TYPES group_type;
1861 WidgetList children_list = NULL;
1862 Widget ret_child = NULL;
1863 int num_children = 0,
1868 if (!parent || !group_info ||
1869 (x_pos < 0) || (y_pos < 0))
1872 group_type = group_info->group_type;
1873 num_rows = group_info->num_rows;
1874 num_columns = group_info->num_cols;
1877 * Get number of children
1879 XtVaGetValues(parent,
1880 XmNnumChildren, &num_children,
1881 XmNchildren, &children_list,
1884 if (num_children <= 0)
1889 case DTB_GROUP_NONE:
1892 case DTB_GROUP_ROWS:
1900 case DTB_GROUP_COLUMNS:
1908 case DTB_GROUP_ROWSCOLUMNS:
1909 if (!num_rows && !num_columns)
1917 if (y_pos < num_rows)
1918 i = (x_pos * num_rows) + y_pos;
1925 if (x_pos < num_columns)
1926 i = x_pos + (y_pos * num_columns);
1934 if ((i >= 0) && (i < num_children))
1936 ret_child = children_list[i];
1946 DTB_GROUP_TYPES group_type,
1947 DTB_ALIGN_TYPES row_align,
1948 DTB_ALIGN_TYPES col_align,
1956 DtbGroupInfo *group_info;
1960 case DTB_GROUP_COLUMNS:
1965 case DTB_GROUP_ROWS:
1972 #ifdef DTB_GROUP_USERDATA
1973 XtVaGetValues(parent, XmNuserData, (XtPointer)&group_info, NULL);
1977 XtRemoveEventHandler(parent,
1978 SubstructureNotifyMask, False,
1979 align_handler, (XtPointer)group_info);
1981 XtRemoveCallback(parent, XtNdestroyCallback,
1982 free_group_info, (XtPointer)group_info);
1984 XtFree((char *)group_info);
1988 group_info = (DtbGroupInfo *)XtMalloc(sizeof(DtbGroupInfo));
1990 group_info->group_type = group_type;
1991 group_info->row_align = row_align;
1992 group_info->col_align = col_align;
1993 group_info->margin = margin;
1994 group_info->num_rows = num_rows;
1995 group_info->num_cols = num_cols;
1996 group_info->hoffset = hoffset;
1997 group_info->voffset = voffset;
1998 group_info->ref_widget = NULL;
2000 #ifdef DTB_GROUP_USERDATA
2001 XtVaSetValues(parent, XmNuserData, (XtPointer)group_info, NULL);
2004 align_children(parent, group_info, True);
2006 switch(group_info->group_type)
2008 case DTB_GROUP_NONE:
2011 case DTB_GROUP_ROWS:
2012 if (group_info->row_align == DTB_ALIGN_HCENTER)
2013 XtAddEventHandler(parent,
2014 SubstructureNotifyMask, False,
2015 align_handler, (XtPointer)group_info);
2018 case DTB_GROUP_COLUMNS:
2019 if ((group_info->col_align == DTB_ALIGN_LABELS) ||
2020 (group_info->col_align == DTB_ALIGN_VCENTER))
2021 XtAddEventHandler(parent,
2022 SubstructureNotifyMask, False,
2023 align_handler, (XtPointer)group_info);
2026 case DTB_GROUP_ROWSCOLUMNS:
2027 if ((group_info->row_align == DTB_ALIGN_HCENTER) ||
2028 (group_info->col_align == DTB_ALIGN_LABELS) ||
2029 (group_info->col_align == DTB_ALIGN_VCENTER))
2030 XtAddEventHandler(parent,
2031 SubstructureNotifyMask, False,
2032 align_handler, (XtPointer)group_info);
2037 XtAddCallback(parent, XtNdestroyCallback,
2038 free_group_info, (XtPointer)group_info);
2045 DtbGroupInfo *group_info,
2049 WidgetList children_list = NULL;
2050 int num_children = 0;
2052 if (!parent || !group_info)
2055 if (group_info->group_type != DTB_GROUP_NONE)
2057 XtVaGetValues(parent,
2058 XmNnumChildren, &num_children,
2059 XmNchildren, &children_list,
2062 XtUnmanageChildren(children_list, num_children);
2065 switch(group_info->group_type)
2067 case DTB_GROUP_NONE:
2070 case DTB_GROUP_ROWS:
2071 align_rows(parent, group_info, init);
2072 align_left(parent, group_info);
2075 case DTB_GROUP_COLUMNS:
2076 align_cols(parent, group_info, init);
2077 align_top(parent, group_info);
2080 case DTB_GROUP_ROWSCOLUMNS:
2081 align_rows(parent, group_info, init);
2082 align_cols(parent, group_info, init);
2087 if (group_info->group_type != DTB_GROUP_NONE)
2089 XtManageChildren(children_list, num_children);
2097 XtPointer client_data,
2102 DtbGroupInfo *group_info = (DtbGroupInfo *)client_data;
2103 WidgetList children_list;
2104 int num_children = 0;
2105 Boolean relayout_all = False;
2111 XtVaGetValues(widget,
2112 XmNnumChildren, &num_children,
2113 XmNchildren, &children_list,
2116 if (num_children <= 0)
2119 XtRemoveEventHandler(widget,
2120 SubstructureNotifyMask, False,
2121 align_handler, (XtPointer)client_data);
2123 if (event->type == ConfigureNotify) {
2124 XConfigureEvent *xcon = &event->xconfigure;
2125 Widget resized_child;
2127 if (xcon->window != xcon->event)
2129 resized_child = XtWindowToWidget(XtDisplay(widget), xcon->window);
2131 switch(group_info->group_type)
2133 case DTB_GROUP_NONE:
2136 case DTB_GROUP_ROWS:
2137 if (group_info->row_align == DTB_ALIGN_HCENTER)
2138 relayout_all = True;
2141 case DTB_GROUP_COLUMNS:
2142 if ((group_info->col_align == DTB_ALIGN_LABELS) ||
2143 (group_info->col_align == DTB_ALIGN_VCENTER))
2144 relayout_all = True;
2147 case DTB_GROUP_ROWSCOLUMNS:
2148 if ((group_info->row_align == DTB_ALIGN_HCENTER) ||
2149 (group_info->col_align == DTB_ALIGN_LABELS) ||
2150 (group_info->col_align == DTB_ALIGN_VCENTER))
2151 relayout_all = True;
2159 * Comment out for now
2160 * This is causing way too many calls to align_children()
2161 if (event->type == CreateNotify) {
2162 XCreateWindowEvent *xcreate = &event->xcreatewindow;
2165 new_child = XtWindowToWidget(XtDisplay(widget), xcreate->window);
2167 fprintf(stderr, "align_handler(%s) - child %s created\n",
2172 relayout_all = True;
2176 if (event->type == DestroyNotify) {
2177 XDestroyWindowEvent *xdestroy = &event->xdestroywindow;
2178 Widget destroyed_child;
2180 destroyed_child = XtWindowToWidget(XtDisplay(widget),
2183 relayout_all = True;
2188 align_children(widget, group_info, False);
2191 XtAddEventHandler(widget,
2192 SubstructureNotifyMask, False,
2193 align_handler, (XtPointer)client_data);
2200 XtPointer client_data,
2204 DtbGroupInfo *group_info = (DtbGroupInfo *)client_data;;
2206 XtFree((char *)group_info);
2213 DtbGroupInfo *group_info,
2217 if (!parent || !group_info || (group_info->group_type == DTB_GROUP_COLUMNS))
2220 switch (group_info->row_align)
2223 align_top(parent, group_info);
2226 case DTB_ALIGN_HCENTER:
2227 align_hcenter(parent, group_info, init);
2230 case DTB_ALIGN_BOTTOM:
2231 align_bottom(parent, group_info);
2243 DtbGroupInfo *group_info,
2247 if (!parent || !group_info || (group_info->group_type == DTB_GROUP_ROWS))
2250 switch (group_info->col_align)
2252 case DTB_ALIGN_LEFT:
2253 align_left(parent, group_info);
2256 case DTB_ALIGN_LABELS:
2257 align_labels(parent, group_info);
2260 case DTB_ALIGN_VCENTER:
2261 align_vcenter(parent, group_info, init);
2264 case DTB_ALIGN_RIGHT:
2265 align_right(parent, group_info);
2277 DtbGroupInfo *group_info
2280 WidgetList children_list;
2283 int num_children = 0,
2291 if (!parent || !group_info)
2297 XtVaGetValues(parent,
2298 XmNnumChildren, &num_children,
2299 XmNchildren, &children_list,
2302 if (num_children <= 0)
2305 get_group_cell_size(parent, group_info, &cell_width, &cell_height);
2306 get_group_row_col(parent, group_info, &num_rows, &num_columns);
2308 for (j = 0; j < num_rows; j++)
2310 for (i = 0; i < num_columns; i++)
2315 child = get_group_child(parent, group_info, i, j);
2320 if ((i == 0) && (j == 0))
2322 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
2323 XtSetArg(args[n], XmNleftOffset, 0); n++;
2324 XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++;
2326 XtSetValues(child, args, n);
2333 int offset = group_info->hoffset;
2334 DTB_GROUP_TYPES group_type = group_info->group_type;
2336 previous_child = get_group_child(parent, group_info, i-1, j);
2338 if (!previous_child)
2341 if (group_type == DTB_GROUP_ROWSCOLUMNS)
2343 Dimension width = 0;
2345 XtVaGetValues(previous_child, XmNwidth, &width, NULL);
2346 offset += (cell_width - (int)(width));
2349 XtSetArg(args[n], XmNleftAttachment,
2350 XmATTACH_WIDGET); n++;
2351 XtSetArg(args[n], XmNleftWidget, previous_child); n++;
2352 XtSetArg(args[n], XmNleftOffset, offset); n++;
2353 XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++;
2355 XtSetValues(child, args, n);
2360 previous_child = get_group_child(parent, group_info, i, j-1);
2364 XtSetArg(args[n], XmNleftAttachment,
2365 XmATTACH_OPPOSITE_WIDGET); n++;
2366 XtSetArg(args[n], XmNleftWidget, previous_child); n++;
2367 XtSetArg(args[n], XmNleftOffset, 0); n++;
2368 XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++;
2370 XtSetValues(child, args, n);
2380 DtbGroupInfo *group_info
2383 WidgetList children_list;
2386 int num_children = 0,
2395 if (!parent || !group_info)
2401 XtVaGetValues(parent,
2402 XmNnumChildren, &num_children,
2403 XmNchildren, &children_list,
2406 if (num_children <= 0)
2409 get_group_cell_size(parent, group_info, &cell_width, &cell_height);
2410 get_group_row_col(parent, group_info, &num_rows, &num_columns);
2412 for (j = 0; j < num_rows; j++)
2414 for (i = 0; i < num_columns; i++)
2419 child = get_group_child(parent, group_info, i, j);
2424 if ((i == 0) && (j == 0))
2426 Dimension width = 0;
2428 XtVaGetValues(child, XmNwidth, &width, NULL);
2430 offset = (cell_width - width);
2432 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
2433 XtSetArg(args[n], XmNleftOffset, offset); n++;
2434 XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++;
2436 XtSetValues(child, args, n);
2443 previous_child = get_group_child(parent, group_info, i-1, j);
2445 if (!previous_child)
2448 offset = group_info->hoffset;
2450 if (group_info->group_type == DTB_GROUP_ROWSCOLUMNS)
2452 Dimension width = 0;
2454 XtVaGetValues(child, XmNwidth, &width, NULL);
2455 offset += (cell_width - width);
2458 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
2459 XtSetArg(args[n], XmNleftWidget, previous_child); n++;
2460 XtSetArg(args[n], XmNleftOffset, offset); n++;
2461 XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++;
2463 XtSetValues(child, args, n);
2468 previous_child = get_group_child(parent, group_info, i, j-1);
2472 XtSetArg(args[n], XmNrightAttachment,
2473 XmATTACH_OPPOSITE_WIDGET); n++;
2474 XtSetArg(args[n], XmNrightWidget, previous_child); n++;
2475 XtSetArg(args[n], XmNrightOffset, 0); n++;
2476 XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++;
2478 XtSetValues(child, args, n);
2488 DtbGroupInfo *group_info
2491 WidgetList children_list = NULL,
2493 Widget previous_child = NULL,
2495 previous_ref_widget = NULL;
2496 Dimension ref_lbl_width = 0,
2497 max_label_width = 0,
2498 max_value_width = 0;
2499 int num_children = 0,
2508 if (!parent || !group_info)
2514 XtVaGetValues(parent,
2515 XmNnumChildren, &num_children,
2516 XmNchildren, &children_list,
2519 if (num_children <= 0)
2522 get_group_cell_size(parent, group_info, &cell_width, &cell_height);
2524 get_widest_label(children_list, num_children, &child, &max_label_width);
2525 get_widest_value(children_list, num_children, &child, &max_value_width);
2527 if (cell_width < (int)(max_label_width + max_value_width))
2528 cell_width = (int)(max_label_width + max_value_width);
2530 get_group_row_col(parent, group_info, &num_rows, &num_columns);
2533 one_col = (WidgetList)XtMalloc(num_rows * sizeof(WidgetList));
2535 for (i = 0; i < num_columns; i++)
2538 Dimension ref_width;
2542 for (j = 0; j < num_rows; j++)
2543 one_col[j] = get_group_child(parent, group_info, i, j);
2545 get_widest_label(one_col, num_rows, &ref_widget, &ref_width);
2550 if (previous_ref_widget)
2551 offset = (i * (group_info->hoffset + cell_width));
2555 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
2556 XtSetArg(args[n], XmNleftOffset, offset); n++;
2557 XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++;
2559 XtSetValues(ref_widget, args, n);
2561 for (j = 0; j < num_rows; j++)
2563 child = get_group_child(parent, group_info, i, j);
2565 if (!child || (child == ref_widget))
2568 offset = (i * (group_info->hoffset + cell_width));
2569 offset += (int)(ref_width - get_label_width(child));
2572 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
2573 XtSetArg(args[n], XmNleftOffset, offset); n++;
2574 XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++;
2576 XtSetValues(child, args, n);
2579 previous_ref_widget = ref_widget;
2587 DtbGroupInfo *group_info,
2591 WidgetList children_list;
2593 DTB_GROUP_TYPES group_type;
2594 int num_children = 0,
2605 if (!parent || !group_info)
2611 XtVaGetValues(parent,
2612 XmNnumChildren, &num_children,
2613 XmNchildren, &children_list,
2616 if (num_children <= 0)
2619 get_group_cell_size(parent, group_info, &cell_width, &cell_height);
2621 get_group_row_col(parent, group_info, &num_rows, &num_columns);
2623 offset = group_info->hoffset;
2625 group_type = group_info->group_type;
2627 if (group_type == DTB_GROUP_ROWSCOLUMNS)
2629 group_width = (num_columns * cell_width) + ((num_columns-1) * offset);
2632 for (i = 0; i < num_columns; i++)
2634 if (group_type == DTB_GROUP_ROWSCOLUMNS)
2635 gridline = (((i * (cell_width + offset)) + (cell_width/2)) * 100)/group_width;
2639 for (j = 0; j < num_rows; j++)
2643 Dimension width = 0;
2645 child = get_group_child(parent, group_info, i, j);
2650 XtVaGetValues(child, XmNwidth, &width, NULL);
2656 if (!XtIsSubclass(child, compositeWidgetClass))
2658 offset = (cell_width - (int)width)/2;
2660 if (group_type == DTB_GROUP_ROWSCOLUMNS)
2661 offset += (i * (cell_width + group_info->hoffset));
2664 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
2665 XtSetArg(args[n], XmNleftOffset, offset); n++;
2666 XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++;
2670 XtSetArg(args[n], XmNleftAttachment,
2671 XmATTACH_POSITION); n++;
2672 XtSetArg(args[n], XmNleftPosition, gridline); n++;
2673 XtSetArg(args[n], XmNleftOffset, (int)(-(width/2))); n++;
2674 XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++;
2677 XtSetValues(child, args, n);
2686 DtbGroupInfo *group_info
2689 WidgetList children_list;
2690 Widget previous_child = NULL,
2692 int num_children = 0,
2700 if (!parent || !group_info)
2706 XtVaGetValues(parent,
2707 XmNnumChildren, &num_children,
2708 XmNchildren, &children_list,
2711 if (num_children <= 0)
2714 get_group_cell_size(parent, group_info, &cell_width, &cell_height);
2715 get_group_row_col(parent, group_info, &num_rows, &num_columns);
2717 for (j = 0; j < num_rows; j++)
2719 for (i = 0; i < num_columns; i++)
2724 child = get_group_child(parent, group_info, i, j);
2729 if ((i == 0) && (j == 0))
2731 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
2732 XtSetArg(args[n], XmNtopOffset, 0); n++;
2733 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
2735 XtSetValues(child, args, n);
2742 previous_child = get_group_child(parent, group_info, 0, j-1);
2746 DTB_GROUP_TYPES group_type = group_info->group_type;
2747 int offset = group_info->voffset;
2749 if (group_type == DTB_GROUP_ROWSCOLUMNS)
2751 Dimension height = 0;
2753 XtVaGetValues(previous_child, XmNheight, &height, NULL);
2755 offset += (cell_height - (int)(height));
2758 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
2759 XtSetArg(args[n], XmNtopWidget, previous_child); n++;
2760 XtSetArg(args[n], XmNtopOffset, offset); n++;
2761 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
2763 XtSetValues(child, args, n);
2768 previous_child = get_group_child(parent, group_info, i-1, j);
2772 XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
2773 XtSetArg(args[n], XmNtopWidget, previous_child); n++;
2774 XtSetArg(args[n], XmNtopOffset, 0); n++;
2775 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
2777 XtSetValues(child, args, n);
2788 DtbGroupInfo *group_info
2791 WidgetList children_list;
2794 int num_children = 0,
2803 if (!parent || !group_info)
2809 XtVaGetValues(parent,
2810 XmNnumChildren, &num_children,
2811 XmNchildren, &children_list,
2814 if (num_children <= 0)
2817 get_group_cell_size(parent, group_info, &cell_width, &cell_height);
2818 get_group_row_col(parent, group_info, &num_rows, &num_columns);
2820 for (j = 0; j < num_rows; j++)
2822 for (i = 0; i < num_columns; i++)
2827 child = get_group_child(parent, group_info, i, j);
2832 if ((i == 0) && (j == 0))
2834 Dimension height = 0;
2836 XtVaGetValues(child, XmNheight, &height, NULL);
2838 offset = cell_height - height;
2840 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
2841 XtSetArg(args[n], XmNtopOffset, offset); n++;
2842 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
2844 XtSetValues(child, args, n);
2851 previous_child = get_group_child(parent, group_info, 0, j-1);
2855 Dimension height = 0;
2857 XtVaGetValues(child, XmNheight, &height, NULL);
2859 offset = group_info->voffset;
2861 if (group_info->group_type == DTB_GROUP_ROWSCOLUMNS)
2862 offset += (cell_height - height);
2864 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
2865 XtSetArg(args[n], XmNtopWidget, previous_child); n++;
2866 XtSetArg(args[n], XmNtopOffset, offset); n++;
2867 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
2869 XtSetValues(child, args, n);
2874 previous_child = get_group_child(parent, group_info, i-1, j);
2876 if (child && previous_child)
2878 XtSetArg(args[n], XmNbottomAttachment,
2879 XmATTACH_OPPOSITE_WIDGET); n++;
2880 XtSetArg(args[n], XmNbottomWidget, previous_child); n++;
2881 XtSetArg(args[n], XmNbottomOffset, 0); n++;
2882 XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++;
2884 XtSetValues(child, args, n);
2894 DtbGroupInfo *group_info,
2898 WidgetList children_list = NULL;
2900 DTB_GROUP_TYPES group_type;
2901 int num_children = 0,
2912 if (!parent || !group_info)
2918 XtVaGetValues(parent,
2919 XmNnumChildren, &num_children,
2920 XmNchildren, &children_list,
2923 if (num_children <= 0)
2926 group_type = group_info->group_type;
2928 get_group_cell_size(parent, group_info, &cell_width, &cell_height);
2929 get_group_row_col(parent, group_info, &num_rows, &num_columns);
2931 offset = group_info->voffset;
2933 if (group_type == DTB_GROUP_ROWSCOLUMNS)
2935 group_height = (num_rows * cell_height) + ((num_rows-1) * offset);
2938 for (j = 0; j < num_rows; j++)
2940 if (group_type == DTB_GROUP_ROWSCOLUMNS)
2942 (((j * (cell_height + offset)) + (cell_height/2)) * 100)/group_height;
2946 for (i = 0; i < num_columns; i++)
2950 Dimension height = 0;
2952 child = get_group_child(parent, group_info, i, j);
2957 XtVaGetValues(child, XmNheight, &height, NULL);
2961 int init_offset = 0;
2963 if (!XtIsSubclass(child, compositeWidgetClass))
2965 init_offset = (cell_height - (int)height)/2;
2967 if (group_type == DTB_GROUP_ROWSCOLUMNS)
2968 init_offset += (j * (cell_height + group_info->voffset));
2971 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
2972 XtSetArg(args[n], XmNtopOffset, init_offset); n++;
2973 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
2977 XtSetArg(args[n], XmNtopAttachment,
2978 XmATTACH_POSITION); n++;
2979 XtSetArg(args[n], XmNtopPosition, gridline); n++;
2980 XtSetArg(args[n], XmNtopOffset, (int)(-(height/2))); n++;
2981 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
2984 XtSetValues(child, args, n);
2991 * Returns the directory that the executable for this process was loaded
2995 dtb_get_exe_dir(void)
3002 * Determines the directory the executable for this process was loaded from.
3011 Boolean foundDir= False;
3013 if ((buf == NULL) || (bufSize < 1))
3018 if (determine_exe_dir_from_argv(argv0, buf, bufSize) >= 0)
3025 if (determine_exe_dir_from_path(argv0, buf, bufSize) >= 0)
3032 * Convert relative path to absolute, so that directory changes will
3035 if (foundDir && (buf[0] != '/'))
3037 char cwd[MAXPATHLEN+1];
3038 char *env_pwd = NULL;
3039 char *path_prefix = NULL;
3041 if (getcwd(cwd, MAXPATHLEN+1) != NULL)
3047 env_pwd = getenv("PWD");
3048 if (env_pwd != NULL)
3050 path_prefix = env_pwd;
3054 if (path_prefix != NULL)
3056 char *abs_exe_dir = new char[MAXPATHLEN+1];
3057 if (strcmp(buf, ".") != 0) {
3058 snprintf(abs_exe_dir, MAXPATHLEN+1, "%s/%s", path_prefix, buf);
3060 snprintf(abs_exe_dir, MAXPATHLEN+1, "%s", path_prefix);
3062 strcpy(buf, abs_exe_dir);
3063 delete [] abs_exe_dir;
3067 return foundDir? 0:-1;
3072 * Looks for absolute path in arv[0].
3075 determine_exe_dir_from_argv(
3082 Boolean foundit= False;
3084 for (i= strlen(argv0)-1; (i >= 0) && (argv0[i] != '/'); --i)
3090 int maxStringSize= min(i, bufSize);
3091 strncpy(buf, argv0, maxStringSize);
3092 buf[min(maxStringSize, bufSize-1)]= 0;
3096 return foundit? 0:-1;
3101 * Assumes: bufSize > 0
3104 determine_exe_dir_from_path (
3110 Boolean foundDir= False;
3111 Boolean moreDirs= True;
3112 char *szExeName= argv0;
3113 int iExeNameLen= strlen(szExeName);
3115 char *szPathVar = new char[MAXPATHLEN+1];
3117 char *szCurrentPath = new char[MAXPATHLEN+1];
3118 int iCurrentPathLen= 0;
3119 int iCurrentPathStart= 0;
3121 uid_t euid= geteuid();
3122 uid_t egid= getegid();
3124 szTemp= getenv("PATH");
3131 strncpy(szPathVar, szTemp, MAXPATHLEN);
3132 szPathVar[MAXPATHLEN]= 0;
3133 iPathVarLen= strlen(szPathVar);
3136 while ((!foundDir) && (moreDirs))
3138 /* find the current directory name */
3139 for (i= iCurrentPathStart; (i < iPathVarLen) && (szPathVar[i] != ':');
3144 iCurrentPathLen= i - iCurrentPathStart;
3145 if ((iCurrentPathLen + iExeNameLen + 2) > MAXPATHLEN)
3147 iCurrentPathLen= MAXPATHLEN - (iExeNameLen + 2);
3150 /* create a possible path to the executable */
3151 strncpy(szCurrentPath, &szPathVar[iCurrentPathStart], iCurrentPathLen);
3152 szCurrentPath[iCurrentPathLen]= 0;
3153 strcat(szCurrentPath, "/");
3154 strcat(szCurrentPath, szExeName);
3156 /* see if the executable exists (and we can execute it) */
3157 if (path_is_executable(szCurrentPath, euid, egid))
3162 /* skip past the current directory name */
3165 iCurrentPathStart+= iCurrentPathLen;
3166 while ( (iCurrentPathStart < iPathVarLen)
3167 && (szPathVar[iCurrentPathStart] != ':') )
3169 ++iCurrentPathStart; /* find : */
3171 if (iCurrentPathStart < iPathVarLen)
3173 ++iCurrentPathStart; /* skip : */
3175 if (iCurrentPathStart >= iPathVarLen)
3180 } /* while !foundDir */
3184 szCurrentPath[iCurrentPathLen]= 0;
3185 strncpy(buf, szCurrentPath, bufSize);
3188 delete [] szPathVar;
3189 delete [] szCurrentPath;
3190 return foundDir? 0:-1;
3195 * returns False is path does not exist or is not executable
3204 Boolean bExecutable= False;
3207 if (stat(path, &sStat) == 0)
3209 Boolean bDetermined= False;
3213 if (!S_ISREG(sStat.st_mode))
3215 /* not a regular file */
3224 && ( ((sStat.st_mode & S_IXOTH) != 0)
3225 || ((sStat.st_mode & S_IXGRP) != 0)
3226 || ((sStat.st_mode & S_IXUSR) != 0) )
3236 if ( (((sStat.st_mode & S_IXOTH) != 0) )
3237 || (((sStat.st_mode & S_IXGRP) != 0) && (sStat.st_gid == egid))
3238 || (((sStat.st_mode & S_IXUSR) != 0) && (sStat.st_gid == euid))