r1009: Move the dependencies to newer package names
[cinelerra_cv/mob.git] / guicast / bcrepeater.C
blobbc95e0fcefac1e0d1ffdfb55c2c3a7a9accf0406
1 #include "bcrepeater.h"
2 #include "bcsignals.h"
3 #include "bcwindow.h"
4 #include "condition.h"
6 #include <unistd.h>
8 BC_Repeater::BC_Repeater(BC_WindowBase *top_level, long delay)
9  : Thread()
11         set_synchronous(1);
12         pause_lock = new Condition(0, "BC_Repeater::pause_lock");
13         startup_lock = new Condition(0, "BC_Repeater::startup_lock");
14         repeat_lock = new Condition(1, "BC_Repeater::repeat_lock");
15         repeating = 0;
16         interrupted = 0;
17         this->delay = delay;
18         this->top_level = top_level;
22 BC_Repeater::~BC_Repeater()
24         interrupted = 1;
25         pause_lock->unlock();
26         repeat_lock->unlock();
28         Thread::end();
29         Thread::join();
31         delete pause_lock;
32         delete startup_lock;
33         delete repeat_lock;
36 void BC_Repeater::initialize()
38         start();
39 // This is important.  It doesn't unblock until the thread is running.
40         startup_lock->lock("BC_Repeater::initialize");
43 int BC_Repeater::start_repeating()
45 //printf("BC_Repeater::start_repeating 1 %d\n", delay);
46         repeating++;
47         if(repeating == 1)
48         {
49 // Resume the loop
50                 pause_lock->unlock();
51         }
52         return 0;
55 int BC_Repeater::stop_repeating()
57 // Recursive calling happens when mouse wheel is used.
58         if(repeating > 0)
59         {
60                 repeating--;
61 // Pause the loop
62                 if(repeating == 0) pause_lock->lock("BC_Repeater::stop_repeating");
63         }
64         return 0;
67 void BC_Repeater::run()
69 //printf("BC_Repeater::run 1 %d\n", getpid());
70         next_delay = delay;
71         Thread::disable_cancel();
72         startup_lock->unlock();
74         while(!interrupted)
75         {
76                 Thread::enable_cancel();
77                 timer.delay(next_delay);
78                 Thread::disable_cancel();
79 //if(next_delay <= 0) printf("BC_Repeater::run delay=%d next_delay=%d\n", delay, next_delay);
81 // Test exit conditions
82                 if(interrupted) return;
83 // Busy wait here
84 //              if(repeating <= 0) continue;
86 // Test for pause
87                 pause_lock->lock("BC_Repeater::run");
88                 pause_lock->unlock();
89                 timer.update();
91 // Test exit conditions
92                 if(interrupted) return;
93                 if(repeating <= 0) continue;
95 // Wait for existing signal to be processed before sending a new one
96                 repeat_lock->lock("BC_Repeater::run");
98 // Test exit conditions
99                 if(interrupted)
100                 {
101                         repeat_lock->unlock();
102                         return;
103                 }
104                 if(repeating <= 0)
105                 {
106                         repeat_lock->unlock();
107                         continue;
108                 }
110 // Wait for window to become available.
111                 top_level->lock_window("BC_Repeater::run");
113 // Test exit conditions
114                 if(interrupted)
115                 {
116                         repeat_lock->unlock();
117                         top_level->unlock_window();
118                         return;
119                 }
120                 if(repeating <= 0)
121                 {
122                         repeat_lock->unlock();
123                         top_level->unlock_window();
124                         continue;
125                 }
127 // Stick event into queue
128                 top_level->arm_repeat(delay);
129                 top_level->unlock_window();
130                 next_delay = delay - timer.get_difference();
131                 if(next_delay <= 0) next_delay = 0;
133 // Test exit conditions
134                 if(interrupted) 
135                 {
136                         repeat_lock->unlock();
137                         return;
138                 }
139                 if(repeating <= 0)
140                 {
141                         repeat_lock->unlock();
142                         continue;
143                 }
144         }