2 * this file is part of the "wmtrash" project
3 * Copyright (C) 2004 by Jean Philippe GUILLEMIN <jp.guillemin@free.fr>
4 * license: This software is under GPL license
21 // Start main *******************************************************************
23 int main( int argc
, char *argv
[] ) {
25 // Here we parse command line args and configfile *******************************************************************
27 static char *defaultcf
;
28 static char *configfile
;
31 homecf
= malloc(MEDIUM_STRING
);
32 configfile
= malloc(MEDIUM_STRING
);
34 defaultcf
= malloc(MEDIUM_STRING
);
35 strncpy(defaultcf
, __CONFPATH
, MEDIUM_STRING
);
36 strcat(defaultcf
, "/");
37 strcat(defaultcf
, __CONFFILE
);
39 homedir
= malloc(SHORT_STRING
);
40 homedir
= getenv("HOME");
42 strncpy(homecf
, homedir
, SHORT_STRING
);
44 strcat(homecf
, ".wmtrash.cf");
47 if ((test1
= access(homecf
, F_OK
)) == -1){
48 if ((test2
= fcopy(defaultcf
, homecf
)) == EXIT_FAILURE
){
49 fprintf (stderr
,"Error creating config file %s !\n",homecf
);
58 while ((i
= getopt(argc
, argv
, "hc:")) != EOF
){
60 case 'c': /* config file */
61 strncpy(configfile
, optarg
, MEDIUM_STRING
);
63 case 'h': usage(homecf
, defaultcf
); exit (EXIT_SUCCESS
);
69 gtk_init(&argc
, &argv
);
70 dockapp
= (GtkWidget
*) build_dockapp(configfile
);
71 gtk_widget_show_all (dockapp
);
77 GtkWidget
* build_dockapp(char *configfile
) {
78 static GtkWidget
*mainwin
;
79 static GtkWidget
*mainbox
;
80 static GtkWidget
*box
;
81 static GtkWidget
*pixmap
;
82 static GdkBitmap
*mask
;
83 static GtkWidget
*pixmap_widget
;
85 static struct wmtrash
*wmtrash
;
86 wmtrash
= malloc(sizeof(struct wmtrash
));
87 memset(wmtrash
, 0, sizeof(struct wmtrash
));
90 char *image_path_file
;
92 strncpy (wmtrash
->param_img
, "trashicon", MEDIUM_STRING
);
93 strncpy (wmtrash
->param_fm
, "filemanager", MEDIUM_STRING
);
94 strncpy (wmtrash
->param_path
, "trashpath", MEDIUM_STRING
);
95 strncpy (wmtrash
->configfile
, configfile
, MEDIUM_STRING
);
97 image_path_file
= malloc(LONG_STRING
);
99 parse_from_config(wmtrash
->configfile
, wmtrash
->param_img
, wmtrash
->imagefile
);
100 sprintf(image_path_file
, "%s/%s", __ICONPATH
, wmtrash
->imagefile
);
101 parse_from_config(wmtrash
->configfile
, wmtrash
->param_fm
, wmtrash
->fm
);
102 parse_from_config(wmtrash
->configfile
, wmtrash
->param_path
, wmtrash
->path
);
104 // GTK stuff *******************************************************************
105 gtk_widget_destroy(mainwin
);
106 mainwin
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
107 gtk_widget_realize(mainwin
);
108 mainbox
= create_main_dockapp_icon_window(mainwin
, 52);
110 box
= gtk_event_box_new();
111 pixmap
= (gpointer
) gdk_pixmap_create_from_xpm (mainwin
->window
, &mask
,
112 NULL
, image_path_file
);
113 pixmap_widget
= gtk_pixmap_new((gpointer
) pixmap
, mask
);
114 gtk_container_add(GTK_CONTAINER(box
), pixmap_widget
);
117 gtk_container_add (GTK_CONTAINER (mainbox
), box
);
119 gtk_signal_connect (GTK_OBJECT(box
), "button_press_event", GTK_SIGNAL_FUNC(launchonclick
), wmtrash
);
121 free(image_path_file
);
126 // Function create_main_dockapp_icon_window (c) 2000, Alexey Vyskubov <alexey@pepper.spb.ru>
128 GtkWidget
*create_main_dockapp_icon_window
132 GtkWidget
*dockappbox
; // This will become icon box
136 xmw
= GDK_WINDOW_XWINDOW(mw
->window
);
138 dockappbox
= gtk_event_box_new();
139 gtk_widget_set_usize(dockappbox
, s
, s
);
140 gtk_container_add (GTK_CONTAINER (mw
), dockappbox
);
141 gtk_widget_realize(dockappbox
);
143 // Time for game with Xlib
144 wm_hints
= XAllocWMHints();
145 wm_hints
->window_group
= xmw
;
146 wm_hints
->icon_window
= GDK_WINDOW_XWINDOW(dockappbox
->window
);
147 wm_hints
->icon_x
= 0;
148 wm_hints
->icon_y
= 0;
149 wm_hints
->initial_state
= WithdrawnState
;
150 wm_hints
->flags
= StateHint
|
155 XSetWMHints(GDK_DISPLAY(), xmw
, wm_hints
);
160 } // end create_main_dockapp_icon_window
163 /* the function to execute command when left button is clicked *************************************
164 or change the command and pixmap icon when right button is 2-clicked */
167 (GtkWidget
*event_box
,
168 GdkEventButton
*event
,
169 struct wmtrash
*data
)
172 cmd
=malloc(BIG_STRING
);
173 memset(cmd
, 0, BIG_STRING
);
175 /* left button of mouse is clicked */
176 if(event
->button
== 1){
177 strcat (cmd
, data
->fm
);
179 strcat (cmd
, data
->path
);
181 //fprintf(stderr, cmd); //debug
182 int output
= system(cmd
);
184 fprintf(stderr
, "error launching command in function \"launchonclick\"\n");
188 if((event
->button
== 3)&&(event
->type
== GDK_2BUTTON_PRESS
)) {
189 strcat (cmd
, "rm -rf");
191 strcat (cmd
, data
->path
);
193 strcat (cmd
, data
->path
);
195 //fprintf(stderr, cmd); //debug
196 int output
= system(cmd
);
198 fprintf(stderr
, "error launching command in function \"launchonclick\"\n");
203 /* right button of mouse is 2-clicked */
204 if((event
->button
== 2)&&(event
->type
== GDK_2BUTTON_PRESS
)){
206 /* create a new text entry window for entering the new command */
207 GtkWidget
*dialog
, *table
, *vbox
;
208 GtkWidget
*entry1
, *entry2
, *button
;
210 dialog
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
211 gtk_window_set_title (GTK_WINDOW (dialog
), "Change command & pixmap");
212 gtk_container_set_border_width (GTK_CONTAINER (dialog
), 5);
215 table
= gtk_table_new(2,2, TRUE
);
216 gtk_table_set_col_spacings(GTK_TABLE (table
), 5);
217 gtk_table_set_row_spacings(GTK_TABLE (table
), 5);
219 vbox
= gtk_vbox_new (FALSE
, 0);
221 // entry box parameters
222 entry1
= gtk_entry_new ();
223 entry2
= gtk_entry_new ();
224 gtk_entry_set_max_length (GTK_ENTRY (entry1
), 120);
225 gtk_entry_set_max_length (GTK_ENTRY (entry2
), 120);
227 gtk_signal_connect (GTK_OBJECT (entry1
), "changed", GTK_SIGNAL_FUNC (enter_callback1
), data
);
228 gtk_signal_connect (GTK_OBJECT (entry2
), "changed", GTK_SIGNAL_FUNC (enter_callback2
), data
);
230 gtk_entry_set_text (GTK_ENTRY (entry1
), data
->fm
);
231 gtk_entry_set_text (GTK_ENTRY (entry2
), data
->path
);
232 gtk_editable_set_editable (GTK_EDITABLE (entry1
), TRUE
);
233 gtk_entry_set_visibility (GTK_ENTRY (entry1
), TRUE
);
234 gtk_editable_set_editable (GTK_EDITABLE (entry2
), TRUE
);
235 gtk_entry_set_visibility (GTK_ENTRY (entry2
), TRUE
);
238 button
= gtk_button_new_with_label("OK");
239 //label = gtk_label_new ("OK");
240 gtk_signal_connect (GTK_OBJECT (button
), "clicked", GTK_SIGNAL_FUNC (close_callback
), data
);
242 gtk_container_add (GTK_CONTAINER (vbox
), entry1
);
243 gtk_container_add (GTK_CONTAINER (vbox
), entry2
);
245 gtk_table_attach_defaults(GTK_TABLE(table
), vbox
, 0,1, 0,2);
246 gtk_table_attach_defaults(GTK_TABLE(table
), button
, 1,2, 0,2);
248 gtk_container_add (GTK_CONTAINER (dialog
), table
);
249 gtk_widget_show_all(dialog
);
254 } // end launchonclick
256 /* some callback to handle change of values in entry boxes************************* */
257 void enter_callback1(
259 struct wmtrash
*data
){
261 entry_text
= malloc(BIG_STRING
);
262 memset(entry_text
, 0, BIG_STRING
);
263 strncpy (entry_text
, gtk_entry_get_text (GTK_ENTRY (entry
)), BIG_STRING
);
264 memset(data
->fm
, 0, BIG_STRING
);
265 strncpy (data
->fm
, entry_text
, BIG_STRING
);
268 void enter_callback2(
270 struct wmtrash
*data
){
272 entry_text
= malloc(BIG_STRING
);
273 memset(entry_text
, 0, BIG_STRING
);
274 strncpy (entry_text
, gtk_entry_get_text (GTK_ENTRY (entry
)), BIG_STRING
);
275 memset(data
->path
, 0, BIG_STRING
);
276 strncpy (data
->path
, entry_text
, BIG_STRING
);
281 struct wmtrash
*data
){
285 replace_value_in_config(data
->configfile
, data
->param_fm
, data
->fm
);
286 replace_value_in_config(data
->configfile
, data
->param_path
, data
->path
);
287 parent
= gtk_widget_get_ancestor(entry
, GTK_TYPE_WINDOW
);
288 gtk_widget_destroy(parent
); // close the dialog box
289 dockapp
= (GtkWidget
*) build_dockapp(data
->configfile
); // will redraw icons
290 gtk_widget_show_all (dockapp
);
294 // the function to parse the config file for parameters *********************************************
295 int parse_from_config
306 line
= malloc(LONG_STRING
);
307 buffer
= malloc(MEDIUM_STRING
);
308 sep
= malloc(SHORT_STRING
);
309 val
= malloc(MEDIUM_STRING
);
311 if((file
=fopen(filename
, "rb")) == 0) {
312 fprintf (stderr
,"Error opening file %s !\n",filename
);
316 while (fgets (line
, LONG_STRING
, file
) !=NULL
) {
317 if (strstr (line
, "[") !=0) continue;
318 if (strstr (line
, "#") !=0) continue;
319 memset(val
, 0, MEDIUM_STRING
);
320 c
= sscanf (line
, "%s %s %s", buffer
, sep
, val
);
322 if (strncmp (param
, buffer
, MEDIUM_STRING
) == 0) {
323 memset(value
, 0, BIG_STRING
);
325 strncpy(value
,line
+ strlen(buffer
) + strlen(sep
) +2, BIG_STRING
);
326 //fprintf(stderr,"%s\n", value);
327 char *p
= strchr (value
, '\n');
332 return(EXIT_SUCCESS
);
334 memset(line
, 0, LONG_STRING
);
341 return(EXIT_FAILURE
);
342 } // end parse_from_config
345 // the function to parse the config file to replace the value of a given parameter ****************************
346 int replace_value_in_config
358 bigbuffer
= malloc(EXTRALONG_STRING
);
359 line
= malloc(LONG_STRING
);
360 buffer
= malloc(MEDIUM_STRING
);
361 sep
= malloc(MEDIUM_STRING
);
362 old_value
= malloc(BIG_STRING
);
364 if((file
=fopen(filename
, "rb")) == 0) {
365 fprintf (stderr
,"Error opening file %s !\n",filename
);
369 memset(bigbuffer
, 0, EXTRALONG_STRING
);
370 while (fgets (line
, LONG_STRING
, file
) !=NULL
) {
371 memset(buffer
, 0, MEDIUM_STRING
);
372 c
= sscanf (line
, "%s %s %s\n", buffer
, sep
, old_value
);
374 if (strncmp (param
, buffer
, MEDIUM_STRING
) == 0) {
375 memset(line
, 0, LONG_STRING
);
376 sprintf(line
, "%s %s %s\n", buffer
, sep
, new_value
);
379 strncat (bigbuffer
, line
, LONG_STRING
);
380 memset(line
, 0, LONG_STRING
);
384 if((file
=fopen(filename
, "w+")) == 0) {
385 fprintf (stderr
,"Error opening file %s !\n",filename
);
388 fprintf(file
,bigbuffer
);
390 memset(bigbuffer
, 0, EXTRALONG_STRING
);
397 return(EXIT_SUCCESS
);
398 } // end replace_value_in_config *************************************************************************
405 int usage(char *homecf
, char *defaultcf
) {
406 fprintf(stdout
,"\nwmtrash v0.2 : Desktop trash dockapp\n");
407 fprintf(stdout
, "Usage : \n");
408 fprintf(stdout
,"- single LEFT click : browse trash\n");
409 fprintf(stdout
,"- double MIDDLE click : change location & filemanager\n");
410 fprintf(stdout
,"- double RIGHT click : empty trash\n");
411 fprintf(stdout
, "---------------\n");
412 fprintf(stdout
, "How to start it : \n"
413 "\t wmtrash [-c path_to_configfile] use a custom config\n"
414 "\t wmtrash [-h] display this help\n");
415 fprintf(stdout
, "---------------\n");
416 fprintf(stdout
,"home config file is %s\n", homecf
);
417 fprintf(stdout
,"default config file is %s\n",defaultcf
);
418 return(EXIT_SUCCESS
);
420 //*************************************************************************
424 // this one just copy sfile into dfile :)
425 int fcopy( char *sfile
,
427 int c
; /* Character read/written between files */
428 FILE *IPFile
; /* Pointer to the I/P file. FILE is a
429 structure defined in <stdio.h> */
432 /* Open the file - */
433 if ((IPFile
= fopen(sfile
,"r")) == 0) {
434 fprintf (stderr
,"Error opening file %s !\n",sfile
);
435 return (EXIT_FAILURE
);
437 if ((OPFile
= fopen(dfile
,"w")) == 0) {
438 fprintf (stderr
,"Error opening file %s !\n",dfile
);
439 return (EXIT_FAILURE
);
441 /* Read one character at a time, checking
442 for the End of File. EOF is defined
443 in <stdio.h> as -1 */
444 while ((c
= fgetc(IPFile
)) != EOF
){
445 fputc(c
, OPFile
); /* O/P the character */
448 fclose(IPFile
); /* Close the files. */
449 fclose(OPFile
); /* Close the files. */
450 return (EXIT_SUCCESS
);