1 /*****************************************************************************
2  ** File          : iconman.c                                               **
3  ** Purpose       : Icon Application Manager                                **
4  ** Author        : Lionel Mallet                                           **
5  ** Date          : 12th Feb 1992                                           **
6  ** Documentation : Xedw Design Folder                                      **
7  ** Related Files : parse.c dirman.c                                        **
8  *****************************************************************************/
9 
10 #include "xdtm.h"
11 #include "parse.h"
12 #include "menus.h" /* Get current_mode definition */
13 
14 #include <stdio.h>
15 
16 #include "Xedw/XedwList.h"
17 #include <X11/Xaw/SimpleMenu.h>
18 #include <X11/Xaw/SmeBSB.h>
19 #include <X11/Xaw/SmeLine.h>
20 #define CHAR sizeof(char)
21 
22 #ifdef HAS_STRSTR
23 #define mystrstr(cs, ct)	strstr(cs, ct)
24 #else
25 extern char *mystrstr(char *, char *);
26 #endif
27 
28 /* external and forward functions definitions */
29 #if NeedFunctionPrototypes
30   public String build_args(String);
31   public Widget createIconMenu(AppProgram **, Cardinal);
32   extern int execute(String, String, String, Boolean, AppProgram *);
33   public void ExecuteIconProgram(Widget, AppProgram*, XtPointer);
34   extern String getfilename(String);
35   public void PopMenu(Widget, XButtonEvent*);
36   extern void selection_made(Widget, caddr_t, caddr_t);
37   extern void setCursor(Cursor);
38 #else
39   public String build_args();
40   public Widget createIconMenu();
41   extern int execute();
42   public void ExecuteIconProgram();
43   extern String getfilename();
44   public void PopMenu();
45   extern void selection_made();
46   extern void setCursor();
47 #endif
48 
49 extern XdtmList **icon_list;   /* List with icons and/or filenames */
50 
51 /*****************************************************************************
52  *                              build_args                                   *
53  *****************************************************************************/
54 #if NeedFunctionPrototypes
build_args(String program)55 public String build_args(String program)
56 #else
57 public String build_args(program)
58      String program;
59 #endif
60 {
61   /* Given the program with it's previous arguments, this procedure
62    * will insert the highlighted file into the place specified by
63    * the %[d|b|f] or on the end if none found.
64    *       %d refers to the current working directory
65    *       %b refers to the basename of the highlighted file
66    *       %e refers to the extension of the highlighted file or NULL.
67    *       %n refers to the name of the highlighted file (%b.%e).
68    *       %f refers to the fullname of the highlighted file (%d[/]%n).
69    *
70    * - Takes the program string.
71    * + Returns the resultant command line.
72    */
73 
74     extern Widget directoryManager;
75     extern String cwd;
76     XedwListReturnStruct *list;
77     Cardinal i = 0;
78     String name, basename, fullname, extension, mark = "%", ext_sep = ".";
79     String tmpl = program, ptr, pos, cmd = XtCalloc(1, sizeof(char));
80 
81     /* Get the list */
82     list = XedwListShowCurrent(directoryManager);
83 
84     /* Build fullname, basename and extension from path and name */
85     name = getfilename(list->string);
86     basename = XtNewString(name);
87     if ((strcmp(basename, ".") == 0) || (strcmp(basename, "..") == 0)) {
88 	/* current dir or dot dot dir */
89 	extension = XtNewString("");
90     } else if (basename[0] == '.')  { /* file starting with dot,
91 					 basename = name,
92 					 extension = next_occurence_of_dot */
93 	String basewithoutdot = &basename[1]; /* jump over dot in basename */
94 	extension = mystrstr(basewithoutdot, ext_sep);
95 	if (extension) {
96 	    extension++;
97 	    basewithoutdot = strtok(basewithoutdot, ext_sep);
98 	} else extension = XtNewString("");
99     }
100     else {
101 	extension = mystrstr(basename, ext_sep);
102 	if (extension) {
103 	    extension++;
104 	    basename = strtok(basename, ext_sep);
105 	} else extension = XtNewString("");
106     }
107 
108     fullname = XtMalloc(CHAR * (strlen(name) + strlen(cwd) + 2));
109     strcpy(fullname, cwd);
110     if (cwd[strlen(cwd) - 1] != '/') strcat(fullname, "/");
111     strcat(fullname, name);
112 
113     while ((pos = mystrstr(tmpl, mark)))
114     {
115 	cmd = XtRealloc(cmd, (pos - tmpl) + CHAR * (i + 1));
116 
117 	for (ptr = tmpl; ptr < pos; ptr++) cmd[i++] = *ptr;
118 	cmd[i] = 0;
119 	pos++;
120 	switch (*pos)
121 	{
122 	case 'd':
123 	    cmd = XtRealloc(cmd, CHAR * (strlen(cmd) + strlen(cwd) + 1));
124 	    strcat(cmd, cwd); break;
125 	case 'b':
126 	    cmd = XtRealloc(cmd, CHAR * (strlen(cmd) + strlen(basename) + 1));
127 	    strcat(cmd, basename); break;
128 	case 'e':
129 	    cmd = XtRealloc(cmd, CHAR * (strlen(cmd) + strlen(extension) + 1));
130 	    strcat(cmd, extension); break;
131 	case 'n':
132 	    cmd = XtRealloc(cmd, CHAR * (strlen(cmd) + strlen(name) + 1));
133 	    strcat(cmd, name); break;
134 	case 'f':
135 	    cmd = XtRealloc(cmd, CHAR * (strlen(cmd) + strlen(fullname) + 1));
136 	    strcat(cmd, fullname); break;
137 	default:
138 	    printf("Wrong argument list in cmd!\n");
139 	}
140 	i = strlen(cmd);
141 	pos++;
142 	tmpl = pos;
143     }
144     if (strlen(tmpl)) {
145 	cmd = XtRealloc(cmd, CHAR * (strlen(cmd) + strlen(tmpl) + 1));
146 	strcat(cmd, tmpl);
147     }
148 
149     XtFree(basename);
150     XtFree(fullname);
151     XedwListFreeCurrent(list);
152     return(cmd);
153 }
154 
155 /*****************************************************************************
156  *                              ExecuteIconProgram                           *
157  *****************************************************************************/
158 #if NeedFunctionPrototypes
ExecuteIconProgram(Widget w,AppProgram * prog,XtPointer call_data)159 public void ExecuteIconProgram(Widget w, AppProgram *prog,
160 			       XtPointer call_data)
161 #else
162 public void ExecuteIconProgram(w, prog, call_data)
163      Widget w;
164      AppProgram *prog;
165      XtPointer call_data;
166 #endif
167 {
168   /* Callback: when an item of the object menu is selected, builds the
169    * command to execute with the template associated to the item, and
170    * executes the command.
171    */
172 
173     extern Cursor busy;
174     String pgm, cmd, tmpl = XtNewString(prog->program);
175 
176     setCursor(busy);
177     cmd = build_args(tmpl);
178     pgm = XtNewString(cmd);
179     pgm = strtok(pgm, " ");
180 
181     if (pgm) execute(NULL, pgm, cmd, False, prog);
182     setCursor(NULL);
183     XtFree(cmd);
184     XtFree(pgm);
185     XtFree(tmpl);
186 }
187 
188 
189 /*****************************************************************************
190  *                              createIconMenu                               *
191  *****************************************************************************/
192 #if NeedFunctionPrototypes
createIconMenu(AppProgram * proglist[],Cardinal number)193 public Widget createIconMenu(AppProgram *proglist[], Cardinal number)
194 #else
195 public Widget createIconMenu(proglist, number)
196      AppProgram *proglist[];
197      Cardinal number;
198 #endif
199 {
200   /* Given a list of AppProgram stucture pointers, this procedure
201    * creates the menu and the menu panes.
202    *
203    * + Return the menu created.
204    */
205 
206     extern Widget directoryManager;
207     Widget menu;
208     Widget menuEntry;
209     Cardinal i = 0, n;
210     Arg arglist[3];
211 
212     XtSetArg(arglist[i], XtNlabel, "Menu");i++;
213     menu = XtCreatePopupShell("iconMenu", simpleMenuWidgetClass,
214 			      directoryManager, arglist, i);
215 
216     for (n=0; n < number; n++) {
217 	if (!proglist[n]) { /* a separator line */
218 	    menuEntry = XtCreateManagedWidget("line", smeLineObjectClass,
219 					      menu, NULL, 0);
220 	} else {
221 	    String label = proglist[n]->string;
222 
223 	    i = 0;
224 	    XtSetArg(arglist[i], XtNlabel, label); i++;
225 	    menuEntry = XtCreateManagedWidget(label, smeBSBObjectClass,
226 					      menu, arglist, i);
227 
228 	    XtAddCallback(menuEntry, XtNcallback,
229 			  (XtCallbackProc)ExecuteIconProgram,
230 			  (XtPointer) proglist[n]);
231 	}
232     }
233     return(menu);
234 }
235 
236 /*****************************************************************************
237  *                              PopMenu                                      *
238  *****************************************************************************/
239 #if NeedFunctionPrototypes
PopMenu(Widget w,XButtonEvent * event)240 public void PopMenu(Widget w, XButtonEvent *event)
241 #else
242 public void PopMenu(w, event)
243      Widget w;
244      XButtonEvent *event;
245 #endif
246 {
247   /* Given the directoryManager and the X Event that triggered the action,
248    * selects the current object and pops the menu under mouse cursor.
249    */
250 
251     XedwListReturnStruct *list;
252     iconOps *ops;
253     Widget menu;
254 
255     if (current_mode.mode == Short) return; /* No menus in Short mode */
256 
257     selection_made(w, (caddr_t)0, (caddr_t)0);
258     /* Get the list */
259     list = XedwListShowCurrent(w);
260     if (list->xedwList_index != XDTM_LIST_NONE) {
261 	ops = (iconOps *)(icon_list[list->xedwList_index]->user_data);
262 
263 	if (ops && (menu = ops->menu)) {
264 	    int menu_x, menu_y;
265 	    Dimension menu_width, menu_height;
266 
267 	    XtVaGetValues(menu, XtNwidth, &menu_width,
268 			        XtNheight, &menu_height, NULL);
269 
270 	    if ((menu_x = event->x_root) >= 0)
271 	    {
272 		int scr_width = WidthOfScreen(XtScreen(menu));
273 		if (menu_x + menu_width > scr_width)
274 		  menu_x = scr_width - menu_width;
275 	    }
276 
277 	    if ((menu_y = event->y_root) >= 0)
278 	    {
279 		int scr_height = HeightOfScreen(XtScreen(menu));
280 		if (menu_y + menu_height > scr_height)
281 		  menu_y = scr_height - menu_height;
282 	    }
283 	    XtVaSetValues(menu, XtNx, (Position)menu_x,
284 			        XtNy, (Position)menu_y, NULL);
285 	    XGrabButton( XtDisplay(w), AnyButton, AnyModifier, XtWindow(w),
286 			TRUE, ButtonPressMask|ButtonReleaseMask,
287 			GrabModeAsync, GrabModeAsync, None, None );
288 	    XtPopupSpringLoaded(menu);
289 	}
290     }
291     XedwListFreeCurrent(list);
292 }
293 
294 
295 
296 
297 
298