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