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