1 /****************************************************************************
2 ** FILE: callbacks.c
3 **
4 ** xbmbrowser is Public Domain. However it, and all the code still belong to me.
5 ** I do, however grant permission for you to freely copy and distribute it on
6 ** the condition that this and all other copyright notices remain unchanged in
7 ** all distributions.
8 **
9 ** This software comes with NO warranty whatsoever. I therefore take no
10 ** responsibility for any damages, losses or problems that the program may
11 ** cause.
12 **                                     Anthony Thyssen and Ashley Roll
13 *****************************************************************************
14 */
15 
16 #include "xbmbrowser.h"
17 
18 void
set_name(widget,event)19 set_name(widget, event)
20 /* This function is added to the notify callback on all the
21 ** menuButtons so that the global 'bitmap_info' contains the most
22 ** reciently selected bitmap information line. This is then used
23 ** in  popup_user_menu() when a menu is requested to set the other
24 ** information about the file the pointed to widget represents.
25 */
26   Widget   widget;
27   XEvent  *event;
28 {
29   current_item = (Item *)GetInfoPtr( widget );
30   XtVaSetValues( label, XtNlabel, (XtPointer)current_item->info, NULL );
31 }
32 
33 
34 void
set_label(widget,event)35 set_label(widget, event)
36 /* As the pointer leaves a window -- set the label widget to point to
37 ** file counts and/or some error string stored in the label_info string.
38 */
39   Widget    widget;
40   XEvent   *event;
41 {
42   XtVaSetValues(label, XtNlabel, (XtArgVal)label_info, NULL);
43   /* current_item = NULL; */
44 }
45 
46 
47 void
rescan(widget,client_data,call_data)48 rescan(widget, client_data, call_data )
49 /* User pressed the rescan button -- so do it
50 ** NOTE: no arguments used
51 */
52   Widget    widget;
53   XtPointer client_data, call_data;
54 {
55   set_busywait();
56   rescan_images();
57   clear_busywait();
58 }
59 
60 
61 void
scan(widget,client_data,call_data)62 scan(widget, client_data, call_data )
63 /* User pressed the scan button -- so do it
64 ** NOTE: no arguments used
65 */
66   Widget    widget;
67   XtPointer client_data, call_data;
68 {
69   set_busywait();
70   scan_images();
71   clear_busywait();
72 }
73 
74 
75 void
dir_return(widget,event)76 dir_return(widget, event)
77 /* Event:- User pressed return in directory widget.
78 ** Try to change directory to the dirwidget contents
79 ** NOTE: Arguments not used.
80 */
81   Widget     widget;
82   XEvent    *event;
83 {
84   set_busywait();
85   change_dir( XawDialogGetValueString(dirwidget) );
86   clear_busywait();
87 }
88 
89 
90 void
dir_menu(widget,client_data,call_data)91 dir_menu(widget, client_data, call_data )
92 /* User selected a directory from the directory menu.
93 ** Try to change dir to item selected by the user.
94 ** NOTE: List widget call back data required.
95 */
96   Widget    widget;
97   XtPointer client_data, call_data;
98 {
99   XawListReturnStruct *dir = (XawListReturnStruct *)call_data;
100 
101   set_busywait();
102   change_dir( dir->string );
103   clear_busywait();
104 }
105 
106 
107 void
pos_dir(widget,event)108 pos_dir(widget, event)
109 /* Event:- User is tring to popup directory menu.
110 ** This procedure positions the menu under the cursour
111 */
112   Widget        widget;
113   XButtonEvent *event;
114 {
115   Position w;
116 
117   XtVaGetValues(dirmenu, XtNwidth, &w, NULL);
118   XtVaSetValues(dirmenu, XtNx, event->x_root - w/2,
119                          XtNy, event->y_root, NULL);
120 }
121 
122 
123 void
toggle_option(widget,client_data,call_data)124 toggle_option(widget, client_data, call_data )
125 /* toggle the options in the options menu.
126 ** NOTE: the client data is a pointer to the Boolean value which
127 ** is to be toggled.
128 */
129   Widget     widget;
130   XtPointer  client_data, call_data;
131 {
132   Boolean *value = client_data;
133 
134   set_busywait();
135 
136   *value = !*value;  /* toggle the user option */
137   XtVaSetValues(widget, XtNleftBitmap, *value ? tickon : tickoff, NULL);
138 
139   if ( value == &app_data.solid_bgnd )
140     set_stipple();             /* Add or remove the stipple pattern */
141 
142   if (   value == &app_data.shape_syms
143       || value == &app_data.solid_bgnd )
144     redisplay_images(False);   /* Display style change -- FAST (dont unmap) */
145   else
146   if (   value == &app_data.label_all
147       || value == &app_data.label_icons
148       || value == &app_data.label_syms )
149     redisplay_images(True);    /* Display style change -- FAST (with unmap) */
150   else
151   if ( value == &app_data.recursive )
152     rescan_images();           /* Rescan directory and merge in changes */
153   else
154   /* if ( vaule == &app_data.show_{...} ) */
155     reassign_images();         /* just reassign -- dont re-read directory */
156 
157   clear_busywait();
158 }
159 
160 
161 void
popup_user_menu(widget,event)162 popup_user_menu(widget, event)
163 /* Initialize the substitution variables, figure out which menu is
164 ** to be popped up, and if required popup the user defined menu.
165 ** or other action required by the situation.
166 **
167 ** NOTE: This routine must be registered with XtRegisterGrabAction()
168 ** for it to work properly. See final note on the MenuButton widget
169 ** in the Xaw Interface Guide.     --- Anthony Thyssen   2 May 1994
170 */
171   Widget        widget;
172   XButtonEvent  *event;  /* this may client data */
173 {
174   Widget         popup_menu = NULL;   /* menu to position and popup */
175 
176   /* Assume that no item has been selected */
177   file_name[0] = '\0';
178   base_name[0] = '\0';
179   suffix[0]    = '\0';
180 
181   if ( widget == mainmenu ) {
182     /* User pushed the main menu button */
183     popup_menu = menu_main;
184   }
185   else if ( widget == iconbox && (event->subwindow == None) ) {
186     /* Button press inside the icon box itself (NOT a icon)
187     ** NOTE: the test for subwindow insurse that we really are in the
188     ** iconbox window and not a sub-window of iconbox EG: a dispayed icon
189     ** or symbol. This is needed because XtRegisterGrabAction() is searched
190     ** from the top down and not the bottom up.
191     */
192     popup_menu = menu_global;
193   }
194   else if ( current_item != NULL ) {
195     /* OK button press was within a displayed icon or symbol
196     ** So grab the file name being represented by that widget
197     */
198     strcpy(file_name, current_item->fname );
199 
200     switch( event->button ) {
201     case Button1:
202       if ( IsDirItem(current_item) ) {
203         /* CD into the directory selected */
204 	set_busywait();
205 	change_dir(file_name);   /* WARNING: change_dir() modifies string */
206 	clear_busywait();        /*          do not pass item->fname direct */
207 	return;          /* done -- don't continue */
208       } /* fall through if NOT a directory */
209     case Button2:
210       /* popup global menu */
211       popup_menu = menu_global;
212       break;
213     case Button3:
214     case Button4:
215     case Button5:
216       /* popup appropiate menu for the file type */
217       switch( current_item->type ) {
218       case Xbm:     popup_menu = menu_bitmap;    break;
219       case Xpm:
220       case XpmBad:  popup_menu = menu_pixmap;    break;
221       case Dir:
222       case DirUp:
223       case DirLink:
224       case DirBad:  popup_menu = menu_directory; break;
225       default:      popup_menu = menu_other;     break;
226       }
227     }
228   }
229 
230   /* Menu Determined -- Do the popup */
231   if( popup_menu != NULL ) {
232     char      *s;    /* where the suffix starts in file_name */
233 
234     /* now complete the substitution list if file_name set */
235     if ( file_name[0] != '\0' ) {
236       /* extract the basename and suffix of the filename */
237       s = rindex(file_name, '.');   /* find split point */
238       if ( s == file_name || s == NULL ) {
239 	/* The suffix is the whole filename OR non-existant */
240 	strcpy(base_name, file_name);  /* base_name = file_name */
241 	suffix[0] = '\0';              /* suffix = "" */
242       } else {
243 	/* A valid split point was found -- split file_name */
244 	int len = s - file_name;
245 	strncpy(base_name, file_name,  len );  /* base_name is upto suffix */
246 	base_name[len] = '\0';
247 	strcpy(suffix, s);                   /* suffix (includes `.') */
248       }
249     }
250 
251     /* width is invalid unless realised -- so do so */
252     XtRealizeWidget(popup_menu);
253 
254     /* position the menu as appropriate */
255     if ( XtIsSubclass( widget, commandWidgetClass ) ) {
256       /* Position under the button pushed -- no event given */
257       Position    x, y, h;
258       XtVaGetValues(widget, XtNheight, &h, NULL);
259       XtTranslateCoords(widget, 0, h+2, &x, &y );
260       XtVaSetValues(popup_menu, XtNx, x, XtNy, y, NULL);
261     }
262     else {
263       /* Position relative to the users pointer */
264       Dimension   w;    /* width of this menu */
265       XtVaGetValues(popup_menu, XtNwidth, &w, NULL); /* get width */
266       XtVaSetValues(popup_menu, XtNx, event->x_root - w/2,
267 				XtNy, event->y_root, NULL);
268     }
269     /* OK now popup the menu -- and let user-menu take it from here */
270     XtPopupSpringLoaded(popup_menu);
271 
272   } else {
273     /* no menu found -- beep user */
274     XBell( event->display, 0 );
275   }
276 }
277 
278