1 /* vim:tabstop=4:expandtab:shiftwidth=4
2  *
3  * Idesk -- Timer.cpp
4  *
5  * Copyright (c) 2005, FixXxeR (avelar@gmail.com)
6  * based from Timer.cc (vdesk project) by MrChuoi <mrchuoi at yahoo dot com>
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  *      Redistributions of source code must retain the above copyright
13  *      notice, this list of conditions and the following disclaimer.
14  *
15  *      Redistributions in binary form must reproduce the above copyright
16  *      notice, this list of conditions and the following disclaimer in the
17  *      documentation and/or other materials provided with the distribution.
18  *
19  *      Neither the name of the <ORGANIZATION> nor the names of its
20  *      contributors may be used to endorse or promote products derived from
21  *      this software without specific prior written permission.
22  *
23  * (See the included file COPYING / BSD )
24  */
25 
26 #include "Database.h"
27 #include <X11/Xlib.h>
28 #include "Timer.h"
29 #include <sys/time.h>
30 
31 vector<TimerControl*> Timer::items;
32 
Timer(AbstractContainer * con)33 Timer::Timer(AbstractContainer * con):container(con)
34 {
35 	XDesktopContainer * xContainer = dynamic_cast<XDesktopContainer *>(container);
36 	c = ConnectionNumber(xContainer->getDisplay());
37 	if( fcntl( c, F_SETFD, 1 ) == -1) {
38 		cerr << "* Error: Couldn't mark display connection as close-on-exec\n";
39 		exit(0);
40 	}
41 }
42 
Update()43 void Timer::Update()
44 {
45 	int i, s = 1000000000;
46 	time_t now = time(0);
47 
48 	for( i=items.size()-1; i>=0; i-- ) {
49 		int d = items[i]->GetDelay( now );
50 		if( d<=0 ) {
51 			items[i]->OnTime();
52 			if( !items[i]->IsOneShot() )
53 				d = items[i]->Reset();
54 			else {
55 				items.erase( items.begin() + i );
56 				continue;
57 			}
58 		}
59 		if( s>d ) s = d;
60 	}
61 	if( !s || s==1000000000 ) {
62 		usleep( 100 );
63 		return;
64 	}
65 
66 	fd_set rfds;
67 	timeval tv = { s, 0 };
68 	FD_ZERO( &rfds );
69 	FD_SET( c, &rfds );
70 	if( !select( c+1, &rfds, 0, 0, &tv ) ) { // timeout
71 		now = time(0);
72 		for( i=items.size()-1; i>=0; i-- ) {
73 			TimerControl *t = items[i];
74 
75 			if( t->GetDelay( now )<=0 ) {
76 				t->OnTime();
77 				if( t->IsOneShot() )
78 					items.erase( items.begin()+i );
79 				else
80 					t->Reset();
81 			}
82 		}
83 	}
84 }
85 
Add(TimerControl * t,long d)86 void Timer::Add( TimerControl *t, long d )
87 {
88 	t->SetDelay( d );
89 	for( int i=0; i<items.size(); i++ )
90 		if( t==items[i] ) return;
91 	items.push_back( t );
92 }
93 
Remove(TimerControl * t)94 void Timer::Remove( TimerControl *t )
95 {
96 	for( int i=0; i<items.size(); i++ )
97 		if( t==items[i] ) {
98 			items.erase( items.begin() + i );
99 			return;
100 		}
101 }
102