wmclockmon: update change-log
[dockapps.git] / washerdryer / washerDryer / washerDryer.c
blobde4160dfde8cdbcb9d8678f00404e2e82c888898
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <time.h>
5 #include <sys/wait.h>
6 #include <X11/xpm.h>
7 #include <gtk/gtk.h>
9 #include <libdockapp/wmgeneral.h>
10 #include <libdockapp/misc.h>
11 #include "wdryer.xpm"
13 #define CHAR_WIDTH 5
14 #define CHAR_HEIGHT 7
15 #define VERSION "1.1"
17 /* function headers */
18 int Read_Config_File(char* filename);
19 void DrawStatus(int intProcNum, int intStatus);
20 void DecrementTimer ();
21 void ExecAction (char chrType);
22 void displayUsage ();
23 int configure_washerdryer ();
24 void callback (GtkWidget * widget, gpointer data);
25 int delete_event (GtkWidget * widget, GdkEvent * event, gpointer data);
26 void destroy (GtkWidget * widget, gpointer data);
27 void destroyAndReloadConfig(GtkWidget* widget);
29 /* globals */
30 //I put these Widgets here to grab
31 //text in event handler (callback)
32 static GtkWidget *wEntry;
33 static GtkWidget *dEntry;
34 static GtkWidget *txtNewTime;
35 static GtkWidget *mainConfigWindow;
37 char cmdDry[256];
38 char *commandDry = cmdDry;
39 char cmdWash[256];
40 char *commandWash = cmdWash;
41 char wdryer_mask_bits[64 * 64];
42 int wdryer_mask_width = 64;
43 int wdryer_mask_height = 64;
45 int wInCommandMode = 0; // 0 = default/bell 1 = command
46 int dInCommandMode = 0;
48 int tmp_wInCmdMode = 0;
49 int tmp_dInCmdMode = 0;
50 int oldsec = 0;
52 //starting times of washer and dryer
53 int intDefaultWasherTime = 0;
54 int intDefaultDryerTime = 0;
55 int intStartingTimes[10] = {0,0,0,0,0,0,0,0,0,0};
57 //washer and dryer processes
58 int intMin[10] = {0,0,0,0,0,0,0,0,0,0};
59 int intSec[10] = {0,0,0,0,0,0,0,0,0,0};
60 char chrType[10] = {'w','w','w','w','w',
61 'w','w','w','w','w'};
62 //for drawing status
63 int intPrevStatus[10] = {0,0,0,0,0,0,0,0,0,0};
66 /*************
67 * main method
68 *************/
69 int main (int argc, char *argv[])
71 char config_file[256] = {'\0'};
72 int intFreeChk;
73 int intFullCount = 0;
74 int i, intTemp;
75 XEvent Event;
76 int buttonStatus = -1;
77 long starttime;
78 long curtime;
79 struct tm *time_struct;
80 struct tm old_time_struct;
82 //gtk_init (&argc, &argv);
84 commandDry[0] = '\0';
85 commandWash[0] = '\0';
87 //parse command line
88 for (i = 1; i < argc; i++)
90 char *arg = argv[i];
91 if (*arg == '-')
93 switch (arg[1])
95 case 'd':
96 if(argc > (i+1))
98 strncpy(commandDry, argv[i + 1], 256);
99 ++i;
100 dInCommandMode = 1;
102 break;
103 case 'w':
104 if(argc > (i+1))
106 strncpy (commandWash, argv[i + 1], 256);
107 ++i;
108 wInCommandMode = 1;
110 break;
111 case 'W':
112 if(argc > (i+1))
114 intDefaultWasherTime = atoi(argv[i+1]);
115 for(intTemp = 0; intTemp < 10; ++intTemp)
116 intStartingTimes[intTemp] = atoi(argv[i+1]);
117 ++i;
119 break;
120 case 'D':
121 if(argc > (i+1))
123 intDefaultDryerTime = atoi(argv[i+1]);
124 ++i;
126 break;
127 case 'v':
128 printf ("%s\n", VERSION);
129 _exit (0);
130 break;
131 case 'c':
132 if(argc > (i+1))
134 strncpy(config_file, argv[i+1], 256);
135 ++i;
137 break;
138 default:
139 fprintf(stderr, "Unrecognized option: %s\n", arg);
140 displayUsage ();
141 _exit (0);
142 break;
145 else
147 fprintf(stderr, "Unrecognized option: %s\n", arg);
148 displayUsage ();
152 //read config file
153 if(config_file[0] != 0)
155 //fprintf(stderr, "Using user-specified config file '%s'.\n", config_file);
156 Read_Config_File(config_file);
158 else
160 sprintf(config_file, "%s/.wdryerrc", getenv("HOME"));
161 Read_Config_File(config_file);
164 //insure sanity
165 if(intDefaultWasherTime < 1)
166 intDefaultWasherTime = 1;
167 if(intDefaultDryerTime < 1)
168 intDefaultDryerTime = 1;
169 for(intTemp = 0; intTemp<10; ++intTemp)
171 if(intStartingTimes[intTemp] < 1)
172 intStartingTimes[intTemp] = 1;
176 gtk_init (&argc, &argv);
177 createXBMfromXPM (wdryer_mask_bits, wdryer_xpm, wdryer_mask_width,
178 wdryer_mask_height);
180 openXwindow (argc, argv, wdryer_xpm, wdryer_mask_bits, wdryer_mask_width,
181 wdryer_mask_height);
183 //setMaskXY(-64, 0);
185 //clickable regions
186 AddMouseRegion (0, 8, 6, 28, 24); //0: washer
187 AddMouseRegion (1, 32, 6, 52, 24); //1: dryer
188 AddMouseRegion (2, 6, 26, 57, 57); //2: main area
190 starttime = time (0);
191 curtime = time (0);
193 time_struct = localtime (&curtime);
195 /*****************************
196 * while program is running...
197 *****************************/
198 while (1)
200 curtime = time (0);
202 waitpid (0, NULL, WNOHANG);
204 old_time_struct = *time_struct;
205 time_struct = localtime (&curtime);
207 if (curtime >= starttime)
209 //decrement timer, draw status
210 if (oldsec < time_struct->tm_sec)
211 DecrementTimer ();
212 oldsec = (time_struct->tm_sec);
214 RedrawWindow ();
216 // X Events
217 while (XPending (display))
219 XNextEvent (display, &Event);
220 switch (Event.type)
222 case Expose:
223 RedrawWindow ();
224 break;
225 case DestroyNotify:
226 XCloseDisplay (display);
227 _exit (0);
228 break;
229 case ButtonPress:
230 i = CheckMouseRegion (Event.xbutton.x, Event.xbutton.y);
231 buttonStatus = i;
232 if (buttonStatus == i && buttonStatus >= 0)
234 switch (buttonStatus)
236 /*****************
237 * click on washer
238 *****************/
239 case 0:
240 intFullCount = 0;
241 for(intFreeChk=0;intFreeChk<10;++intFreeChk)
243 if( (intSec[intFreeChk] == 0) &&
244 (intMin[intFreeChk] == 0) &&
245 (intFullCount < 5))
247 intMin[intFreeChk] = intDefaultWasherTime;
248 intStartingTimes[intFreeChk] = intDefaultWasherTime;
249 chrType[intFreeChk] = 'w';
250 break;
252 if(chrType[intFreeChk] == 'w')
253 ++intFullCount;
255 break;
256 /****************
257 * click on dryer
258 ****************/
259 case 1:
260 intFullCount = 0;
261 for(intFreeChk=0;intFreeChk<10;++intFreeChk)
263 if((intSec[intFreeChk] == 0) &&
264 (intMin[intFreeChk] == 0) &&
265 (intFullCount < 5))
267 intMin[intFreeChk] = intDefaultDryerTime;
268 intStartingTimes[intFreeChk] = intDefaultDryerTime;
269 chrType[intFreeChk] = 'd';
270 break;
272 if(chrType[intFreeChk] == 'd')
273 ++intFullCount;
275 break;
276 /***************
277 * click on main
278 ***************/
279 case 2: // main area
280 //open GUI
281 configure_washerdryer ();
282 break;
283 } //end switch
284 } //end if
286 break;
288 case ButtonRelease:
289 i = CheckMouseRegion (Event.xbutton.x, Event.xbutton.y);
291 if (buttonStatus == i && buttonStatus >= 0)
293 switch (buttonStatus)
295 case 0:
296 break;
297 case 1:
298 break;
299 case 2:
300 break;
301 case 3:
302 break;
303 case 4:
304 break;
305 case 5:
306 break;
309 buttonStatus = -1;
310 RedrawWindow ();
311 break;
313 } //end switch Event.type
315 } //end X events
317 usleep (100000L);
319 } //end big if
321 } //end infinite loop
323 return 0;
325 } //end main
327 /***********************************
328 * Draws status bar. Given the slot
329 * number (intProcNum) and the
330 * percentage completed (intStatus),
331 * implements the copyXPMArea
332 * command on the xpm file.
333 ***********************************/
334 void DrawStatus(int intProcNum, int intStatus)
336 int intXPMx;
338 //error correcting
339 if((intProcNum > 9) || (intProcNum < 0))
340 return;
341 if(intStatus > 100)
342 intStatus = 100;
343 if(intStatus < 0)
344 intStatus = 0;
346 //location of image on xpm
347 //just accept the math :-)
348 intXPMx = ((100 - intStatus) * 9) / 10;
349 intXPMx = intXPMx - (intXPMx%3);
351 //draws if necessary
352 if(intPrevStatus[intProcNum] != intXPMx)
354 copyXPMArea (intXPMx, 64,
355 3, 30,
356 8 + intProcNum*5, 27);
358 intPrevStatus[intProcNum] = intXPMx;
362 /******************************
363 * calls DrawStatus, decrements
364 * timer, and executes command
365 * or beep if timer reaches zero
366 *******************************/
367 void DecrementTimer ()
369 int intCurrWDisplay = 0;
370 int intCurrDDisplay = 0;
371 int intCtr;
372 int intStatus;
373 //for each instance...
374 for(intCtr=0; intCtr < 10; ++intCtr)
376 /*******
377 * draws
378 *******/
379 //calculate percentage
380 intStatus = ((
381 (intMin[intCtr] * 60) +
382 intSec[intCtr])
383 * 100)
384 / (intStartingTimes[intCtr]*60);
386 //draw status bar
387 if((chrType[intCtr] == 'w') && (intCurrWDisplay < 5))
389 DrawStatus(intCurrWDisplay, intStatus);
390 ++intCurrWDisplay;
392 else if(intCurrDDisplay < 10)
394 DrawStatus(5 + intCurrDDisplay, intStatus);
395 ++intCurrDDisplay;
398 /*****************
399 * decrements time
400 *****************/
401 //if it's already 0, don't decrement it
402 if((intSec[intCtr] == 0) && (intMin[intCtr] == 0))
403 continue;
405 --intSec[intCtr];
406 if (intSec[intCtr] == -1)
408 intSec[intCtr] = 59;
409 --intMin[intCtr];
412 //executes action/beeps, if necessazry
413 if (intSec[intCtr] == 0 && intMin[intCtr] == 0)
414 ExecAction (chrType[intCtr]);
416 } //end for
420 /***************************
421 * executes action, or beeps
422 ***************************/
423 void ExecAction (char chrType)
425 if(chrType == 'd')
427 if (dInCommandMode)
429 execCommand (commandDry);
431 else
433 printf ("\07"); //beep
434 fflush (stdout);
437 else
439 if (wInCommandMode)
441 execCommand (commandWash);
443 else
445 printf ("\07"); //beep
446 fflush (stdout);
451 /*************************
452 * gives command line help
453 *************************/
454 void displayUsage (void)
456 fprintf (stderr, "\nwasherDryer - by Mike Foley <foley@ucsd.edu>\n\n");
457 fprintf (stderr, "usage:\n");
458 fprintf (stderr, " -c <filename> use specified config file\n");
459 fprintf (stderr, " -W <int> washer time\n");
460 fprintf (stderr, " -D <int> dryer time\n");
461 fprintf (stderr, " -w <command> washer command (system bell is default)\n");
462 fprintf (stderr, " -d <command> dryer command (system bell is default)\n");
463 fprintf (stderr, " -h this help screen\n");
464 fprintf (stderr, " -v print the version number\n\n");
465 _exit (0);
468 /**********************
469 * handles click events
470 * in GUI window
471 **********************/
472 void callback (GtkWidget * widget, gpointer data)
474 int intProcToChange;
475 GtkWidget *dialog, *btnOK, *lblMain;
476 char strInputText[4];
478 //fprintf(stderr,"event received: %s\n", (char *)data);
479 /*****************************
480 * if user clicked bell button
481 *****************************/
482 if ((char *) data == "d_bell_button") {
483 tmp_dInCmdMode = 0;
484 gtk_entry_set_text (GTK_ENTRY (dEntry), "");
485 gtk_entry_set_editable (GTK_ENTRY (dEntry), FALSE);
487 else if ((char *) data == "w_bell_button") {
488 tmp_wInCmdMode = 0;
489 gtk_entry_set_text (GTK_ENTRY (wEntry), "");
490 gtk_entry_set_editable (GTK_ENTRY (wEntry), FALSE);
493 /********************************
494 * if user clicked command button
495 ********************************/
496 else if ((char *) data == "d_command_button") {
497 tmp_dInCmdMode = 1;
498 gtk_entry_set_editable (GTK_ENTRY (dEntry), TRUE);
499 gtk_entry_set_text (GTK_ENTRY (dEntry), commandDry);
501 else if ((char *) data == "w_command_button") {
502 tmp_wInCmdMode = 1;
503 gtk_entry_set_editable (GTK_ENTRY (wEntry), TRUE);
504 gtk_entry_set_text (GTK_ENTRY (wEntry), commandWash);
507 /********************
508 * if user clicked ok
509 ********************/
510 else if ((char *) data == "ok")
512 if (tmp_dInCmdMode == 1)
513 strncpy (commandDry, gtk_entry_get_text (GTK_ENTRY (dEntry)), 256);
514 if (tmp_wInCmdMode == 1)
515 strncpy (commandWash, gtk_entry_get_text (GTK_ENTRY (wEntry)), 256);
516 wInCommandMode = tmp_wInCmdMode;
517 dInCommandMode = tmp_dInCmdMode;
519 /************************
520 * if user changed a time
521 ************************/
522 else if(strstr((char *) data, "Change_"))
524 intProcToChange = ((char *)data)[7] - 48;
526 //min = sec = starting time = new time
527 intMin[intProcToChange] = intSec[intProcToChange] =
528 intStartingTimes[intProcToChange] =
529 atoi(gtk_entry_get_text(GTK_ENTRY (txtNewTime)));
531 if(intMin[intProcToChange] == 0)
533 intSec[intProcToChange] =
534 intStartingTimes[intProcToChange] = 1;
537 //fprintf(stderr, "intMin[%i], intStartingTimes[%i] changed to %i, %i\n",
538 // intProcToChange, intProcToChange, intMin[intProcToChange],
539 // intStartingTimes[intProcToChange]);
541 /************************
542 * if user clicked cancel
543 ************************/
544 else if (!strcmp ((char *) data, "cancel"))
548 /***********************
549 * if user clicked clear
550 ***********************/
551 /*if (!strcmp ((char *) data, "clear"))
553 commandDry[0] = '\0';
554 commandWash[0] = '\0';
555 gtk_entry_set_text (GTK_ENTRY (dEntry), commandDry);
556 gtk_entry_set_text (GTK_ENTRY (wEntry), commandWash);
559 /************************************
560 * if user clicked one of the Deletes
561 ************************************/
562 else if(strstr((char *) data, "Delete"))
564 intProcToChange = ((char *)data)[6] - 48;
565 intMin[intProcToChange] = 0;
566 intSec[intProcToChange] = 0;
569 /****************************************
570 * if user clicked one of the Change btns
571 ****************************************/
572 else if(strstr((char *) data, "Change"))
574 intProcToChange = ((char *)data)[6] - 48;
576 /* Create the widgets */
577 dialog = gtk_dialog_new();
579 lblMain = gtk_label_new("New time (min):");
581 txtNewTime = gtk_entry_new_with_max_length(3);
582 sprintf(strInputText, "%i", intMin[intProcToChange]);
583 gtk_entry_set_text((GtkEntry *)txtNewTime, (char *)strInputText);
585 btnOK = gtk_button_new_with_label("Ok");
586 //sprintf(buffer, "Change_%i", intProcToChange);
587 //I am so dumb
588 switch(intProcToChange)
590 case 0:
591 gtk_signal_connect (GTK_OBJECT (btnOK), "clicked",
592 GTK_SIGNAL_FUNC (callback), (gpointer) "Change_0");
593 break;
594 case 1:
595 gtk_signal_connect (GTK_OBJECT (btnOK), "clicked",
596 GTK_SIGNAL_FUNC (callback), (gpointer) "Change_1");
597 break;
598 case 2:
599 gtk_signal_connect (GTK_OBJECT (btnOK), "clicked",
600 GTK_SIGNAL_FUNC (callback), (gpointer) "Change_2");
601 break;
602 case 3:
603 gtk_signal_connect (GTK_OBJECT (btnOK), "clicked",
604 GTK_SIGNAL_FUNC (callback), (gpointer) "Change_3");
605 break;
606 case 4:
607 gtk_signal_connect (GTK_OBJECT (btnOK), "clicked",
608 GTK_SIGNAL_FUNC (callback), (gpointer) "Change_4");
609 break;
610 case 5:
611 gtk_signal_connect (GTK_OBJECT (btnOK), "clicked",
612 GTK_SIGNAL_FUNC (callback), (gpointer) "Change_5");
613 break;
614 case 6:
615 gtk_signal_connect (GTK_OBJECT (btnOK), "clicked",
616 GTK_SIGNAL_FUNC (callback), (gpointer) "Change_6");
617 break;
618 case 7:
619 gtk_signal_connect (GTK_OBJECT (btnOK), "clicked",
620 GTK_SIGNAL_FUNC (callback), (gpointer) "Change_7");
621 break;
622 case 8:
623 gtk_signal_connect (GTK_OBJECT (btnOK), "clicked",
624 GTK_SIGNAL_FUNC (callback), (gpointer) "Change_8");
625 break;
626 case 9:
627 gtk_signal_connect (GTK_OBJECT (btnOK), "clicked",
628 GTK_SIGNAL_FUNC (callback), (gpointer) "Change_9");
629 break;
631 /* Ensure that the dialog box is destroyed when the user clicks ok. */
632 //###
634 gtk_signal_connect_object(GTK_OBJECT(btnOK),
635 "clicked", gtk_widget_destroy, GTK_OBJECT(dialog));
636 gtk_signal_connect_object (GTK_OBJECT (btnOK),
637 "clicked", gtk_widget_destroy, GTK_OBJECT (mainConfigWindow));
639 gtk_signal_connect_object (GTK_OBJECT (btnOK),
640 "clicked", destroyAndReloadConfig, GTK_OBJECT (dialog));
642 /* add stuff */
643 //gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), lblMain);
644 //gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), btnOK);
645 //gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), txtNewTime);
646 gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area),
647 btnOK, TRUE, TRUE, 0);
648 gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->vbox),
649 lblMain, TRUE, TRUE, 0);
650 gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->vbox),
651 txtNewTime, TRUE, TRUE, 0);
652 gtk_widget_show_all (dialog);
656 /* This callback quits the program */
657 int delete_event (GtkWidget * widget, GdkEvent * event, gpointer data)
659 return (FALSE);
662 //destroys a widget, plus reloads mainConfigWindow
663 void destroyAndReloadConfig(GtkWidget* widget)
665 if(widget != NULL)
666 gtk_widget_destroy(widget);
667 gtk_widget_destroy(mainConfigWindow);
668 configure_washerdryer();
671 //destroys window
672 void destroy (GtkWidget * widget, gpointer data)
674 gtk_main_quit ();
677 /******************************
678 * pops up configuration window
679 ******************************/
680 int configure_washerdryer ()
682 int intLoadsIn = 0;
683 int intProcNo;
684 char buffer[32];
685 char bufferChangeBtn[16];
686 int intTimeElapsed;
687 GtkWidget *frame;
688 GtkWidget *button;
689 GtkWidget *buttonChange;
690 GtkWidget *buttonDryC;
691 GtkWidget *buttonWashC;
692 GtkWidget *box1;
693 GtkWidget *box2;
694 GtkWidget *innerHbox;
695 GtkWidget *sub_vbox;
696 GtkWidget *label;
698 tmp_wInCmdMode = wInCommandMode;
699 tmp_dInCmdMode = dInCommandMode;
701 // Create a new window
702 mainConfigWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
703 gtk_window_set_title (GTK_WINDOW (mainConfigWindow), "Configure");
704 gtk_window_set_wmclass (GTK_WINDOW (mainConfigWindow), "washerdryerconf", "");
706 gtk_signal_connect (GTK_OBJECT (mainConfigWindow), "destroy",
707 GTK_SIGNAL_FUNC (destroy), NULL);
709 // Sets the border width of the window.
710 gtk_container_set_border_width (GTK_CONTAINER (mainConfigWindow), 10);
712 // Create Vertical box
713 box1 = gtk_vbox_new (FALSE, 0);
714 // Add vertical box to main window
715 gtk_container_add (GTK_CONTAINER (mainConfigWindow), box1);
716 gtk_widget_show (box1);
718 /////
720 /********************
721 * washer action frame
722 ********************/
723 frame = gtk_frame_new ("Washer Action");
724 gtk_box_pack_start (GTK_BOX (box1), frame, TRUE, TRUE, 2);
725 gtk_widget_show (frame);
727 //Create Vertical box
728 sub_vbox = gtk_vbox_new (FALSE, 0);
729 //Add vertical box to main window
730 gtk_container_add (GTK_CONTAINER (frame), sub_vbox);
731 gtk_widget_show (sub_vbox);
733 box2 = gtk_hbox_new (FALSE, 0);
734 gtk_box_pack_start (GTK_BOX (sub_vbox), box2, TRUE, TRUE, 2);
736 //Bell radio button
737 button = gtk_radio_button_new_with_label (NULL, "System Bell");
738 gtk_signal_connect (GTK_OBJECT (button), "clicked",
739 GTK_SIGNAL_FUNC (callback), (gpointer) "w_bell_button");
740 gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 2);
741 gtk_widget_show (button);
743 //Command radio button
744 buttonWashC = gtk_radio_button_new_with_label (gtk_radio_button_group
745 (GTK_RADIO_BUTTON (button)),
746 "Command");
747 gtk_signal_connect (GTK_OBJECT (buttonWashC), "clicked",
748 GTK_SIGNAL_FUNC (callback),
749 (gpointer) "w_command_button");
750 gtk_box_pack_start (GTK_BOX (box2), buttonWashC, FALSE, FALSE, 2);
751 gtk_widget_show (buttonWashC);
752 gtk_widget_show (box2);
755 box2 = gtk_hbox_new (FALSE, 0);
756 gtk_box_pack_start (GTK_BOX (sub_vbox), box2, TRUE, TRUE, 2);
758 label = gtk_label_new ("Command: ");
759 gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
760 gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 2);
761 gtk_widget_show (label);
763 /* Create "Command" text entry area */
764 wEntry = gtk_entry_new_with_max_length (100);
765 gtk_entry_set_editable (GTK_ENTRY (wEntry), FALSE);
766 gtk_signal_connect (GTK_OBJECT (wEntry), "activate",
767 GTK_SIGNAL_FUNC (callback), wEntry);
768 gtk_box_pack_start (GTK_BOX (box2), wEntry, FALSE, FALSE, 2);
769 gtk_widget_show (wEntry);
770 gtk_widget_show (box2);
772 box2 = gtk_hbox_new (FALSE, 0);
773 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 2);
775 /////
777 /********************
778 * dryer action frame
779 ********************/
780 frame = gtk_frame_new ("Dryer Action");
781 gtk_box_pack_start (GTK_BOX (box1), frame, TRUE, TRUE, 2);
782 gtk_widget_show (frame);
784 // Create Vertical box
785 sub_vbox = gtk_vbox_new (FALSE, 0);
786 // Add vertical box to main window
787 gtk_container_add (GTK_CONTAINER (frame), sub_vbox);
788 gtk_widget_show (sub_vbox);
790 box2 = gtk_hbox_new (FALSE, 0);
791 gtk_box_pack_start (GTK_BOX (sub_vbox), box2, TRUE, TRUE, 2);
793 //Bell radio button
794 button = gtk_radio_button_new_with_label (NULL, "System Bell");
795 gtk_signal_connect (GTK_OBJECT (button), "clicked",
796 GTK_SIGNAL_FUNC (callback), (gpointer) "d_bell_button");
797 gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 2);
798 gtk_widget_show (button);
800 //Command radio button
801 buttonDryC = gtk_radio_button_new_with_label (gtk_radio_button_group
802 (GTK_RADIO_BUTTON (button)),
803 "Command");
804 gtk_signal_connect (GTK_OBJECT (buttonDryC), "clicked",
805 GTK_SIGNAL_FUNC (callback),
806 (gpointer) "d_command_button");
807 gtk_box_pack_start (GTK_BOX (box2), buttonDryC, FALSE, FALSE, 2);
808 gtk_widget_show (buttonDryC);
809 gtk_widget_show (box2);
812 /**************
813 * Status frame
814 **************/
815 frame = gtk_frame_new ("Status");
816 gtk_box_pack_start (GTK_BOX (box1), frame,TRUE, TRUE, 2);
817 gtk_widget_show (frame);
819 for(intProcNo = 0; intProcNo<10; ++intProcNo)
821 //if process is still running
822 if((intSec[intProcNo] != 0) || (intMin[intProcNo] != 0))
824 ++intLoadsIn;
826 if(intLoadsIn == 1)
828 box2 = gtk_vbox_new (FALSE, 0);
829 gtk_container_add (GTK_CONTAINER (frame), box2);
830 gtk_widget_show (box2);
833 innerHbox = gtk_hbox_new (FALSE, 2);
834 gtk_container_add (GTK_CONTAINER (box2), innerHbox);
835 gtk_widget_show (innerHbox);
837 if(chrType[intProcNo] == 'w')
838 sprintf(buffer,"Washer: ");
839 else
840 sprintf(buffer," Dryer: ");
842 label = gtk_label_new (buffer);
843 gtk_misc_set_alignment (GTK_MISC (label), 2, 2);
844 gtk_box_pack_start (GTK_BOX (innerHbox), label, TRUE, FALSE, 2);
845 gtk_widget_show (label);
847 sprintf(bufferChangeBtn, "%2i", intMin[intProcNo]);
848 buttonChange = gtk_button_new_with_label (bufferChangeBtn);
849 sprintf(bufferChangeBtn,"Change%i", intProcNo);
850 /**************************************
851 * why do I do it this way? because I'm
852 * dumb and I don't know a better way
853 **************************************/
854 switch(intProcNo)
856 case 0:
857 gtk_signal_connect (GTK_OBJECT (buttonChange), "clicked",
858 GTK_SIGNAL_FUNC (callback), (gpointer)"Change0");
859 break;
860 case 1:
861 gtk_signal_connect (GTK_OBJECT (buttonChange), "clicked",
862 GTK_SIGNAL_FUNC (callback), (gpointer)"Change1");
863 break;
864 case 2:
865 gtk_signal_connect (GTK_OBJECT (buttonChange), "clicked",
866 GTK_SIGNAL_FUNC (callback), (gpointer)"Change2");
867 break;
868 case 3:
869 gtk_signal_connect (GTK_OBJECT (buttonChange), "clicked",
870 GTK_SIGNAL_FUNC (callback), (gpointer)"Change3");
871 break;
872 case 4:
873 gtk_signal_connect (GTK_OBJECT (buttonChange), "clicked",
874 GTK_SIGNAL_FUNC (callback), (gpointer)"Change4");
875 break;
876 case 5:
877 gtk_signal_connect (GTK_OBJECT (buttonChange), "clicked",
878 GTK_SIGNAL_FUNC (callback), (gpointer)"Change5");
879 break;
880 case 6:
881 gtk_signal_connect (GTK_OBJECT (buttonChange), "clicked",
882 GTK_SIGNAL_FUNC (callback), (gpointer)"Change6");
883 break;
884 case 7:
885 gtk_signal_connect (GTK_OBJECT (buttonChange), "clicked",
886 GTK_SIGNAL_FUNC (callback), (gpointer)"Change7");
887 break;
888 case 8:
889 gtk_signal_connect (GTK_OBJECT (buttonChange), "clicked",
890 GTK_SIGNAL_FUNC (callback), (gpointer)"Change8");
891 break;
892 case 9:
893 gtk_signal_connect (GTK_OBJECT (buttonChange), "clicked",
894 GTK_SIGNAL_FUNC (callback), (gpointer)"Change9");
895 break;
897 gtk_box_pack_start (GTK_BOX(innerHbox), buttonChange, FALSE, FALSE, 2);
898 gtk_widget_show (buttonChange);
900 sprintf(buffer, " min remaining");
901 label = gtk_label_new (buffer);
902 gtk_misc_set_alignment (GTK_MISC (label), 2, 2);
903 gtk_box_pack_start (GTK_BOX (innerHbox), label, FALSE, FALSE, 2);
904 gtk_widget_show (label);
906 button = gtk_button_new_with_label ("Delete");
907 sprintf(buffer,"Delete%i", intProcNo);
909 /*************************************
910 * why this way? see above switch stmt
911 *************************************/
912 switch(intProcNo)
914 case 0:
915 gtk_signal_connect (GTK_OBJECT (button), "clicked",
916 GTK_SIGNAL_FUNC (callback), (gpointer)"Delete0");
917 break;
918 case 1:
919 gtk_signal_connect (GTK_OBJECT (button), "clicked",
920 GTK_SIGNAL_FUNC (callback), (gpointer)"Delete1");
921 break;
922 case 2:
923 gtk_signal_connect (GTK_OBJECT (button), "clicked",
924 GTK_SIGNAL_FUNC (callback), (gpointer)"Delete2");
925 break;
926 case 3:
927 gtk_signal_connect (GTK_OBJECT (button), "clicked",
928 GTK_SIGNAL_FUNC (callback), (gpointer)"Delete3");
929 break;
930 case 4:
931 gtk_signal_connect (GTK_OBJECT (button), "clicked",
932 GTK_SIGNAL_FUNC (callback), (gpointer)"Delete4");
933 break;
934 case 5:
935 gtk_signal_connect (GTK_OBJECT (button), "clicked",
936 GTK_SIGNAL_FUNC (callback), (gpointer)"Delete5");
937 break;
938 case 6:
939 gtk_signal_connect (GTK_OBJECT (button), "clicked",
940 GTK_SIGNAL_FUNC (callback), (gpointer)"Delete6");
941 break;
942 case 7:
943 gtk_signal_connect (GTK_OBJECT (button), "clicked",
944 GTK_SIGNAL_FUNC (callback), (gpointer)"Delete7");
945 break;
946 case 8:
947 gtk_signal_connect (GTK_OBJECT (button), "clicked",
948 GTK_SIGNAL_FUNC (callback), (gpointer)"Delete8");
949 break;
950 case 9:
951 gtk_signal_connect (GTK_OBJECT (button), "clicked",
952 GTK_SIGNAL_FUNC (callback), (gpointer)"Delete9");
953 break;
957 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
958 GTK_SIGNAL_FUNC (gtk_widget_destroy),
959 GTK_OBJECT (mainConfigWindow));
962 gtk_signal_connect_object (GTK_OBJECT (button),
963 "clicked", destroyAndReloadConfig, NULL);
965 gtk_box_pack_start (GTK_BOX (innerHbox), button, FALSE, FALSE, 4);
966 gtk_widget_show (button);
969 } //end for
972 //if no loads
973 if(intLoadsIn == 0)
975 box2 = gtk_hbox_new (FALSE, 0);
976 gtk_container_add (GTK_CONTAINER (frame), box2);
977 gtk_widget_show (box2);
979 label = gtk_label_new (" No loads in washer/dryer.");
980 gtk_misc_set_alignment (GTK_MISC (label), 2, 2);
981 gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 2);
982 gtk_widget_show (label);
985 /****************************
986 * doing some more dryer shit
987 ****************************/
988 box2 = gtk_hbox_new (FALSE, 0);
989 gtk_box_pack_start (GTK_BOX (sub_vbox), box2, TRUE, TRUE, 2);
991 label = gtk_label_new ("Command: ");
992 gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
993 gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 2);
994 gtk_widget_show (label);
996 /* Create "Command" text entry area */
997 dEntry = gtk_entry_new_with_max_length (100);
998 gtk_entry_set_editable (GTK_ENTRY (dEntry), FALSE);
999 gtk_signal_connect (GTK_OBJECT (dEntry), "activate",
1000 GTK_SIGNAL_FUNC (callback), dEntry);
1001 gtk_box_pack_start (GTK_BOX (box2), dEntry, FALSE, FALSE, 2);
1002 gtk_widget_show (dEntry);
1003 gtk_widget_show (box2);
1005 box2 = gtk_hbox_new (FALSE, 0);
1006 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 2);
1008 // Create "Cancel" button
1009 button = gtk_button_new_with_label ("Cancel");
1010 //gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (delete_event), NULL);
1011 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1012 GTK_SIGNAL_FUNC (callback), "cancel");
1013 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
1014 GTK_SIGNAL_FUNC (gtk_widget_destroy),
1015 GTK_OBJECT (mainConfigWindow));
1016 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 2);
1017 gtk_widget_show (button);
1019 // Create "Clear" button
1020 /* button = gtk_button_new_with_label ("Clear");
1021 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1022 GTK_SIGNAL_FUNC (callback), "clear");
1023 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 2);
1024 gtk_widget_show (button);
1028 // Create "Ok" button
1029 button = gtk_button_new_with_label ("Ok");
1030 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1031 GTK_SIGNAL_FUNC (callback), "ok");
1032 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
1033 GTK_SIGNAL_FUNC (gtk_widget_destroy),
1034 GTK_OBJECT (mainConfigWindow));
1035 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 2);
1036 gtk_widget_show (button);
1037 gtk_widget_show (box2);
1039 gtk_widget_show (mainConfigWindow);
1041 if (dInCommandMode == 1)
1042 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (buttonDryC), TRUE);
1043 if (wInCommandMode == 1)
1044 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (buttonWashC), TRUE);
1046 intTimeElapsed = time(0);
1047 gtk_main ();
1048 intTimeElapsed = time(0) - intTimeElapsed;
1049 while(intTimeElapsed > 0)
1051 DecrementTimer();
1052 --intTimeElapsed;
1054 return 0;
1057 /***********************************
1058 * Reads a string from configuration
1059 * file. Taken from wminet
1060 ***********************************/
1061 int ReadConfigString(FILE *fp, char *setting, char *value)
1063 char str[1024];
1064 char buf[1024];
1065 int i;
1066 int len;
1067 int slen;
1068 char *p=NULL;
1071 if (!fp)
1073 return 0;
1076 sprintf(str, "%s=", setting);
1077 slen = strlen(str);
1079 fseek(fp, 0, SEEK_SET);
1081 while ( !feof(fp) )
1083 if (!fgets(buf, 512, fp))
1084 break;
1086 len = strlen(buf);
1088 // strip linefeed
1089 for (i=0; i!=len; i++)
1091 if (buf[i] == '\n')
1093 buf[i] = 0;
1097 if ( strncmp(buf, str, strlen(str)) == 0)
1099 // found our setting
1100 for(i=0; i!=slen; i++)
1102 if ( buf[i] == '=' )
1104 p=buf+i+1;
1105 strcpy(value, p);
1106 return 1;
1111 return 0;
1115 /*****************************
1116 * reads int from config file.
1117 * taken from wminet
1118 *****************************/
1119 int ReadConfigInt(FILE *fp, char *setting, int *value)
1121 char buf[1024];
1123 if (ReadConfigString(fp, setting, (char *) &buf))
1125 *value = atoi(buf);
1126 return 1;
1129 return 0;
1133 /*****************************
1134 * Read config file and stores
1135 * values to local variables
1136 *****************************/
1137 int Read_Config_File(char* filename )
1139 FILE* fp;
1141 fp = fopen(filename, "r");
1142 if (fp)
1144 if(intDefaultWasherTime == 0)
1146 ReadConfigInt(fp, "washer_time", &intDefaultWasherTime);
1148 if(intDefaultDryerTime == 0)
1150 ReadConfigInt(fp, "dryer_time", &intDefaultDryerTime);
1152 if(commandWash[0] == '\0')
1154 ReadConfigInt(fp, "exec_washer_action", &wInCommandMode);
1156 if(commandDry[0] == '\0')
1158 ReadConfigInt(fp, "exec_dryer_action", &dInCommandMode);
1160 tmp_wInCmdMode = wInCommandMode;
1161 tmp_dInCmdMode = dInCommandMode;
1162 if(commandWash[0] == '\0')
1164 ReadConfigString(fp, "washer_action", commandWash);
1166 if(commandDry[0] == '\0')
1168 ReadConfigString(fp, "dryer_action", commandDry);
1171 fclose(fp);
1172 return 1;
1174 else
1176 perror("Read_Config_File");
1177 fprintf(stderr, "Unable to open %s, no settings read.\n", filename);
1178 return 0;