#include "bctimer.h"
#include "bcwindow.h"
-#include "colors.h"
+#include "bccolors.h"
#include "keys.h"
#include "mutex.h"
#include "condition.h"
this->vw = vw;
this->vh = vh;
this->frame_rate = rate;
- this->cycle_start = 0;
- this->age = 0;
- this->seq_no = 0;
- this->in_use = 1;
+
+ cycle_start = 0;
+ age = 0;
+ seq_no = 0;
+ in_use = 1;
+ hidden = 0;
+ audio_data = 0;
+ audio_size = 0;
+ playing_audio = 0;
}
VIcon::
~VIcon()
{
clear_images();
+ delete [] audio_data;
}
void VIcon::
}
void VIcon::
-draw_vframe(BC_WindowBase *wdw, int x, int y)
+draw_vframe(VIconThread *vt, BC_WindowBase *wdw, int x, int y)
+{
+ VFrame *vfrm = frame();
+ if( !vfrm ) return;
+ int sx0 = 0, sx1 = sx0 + vt->view_w;
+ int sy0 = 0, sy1 = sy0 + vt->view_h;
+ int dx0 = x, dx1 = dx0 + vw;
+ int dy0 = y, dy1 = dy0 + vh;
+ if( (x=vt->draw_x0-dx0) > 0 ) { sx0 += (x*vt->view_w)/vw; dx0 = vt->draw_x0; }
+ if( (x=dx1-vt->draw_x1) > 0 ) { sx1 -= (x*vt->view_w)/vw; dx1 = vt->draw_x1; }
+ if( (y=vt->draw_y0-dy0) > 0 ) { sy0 += (y*vt->view_h)/vh; dy0 = vt->draw_y0; }
+ if( (y=dy1-vt->draw_y1) > 0 ) { sy1 -= (y*vt->view_h)/vh; dy1 = vt->draw_y1; }
+ int sw = sx1 - sx0, sh = sy1 - sy0;
+ int dw = dx1 - dx0, dh = dy1 - dy0;
+ if( dw > 0 && dh > 0 && sw > 0 && sh > 0 )
+ wdw->draw_vframe(vfrm, dx0,dy0, dw,dh, sx0,sy0, sw,sh);
+}
+
+void VIconThread::
+set_drawing_area(int x0, int y0, int x1, int y1)
{
- wdw->draw_vframe(frame(), x,y, vw,vh);
+ draw_x0 = x0; draw_y0 = y0;
+ draw_x1 = x1; draw_y1 = y1;
}
VIcon *VIconThread::low_vicon()
this->view_win = 0; this->vicon = 0;
this->view_w = vw; this->view_h = vh;
this->viewing = 0;
+ this->draw_x0 = 0; this->draw_x1 = wdw->get_w();
+ this->draw_y0 = 0; this->draw_y1 = wdw->get_h();
draw_lock = new Condition(0, "VIconThread::draw_lock", 1);
timer = new Timer();
this->refresh_rate = VICON_RATE;
done = 0;
- interrupted = 1;
+ interrupted = -1;
+ stop_age = 0;
}
VIconThread::
draw_lock->unlock();
if( Thread::running() ) {
Thread::cancel();
- Thread::join();
}
+ Thread::join();
t_heap.remove_all_objects();
delete timer;
delete draw_lock;
wdw->lock_window("VIconThread::start_drawing");
if( view_win )
wdw->set_active_subwindow(view_win);
- if( interrupted )
+ if( interrupted < 0 )
draw_lock->unlock();
+ timer->update();
+ timer->subtract(-stop_age);
+ interrupted = 0;
wdw->unlock_window();
}
{
wdw->lock_window("VIconThread::stop_drawing");
set_view_popup(0);
- interrupted = 1;
+ if( !interrupted )
+ interrupted = 1;
+ stop_age = timer->get_difference();
wdw->unlock_window();
}
return 1;
}
-int ViewPopup::button_press_event()
-{
- vt->set_view_popup(0);
- return 1;
-}
-
bool VIconThread::
visible(VIcon *vicon, int x, int y)
{
- int y0 = 0;
- int my = y + vicon->vh;
- if( my <= y0 ) return false;
- int y1 = y0 + wdw->get_h();
- if( y >= y1 ) return false;
- int x0 = 0;
- int mx = x + vicon->vw;
- if( mx <= x0 ) return false;
- int x1 = x0 + wdw->get_w();
- if( x >= x1 ) return false;
+ if( vicon->hidden ) return false;
+ if( y+vicon->vh <= draw_y0 ) return false;
+ if( y >= draw_y1 ) return false;
+ if( x+vicon->vw <= draw_x0 ) return false;
+ if( x >= draw_x1 ) return false;
return true;
}
int key = get_keypress();
return vt->keypress_event(key);
}
+
ViewPopup::ViewPopup(VIconThread *vt, VFrame *frame, int x, int y, int w, int h)
: BC_Popup(vt->wdw, x, y, w, h, BLACK)
{
void ViewPopup::draw_vframe(VFrame *frame)
{
+ if( !frame ) return;
BC_WindowBase::draw_vframe(frame, 0,0, get_w(),get_h());
}
ViewPopup *VIconThread::new_view_window(VFrame *frame)
{
- int wx = viewing->get_vx() - view_w, rx = 0;
- int wy = viewing->get_vy() - view_h, ry = 0;
- wdw->get_root_coordinates(wx, wy, &rx, &ry);
+ BC_WindowBase *parent = wdw->get_parent();
+ XineramaScreenInfo *info = parent->get_xinerama_info(-1);
+ int cx = info ? info->x_org + info->width/2 : parent->get_root_w(0)/2;
+ int cy = info ? info->y_org + info->height/2 : parent->get_root_h(0)/2;
+ int vx = viewing->get_vx(), rx = 0;
+ int vy = viewing->get_vy(), ry = 0;
+ wdw->get_root_coordinates(vx, vy, &rx, &ry);
+ rx += (rx >= cx ? -view_w : viewing->vw);
+ ry += (ry >= cy ? -view_h : viewing->vh);
ViewPopup *vwin = new ViewPopup(this, frame, rx, ry, view_w, view_h);
wdw->set_active_subwindow(vwin);
return vwin;
int VIconThread::
update_view()
{
+ if( viewing ) viewing->stop_audio();
delete view_win; view_win = 0;
if( (viewing=vicon) != 0 ) {
VFrame *frame = viewing->frame();
view_win = new_view_window(frame);
view_win->show_window();
+ vicon->start_audio();
}
wdw->set_active_subwindow(view_win);
return 1;
if( !draw_img && !draw_win ) return 0;
if( !vicon->frame() ) return 0;
if( draw_img ) {
- vicon->draw_vframe(wdw, x, y);
+ vicon->draw_vframe(this, wdw, x, y);
img_dirty = 1;
}
if( draw_win ) {
return 1;
}
+void VIconThread::hide_vicons(int v)
+{
+ for( int i=0; i<t_heap.size(); ++i ) {
+ t_heap[i]->hidden = v;
+ t_heap[i]->age = 0;
+ }
+}
+
void VIconThread::
run()
{
while(!done) {
draw_lock->lock("VIconThread::run 0");
- if( done ) break;;
+ if( done ) break;
wdw->lock_window("BC_WindowBase::run 1");
- interrupted = 0;
drawing_started();
reset_images();
int64_t seq_no = 0, now = 0;
now = timer->get_difference();
if( now >= draw_flash ) break;
draw(next);
- if( !next->seq_no ) next->cycle_start = now;
+ if( !next->seq_no ) {
+ next->cycle_start = now;
+ if( next->playing_audio )
+ next->start_audio();
+ }
int64_t ref_no = (now - next->cycle_start) / 1000. * refresh_rate;
int count = ref_no - next->seq_no;
if( count < 1 ) count = 1;
}
}
+
+void VIcon::init_audio(int audio_size)
+{
+ this->audio_size = audio_size;
+ audio_data = new uint8_t[audio_size];
+ memset(audio_data, 0, audio_size);
+}
+
void VIcon::dump(const char *dir)
{
mkdir(dir,0777);