4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "bcdisplay.h"
23 #include "bcrepeater.h"
24 #include "bcsignals.h"
26 #include "condition.h"
30 BC_Repeater::BC_Repeater(BC_WindowBase *window, long delay)
33 pause_lock = new Condition(0, "BC_Repeater::pause_lock");
34 startup_lock = new Condition(0, "BC_Repeater::startup_lock");
35 repeat_lock = new Condition(1, "BC_Repeater::repeat_lock");
39 windows.append(window);
43 BC_Repeater::~BC_Repeater()
47 repeat_lock->unlock();
57 void BC_Repeater::initialize()
60 // This is important. It doesn't unblock until the thread is running.
61 startup_lock->lock("BC_Repeater::initialize");
64 int BC_Repeater::start_repeating()
66 //printf("BC_Repeater::start_repeating 1 %d\n", delay);
76 int BC_Repeater::stop_repeating()
78 // Recursive calling happens when mouse wheel is used.
83 if(repeating == 0) pause_lock->lock("BC_Repeater::stop_repeating");
88 int BC_Repeater::start_repeating(BC_WindowBase *window)
90 // Test if the window already exists
91 // for(int i = 0; i < windows.size(); i++)
93 // if(windows.get(i) == window)
98 //printf("BC_Repeater::start_repeating 1 %d\n", delay);
100 // Add window to users
102 windows.append(window);
106 pause_lock->unlock();
111 int BC_Repeater::stop_repeating(BC_WindowBase *window)
113 for(int i = 0; i < windows.size(); i++)
115 if(windows.get(i) == window)
117 // Remove all entries of window
118 windows.remove_number(i);
120 // Recursive calling happens when mouse wheel is used.
127 pause_lock->lock("BC_Repeater::stop_repeating");
137 int BC_Repeater::stop_all_repeating(BC_WindowBase *window)
139 for(int i = 0; i < windows.size(); i++)
141 if(windows.get(i) == window)
143 // Remove all entries of window
144 windows.remove_number(i);
146 // Recursive calling happens when mouse wheel is used.
153 pause_lock->lock("BC_Repeater::stop_repeating");
162 void BC_Repeater::run()
164 //printf("BC_Repeater::run 1 %d\n", getpid());
166 Thread::disable_cancel();
167 startup_lock->unlock();
171 Thread::enable_cancel();
172 timer.delay(next_delay);
173 Thread::disable_cancel();
174 //if(next_delay <= 0) printf("BC_Repeater::run delay=%d next_delay=%d\n", delay, next_delay);
176 // Test exit conditions
177 if(interrupted) return;
179 // if(repeating <= 0) continue;
182 pause_lock->lock("BC_Repeater::run");
183 pause_lock->unlock();
186 // Test exit conditions
187 if(interrupted) return;
188 if(repeating <= 0) continue;
190 // Wait for existing signal to be processed before sending a new one
191 repeat_lock->lock("BC_Repeater::run");
193 // Test exit conditions
196 repeat_lock->unlock();
201 repeat_lock->unlock();
206 BC_Display::display_global->lock_display("BC_Repeater::run");
207 // Test exit conditions again
210 repeat_lock->unlock();
211 BC_Display::display_global->unlock_display();
216 repeat_lock->unlock();
217 BC_Display::display_global->unlock_display();
221 // Stick event into queue
222 BC_Display::display_global->arm_repeat(delay);
223 BC_Display::display_global->unlock_display();
225 // Wait for window to become available.
226 windows.get(0)->lock_window("BC_Repeater::run");
228 // Test exit conditions again
231 repeat_lock->unlock();
232 windows.get(0)->unlock_window();
237 repeat_lock->unlock();
238 windows.get(0)->unlock_window();
242 // Stick event into queue
243 windows.get(0)->arm_repeat(delay);
244 windows.get(0)->unlock_window();
249 next_delay = delay - timer.get_difference();
250 if(next_delay <= 0) next_delay = 0;
252 // Test exit conditions
255 repeat_lock->unlock();
260 repeat_lock->unlock();