1 /********************************************************************\
2 **                             _________________________________    **
3 **   A n t h o n y            |________    __    __    _________|   **
4 **                                     |  |o_|  |o_|  |             **
5 **           T h y s s e n           __|   __    __   |__           **
6 **                                __|   __|  |  |  |__   |__        **
7 **  `` Dragon Computing! ''    __|   __|     |  |     |__   |__     **
8 **                            |_____|        |__|        |_____|    **
9 **                                                                  **
10 \********************************************************************/
11 /*
12 ** user_functs.c
13 **
14 **   Some of the Application proceedures to perform the actions required
15 ** to control this application.  These routines are called by button presses
16 ** and other user input functions in the ``callbacks.c'' module, and by
17 ** a `user defined menu' calling functions declared in ``user-menu.c''
18 ** and implemented below.
19 **
20 ** NOTE: the busywait routines MUST not be called by any of these routines.
21 ** This is handled by the callback routines and the user menu handler.
22 */
23 #include "xbmbrowser.h"
24 #include <pwd.h>
25 
26 void
quit_browser()27 quit_browser()
28 /* Quit the application...
29 ** The server de-allocates all pixmaps, colors, and widgets so just exit
30 ** NOTE: This routine could be called directly, as a callback or as an event!
31 */
32 {
33   exit(0);
34 }
35 
36 
expand_tilder(text)37 void expand_tilder(text)                /* expand in-situ in twiddle */
38 /*
39 ** Expand Tilder
40 ** This was provided by   Chris McDonald   chris@budgie.cs.uwa.edu.au
41 ** and has been modified to use fast string library functions.
42 **
43 ** NOTE: home_dir was set to   (char *) getenv("HOME")  in main()
44 */
45   char *text;
46 {
47   static char buf[MAXNAMLEN];
48   char *s, *t, *t1;
49   struct passwd *p, *getpwnam();
50 
51   s = text;
52   while ( *s == ' ' || *s == '\t' ) s++;  /* skip any leading space */
53   if ( *s != '~' ) return;                /* if not a tilde -- return */
54 
55   /* expand the tilde */
56   s++;                                    /* skip leading twiddle */
57   t = buf;                                /* copy ~.../ into buf */
58   while (*s && *s != '/') *t++ = *s++;
59   *t = '\0';
60   if(*buf && (p = getpwnam(buf)) == '\0') /* find correct home */
61      return;                                 /* error -- return */
62   t1 = *buf ? p->pw_dir : home_dir;
63   t = buf;
64   strcpy(t, t1);                          /* buf <- home_dir */
65   strcat(t, s);                           /* copy rest of text into buf */
66 
67   strcpy(text, buf);                      /* copy it back and return it */
68 }
69 
70 
71 void
change_dir(dir)72 change_dir(dir)
73 /* Change the current directory to the directory given
74 ** Return false if we failed to enter sub-directory.
75 */
76   char *dir;
77 {
78   char     newdir[1028];
79 
80   strcpy(newdir, dir);     /* save the given variable into a buffer */
81   expand_tilder(newdir);   /* if a ~ string expand the tilde */
82 
83   /* change the current directory to the new directory */
84   if( chdir(newdir) == 0 ) {  /* if success */
85 
86     /* get the full path of the new directory */
87     (void) getcwd(newdir, MAXNAMLEN);
88     if( strcmp(newdir,"/") != 0 )
89       (void) strncat(newdir, "/", MAXNAMLEN);
90 
91     /* did we actually change directory */
92     if( strcmp(dir_name, newdir) != 0 ) {
93       strcpy(dir_name, newdir);          /* set the dir_name */
94       if( app_data.recursive )           /* Reset resursive option */
95         toggle_option(recur_opt, &app_data.recursive, NULL); /* fake it */
96       scan_images();                     /* complete scan of icon images */
97     }
98   }
99 
100   /* Set or Reset the dialog widget to the correct directory path */
101   XtVaSetValues(dirwidget, XtNvalue, (XtArgVal)dir_name, NULL );
102   XtVaSetValues(XtNameToWidget(dirwidget, "value"),
103                    XtNinsertPosition, (XtArgVal)strlen(dir_name), NULL);
104 }
105 
106 
107 void
exec_string(command)108 exec_string(command)
109 /* Given a command to execute -- execute it! */
110   char *command;
111 {
112   system(command);
113 }
114 
115 
116 /* ------------------------------------------------------------------------- */
117 /* The following is the code to provide user dialog control
118 ** For this to work the  input()  and  confirm()  routines
119 ** must be declared as input routines to the user-menu module.
120 */
121 #define PARENT  mainpw  /* the main (composite) widget of application */
122 #define AT_X    50      /* relative position to this window for popup */
123 #define AT_Y    110
124 
125 /* the dialog widget is created if and when needed */
126 static Widget   user_popup  = (Widget) NULL;
127 static Widget   user_dialog = (Widget) NULL;
128 static Boolean  user_input  = FALSE;  /* user input field in dialog? */
129 
130 static void     user_ok();
131 static XtActionsRec  ok_actions[] = {
132 /* action_name    routine */
133   { "Ok",         user_ok }     /* OK button on dialogs */
134 };
135 
136 static char ok_trans[] =
137   "<Key>Return:  Ok() \n\
138    Ctrl<Key>M:   Ok() ";
139 
140 
141 static void
user_ok(widget,client_data,call_data)142 user_ok(widget, client_data, call_data )
143 /* OK button pressed on the user input dialog.
144 ** If any input set copy it into the input string and
145 ** tell the user_menu module to continue the function sequence
146 */
147   Widget    widget;
148   XtPointer client_data, call_data;
149 {
150   if ( user_input ) {
151     strncpy(input, XawDialogGetValueString(user_dialog), MAXNAMLEN);
152     input[MAXNAMLEN-1] = '\0';  /* just in case */
153   }
154 
155   /* expand string is first non-space char is a ~ */
156   expand_tilder(input);   /* if a ~ string expand the tilde */
157 
158   XtPopdown(user_popup);
159 
160   /* Now Continue the function sequence of this user menu item (if any) */
161   menu_item_continue();
162 }
163 
164 
165 static void
user_cancel(widget,client_data,call_data)166 user_cancel(widget, client_data, call_data )
167 /* Cancel button pressed on the user input dialog.
168 ** Tell user-menu module to abort the current function sequence.
169 */
170   Widget    widget;
171   XtPointer client_data, call_data;
172 {
173   XtPopdown(user_popup);
174   menu_item_abort();
175 }
176 
177 
178 static void
setup_dialog(prompt,value)179 setup_dialog(prompt, value)
180 /* Create and position the user input/confirm dialog popup
181 ** as required for the current user function.
182 */
183   char *prompt, *value;
184 {
185   Position x, y;
186   Dimension  w;
187 
188   /* where to place the widget,  AT_X/Y are constants in xbmbrowser.h */
189   XtTranslateCoords(PARENT, AT_X, AT_Y, &x, &y);
190 
191   /* If dialog not created -- build it */
192   if ( user_popup == NULL ) {
193     /* figure out its start width */
194     XtVaGetValues(PARENT, XtNwidth, &w, NULL);
195     w -= 2 * AT_X;              /* its correct start width */
196     w = ( w < 150 ) ? 150 : w;  /* minimum width */
197     w = ( w > 600 ) ? 600 : w;  /* maximum width */
198 
199     user_popup = XtVaCreatePopupShell(
200 		   "user_popup", transientShellWidgetClass, PARENT,
201 		   XtNx,     (XtArgVal)x,
202                    XtNy,     (XtArgVal)y,
203                    XtNwidth, (XtArgVal)w, NULL);
204     user_dialog = XtVaCreateManagedWidget(
205 		   "user_dialog", dialogWidgetClass, user_popup,
206 		   XtNvalue, (XtArgVal)"", /* insure text widget created */
207                    XtNwidth, (XtArgVal)w, NULL);
208     XawDialogAddButton(user_dialog, "Ok",     user_ok,     NULL);
209     XawDialogAddButton(user_dialog, "Cancel", user_cancel, NULL);
210     XtAppAddActions(XtWidgetToApplicationContext(PARENT),
211                    ok_actions, XtNumber(ok_actions) );
212   }
213   else {
214     /* dialog already defined so just position it - again */
215     XtVaSetValues(user_popup,  XtNx,     (XtArgVal)x,
216                                XtNy,     (XtArgVal)y, NULL);
217   }
218 
219   /* initialize the initial value of widget */
220   XtVaSetValues(user_dialog,
221              XtNlabel, (XtArgVal)prompt,   /* set the dialog label */
222              XtNvalue, (XtArgVal)value,    /* set the text widget */
223              NULL);
224 
225   /* reset the width of the input text widget */
226   if ( value != NULL ) {
227     XtVaGetValues(user_dialog, XtNwidth, (XtArgVal *)&w, NULL);
228     XtVaSetValues(XtNameToWidget(user_dialog, "value"),
229                                XtNwidth, (XtArgVal)w, NULL);
230 
231     /* KLUDGE :- this widget seems to lose its translations if
232     ** the dialog is used for a confirm action since we last used it
233     */
234     XtOverrideTranslations(XtNameToWidget(user_dialog, "value"),
235     				   XtParseTranslationTable(ok_trans));
236   }
237 }
238 
239 
240 void
user_confirm(prompt)241 user_confirm(prompt)
242 /* Ask the user to confirm the action given.
243 ** This routine is called from the user-menu module as a input
244 ** function. user-menu is expected to stop the current function
245 ** sequence until the user confirms or aborts the sequence.
246 */
247   char *prompt;
248 {
249   user_input = FALSE;                   /* no input substition on return */
250   setup_dialog(prompt, NULL);           /* setup the dialog widget */
251   XtPopup(user_popup,XtGrabExclusive);  /* pop up the confirm dialog */
252 
253   /* return (user-menu moudle will return to application loop) */
254 }
255 
256 
257 void
input_string(prompt,initial)258 input_string(prompt, initial)
259 /* Prompt the user for some input and store it into the input string
260 ** This routine is called from the user-menu module as a input
261 ** function. user-menu is expected to stop the current function
262 ** sequence until the user confirms or aborts the sequence.
263 */
264   char *prompt, *initial;
265 {
266   user_input = TRUE;                    /* do set input substition string */
267   setup_dialog(prompt, initial);        /* setup the dialog widget */
268   XtPopup(user_popup,XtGrabExclusive);  /* pop up the confirm dialog */
269 
270   /* return (user-menu moudle will return to application loop) */
271 }
272 
273 
274 void
file_selected()275 file_selected()
276 /* Check that a file was selected when this menu itme was called.
277 ** If no item selected (IE: the filename %f item is an empty string)
278 ** Then abort the sequence and popup a dialog. It doesn't matter
279 ** if the user selects the OK button as the current menu item sequence
280 ** will have already been aborted.
281 */
282 {
283   /* Was a file selected when calling this function sequence */
284   if ( file_name[0] == '\0' ) {
285 
286     /* Notify the user of abort */
287     user_input = FALSE;                   /* no input substition on return */
288     setup_dialog( "ABORT -- No File Selected -- ABORT", NULL);
289     XtPopup(user_popup,XtGrabExclusive);  /* pop up the confirm dialog */
290 
291     /* Abort the sequence in user_menu */
292     menu_item_abort();
293   }
294 
295   /* return (user-menu moudle will continue or abort as required) */
296 }
297 
298 
299