mirror of
https://github.com/game-stop/veejay.git
synced 2025-12-19 06:10:01 +01:00
1115 lines
30 KiB
C
1115 lines
30 KiB
C
/* Gveejay Reloaded - graphical interface for VeeJay
|
|
* (C) 2002-2006 Niels Elburg <nelburg@looze.net>
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
#include <config.h>
|
|
#include <libvjnet/vj-client.h>
|
|
#include <libvjmsg/vj-common.h>
|
|
#include <veejay/vims.h>
|
|
#include <gtk/gtk.h>
|
|
#include <string.h>
|
|
#include <gdk/gdkx.h>
|
|
#include <glib.h>
|
|
#include <gdk/gdk.h>
|
|
#include <libvevo/libvevo.h>
|
|
|
|
#include "sequence.h"
|
|
#include "tracksources.h"
|
|
|
|
#define SEQ_BUTTON_CLOSE 0
|
|
#define SEQ_BUTTON_RULE 1
|
|
|
|
#ifdef STRICT_CHECKING
|
|
#include <assert.h>
|
|
#endif
|
|
#include <gveejay-reloaded/common.h>
|
|
#include <gveejay-reloaded/utils.h>
|
|
#include <gveejay-reloaded/widgets/gtktimeselection.h>
|
|
#include <gveejay-reloaded/vj-api.h>
|
|
|
|
#define __MAX_TRACKS 64
|
|
typedef struct
|
|
{
|
|
GtkWidget *event_box;
|
|
GtkWidget *frame;
|
|
GtkWidget *main_vbox;
|
|
GtkWidget *panel;
|
|
GtkWidget *hbox;
|
|
GtkWidget *area;
|
|
GtkWidget *sub_frame;
|
|
GtkWidget *sub_hbox;
|
|
GtkWidget *toggle;
|
|
GtkWidget *buttons[8];
|
|
GtkWidget *icons[8];
|
|
GtkWidget *button_box;
|
|
GtkWidget *timeline_;
|
|
GtkWidget *labels_[4];
|
|
GtkWidget *sliders_[4];
|
|
GtkWidget *button_box2;
|
|
GtkWidget *buttons2[8];
|
|
void *tracks;
|
|
gint dim[2];
|
|
int num;
|
|
int status_lock;
|
|
void *backlink;
|
|
int status_cache[32];
|
|
int history[4][32];
|
|
} sequence_view_t;
|
|
|
|
typedef struct
|
|
{
|
|
sequence_view_t **view;
|
|
void *preview;
|
|
GtkWidget *main_window;
|
|
GtkWidget *main_box;
|
|
GtkWidget *status_bar;
|
|
GtkWidget *scroll;
|
|
void *data;
|
|
int selected;
|
|
int sensitive;
|
|
float fps;
|
|
int width;
|
|
int height;
|
|
int master_track;
|
|
GdkPixbuf *logo;
|
|
GtkWidget *preview_toggle;
|
|
int pw;
|
|
int ph;
|
|
} multitracker_t;
|
|
|
|
static volatile int MAX_TRACKS = 4;
|
|
|
|
|
|
static int mt_new_connection_dialog(multitracker_t *mt, char *hostname,int len, int *port_num);
|
|
static void add_buttons( sequence_view_t *p, sequence_view_t *seqv , GtkWidget *w);
|
|
static void add_buttons2( sequence_view_t *p, sequence_view_t *seqv , GtkWidget *w);
|
|
static sequence_view_t *new_sequence_view( void *vp, int num );
|
|
static void update_pos( void *data, gint total, gint current );
|
|
static gboolean seqv_mouse_press_event ( GtkWidget *w, GdkEventButton *event, gpointer user_data);
|
|
|
|
|
|
static void gtk_image_set_from_pixbuf__( GtkImage *w, GdkPixbuf *p, const char *f, int l )
|
|
{
|
|
gtk_image_set_from_pixbuf(w, p);
|
|
}
|
|
|
|
|
|
static void gtk_widget_set_sensitive__( GtkWidget *w, gboolean state, const char *f, int l )
|
|
{
|
|
#ifdef STRICT_CHECKING
|
|
if( !GTK_IS_WIDGET(w) )
|
|
veejay_msg(0, "Invalid widget '%s', %d", f, l );
|
|
assert( GTK_IS_WIDGET(w) );
|
|
#endif
|
|
gtk_widget_set_sensitive(w, state );
|
|
}
|
|
|
|
#ifdef STRICT_CHECKING
|
|
#define gtk_image_set_from_pixbuf_(w,p) gtk_image_set_from_pixbuf__( w,p, __FUNCTION__,__LINE__ );
|
|
#define gtk_widget_set_sensitive_( w,p ) gtk_widget_set_sensitive__( w,p,__FUNCTION__,__LINE__ )
|
|
#else
|
|
#define gtk_image_set_from_pixbuf_(w,p) gtk_image_set_from_pixbuf(w,p)
|
|
#define gtk_widget_set_sensitive_( w,p ) gtk_widget_set_sensitive(w,p)
|
|
#endif
|
|
static void status_print(multitracker_t *mt, const char format[], ... )
|
|
{
|
|
char buf[1024];
|
|
va_list args;
|
|
bzero(buf,1024);
|
|
va_start(args,format);
|
|
vsnprintf( buf,sizeof(buf), format, args );
|
|
int nr,nw;
|
|
gchar *text = g_locale_to_utf8( buf, -1, &nr, &nw, NULL );
|
|
text[strlen(text)-1] = '\0';
|
|
gtk_statusbar_push( GTK_STATUSBAR(mt->status_bar), 0, text);
|
|
g_free(text);
|
|
va_end(args);
|
|
}
|
|
|
|
static GdkPixbuf *load_logo_image( )
|
|
{
|
|
char path[1024];
|
|
bzero(path,1024);
|
|
get_gd(path,NULL, "veejay-logo.png");
|
|
return gdk_pixbuf_new_from_file( path,NULL );
|
|
}
|
|
|
|
int multitrack_get_sequence_view_id( void *data )
|
|
{
|
|
sequence_view_t *s = (sequence_view_t*) data;
|
|
return s->num;
|
|
}
|
|
|
|
static void set_logo(GtkWidget *area)
|
|
{
|
|
/* GdkPixbuf *buf2 = gdk_pixbuf_scale_simple( logo_img_,114,96, GDK_INTERP_BILINEAR );
|
|
gtk_image_set_from_pixbuf_( GTK_IMAGE(area), buf2 );
|
|
gdk_pixbuf_unref( buf2 );*/
|
|
}
|
|
|
|
void multitrack_sync_start(void *data)
|
|
{
|
|
multitracker_t *mt = (multitracker_t*)data;
|
|
gvr_queue_vims( mt->preview,-1,VIMS_VIDEO_PLAY_STOP );
|
|
gvr_queue_vims( mt->preview,-1,VIMS_VIDEO_GOTO_START );
|
|
gvr_queue_vims( mt->preview,-1,VIMS_VIDEO_PLAY_FORWARD );
|
|
}
|
|
|
|
static void seq_gotostart(GtkWidget *w, gpointer data )
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) data;
|
|
multitracker_t *mt = (multitracker_t*)v->backlink;
|
|
|
|
gvr_queue_vims( mt->preview, v->num ,VIMS_VIDEO_GOTO_START );
|
|
}
|
|
|
|
static void seq_reverse(GtkWidget *w, gpointer data)
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) data;
|
|
multitracker_t *mt = (multitracker_t*)v->backlink;
|
|
|
|
gvr_queue_vims( mt->preview, v->num ,VIMS_VIDEO_PLAY_BACKWARD );
|
|
}
|
|
|
|
static void seq_pause(GtkWidget *w, gpointer data)
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) data;
|
|
multitracker_t *mt = (multitracker_t*)v->backlink;
|
|
|
|
gvr_queue_vims( mt->preview, v->num ,VIMS_VIDEO_PLAY_STOP );
|
|
}
|
|
|
|
static void seq_play( GtkWidget *w, gpointer data)
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) data;
|
|
multitracker_t *mt = (multitracker_t*)v->backlink;
|
|
|
|
gvr_queue_vims( mt->preview, v->num ,VIMS_VIDEO_PLAY_FORWARD );
|
|
}
|
|
|
|
static void seq_gotoend(GtkWidget *w, gpointer data)
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) data;
|
|
multitracker_t *mt = (multitracker_t*)v->backlink;
|
|
|
|
gvr_queue_vims( mt->preview, v->num ,VIMS_VIDEO_GOTO_END );
|
|
}
|
|
|
|
static void seq_speeddown(GtkWidget *w, gpointer data)
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) data;
|
|
multitracker_t *mt = (multitracker_t*)v->backlink;
|
|
|
|
gint n = v->status_cache[ SAMPLE_SPEED ];
|
|
|
|
if( n < 0 ) n += 1;
|
|
if( n > 0 ) n -= 1;
|
|
|
|
gvr_queue_mvims( mt->preview, v->num ,VIMS_VIDEO_SET_SPEED , n );
|
|
}
|
|
|
|
static void seq_speedup(GtkWidget *w, gpointer data)
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) data;
|
|
multitracker_t *mt = (multitracker_t*)v->backlink;
|
|
|
|
gint n = v->status_cache[ SAMPLE_SPEED ];
|
|
|
|
if( n < 0 ) n -= 1;
|
|
if( n > 0 ) n += 1;
|
|
|
|
gvr_queue_mvims( mt->preview, v->num ,VIMS_VIDEO_SET_SPEED , n );
|
|
}
|
|
|
|
static void seq_prevframe(GtkWidget *w, gpointer data)
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) data;
|
|
multitracker_t *mt = (multitracker_t*)v->backlink;
|
|
|
|
gvr_queue_vims( mt->preview, v->num ,VIMS_VIDEO_PREV_FRAME );
|
|
|
|
}
|
|
|
|
static void seq_nextframe(GtkWidget *w, gpointer data)
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) data;
|
|
multitracker_t *mt = (multitracker_t*)v->backlink;
|
|
|
|
gvr_queue_vims( mt->preview, v->num ,VIMS_VIDEO_SKIP_FRAME );
|
|
}
|
|
|
|
static void seq_speed( GtkWidget *w, gpointer data)
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) data;
|
|
multitracker_t *mt = v->backlink;
|
|
if(v->status_lock)
|
|
return;
|
|
|
|
gdouble value = GTK_ADJUSTMENT( GTK_RANGE(w)->adjustment )->value;
|
|
gint speed = (gint) value;
|
|
gvr_queue_mvims( mt->preview, v->num ,VIMS_VIDEO_SET_SPEED , speed );
|
|
}
|
|
|
|
static void seq_opacity( GtkWidget *w, gpointer data)
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) data;
|
|
multitracker_t *mt = v->backlink;
|
|
|
|
if(v->status_lock)
|
|
return;
|
|
|
|
gdouble value = GTK_ADJUSTMENT( GTK_RANGE(w)->adjustment )->value;
|
|
gint opacity = (gint)( value * 255.0);
|
|
gvr_queue_mmvims( mt->preview, v->num ,VIMS_CHAIN_MANUAL_FADE, 0, opacity );
|
|
}
|
|
|
|
|
|
static void update_pos( void *user_data, gint total, gint current )
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) user_data;
|
|
multitracker_t *mt = v->backlink;
|
|
if(v->status_lock)
|
|
return;
|
|
|
|
gtk_adjustment_set_value(
|
|
GTK_ADJUSTMENT(GTK_RANGE(v->timeline_)->adjustment), 1.0 / (gdouble) total * current );
|
|
|
|
char *now = format_time( current , mt->fps);
|
|
gtk_label_set_text( v->labels_[0], now );
|
|
g_free(now);
|
|
}
|
|
|
|
static void update_speed( void *user_data, gint speed )
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) user_data;
|
|
multitracker_t *mt = v->backlink;
|
|
if(v->status_lock)
|
|
return;
|
|
|
|
gtk_adjustment_set_value( GTK_ADJUSTMENT( GTK_RANGE( v->sliders_[0] )->adjustment), (gdouble) speed );
|
|
}
|
|
|
|
#define FIRST_ROW_END 5
|
|
static struct
|
|
{
|
|
const char *name;
|
|
int vims_id;
|
|
const char *file;
|
|
void (*f)();
|
|
} button_template_t[] =
|
|
{
|
|
{ "button_gotostart", VIMS_VIDEO_GOTO_START, "button_gotostart.png", seq_gotostart },
|
|
{ "button_reverse", VIMS_VIDEO_PLAY_BACKWARD, "button_reverse.png" , seq_reverse },
|
|
{ "button_pauseplay", VIMS_VIDEO_PLAY_STOP, "button_pause.png", seq_pause},
|
|
{ "button_play", VIMS_VIDEO_PLAY_FORWARD, "button_play.png", seq_play },
|
|
{ "button_gotoend", VIMS_VIDEO_GOTO_END, "button_gotoend.png",seq_gotoend },
|
|
|
|
{ "button_speeddown", VIMS_VIDEO_SET_SPEED, "button_down.png", seq_speeddown },
|
|
{ "button_speedup", VIMS_VIDEO_SET_SPEED, "button_up.png", seq_speedup },
|
|
{ "button_prevframe", VIMS_VIDEO_PREV_FRAME, "button_prev.png", seq_prevframe },
|
|
{ "button_nextframe", VIMS_VIDEO_SKIP_FRAME, "button_skip.png", seq_nextframe },
|
|
{ NULL , 0 , NULL },
|
|
};
|
|
|
|
static void add_buttons( sequence_view_t *p, sequence_view_t *seqv , GtkWidget *w)
|
|
{
|
|
int i;
|
|
for( i = 0; i < FIRST_ROW_END;i ++ )
|
|
{
|
|
char path[1024];
|
|
bzero(path,1024);
|
|
get_gd(path,NULL, button_template_t[i].file );
|
|
seqv->icons[i] = gtk_image_new_from_file( path );
|
|
seqv->buttons[i] = gtk_button_new_with_label(" ");
|
|
gtk_widget_set_size_request( seqv->icons[i],24,20 );
|
|
|
|
gtk_button_set_image( GTK_BUTTON(seqv->buttons[i]), seqv->icons[i] );
|
|
gtk_widget_set_size_request( seqv->buttons[i],24,20 );
|
|
gtk_box_pack_start( GTK_BOX(w), seqv->buttons[i], TRUE,TRUE, 0 );
|
|
g_signal_connect( G_OBJECT( seqv->buttons[i] ), "clicked", G_CALLBACK( button_template_t[i].f),
|
|
(gpointer)p );
|
|
gtk_widget_show( seqv->buttons[i] );
|
|
|
|
}
|
|
}
|
|
|
|
static void add_buttons2( sequence_view_t *p, sequence_view_t *seqv , GtkWidget *w)
|
|
{
|
|
int i;
|
|
for( i = FIRST_ROW_END; button_template_t[i].name != NULL ;i ++ )
|
|
{
|
|
char path[1024];
|
|
bzero(path,1024);
|
|
get_gd(path,NULL, button_template_t[i].file );
|
|
seqv->icons[i] = gtk_image_new_from_file( path );
|
|
seqv->buttons2[i] = gtk_button_new_with_label(" ");
|
|
gtk_widget_set_size_request( seqv->icons[i],24,20 );
|
|
|
|
gtk_button_set_image( GTK_BUTTON(seqv->buttons2[i]), seqv->icons[i] );
|
|
gtk_widget_set_size_request( seqv->buttons2[i],24,20 );
|
|
gtk_box_pack_start( GTK_BOX(w), seqv->buttons2[i], TRUE,TRUE, 0 );
|
|
g_signal_connect( G_OBJECT( seqv->buttons2[i] ), "clicked", G_CALLBACK( button_template_t[i].f),
|
|
(gpointer*)p );
|
|
gtk_widget_show( seqv->buttons2[i] );
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void playmode_sensitivity( sequence_view_t *p, gint pm )
|
|
{
|
|
int i;
|
|
#ifdef STRICT_CHECKING
|
|
assert( p != NULL );
|
|
#endif
|
|
if( pm == MODE_STREAM || MODE_PLAIN || MODE_SAMPLE )
|
|
{
|
|
if(p->toggle)
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->toggle ), TRUE );
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->panel ), TRUE );
|
|
|
|
}
|
|
|
|
if( pm == MODE_STREAM )
|
|
{
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->button_box2 ), FALSE );
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->button_box ), FALSE );
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->sliders_[0] ), FALSE );
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->timeline_ ), FALSE );
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->sliders_[1] ), TRUE );
|
|
for( i = 0; i < FIRST_ROW_END;i ++ )
|
|
{
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->buttons[i] ), FALSE );
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pm == MODE_SAMPLE || pm == MODE_PLAIN )
|
|
{
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->button_box2 ), TRUE );
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->button_box ), TRUE );
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->sliders_[0] ), TRUE );
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->timeline_ ), TRUE );
|
|
for( i = 0; i < FIRST_ROW_END;i ++ )
|
|
{
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->buttons[i] ), TRUE );
|
|
}
|
|
|
|
}
|
|
if( pm == MODE_SAMPLE )
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->sliders_[1] ), TRUE );
|
|
else
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( p->sliders_[1] ), FALSE );
|
|
}
|
|
}
|
|
|
|
|
|
static void update_widgets(int *status, sequence_view_t *p, int pm)
|
|
{
|
|
multitracker_t *mt = (multitracker_t*) p->backlink;
|
|
int *h = p->history[pm];
|
|
if( h[PLAY_MODE] != pm )
|
|
playmode_sensitivity( p, pm );
|
|
|
|
if( pm == MODE_STREAM )
|
|
{
|
|
update_pos( p, status[TOTAL_FRAMES], 0 );
|
|
update_speed( p, 1 );
|
|
}
|
|
else
|
|
if( pm == MODE_SAMPLE || pm == MODE_PLAIN )
|
|
{
|
|
if( h[FRAME_NUM] != status[FRAME_NUM] )
|
|
update_pos( p, status[TOTAL_FRAMES],status[FRAME_NUM] );
|
|
if( h[SAMPLE_SPEED] != status[SAMPLE_SPEED] )
|
|
update_speed( p, status[SAMPLE_SPEED] );
|
|
}
|
|
|
|
if( h[TOTAL_SLOTS] != status[TOTAL_SLOTS])
|
|
{
|
|
gvr_need_track_list( mt->preview, p->num );
|
|
update_track_view( MAX_TRACKS, get_track_tree( p->tracks ), (void*)p );
|
|
}
|
|
}
|
|
|
|
|
|
int update_multitrack_widgets( void *data, int *array, int track )
|
|
{
|
|
multitracker_t *mt = (multitracker_t*) data;
|
|
sequence_view_t *p = mt->view[ track ];
|
|
|
|
p->status_lock = 1;
|
|
int pm = array[PLAY_MODE];
|
|
int i;
|
|
for( i = 0; i < 20; i ++ )
|
|
p->status_cache[i] = array[i];
|
|
update_widgets(array, p, pm);
|
|
|
|
int *his = p->history[ pm ];
|
|
for( i = 0; i < 20; i ++ )
|
|
his[i] = array[i];
|
|
p->status_lock = 0;
|
|
}
|
|
|
|
/*
|
|
|
|
|
|
static gboolean update_sequence_widgets( gpointer data )
|
|
{
|
|
mt_priv_t *p = (mt_priv_t*) data;
|
|
char status[108];
|
|
int array[101];
|
|
|
|
if( !p->active )
|
|
return TRUE;
|
|
|
|
|
|
p->status_lock = 1;
|
|
|
|
|
|
int pm = array[PLAY_MODE];
|
|
int i;
|
|
for( i = 0; i < 20; i ++ )
|
|
p->status_cache[i] = array[i];
|
|
|
|
update_widgets(array, p, pm);
|
|
|
|
int *his = p->history[ pm ];
|
|
for( i = 0; i < 20; i ++ )
|
|
his[i] = array[i];
|
|
p->status_lock = 0;
|
|
return TRUE;
|
|
}*/
|
|
|
|
static void sequence_preview_size(multitracker_t *mt, int track_num)
|
|
{
|
|
float ratio = mt->width / (float)mt->height;
|
|
int w = 80;
|
|
int h = ( (int)( (float)w/ratio ))/16*16;
|
|
|
|
if(!gvr_track_configure( mt->preview, track_num,w,h ) )
|
|
{
|
|
veejay_msg(0, "Unable to configure preview %d x %d",w , h );
|
|
}
|
|
|
|
}
|
|
|
|
static void sequence_preview_cb(GtkWidget *widget, gpointer user_data)
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) user_data;
|
|
multitracker_t *mt = v->backlink;
|
|
int status = (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ) == TRUE ? 1 : 0 );
|
|
|
|
if(v->status_lock)
|
|
return;
|
|
|
|
gvr_track_toggle_preview( mt->preview, v->num,status );
|
|
|
|
sequence_preview_size( mt, v->num );
|
|
|
|
if( !status )
|
|
{
|
|
float ratio = mt->width / (float) mt->height;
|
|
int w = 160;
|
|
int h = ( (int)( (float)w / ratio)) /16*16;
|
|
GdkPixbuf *logo = gdk_pixbuf_scale_simple( mt->logo, w,h, GDK_INTERP_BILINEAR );
|
|
gtk_image_set_from_pixbuf_(
|
|
GTK_IMAGE( v->area ), logo );
|
|
veejay_msg(2, "Set GVeejayReloaded logo %d x %d",w,h);
|
|
gdk_pixbuf_unref( logo );
|
|
}
|
|
}
|
|
|
|
static void sequence_set_current_frame(GtkWidget *w, gpointer user_data)
|
|
{
|
|
|
|
sequence_view_t *v = (sequence_view_t*) user_data;
|
|
multitracker_t *mt = v->backlink;
|
|
if(v->status_lock)
|
|
return;
|
|
|
|
gdouble pos = GTK_ADJUSTMENT(GTK_RANGE(w)->adjustment)->value;
|
|
gint frame = pos * v->status_cache[TOTAL_FRAMES];
|
|
|
|
gvr_queue_mvims( mt->preview, v->num, VIMS_VIDEO_SET_FRAME, frame );
|
|
}
|
|
|
|
static sequence_view_t *new_sequence_view( void *vp, int num )
|
|
{
|
|
sequence_view_t *seqv = (sequence_view_t*) vj_calloc(sizeof(sequence_view_t));
|
|
|
|
seqv->num = num;
|
|
seqv->backlink = vp;
|
|
|
|
seqv->event_box = gtk_event_box_new();
|
|
gtk_event_box_set_visible_window( seqv->event_box, TRUE );
|
|
GTK_WIDGET_SET_FLAGS( seqv->event_box, GTK_CAN_FOCUS );
|
|
|
|
g_signal_connect( G_OBJECT( seqv->event_box ),
|
|
"button_press_event",
|
|
G_CALLBACK( seqv_mouse_press_event ),
|
|
(gpointer*) seqv );
|
|
gtk_widget_show( GTK_WIDGET( seqv->event_box ) );
|
|
|
|
|
|
gchar *track_title = g_new0( gchar, 20 );
|
|
sprintf(track_title, "Track %d", num );
|
|
seqv->frame = gtk_frame_new( track_title );
|
|
g_free(track_title);
|
|
|
|
gtk_container_set_border_width( GTK_CONTAINER( seqv->frame) , 1 );
|
|
gtk_widget_show( GTK_WIDGET( seqv->frame ) );
|
|
gtk_container_add( GTK_CONTAINER( seqv->event_box), seqv->frame );
|
|
|
|
seqv->main_vbox = gtk_vbox_new(FALSE,0);
|
|
gtk_container_add( GTK_CONTAINER( seqv->frame ), seqv->main_vbox );
|
|
gtk_widget_show( GTK_WIDGET( seqv->main_vbox ) );
|
|
|
|
seqv->area = gtk_image_new();
|
|
|
|
|
|
gtk_box_pack_start( GTK_BOX(seqv->main_vbox),GTK_WIDGET( seqv->area), FALSE,FALSE,0);
|
|
gtk_widget_set_size_request( seqv->area, 176,176 );
|
|
seqv->panel = gtk_frame_new(NULL);
|
|
|
|
if( num > 0 )
|
|
{
|
|
seqv->toggle = gtk_toggle_button_new_with_label( "preview" );
|
|
|
|
gtk_toggle_button_set_active(
|
|
GTK_TOGGLE_BUTTON(seqv->toggle), FALSE );
|
|
g_signal_connect( G_OBJECT( seqv->toggle ), "toggled", G_CALLBACK(sequence_preview_cb),
|
|
(gpointer)seqv );
|
|
gtk_box_pack_start( GTK_BOX(seqv->main_vbox), seqv->toggle,FALSE,FALSE, 0 );
|
|
|
|
gtk_widget_set_sensitive_( GTK_WIDGET( seqv->toggle ), FALSE );
|
|
|
|
gtk_widget_show( seqv->toggle );
|
|
}
|
|
|
|
GtkWidget *vvbox = gtk_vbox_new(FALSE, 0);
|
|
seqv->button_box = gtk_hbox_new(FALSE,0);
|
|
gtk_box_pack_start( GTK_BOX(vvbox), seqv->button_box ,FALSE,FALSE, 0 );
|
|
add_buttons( seqv,seqv,seqv->button_box );
|
|
|
|
gtk_widget_show( seqv->button_box );
|
|
gtk_container_add( GTK_CONTAINER( seqv->main_vbox ), seqv->panel );
|
|
|
|
seqv->button_box2 = gtk_hbox_new(FALSE, 0);
|
|
gtk_box_pack_start( GTK_BOX(vvbox), seqv->button_box2, FALSE,FALSE, 0 );
|
|
add_buttons2( seqv,seqv,seqv->button_box2 );
|
|
gtk_widget_show( seqv->button_box2 );
|
|
gtk_container_add( GTK_CONTAINER( seqv->panel ), vvbox );
|
|
gtk_widget_show(vvbox);
|
|
|
|
GtkWidget *box = gtk_vbox_new(FALSE,0);
|
|
seqv->timeline_ = gtk_hscale_new_with_range( 0.0,1.0,0.1 );
|
|
gtk_scale_set_draw_value( seqv->timeline_, FALSE );
|
|
gtk_widget_set_size_request( seqv->panel,180 ,180);
|
|
gtk_adjustment_set_value(
|
|
GTK_ADJUSTMENT(GTK_RANGE(seqv->timeline_)->adjustment), 0.0 );
|
|
gtk_widget_show( seqv->panel );
|
|
gtk_box_pack_start( GTK_BOX( box ), seqv->timeline_, FALSE,FALSE, 0 );
|
|
gtk_box_pack_start( GTK_BOX( vvbox ), box , FALSE,FALSE,0);
|
|
gtk_widget_show(seqv->timeline_);
|
|
g_signal_connect( seqv->timeline_, "value_changed",
|
|
(GCallback) sequence_set_current_frame, (gpointer*) seqv );
|
|
|
|
GtkWidget *scroll = gtk_scrolled_window_new(NULL,NULL);
|
|
gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW(scroll), GTK_SHADOW_ETCHED_IN );
|
|
gtk_widget_set_size_request(scroll,30,70);
|
|
gtk_container_set_border_width(GTK_CONTAINER(scroll),0);
|
|
gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(scroll),GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
|
|
GtkWidget *vvvbox = gtk_hbox_new(FALSE,0);
|
|
seqv->tracks = create_track_view(seqv->num, MAX_TRACKS, (void*) seqv );
|
|
gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( get_track_tree(seqv->tracks)) , FALSE );
|
|
gtk_widget_set_size_request( get_track_tree(seqv->tracks),20,80 );
|
|
gtk_widget_show(scroll);
|
|
|
|
gtk_scrolled_window_add_with_viewport(
|
|
GTK_SCROLLED_WINDOW( scroll ), get_track_tree(seqv->tracks) );
|
|
gtk_widget_show( get_track_tree(seqv->tracks));
|
|
gtk_box_pack_start( GTK_BOX(vvvbox), scroll, TRUE,TRUE, 0);
|
|
|
|
GtkWidget *hhbox = gtk_hbox_new(FALSE,0);
|
|
|
|
seqv->sliders_[0] = gtk_vscale_new_with_range( -12.0,12.0,1.0 );
|
|
seqv->sliders_[1] = gtk_vscale_new_with_range( 0.0, 1.0, 0.01 );
|
|
|
|
gtk_adjustment_set_value(
|
|
GTK_ADJUSTMENT(GTK_RANGE(seqv->sliders_[0])->adjustment), 1.0 );
|
|
gtk_adjustment_set_value(
|
|
GTK_ADJUSTMENT(GTK_RANGE(seqv->sliders_[1])->adjustment), 0.0 );
|
|
|
|
|
|
gtk_scale_set_digits( GTK_SCALE(seqv->sliders_[1]), 2 );
|
|
g_signal_connect( G_OBJECT( seqv->sliders_[0] ), "value_changed", G_CALLBACK( seq_speed ),
|
|
(gpointer*)seqv );
|
|
g_signal_connect( G_OBJECT( seqv->sliders_[1] ), "value_changed", G_CALLBACK( seq_opacity ),
|
|
(gpointer*)seqv );
|
|
|
|
gtk_box_pack_start( GTK_BOX( hhbox ), seqv->sliders_[0], TRUE, TRUE, 0 );
|
|
gtk_box_pack_start( GTK_BOX( hhbox ), seqv->sliders_[1], TRUE, TRUE, 0 );
|
|
gtk_widget_show( seqv->sliders_[0] );
|
|
gtk_widget_show( seqv->sliders_[1] );
|
|
gtk_box_pack_start( GTK_BOX(vvvbox), hhbox, TRUE,TRUE, 0 );
|
|
gtk_widget_show( hhbox );
|
|
gtk_container_add( GTK_CONTAINER( box ), vvvbox );
|
|
gtk_widget_show( vvvbox );
|
|
gtk_widget_show( box );
|
|
|
|
|
|
GtkWidget *hbox = gtk_hbox_new(FALSE,0);
|
|
gtk_box_set_spacing( hbox, 10 );
|
|
seqv->labels_[0] = gtk_label_new( "00:00:00:00" );
|
|
seqv->labels_[1] = gtk_label_new( "00:00:00:00" );
|
|
gtk_box_pack_start( GTK_BOX( hbox ), seqv->labels_[0], FALSE, FALSE, 0 );
|
|
gtk_box_pack_start( GTK_BOX( hbox ), seqv->labels_[1], FALSE, FALSE, 0 );
|
|
gtk_widget_show( seqv->labels_[0] );
|
|
gtk_widget_show( seqv->labels_[1] );
|
|
gtk_box_pack_start( GTK_BOX(seqv->main_vbox), hbox, FALSE,FALSE, 0 );
|
|
gtk_widget_show( hbox );
|
|
|
|
|
|
gtk_widget_set_sensitive_(GTK_WIDGET(seqv->panel), FALSE );
|
|
|
|
gtk_widget_show( GTK_WIDGET( seqv->area ) );
|
|
|
|
return seqv;
|
|
}
|
|
|
|
|
|
static int vt__[16];
|
|
static int vt___ = 0;
|
|
void *multitrack_sync( void * mt )
|
|
{
|
|
multitracker_t *m = (multitracker_t*) mt;
|
|
sync_info *s = gvr_sync( m->preview );
|
|
if(!vt___)
|
|
{
|
|
veejay_memset(vt__,0,sizeof(vt__));
|
|
vt___ = 1;
|
|
}
|
|
|
|
int i;
|
|
for( i =0; i < MAX_TRACKS ;i ++ )
|
|
{
|
|
if(!vt__[i] && s->status_list[i] == NULL )
|
|
{
|
|
//gtk_widget_set_sensitive_(GTK_WIDGET(m->view[i]), FALSE );
|
|
vt__[i] = 1;
|
|
}
|
|
else if( s->status_list[i] && vt__[i] )
|
|
{
|
|
//gtk_widget_set_sensitive_(GTK_WIDGET(m->view[i]), TRUE );
|
|
vt__[i] = 0;
|
|
}
|
|
}
|
|
s->master = m->master_track;
|
|
return (void*)s;
|
|
}
|
|
|
|
static int mt_new_connection_dialog(multitracker_t *mt, char *hostname,int len, int *port_num)
|
|
{
|
|
GtkWidget *dialog = gtk_dialog_new_with_buttons(
|
|
"Connect to a Veejay",
|
|
GTK_WINDOW( mt->main_box ),
|
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
GTK_STOCK_CANCEL,
|
|
GTK_RESPONSE_REJECT,
|
|
GTK_STOCK_OK,
|
|
GTK_RESPONSE_ACCEPT,
|
|
NULL );
|
|
|
|
|
|
GtkWidget *text_entry = gtk_entry_new();
|
|
gtk_entry_set_text( GTK_ENTRY(text_entry), "localhost" );
|
|
gtk_editable_set_editable( GTK_ENTRY(text_entry), TRUE );
|
|
gtk_dialog_set_default_response( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
|
|
gtk_window_set_resizable( GTK_WINDOW( dialog ), FALSE );
|
|
|
|
gint base = 3490;
|
|
|
|
gint p = (1000 * (mt->selected)) + base;
|
|
|
|
GtkObject *adj = gtk_adjustment_new( p,1024,65535,5,10,0);
|
|
GtkWidget *num_entry = gtk_spin_button_new( adj, 5.0, 0 );
|
|
|
|
GtkWidget *text_label = gtk_label_new( "Hostname" );
|
|
GtkWidget *num_label = gtk_label_new( "Port" );
|
|
g_signal_connect( G_OBJECT(dialog), "response",
|
|
G_CALLBACK( gtk_widget_hide ), G_OBJECT( dialog ) );
|
|
|
|
GtkWidget *vbox = gtk_vbox_new( FALSE, 4 );
|
|
gtk_container_add( GTK_CONTAINER( vbox ), text_label );
|
|
gtk_container_add( GTK_CONTAINER( vbox ), text_entry );
|
|
gtk_container_add( GTK_CONTAINER( vbox ), num_label );
|
|
gtk_container_add( GTK_CONTAINER( vbox ), num_entry );
|
|
gtk_container_add( GTK_CONTAINER( GTK_DIALOG(dialog)->vbox), vbox );
|
|
gtk_widget_show_all( dialog );
|
|
|
|
gint res = gtk_dialog_run( GTK_DIALOG(dialog) );
|
|
|
|
if( res == GTK_RESPONSE_ACCEPT )
|
|
{
|
|
gchar *host = gtk_entry_get_text( GTK_ENTRY( text_entry ) );
|
|
gint port = gtk_spin_button_get_value( GTK_SPIN_BUTTON(num_entry ));
|
|
strncpy( hostname, host, len );
|
|
*port_num = port;
|
|
}
|
|
|
|
gtk_widget_destroy( dialog );
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
void *multitrack_new(
|
|
void (*f)(int,char*,int),
|
|
int (*g)(GdkPixbuf *, GdkPixbuf *, GtkImage *),
|
|
GtkWidget *win,
|
|
GtkWidget *box,
|
|
GtkWidget *msg,
|
|
GtkWidget *preview_toggle,
|
|
gint max_w,
|
|
gint max_h,
|
|
GtkWidget *main_preview_area)
|
|
{
|
|
multitracker_t *mt = NULL;
|
|
|
|
mt = (multitracker_t*) vj_calloc(sizeof(multitracker_t));
|
|
mt->view = (sequence_view_t*) vj_calloc(sizeof(sequence_view_t*) * MAX_TRACKS );
|
|
mt->preview = NULL;
|
|
mt->main_window = win;
|
|
mt->main_box = box;
|
|
mt->status_bar = msg;
|
|
mt->logo = load_logo_image();
|
|
mt->preview_toggle = preview_toggle;
|
|
mt->scroll = gtk_scrolled_window_new(NULL,NULL);
|
|
gtk_widget_set_size_request(mt->scroll,450, 300);
|
|
gtk_container_set_border_width(GTK_CONTAINER(mt->scroll),1);
|
|
gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(mt->scroll),GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS );
|
|
GtkWidget *table = gtk_table_new( 1, MAX_TRACKS, FALSE );
|
|
gtk_box_pack_start( GTK_BOX( mt->main_box ), mt->scroll , FALSE,FALSE, 0 );
|
|
gtk_widget_show(mt->scroll);
|
|
|
|
int c = 0;
|
|
for( c = 0; c < MAX_TRACKS; c ++ )
|
|
{
|
|
mt->view[c] = new_sequence_view( mt, c );
|
|
gtk_table_attach_defaults( table, mt->view[c]->event_box, c, c+1, 0, 1 );
|
|
}
|
|
|
|
gtk_scrolled_window_add_with_viewport(
|
|
GTK_SCROLLED_WINDOW( mt->scroll ), table );
|
|
|
|
gtk_widget_show(table);
|
|
|
|
mt->master_track = 0;
|
|
|
|
|
|
mt->preview = gvr_preview_init( MAX_TRACKS );
|
|
|
|
|
|
|
|
return (void*) mt;
|
|
}
|
|
|
|
|
|
int multitrack_add_track( void *data )
|
|
{
|
|
multitracker_t *mt = (multitracker_t*) data;
|
|
int res = 0;
|
|
char *hostname = vj_calloc( 100 );
|
|
int port_num = 0;
|
|
|
|
if( mt_new_connection_dialog( mt, hostname, 100, &port_num ) == GTK_RESPONSE_ACCEPT )
|
|
{
|
|
int track = 0;
|
|
|
|
if( gvr_track_connect( mt->preview, hostname, port_num, &track ) )
|
|
{
|
|
status_print( mt, "Connection established with veejay runnning on %s port %d",
|
|
hostname, port_num );
|
|
|
|
// gtk_widget_set_sensitive_(GTK_WIDGET(mt->view[track]->panel), TRUE );
|
|
// gtk_widget_set_sensitive_(GTK_WIDGET(mt->view[track]->toggle), TRUE );
|
|
res = 1;
|
|
}
|
|
else
|
|
{
|
|
status_print( mt, "Unable to open connection with %s : %d", hostname, port_num );
|
|
}
|
|
}
|
|
|
|
free( hostname );
|
|
|
|
return res;
|
|
}
|
|
|
|
void multitrack_close_track( void *data )
|
|
{
|
|
multitracker_t *mt = (multitracker_t*) data;
|
|
|
|
if( mt->selected > 0 && mt->selected < MAX_TRACKS )
|
|
{
|
|
gvr_track_disconnect( mt->preview, mt->selected );
|
|
mt->view[mt->selected]->status_lock = 1;
|
|
gtk_toggle_button_set_active(
|
|
GTK_TOGGLE_BUTTON(mt->view[mt->selected]->toggle), FALSE );
|
|
|
|
gtk_widget_set_sensitive_(GTK_WIDGET(mt->view[mt->selected]->panel), FALSE );
|
|
mt->view[mt->selected]->status_lock = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int multrack_audoadd( void *data, char *hostname, int port_num )
|
|
{
|
|
multitracker_t *mt = (multitracker_t*) data;
|
|
|
|
int track = 0;
|
|
|
|
if(!gvr_track_connect( mt->preview, hostname, port_num, &track ) )
|
|
{
|
|
if(!gvr_track_already_open( mt->preview, hostname,port_num))
|
|
return -1;
|
|
}
|
|
|
|
if(mt->pw > 0 && mt->ph > 0 )
|
|
{
|
|
/* re-configure current master track for preview-size */
|
|
sequence_preview_size( mt, mt->master_track );
|
|
|
|
/* configure master preview size */
|
|
if(!gvr_track_configure( mt->preview, track, mt->pw,mt->ph ) )
|
|
{
|
|
veejay_msg(0, "Unable to configure preview %d x %d",mt->pw , mt->ph );
|
|
}
|
|
|
|
|
|
int preview = gvr_get_preview_status( mt->preview, mt->master_track );
|
|
|
|
/* set status of preview toggle button in trackview */
|
|
if( track == 0 )
|
|
{
|
|
mt->view[track]->status_lock=1;
|
|
gtk_toggle_button_set_active(
|
|
GTK_TOGGLE_BUTTON( mt->preview_toggle), (preview ? TRUE: FALSE ) );
|
|
mt->view[track]->status_lock=0;
|
|
}
|
|
else
|
|
{
|
|
mt->view[track]->status_lock=1;
|
|
gtk_toggle_button_set_active(
|
|
GTK_TOGGLE_BUTTON( mt->view[track]->toggle ), (preview ? TRUE: FALSE ) );
|
|
mt->view[track]->status_lock=0;
|
|
|
|
}
|
|
}
|
|
|
|
mt->master_track = track;
|
|
|
|
veejay_msg(VEEJAY_MSG_INFO, "Master track is %d", track);
|
|
gtk_widget_set_sensitive_(GTK_WIDGET(mt->view[track]->panel), TRUE );
|
|
|
|
|
|
return track;
|
|
}
|
|
|
|
int multitrack_locked( void *data)
|
|
{
|
|
multitracker_t *mt = (multitracker_t*) data;
|
|
|
|
return mt->view[mt->master_track]->status_lock;
|
|
}
|
|
|
|
void multitrack_configure( void *data, float fps, int video_width, int video_height )
|
|
{
|
|
multitracker_t *mt = (multitracker_t*) data;
|
|
mt->fps = fps;
|
|
mt->width = video_width;
|
|
mt->height = video_height;
|
|
|
|
|
|
if(mt->width > 360 || mt->height > 288 )
|
|
{
|
|
veejay_msg(2, "Maximum preview resolution clipped to 352x288" );
|
|
mt->width = 352;
|
|
mt->height = 288;
|
|
}
|
|
veejay_msg(2, "Multitrack %d x %d, %2.2f", mt->width,mt->height,mt->fps );
|
|
}
|
|
|
|
void multitrack_set_quality( void *data , int quality )
|
|
{
|
|
multitracker_t *mt = (multitracker_t*) data;
|
|
|
|
int w = 0;
|
|
int h = 0;
|
|
|
|
float ratio = mt->width / (float) mt->height;
|
|
switch( quality )
|
|
{
|
|
case 1:
|
|
w = (mt->width/16)*16;
|
|
h = (w / ratio)/16*16;
|
|
break;
|
|
case 0:
|
|
w = (mt->width / 2)/16*16;
|
|
h = (w / ratio)/16*16;
|
|
break;
|
|
case 2:
|
|
w = (mt->width / 4)/16*16;
|
|
h = (w/ ratio)/16*16;
|
|
break;
|
|
case 3:
|
|
w = (mt->width / 8)/16*16;
|
|
h = (w/ ratio)/16*16;
|
|
break;
|
|
}
|
|
|
|
if( w && h )
|
|
{
|
|
w = (w / 8 ) * 8;
|
|
h = (h / 8 ) * 8;
|
|
}
|
|
|
|
if(!gvr_track_configure( mt->preview, mt->master_track,w,h ) )
|
|
{
|
|
veejay_msg(0, "Unable to configure preview %d x %d",w , h );
|
|
}
|
|
|
|
mt->pw = w;
|
|
mt->ph = h;
|
|
}
|
|
|
|
void multitrack_toggle_preview( void *data, int track_id, int status, GtkWidget *img )
|
|
{
|
|
multitracker_t *mt = (multitracker_t*) data;
|
|
if(track_id == -1)
|
|
{
|
|
gvr_track_toggle_preview( mt->preview, mt->master_track, status );
|
|
veejay_msg(2, "Veejay Master Preview %s", (status ? "Enabled" : "Disabled") );
|
|
|
|
if(!status)
|
|
{
|
|
float ratio = mt->width / (float) mt->height;
|
|
int w = 160;
|
|
int h = ( (int)( (float)w / ratio)) /16*16;
|
|
GdkPixbuf *logo = gdk_pixbuf_scale_simple( mt->logo, w,h, GDK_INTERP_BILINEAR );
|
|
gtk_image_set_from_pixbuf_(
|
|
GTK_IMAGE( mt->view[mt->master_track]->area ), logo );
|
|
|
|
gtk_image_set_from_pixbuf_(
|
|
GTK_IMAGE(img), mt->logo );
|
|
|
|
|
|
veejay_msg(0, "Set track %d preview logo", mt->master_track);
|
|
gdk_pixbuf_unref( logo );
|
|
}
|
|
}
|
|
}
|
|
|
|
void multitrack_release_track(void *data, int id, int release_this )
|
|
{
|
|
multitracker_t *mt = (multitracker_t*) data;
|
|
int stream_id = 0;
|
|
|
|
//release this: track um
|
|
|
|
gvr_ext_lock(mt->preview);
|
|
stream_id = gvr_get_stream_id( mt->preview, release_this );
|
|
gvr_ext_unlock(mt->preview);
|
|
if(stream_id > 0)
|
|
gvr_queue_mvims( mt->preview, id, VIMS_STREAM_DELETE,stream_id );
|
|
}
|
|
|
|
void multitrack_bind_track( void *data, int id, int bind_this )
|
|
{
|
|
multitracker_t *mt = (multitracker_t*) data;
|
|
|
|
if( bind_this < 0 || bind_this > MAX_TRACKS )
|
|
return;
|
|
|
|
if( id < 0 || id > MAX_TRACKS )
|
|
return;
|
|
|
|
gvr_ext_lock(mt->preview);
|
|
char *host = gvr_track_get_hostname( mt->preview, bind_this );
|
|
int port = gvr_track_get_portnum ( mt->preview, bind_this );
|
|
gvr_ext_unlock(mt->preview);
|
|
|
|
if( host != NULL && port > 0 )
|
|
gvr_queue_cxvims( mt->preview, id, VIMS_STREAM_NEW_UNICAST, port,host );
|
|
}
|
|
|
|
void multitrack_update_sequence_image( void *data , int track, GdkPixbuf *img )
|
|
{
|
|
multitracker_t *mt = (multitracker_t*) data;
|
|
|
|
float ratio = mt->width / (float) mt->height;
|
|
int w = 160;
|
|
int h = ((int) (float )w / ratio )/16 *16;
|
|
|
|
GdkPixbuf *scaled = gdk_pixbuf_scale_simple( img, w, h, GDK_INTERP_BILINEAR );
|
|
gtk_image_set_from_pixbuf( mt->view[track]->area, scaled);
|
|
|
|
gdk_pixbuf_unref( scaled );
|
|
}
|
|
|
|
|
|
static gboolean seqv_mouse_press_event ( GtkWidget *w, GdkEventButton *event, gpointer user_data)
|
|
{
|
|
sequence_view_t *v = (sequence_view_t*) user_data;
|
|
multitracker_t *mt = v->backlink;
|
|
|
|
if(event->type == GDK_2BUTTON_PRESS)
|
|
{
|
|
mt->selected = v->num;
|
|
|
|
vj_gui_disable();
|
|
|
|
// hostname, port_num from gvr
|
|
gvr_ext_lock(mt->preview);
|
|
char *host = gvr_track_get_hostname( mt->preview, v->num );
|
|
int port = gvr_track_get_portnum ( mt->preview, v->num );
|
|
gvr_ext_unlock(mt->preview);
|
|
vj_gui_cb( 0, host, port );
|
|
|
|
|
|
veejay_msg(VEEJAY_MSG_INFO, "Connecting to %s:%d", host,port );
|
|
|
|
vj_gui_enable();
|
|
}
|
|
|
|
if( event->type == GDK_BUTTON_PRESS )
|
|
{
|
|
mt->selected = v->num;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|