Initial checkin of veejay 1.4

git-svn-id: svn://code.dyne.org/veejay/trunk@1172 eb8d1916-c9e9-0310-b8de-cf0c9472ead5
This commit is contained in:
Niels Elburg
2008-11-10 20:16:24 +00:00
parent d81258c54c
commit d8e6f98d53
793 changed files with 244409 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
## Process this file with automake to produce Makefile.in
MAINTAINERCLEANFILES = Makefile.in
AM_CFLAGS=$(OP_CFLAGS)
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src $(VEEJAY_CFLAGS ) $(GTK_CFLAGS) \
$(MJPEGTOOLS_CFLAGS) $(GLIB_CFLAGS) $(GLADE_CFLAGS) $(GTKCAIRO_CFLAGS) -DGNOMELOCALEDIR=\""$(datadir)/locale"\" -DGVEEJAY_DATADIR=\""$(gveejay_datadir)"\"
GVEEJAY_BIN=reloaded
bin_PROGRAMS = $(GVEEJAY_BIN)
reloaded_SOURCES = widgets/gtkcolorsel.c widgets/gtkknob.c widgets/cellrendererspin.c widgets/gtktimeselection.c vj-midi.c curve.c utils.c tracksources.c gveejay.c keyboard.c sequence.c multitrack.c vj-api.c ${gveejay_headers}
reloaded_LDFLAGS = $(VEEJAY_LIBS) $(MJPEGTOOLS_LIBS) $(GTK_LIBS) $(GLIB_LIBS)\
$(GLADE_LIBS) $(GTKCAIRO_LIBS) $(FFMPEG_AVCODEC_LIBS) $(FFMPEG_SWSCALER_LIBS) $(ALSA_LIBS) -lgthread-2.0 -export-dynamic

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
/* Gveejay Reloaded - graphical interface for VeeJay
* (C) 2002-2005 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.
*/
#ifndef GVRCOMMON_H
#define GVRCOMMON_H
#define STATUS_BYTES 150
#define STATUS_TOKENS 23
#define VEEJAY_CODENAME VERSION
/* Status bytes */
#define ELAPSED_TIME 0
#define PLAY_MODE 2
#define CURRENT_ID 3
#define SAMPLE_FX 4
#define SAMPLE_START 5
#define SAMPLE_END 6
#define SAMPLE_SPEED 7
#define SAMPLE_LOOP 8
#define SAMPLE_MARKER_START 13
#define STREAM_TYPE 13
#define SAMPLE_MARKER_END 14
#define FRAME_NUM 1
#define TOTAL_FRAMES 6
#define TOTAL_SLOTS 16
#define TOTAL_MEM 17
#define SEQ_ACT 18
#define SEQ_CUR 19
#define CHAIN_FADE 20
#define FRAME_DUP 21
#define MACRO 22
#define CURRENT_ENTRY 15
#define MODE_PLAIN 2
#define MODE_SAMPLE 0
#define MODE_PATTERN 3
#define MODE_STREAM 1
#define STREAM_COL_R 5
#define STREAM_COL_G 6
#define STREAM_COL_B 7
#define STREAM_RECORDED 11
#define STREAM_DURATION 10
#define STREAM_RECORDING 9
#endif

View File

@@ -0,0 +1,96 @@
/* Gveejay Reloaded - graphical interface for VeeJay
* (C) 2002-2005 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 <gtk/gtk.h>
#include <glib.h>
#include <veejay/vj-msg.h>
#include <veejay/vjmem.h>
#include <src/vj-api.h>
#include <stdlib.h>
#include "curve.h"
#ifdef STRICT_CHECKING
#include <assert.h>
#endif
void get_points_from_curve( GtkWidget *curve, int len, float *vec )
{
gtk_curve_get_vector( GTK_CURVE(curve), len, vec );
}
void reset_curve( GtkWidget *curve )
{
gtk_curve_reset(GTK_CURVE(curve));
gtk_curve_set_range( GTK_CURVE(curve), 0.0, 1.0, 0.0, 1.0 );
}
void set_points_in_curve( int type, GtkWidget *curve)
{
gtk_curve_set_curve_type( GTK_CURVE(curve), type );
}
int set_points_in_curve_ext( GtkWidget *curve, unsigned char *blob, int id, int fx_entry, int *lo, int *hi, int *curve_type)
{
int parameter_id = 0;
int start = 0, end =0,type=0;
int entry = 0;
int n = sscanf( (char*) blob, "key%2d%2d%8d%8d%2d", &entry, &parameter_id, &start, &end,&type );
int len = end - start;
int i;
int min = 0, max = 0;
#ifdef STRICT_CHECKING
assert( fx_entry == entry );
#endif
if( len <= 0 )
return -1;
if(n != 5 )
{
veejay_msg(0, "Error parsing KF headeR");
return -1;
}
_effect_get_minmax(id, &min, &max, parameter_id );
unsigned char *in = blob + 25;
float *vec = (float*) vj_calloc(sizeof(float) * len );
for(i = start ; i < end; i ++ )
{
unsigned char *ptr = in + (i * 4);
int value =
( ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24) );
float top = 1.0 / (float) max;
float val = (float)value * top;
vec[i] = val;
}
gtk_curve_set_vector( GTK_CURVE( curve ), len, vec );
gtk_curve_set_curve_type( GTK_CURVE(curve), type );
*lo = start;
*hi = end;
*curve_type = type;
free(vec);
return parameter_id;
}

View File

@@ -0,0 +1,34 @@
/* Gveejay Reloaded - graphical interface for VeeJay
* (C) 2002-2005 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.
*/
#ifndef VJCURVE_H
#define VJCURVE_H
#include <gtk/gtkversion.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#define MAX_PARAMETERS 8
#define MAX_CHAIN_LEN 20
int set_points_in_curve_ext( GtkWidget *curve, unsigned char *blob, int id, int fx_entry, int *lo, int *hi, int *ct);
void set_points_in_curve( int type, GtkWidget *curve);
void reset_curve( GtkWidget *curve );
void get_points_from_curve( GtkWidget *curve, int len, float *v );
#endif

View File

@@ -0,0 +1,262 @@
/* gveejay - Linux VeeJay - GVeejay GTK+-2/Glade User Interface
* (C) 2002-2005 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 <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <glade/glade.h>
#include <veejay/vevo.h>
#include <veejay/vjmem.h>
#include <veejay/vj-msg.h>
#include <src/vj-api.h>
#include <sched.h>
static int port_num = 3490;
static char hostname[255];
static int gveejay_theme = 1;
static int verbosity = 0;
static int timer = 6;
static int col = 0;
static int row = 0;
static int n_tracks = 3;
static int launcher = 0;
static int pw = 176;
static int ph = 144;
static int preview = 0; // off
static int use_threads = 0;
static struct
{
char *file;
} skins[] = {
{ "gveejay.reloaded.glade" },
{ NULL }
};
extern void reloaded_launcher( char *h, int p );
static void usage(char *progname)
{
printf( "Usage: %s <options>\n",progname);
printf( "where options are:\n");
printf( "-h\t\tVeejay host to connect to (defaults to localhost) \n");
printf( "-p\t\tVeejay port to connect to (defaults to 3490) \n");
printf( "-t\t\tDont load gveejay's GTK theme\n");
printf( "-n\t\tDont use colored text\n");
printf( "-v\t\tBe extra verbose (usefull for debugging)\n");
printf( "-s\t\tSet bank resolution (row X columns)\n");
printf( "-P\t\tStart with preview enabled (1=1/1,2=1/2,3=1/4,4=1/8)\n");
printf( "-X\t\tSet number of tracks\n");
printf( "\n\n");
exit(-1);
}
static int set_option( const char *name, char *value )
{
int err = 0;
if( strcmp(name, "h") == 0 || strcmp(name, "hostname") == 0 )
{
strcpy( hostname, optarg );
launcher ++;
}
else if( strcmp(name, "p") == 0 || strcmp(name ,"port") == 0 )
{
if(sscanf( optarg, "%d", &port_num ))
launcher++;
}
else if (strcmp(name, "n") == 0 )
{
veejay_set_colors(0);
}
else if (strcmp(name, "X") == 0 )
{
n_tracks = atoi(optarg);
}
else if( strcmp(name, "t") == 0 || strcmp(name, "no-theme") == 0)
{
gveejay_theme = 0;
}
else if( strcmp(name, "v") == 0 || strcmp(name, "verbose") == 0)
{
verbosity = 1;
}
else if( strcmp(name, "t") == 0 || strcmp(name, "timeout") == 0)
{
timer = atoi(optarg);
}
else if (strcmp(name, "s") == 0 || strcmp(name, "size") == 0)
{
if(sscanf( (char*) optarg, "%dx%d",
&row, &col ) != 2 )
{
fprintf(stderr, "--size parameter requires NxN argument");
err++;
}
}
else if (strcmp(name, "q") == 0 )
{
fprintf(stdout, "%s", get_gveejay_dir());
exit(0);
}
else if (strcmp(name, "P" ) == 0 || strcmp(name, "preview" ) == 0 )
{
preview = atoi(optarg);
if(preview <= 0 || preview > 4 )
{
fprintf(stderr, "--preview [0-4]\n");
err++;
}
}
else
err++;
return err;
}
static volatile gulong g_trap_free_size = 0;
static struct timeval time_last_;
static char **cargv = NULL;
gboolean gveejay_idle(gpointer data)
{
if(gveejay_running())
{
int sync = 0;
if( is_alive(&sync) == FALSE ) {
//@ restart reloaded
veejay_msg(VEEJAY_MSG_WARNING,
"No connection with veejay, attempting restart.");
reloaded_restart();
}
if( sync ) {
if( gveejay_time_to_sync( get_ui_info() ) )
{
if(veejay_update_multitrack( get_ui_info() ))
update_gveejay();
}
}
}
if( gveejay_restart() )
{
//@ reinvoke
if( execvp( cargv[0], cargv ) == -1 )
veejay_msg(VEEJAY_MSG_ERROR, "Unable to restart");
}
return TRUE;
}
static void clone_args( char *argv[], int argc )
{
int i = 0;
if( argc <= 0 )
return;
cargv = (char**) malloc(sizeof(char*) * (argc+1) );
memset( cargv, 0, sizeof(char*) * (argc+1));
for( i = 0; i < argc ; i ++ )
cargv[i] = strdup( argv[i] );
}
int main(int argc, char *argv[]) {
char option[2];
int n;
int err=0;
if(!argc) usage(argv[0]);
clone_args( argv, argc );
// default host to connect to
sprintf(hostname, "127.0.0.1");
while( ( n = getopt( argc, argv, "s:h:p:tnvHf:X:P:q")) != EOF )
{
sprintf(option, "%c", n );
err += set_option( option, optarg);
if(err) usage(argv[0]);
}
if( optind > argc )
err ++;
if( err ) usage(argv[0]);
/*
if( !g_thread_supported() )
{
veejay_msg(2, "Initializing GDK threads");
g_thread_init(NULL);
gdk_threads_init(); // Called to initialize internal mutex "gdk_threads_mutex".
}*/
gtk_init( NULL,NULL );
glade_init();
// g_mem_set_vtable( glib_mem_profiler_table );
vj_mem_init();
vevo_strict_init();
find_user_themes(gveejay_theme);
vj_gui_set_debug_level( verbosity , n_tracks,pw,ph);
vj_gui_set_timeout(timer);
set_skin( 0 );
default_bank_values( &col, &row );
gui_load_theme();
vj_gui_init( skins[0].file, launcher, hostname, port_num, use_threads );
vj_gui_style_setup();
//struct sched_param schp;
//memset( &schp, 0, sizeof( schp ));
//schp.sched_priority = sched_get_priority_min(SCHED_RR );
//if( sched_setscheduler( 0, SCHED_FIFO, &schp ) == 0 )
// veejay_msg(VEEJAY_MSG_INFO, "Reloaded running with low priority");
if( preview )
{
veejay_msg(VEEJAY_MSG_INFO, "Starting with preview enabled");
gveejay_preview(preview);
}
if( launcher )
{
reloaded_launcher( hostname, port_num );
}
memset( &time_last_, 0, sizeof(struct timeval));
while(gveejay_running()) {
gveejay_idle(NULL);
while( gtk_events_pending() )
gtk_main_iteration();
}
return 0;
}

View File

@@ -0,0 +1,330 @@
/* Gveejay Reloaded - graphical interface for VeeJay
* (C) 2002-2005 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 <gtk/gtk.h>
#include "keyboard.h"
static struct
{
const int sdl_mod;
const int gdk_mod;
const gchar *title;
} modifier_translation_table_t[] =
{
{ 0, 0, " " },
{ 0, 16, " " },
{ 3, 1, "shift" },
{ 3, 17, "shift" },
{ 1, 8, "alt" },
{ 1, 24, "alt" },
{ 1, 44, "alt" },
{ 2, 4, "ctrl" },
{ 2, 20, "ctrl" },
{ 0, 0, NULL },
};
/* fixme: introduce keyboard mapping functionality
1. attach VIMS events/VIMS BUNDLES to keys (with arguments)
2. save/load VIMS keyboard mapping
*/
static struct
{
const int gdk_sym; // GDK key
const int sdl_sym; // SDL key
const gchar *title; // plain text
} key_translation_table_t[] =
{
{ GDK_space, SDLK_SPACE, "Space" },
{ GDK_exclam, SDLK_EXCLAIM, "Exclaim" },
{ GDK_quotedbl, SDLK_QUOTEDBL, "Double quote" },
{ GDK_numbersign, SDLK_HASH, "Hash" },
{ GDK_dollar, SDLK_DOLLAR, "Dollar" },
{ GDK_percent, SDLK_PAUSE, "Percent" },
{ GDK_parenleft, SDLK_LEFTPAREN, "Leftparen" },
{ GDK_parenright, SDLK_RIGHTPAREN, "Rightparen" },
{ GDK_asciicircum,SDLK_CARET, "Caret" },
{ GDK_ampersand, SDLK_AMPERSAND, "Ampersand" },
{ GDK_underscore, SDLK_UNDERSCORE, "Underscore" },
{ GDK_braceright, 123, "Rightbrace" },
{ GDK_braceleft, 125, "Leftbrace" },
{ GDK_grave, SDLK_BACKQUOTE, "Aphostrophe" },
{ GDK_asciitilde, 126, "Tilde" },
{ GDK_asterisk, SDLK_ASTERISK, "Asterisk" },
{ GDK_plus, SDLK_PLUS, "Plus" },
{ GDK_comma, SDLK_COMMA, "Comma" },
{ GDK_minus, SDLK_MINUS, "Minus" },
{ GDK_period, SDLK_PERIOD, "Period" },
{ GDK_slash, SDLK_SLASH, "Slash" },
{ GDK_Home, SDLK_HOME, "Home" },
{ GDK_End, SDLK_END, "End" },
{ GDK_Page_Up, SDLK_PAGEUP, "PageUp" },
{ GDK_Page_Down, SDLK_PAGEDOWN, "PageDown" },
{ GDK_Insert, SDLK_INSERT, "Insert" },
{ GDK_Up, SDLK_UP, "Up" },
{ GDK_Down, SDLK_DOWN, "Down" },
{ GDK_Left, SDLK_LEFT, "Left" },
{ GDK_Right, SDLK_RIGHT, "Right" },
{ GDK_Tab, SDLK_TAB, "TAB" },
{ GDK_BackSpace, SDLK_BACKSPACE, "Backspace" },
{ GDK_Escape, SDLK_ESCAPE, "Escape" },
{ GDK_Delete, SDLK_DELETE, "Delete" },
{ GDK_F1, SDLK_F1, "F1" },
{ GDK_F2, SDLK_F2, "F2" },
{ GDK_F3, SDLK_F3, "F3" },
{ GDK_F4, SDLK_F4, "F4" },
{ GDK_F5, SDLK_F5, "F5" },
{ GDK_F6, SDLK_F6, "F6" },
{ GDK_F7, SDLK_F7, "F7" },
{ GDK_F8, SDLK_F8, "F8" },
{ GDK_F9, SDLK_F9, "F9" },
{ GDK_F10, SDLK_F10, "F10" },
{ GDK_F11, SDLK_F11, "F11" },
{ GDK_F12, SDLK_F12, "F12" },
{ GDK_EuroSign, SDLK_EURO, "Euro" },
{ GDK_KP_0, SDLK_KP0, "keypad 0" },
{ GDK_KP_1, SDLK_KP1, "keypad 1" },
{ GDK_KP_2, SDLK_KP2, "keypad 2" },
{ GDK_KP_3, SDLK_KP3, "keypad 3" },
{ GDK_KP_4, SDLK_KP4, "keypad 4" },
{ GDK_KP_5, SDLK_KP5, "keypad 5" },
{ GDK_KP_6, SDLK_KP6, "keypad 6" },
{ GDK_KP_7, SDLK_KP7, "keypad 7" },
{ GDK_KP_8, SDLK_KP8, "keypad 8" },
{ GDK_KP_9, SDLK_KP9, "keypad 9" },
{ GDK_KP_Divide, SDLK_KP_DIVIDE, "keypad /" },
{ GDK_KP_Multiply,SDLK_KP_MULTIPLY, "keypad *" },
{ GDK_KP_Subtract,SDLK_KP_MINUS, "keypad -" },
{ GDK_KP_Add, SDLK_KP_PLUS, "keypad +" },
{ GDK_KP_Equal, SDLK_KP_EQUALS, "keypad =" },
{ GDK_KP_Enter, SDLK_KP_ENTER, "keypad ENTER" },
{ GDK_ISO_Enter, SDLK_RETURN, "ENTER" },
{ GDK_3270_Enter, SDLK_RETURN, "ENTER" },
/* GDK_KP doesnt word on all systems ... */
{ 0xff9f, SDLK_KP0, "keypad 0" },
{ 0xff9c, SDLK_KP1, "keypad 1" },
{ 0xff99, SDLK_KP2, "keypad 2" },
{ 0xff9b, SDLK_KP3, "keypad 3" },
{ 0xff96, SDLK_KP4, "keypad 4" },
{ 0xff9d, SDLK_KP5, "keypad 5" },
{ 0xff98, SDLK_KP6, "keypad 6" },
{ 0xff95, SDLK_KP7, "keypad 7" },
{ 0xff97, SDLK_KP8, "keypad 8" },
{ 0xff9a, SDLK_KP9, "keypad 9" },
{ 0xff9f, SDLK_KP_PERIOD, "keypad ." },
{ GDK_0, SDLK_0, "0" },
{ GDK_1, SDLK_1, "1" },
{ GDK_2, SDLK_2, "2" },
{ GDK_3, SDLK_3, "3" },
{ GDK_4, SDLK_4, "4" },
{ GDK_5, SDLK_5, "5" },
{ GDK_6, SDLK_6, "6" },
{ GDK_7, SDLK_7, "7" },
{ GDK_8, SDLK_8, "8" },
{ GDK_9, SDLK_9, "9" },
{ GDK_colon, SDLK_COLON, "colon" },
{ GDK_semicolon, SDLK_SEMICOLON, "semicolon" },
{ GDK_less, SDLK_LESS, "less" },
{ GDK_equal, SDLK_EQUALS, "equals" },
{ GDK_greater, SDLK_GREATER, "greater" },
{ GDK_question, SDLK_QUESTION, "question" },
{ GDK_at, SDLK_AT, "at" },
{ GDK_bracketleft,SDLK_LEFTBRACKET, "left bracket" },
{ GDK_backslash, SDLK_BACKSLASH, "backslash" },
{ GDK_bracketright,SDLK_RIGHTBRACKET, "right bracket" },
{ GDK_underscore, SDLK_UNDERSCORE, "underscore" },
{ GDK_A, SDLK_a, "A" },
{ GDK_B, SDLK_b, "B" },
{ GDK_C, SDLK_c, "C" },
{ GDK_D, SDLK_d, "D" },
{ GDK_E, SDLK_e, "E" },
{ GDK_F, SDLK_f, "F" },
{ GDK_G, SDLK_g, "G" },
{ GDK_H, SDLK_h, "H" },
{ GDK_I, SDLK_i, "I" },
{ GDK_J, SDLK_j, "J" },
{ GDK_K, SDLK_k, "K" },
{ GDK_L, SDLK_l, "L" },
{ GDK_M, SDLK_m, "M" },
{ GDK_N, SDLK_n, "N" },
{ GDK_O, SDLK_o, "O" },
{ GDK_P, SDLK_p, "P" },
{ GDK_Q, SDLK_q, "Q" },
{ GDK_R, SDLK_r, "R" },
{ GDK_S, SDLK_s, "S" },
{ GDK_T, SDLK_t, "T" },
{ GDK_U, SDLK_u, "U" },
{ GDK_V, SDLK_v, "V" },
{ GDK_W, SDLK_w, "W" },
{ GDK_X, SDLK_y, "Y" },
{ GDK_Z, SDLK_z, "Z" },
{ GDK_a, SDLK_a, "a" },
{ GDK_b, SDLK_b, "b" },
{ GDK_c, SDLK_c, "c" },
{ GDK_d, SDLK_d, "d" },
{ GDK_e, SDLK_e, "e" },
{ GDK_f, SDLK_f, "f" },
{ GDK_g, SDLK_g, "g" },
{ GDK_h, SDLK_h, "h" },
{ GDK_i, SDLK_i, "i" },
{ GDK_j, SDLK_j, "j" },
{ GDK_k, SDLK_k, "k" },
{ GDK_l, SDLK_l, "l" },
{ GDK_m, SDLK_m, "m" },
{ GDK_n, SDLK_n, "n" },
{ GDK_o, SDLK_o, "o" },
{ GDK_p, SDLK_p, "p" },
{ GDK_q, SDLK_q, "q" },
{ GDK_r, SDLK_r, "r" },
{ GDK_s, SDLK_s, "s" },
{ GDK_t, SDLK_t, "t" },
{ GDK_u, SDLK_u, "u" },
{ GDK_v, SDLK_v, "v" },
{ GDK_w, SDLK_w, "w" },
{ GDK_x, SDLK_x, "x" },
{ GDK_y, SDLK_y, "y" },
{ GDK_z, SDLK_z, "z" },
{ 0, 0, NULL },
};
int sdl2gdk_key(int sdl_key)
{
return 0;
}
int gdk2sdl_key(int gdk_key)
{
int i;
for ( i = 0; key_translation_table_t[i].title != NULL ; i ++ )
{
if( gdk_key == key_translation_table_t[i].gdk_sym )
return key_translation_table_t[i].sdl_sym;
}
return 0;
}
int gdk2sdl_mod( int gdk_mod )
{
int i;
for ( i = 0; modifier_translation_table_t[i].title != NULL ; i ++ )
{
if( gdk_mod == modifier_translation_table_t[i].gdk_mod )
return modifier_translation_table_t[i].sdl_mod;
}
return 0;
}
int sdlmod_by_name( gchar *name )
{
int i;
if(!name)
return 0;
for ( i = 0; modifier_translation_table_t[i].title != NULL ; i ++ )
{
if( g_utf8_collate(name,
modifier_translation_table_t[i].title) == 0)
return modifier_translation_table_t[i].sdl_mod;
}
return 0;
}
int sdlkey_by_name( gchar *name )
{
int i;
if(!name)
return 0;
for ( i = 0; key_translation_table_t[i].title != NULL ; i ++ )
{
if( g_utf8_collate(name,
key_translation_table_t[i].title) == 0)
return key_translation_table_t[i].sdl_sym;
}
return 0;
}
gchar *sdlkey_by_id( int sdl_key )
{
int i;
gchar *ret = NULL;
for ( i = 0; key_translation_table_t[i].title != NULL ; i ++ )
{
if( sdl_key == key_translation_table_t[i].sdl_sym )
return (gchar*)key_translation_table_t[i].title;
}
return ret;
}
gchar *sdlmod_by_id( int sdl_mod )
{
int i;
gchar *ret = NULL;
for ( i = 0; modifier_translation_table_t[i].title != NULL ; i ++ )
{
if( sdl_mod == modifier_translation_table_t[i].sdl_mod )
return (gchar*)modifier_translation_table_t[i].title;
}
return ret;
}
gchar *gdkmod_by_id( int gdk_mod )
{
int i;
for( i = 0; modifier_translation_table_t[i].title != NULL ; i ++ )
{
if( gdk_mod == modifier_translation_table_t[i].gdk_mod ||
gdk_mod & modifier_translation_table_t[i].gdk_mod )
return (gchar*)modifier_translation_table_t[i].title;
}
return NULL;
}
gchar *gdkkey_by_id( int gdk_key )
{
int i;
for( i = 0; key_translation_table_t[i].title != NULL ; i ++ )
{
if( gdk_key == key_translation_table_t[i].gdk_sym )
return (gchar*)key_translation_table_t[i].title;
}
return NULL;
}
static void key_func(gboolean pressed, guint16 unicode, guint16 keymod)
{
}
/*
Key snooper functions are called before normal event delivery.
They can be used to implement custom key event handling.
grab_widget<EFBFBD>: the widget to which the event will be delivered.
event<EFBFBD>: the key event.
func_data<EFBFBD>: the func_data supplied to gtk_key_snooper_install().
Returns<EFBFBD>: TRUE to stop further processing of event, FALSE to continue.
*/
gboolean key_snooper(GtkWidget *w, GdkEventKey *event, gpointer user_data)
{
return FALSE;
}
// gtk_key_snooper_install

View File

@@ -0,0 +1,41 @@
/* Gveejay Reloaded - graphical interface for VeeJay
* (C) 2002-2005 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.
*/
#ifndef GDKSDL
#define GDKSDL
#include <gdk/gdkkeysyms.h>
#include <SDL/SDL_keysym.h>
#include <glib.h>
#include <stdio.h>
int sdl2gdk_key( int sdl_key );
int gdk2sdl_key( int gdk_key );
int gdk2sdl_mod( int gdk_mod );
gchar *sdlkey_by_id( int sdl_key );
gchar *sdlmod_by_id( int sdk_mod );
gchar *gdkkey_by_id( int gdk_key );
gchar *gdkmod_by_id(int gdkmod);
int sdlmod_by_name( gchar *name );
int sdlkey_by_name( gchar *name );
int gdk2sdl_mod( int gdk_mod );
gboolean key_snooper(GtkWidget *w, GdkEventKey *event, gpointer user_data);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,55 @@
#ifndef MTRACK_H
#define MTRACK_H
void *multitrack_new(
void (*f)(int,char*,int),
int (*g)(GdkPixbuf *, GdkPixbuf *, GtkImage *),
GtkWidget *win,
GtkWidget *box,
GtkWidget *msg,
GtkWidget *button,
gint max_w,
gint max_h,
GtkWidget *main_preview_area,
void *gui,
int threads);
void multitrack_set_logo(void *data , GtkWidget *img);
int multitrack_add_track( void *data );
void multitrack_close_track( void *data );
int multrack_audoadd( void *data, char *hostname, int port_num );
void multitrack_release_track(void *data, int id, int release_this );
void multitrack_bind_track( void *data, int id, int bind_this );
void multitrack_sync_simple_cmd2( void *data, int vims, int arg );
void *multitrack_sync( void * mt );
void multitrack_configure( void *data, float fps, int video_width, int video_height, int *bw, int *bh );
void multitrack_update_sequence_image( void *data , int track, GdkPixbuf *img );
int update_multitrack_widgets( void *data, int *array, int track );
int multitrack_locked( void *data);
void multitrack_toggle_preview( void *data, int track_id, int status, GtkWidget *img );
void multitrack_set_quality( void *data , int quality );
void multitrack_sync_start(void *data);
void multitrack_sync_simple_cmd( void *data, int vims, int arg );
void multitrack_resize( void *m , int w, int h );
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
/* 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.
*/
#ifndef PREVIEWH
#define PREVIEWH
typedef struct
{
int tracks;
int master;
int *widths;
int *heights;
int **status_list;
GdkPixbuf **img_list;
} sync_info;
void *gvr_preview_init(int max_tracks, int use_thread);
int gvr_track_connect( void *preview, const char *hostname, int port_num, int *track_num );
void gvr_track_disconnect( void *preview, int track_num );
int gvr_track_configure( void *preview, int track_num, int w, int h);
int gvr_track_toggle_preview( void *preview, int track_num, int status );
void gvr_need_track_list( void *preview, int track_id );
int gvr_get_stream_id( void *data, int id );
void gvr_set_master( void *preview, int master_track );
//format and queue vims messages from extern
void gvr_queue_mmvims( void *preview, int track_id, int vims_id, int val1,int val2 );
void gvr_queue_mvims( void *preview, int track_id, int vims_id, int val );
void gvr_queue_vims( void *preview, int track_id, int vims_id );
void gvr_queue_cxvims( void *preview, int track_id, int vims_id, int val1,unsigned char *val2 );
int gvr_track_already_open( void *preview, const char *hostname, int port );
int gvr_get_preview_status( void *preview, int track_num );
char* gvr_track_get_hostname( void *preview , int num );
int gvr_track_get_portnum( void *preview, int num);
int gvr_track_test( void *preview, int track_id );
sync_info *gvr_sync( void *preview );
#endif

View File

@@ -0,0 +1,199 @@
/* Gveejay Reloaded - graphical interface for VeeJay
* (C) 2002-2005 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 <gtk/gtk.h>
#include <glib.h>
#include <veejay/vjmem.h>
extern void veejay_release_track(int id, int release_this);
extern void veejay_bind_track( int id, int bind_this );
extern int multitrack_get_sequence_view_id( void *data );
extern gchar *_utf8str( const char *c_str );
typedef struct
{
int track_id;
GtkWidget *view;
} track_view_t;
static void cell_data_func(
GtkTreeViewColumn *col, GtkCellRenderer *renderer,
GtkTreeModel *model, GtkTreeIter *iter,
gpointer user_data)
{
gint state;
gtk_tree_model_get(model, iter, 1, &state, -1 );
if(state==1)
g_object_set(renderer, "active", TRUE, NULL );
else
g_object_set(renderer, "active", FALSE, NULL );
g_object_set( renderer, "activatable", TRUE, NULL );
}
static void cell_toggled_callback( GtkCellRenderer *cell, gchar *path_string, gpointer user_data )
{
track_view_t *v = (track_view_t*) user_data;
GtkWidget *view = v->view;
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
GtkTreePath *path = gtk_tree_path_new_from_string( path_string );
GtkTreeIter iter;
gtk_tree_model_get_iter( model, &iter, path );
gchar *data = NULL;
gtk_tree_model_get( model, &iter,0, &data, -1 );
int id_data = -1; // invalid
char junk[32];
if(sscanf( data, "%s %d", junk,&id_data ) == 2 )
{
if( gtk_cell_renderer_toggle_get_active( GTK_CELL_RENDERER_TOGGLE( cell) ) )
{
veejay_release_track( v->track_id, id_data);
}
else
{
veejay_bind_track( v->track_id, id_data );
}
g_free(data);
}
gtk_tree_path_free( path );
}
extern int *sequence_get_track_status(void *priv );
void update_track_view( int n_tracks, GtkWidget *widget, void *user_data )
{
GtkTreeView *view = GTK_TREE_VIEW(widget);
GtkTreeModel *model = gtk_tree_view_get_model( view );
GtkListStore *store = GTK_LIST_STORE( model );
GtkTreeIter iter;
gtk_list_store_clear( GTK_LIST_STORE( model ) );
int i;
int id = multitrack_get_sequence_view_id( user_data );
for( i = 0; i < n_tracks; i ++ )
{
if(id != i)
{
char name[12];
sprintf(name,"Track %d", i);
gchar *uname = _utf8str( name );
gtk_list_store_append( store, &iter );
gtk_list_store_set(
store, &iter,
0, uname,
1, 0,
-1 );
g_free( uname );
}
}
gtk_tree_view_set_model( GTK_TREE_VIEW( widget ), model );
}
GtkWidget *get_track_tree( void *data)
{
track_view_t *t = (track_view_t*) data;
return t->view;
}
void *create_track_view(int track_id, int ref_tracks, void *user_data)
{
GtkCellRenderer *renderer, *wrenderer;
GtkTreeModel *model;
GtkWidget *view;
view = gtk_tree_view_new();
renderer = gtk_cell_renderer_text_new();
wrenderer = gtk_cell_renderer_toggle_new();
track_view_t *my_view = (track_view_t*) vj_calloc(sizeof(track_view_t));
gtk_cell_renderer_toggle_set_active( GTK_CELL_RENDERER_TOGGLE(wrenderer) , FALSE );
gtk_tree_view_insert_column_with_attributes(
GTK_TREE_VIEW( view ),
-1,
"T",
renderer,
"text",
0,
NULL );
gtk_tree_view_insert_column_with_attributes(
GTK_TREE_VIEW( view ),
-1,
"-",
wrenderer,
"activatable",
1,
NULL);
// GtkWidget *col = gtk_tree_view_get_column( GTK_TREE_VIEW(view) , 0 );
GtkTreeViewColumn *col = gtk_tree_view_get_column( GTK_TREE_VIEW(view),0);
gtk_tree_view_column_set_fixed_width( col , 20 );
col = gtk_tree_view_get_column( GTK_TREE_VIEW( view ), 1 );
gtk_tree_view_column_set_clickable( col , TRUE );
gtk_tree_view_column_set_fixed_width( col , 10 );
gtk_tree_view_column_set_cell_data_func( col,
wrenderer, cell_data_func, NULL,NULL);
/* build model */
GtkListStore *store;
GtkTreeIter iter;
store = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT );
int i;
for( i = 0; i < ref_tracks ; i ++ )
{
if( i != track_id )
{
char str[16];
sprintf(str,"Track %d",i);
gchar *ustr = _utf8str( str );
gtk_list_store_append( store, &iter );
gtk_list_store_set( store, &iter,
0, ustr,
1, 0,
-1);
g_free(ustr);
}
}
GtkTreeSelection *selection;
selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) );
gtk_tree_selection_set_mode( selection, GTK_SELECTION_NONE );
my_view->track_id = track_id;
my_view->view = view;
g_assert( GTK_IS_TREE_VIEW( view ) );
model = GTK_TREE_MODEL( store );
gtk_tree_view_set_model ( GTK_TREE_VIEW( view ), model );
g_signal_connect( wrenderer, "toggled",
(GCallback) cell_toggled_callback, (gpointer*) my_view);
g_object_unref( model );
return (void*) my_view;
}

View File

@@ -0,0 +1,28 @@
/* Gveejay Reloaded - graphical interface for VeeJay
* (C) 2002-2005 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.
*/
#ifndef TRACCKSOURCES_H
#define TRACCKSOURCES_H
GtkWidget *get_track_tree( void *data);
void *create_track_view( int id, int ref, void *data );
void update_track_view( int n_tracks, GtkWidget *widget, void *user_data );
#endif

View File

@@ -0,0 +1,69 @@
/* Gveejay Reloaded - graphical interface for VeeJay
* (C) 2002-2005 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 <stdio.h>
#include <mjpegtools/mpegconsts.h>
#include <mjpegtools/mpegtimecode.h>
#include <veejay/vjmem.h>
#include <string.h>
int status_to_arr( char *status, int *array )
{
int n = sscanf(status, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
array + 0,
array + 1,
array + 2,
array + 3,
array + 4,
array + 5,
array + 6,
array + 7,
array + 8,
array + 9,
array + 10,
array + 11,
array + 12,
array + 13,
array + 14,
array + 15,
array + 16,
array + 17,
array + 18,
array + 19,
array + 20,
array + 21,
array + 22 );
return n;
}
char *format_time(int pos, float fps)
{
MPEG_timecode_t tc;
veejay_memset(&tc, 0,sizeof(MPEG_timecode_t));
char *tmp = (char*) vj_malloc( 20 );
y4m_ratio_t ratio = mpeg_conform_framerate( fps );
int n = mpeg_framerate_code( ratio );
mpeg_timecode(&tc, pos, n, fps );
snprintf(tmp, 20, "%2d:%2.2d:%2.2d:%2.2d",
tc.h, tc.m, tc.s, tc.f );
return tmp;
}

View File

@@ -0,0 +1,25 @@
/* Gveejay Reloaded - graphical interface for VeeJay
* (C) 2002-2005 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.
*/
#ifndef GVRUTILS
#define GVRUTILS
int status_to_arr( char *status, int *array );
char *format_time( int pos , float fps);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,58 @@
/* gveejay - Linux VeeJay - GVeejay GTK+-2/Glade User Interface
* (C) 2002-2005 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.
*/
#ifndef VJAPI_H
#define VJAPI_H
int veejay_tick();
void *get_ui_info();
void vj_gui_init(char *glade_file, int launcher, char *hostname, int port_num, int threads);
int vj_gui_reconnect( char *host, char *group, int port);
void vj_gui_free();
void vj_fork_or_connect_veejay();
void vj_gui_enable(void);
void vj_gui_disable(void);
void vj_gui_disconnect(void);
void vj_gui_set_debug_level(int level, int preview_p, int pw, int ph);
void get_gd(char *buf, char *suf, const char *filename);
void vj_gui_theme_setup(int default_theme);
void vj_gui_set_timeout(int timer);
void set_skin(int skin);
void default_bank_values(int *col, int *row );
void vj_gui_style_setup();
gboolean gveejay_running();
gboolean is_alive( int *sync );
int vj_gui_sleep_time( void );
int get_total_frames();
int vj_img_cb(GdkPixbuf *img );
int vj_get_preview_box_w();
int vj_get_preview_box_h();
int _effect_get_minmax( int effect_id, int *min, int *max, int index );
void vj_gui_cb(int state, char *hostname, int port_num);
void gveejay_preview(int p);
int is_button_toggled(const char *name);
gchar *_utf8str( const char *c_str );
void find_user_themes();
int gveejay_user_preview();
char *get_glade_path();
char *get_gveejay_dir();
int gveejay_restart();
int gveejay_update();
int update_gveejay();
int veejay_update_multitrack( void *data );
#endif

View File

@@ -0,0 +1,504 @@
/* Gveejay Reloaded - graphical interface for VeeJay
* (C) 2002-2007 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 <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <veejay/vjmem.h>
#include <veejay/vj-msg.h>
#include <alsa/asoundlib.h>
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <veejay/libvevo.h>
#include <veejay/vevo.h>
#include <src/vj-api.h>
extern GtkWidget *glade_xml_get_widget_( GladeXML *m, const char *name );
extern void msg_vims(char *message);
extern void vj_msg(int type, const char format[], ...);
extern int prompt_dialog(const char *title, char *msg);
static int vj_midi_events(void *vv );
typedef struct
{
snd_seq_t *sequencer;
void *vims;
struct pollfd *pfd;
int npfd;
int learn;
int learn_event[4];
int active;
void *mw;
} vmidi_t;
typedef struct
{
int extra;
char *widget;
char *msg;
} dvims_t;
void vj_midi_learn( void *vv )
{
vmidi_t *v = (vmidi_t*) vv;
if(!v->active) return;
v->learn = 1;
vj_msg(VEEJAY_MSG_INFO, "Learning MIDI commands. Touch a midi key and then click a widget");
}
void vj_midi_play(void *vv )
{
vmidi_t *v = (vmidi_t*) vv;
if(!v->active) return;
v->learn = 0;
int a = vj_midi_events(vv);
char msg[100];
snprintf(msg,sizeof(msg), "MIDI listener active, %d events registered", a );
vj_msg(VEEJAY_MSG_INFO, "%s",msg);
}
static int vj_midi_events(void *vv )
{
vmidi_t *v = (vmidi_t*)vv;
char **items = vevo_list_properties(v->vims);
if(!items) return 0;
int i;
int len = 0;
for( i = 0; items[i] != NULL ; i ++ )
{
len ++;
free(items[i]);
}
free(items);
return len;
}
static void vj_midi_reset( void *vv )
{
vmidi_t *v = (vmidi_t*)vv;
char **items = vevo_list_properties(v->vims);
if(!items) return;
int i;
for( i = 0; items[i] != NULL ; i ++ )
{
dvims_t *d = NULL;
if( vevo_property_get( v->vims, items[i],0,&d ) == VEVO_NO_ERROR )
{
if(d->msg) free(d->msg);
if(d->widget) free(d->widget);
free(d);
}
free(items[i]);
}
free(items);
vevo_port_free(v->vims);
v->vims = vpn(VEVO_ANONYMOUS_PORT);
}
void vj_midi_load(void *vv, const char *filename)
{
vmidi_t *v = (vmidi_t*) vv;
if(!v->active) return;
int a = vj_midi_events(vv);
if( a > 0 )
{
char warn[200];
snprintf(warn,sizeof(warn), "There are %d MIDI event known, loading from file will overwrite any existing events. Continue ?", a );
if( prompt_dialog( "MIDI", warn ) == GTK_RESPONSE_REJECT )
return;
}
int fd = open( filename, O_RDONLY );
if(!fd)
{
vj_msg(VEEJAY_MSG_ERROR, "Unable to open file '%s': %s", filename, strerror(errno));
return;
}
struct stat t;
if( fstat( fd, &t) != 0 )
{
vj_msg(VEEJAY_MSG_ERROR,"Unable to load %s: %s", filename, strerror(errno));
return;
}
else
{
if( !S_ISREG( t.st_mode ) && !S_ISLNK(t.st_mode) )
{
vj_msg(VEEJAY_MSG_ERROR, "File '%s' is not a regular file or symbolic link. Refusing to load it.",
filename );
return;
}
}
char *buf = (char*) vj_calloc( 128000 );
int done = 0;
uint32_t count = 0;
if (read( fd, buf, 128000 ) > 0 )
{
int len = strlen( buf );
int j,k=0;
char value[1024];
veejay_memset(value,0,sizeof(value));
for( j = 0; j < len; j ++ )
{
if( buf[j] == '\0' ) break;
if( buf[j] == '\n' )
{
char key[32];
char widget[100];
char message[512];
int extra = 0;
if(sscanf( value, "%s %d %s \"%[^\"]", key, &extra, widget, message ) == 4 )
{
veejay_memset( value,0,sizeof(value));
k = 0;
dvims_t *d = (dvims_t*) vj_calloc(sizeof(dvims_t));
dvims_t *cur = NULL;
d->extra = extra;
d->widget = NULL;
if( strncasecmp( widget, "none", 4 ) !=0 )
d->widget = strdup(widget);
d->msg = strdup(message);
if( vevo_property_get( v->vims, key, 0, &cur ) == VEVO_NO_ERROR )
{
if(cur->widget) free(cur->widget);
if(cur->msg) free(cur->msg);
free(cur);
}
int error = vevo_property_set( v->vims, key, 1, VEVO_ATOM_TYPE_VOIDPTR, &d);
veejay_memset( key,0,sizeof(key));
veejay_memset( widget,0,sizeof(widget));
veejay_memset( message,0,sizeof(message));
count ++;
}
}
if( buf[j] != '\n' && buf[j] != '\0' )
value[k++] = buf[j];
}
}
free(buf);
vj_msg(VEEJAY_MSG_INFO, "Loaded %d MIDI events from %s", count ,filename);
}
void vj_midi_save(void *vv, const char *filename)
{
vmidi_t *v = (vmidi_t*) vv;
if(!v->active) return;
int fd = open( filename, O_TRUNC|O_CREAT|O_WRONLY );
if(!fd)
{
vj_msg(VEEJAY_MSG_ERROR, "Unable to save MIDI settings to %s",filename);
return;
}
char **items = vevo_list_properties( v->vims );
int i;
if( items == NULL )
{
vj_msg(VEEJAY_MSG_ERROR, "No MIDI events learned yet");
return;
}
uint32_t count = 0;
for( i =0 ; items[i] != NULL ;i ++ )
{
char tmp[512];
dvims_t *d = NULL;
if( vevo_property_get( v->vims, items[i], 0, &d ) == VEVO_NO_ERROR )
{
snprintf(tmp, 512, "%s %d %s \"%s\"\n",
items[i],
d->extra,
(d->widget == NULL ? "none" : d->widget ),
d->msg );
write( fd, tmp, strlen( tmp ));
count ++;
}
free(items[i]);
}
free(items);
close(fd);
vj_msg(VEEJAY_MSG_INFO, "Wrote %d MIDI events to %s", count, filename );
}
void vj_midi_learning_vims( void *vv, char *widget, char *msg, int extra )
{
vmidi_t *v = (vmidi_t*) vv;
if(!v->active) return;
if( !v->learn )
return;
dvims_t *d = (dvims_t*) vj_malloc(sizeof(dvims_t));
d->extra = extra;
d->msg = (msg == NULL ? NULL : strdup(msg));
d->widget = (widget == NULL ? NULL : strdup(widget));
char key[32];
snprintf(key,sizeof(key), "%03d%03d", v->learn_event[0],v->learn_event[1] );
dvims_t *cur = NULL;
if( vevo_property_get( v->vims, key, 0, &cur ) == VEVO_NO_ERROR )
{
if( cur->widget ) free(cur->widget );
if( cur->msg ) free(cur->msg);
free(cur);
}
int error = vevo_property_set( v->vims, key, 1, VEVO_ATOM_TYPE_VOIDPTR, &d );
if( error != VEVO_NO_ERROR )
return;
vj_msg( VEEJAY_MSG_INFO,
"Midi %x: %x ,%x learned", v->learn_event[0],v->learn_event[1],v->learn_event[2]);
}
void vj_midi_learning_vims_simple( void *vv, char *widget, int id )
{
char message[100];
if( widget == NULL )
snprintf(message,sizeof(message), "%03d:;", id );
else
snprintf(message,sizeof(message), "%03d:", id );
vj_midi_learning_vims( vv, widget, message, (widget == NULL ? 0 : 1 ) );
}
void vj_midi_learning_vims_spin( void *vv, char *widget, int id )
{
char message[100];
if( widget == NULL )
snprintf(message,sizeof(message), "%03d:;", id );
else
snprintf(message,sizeof(message), "%03d:", id );
vj_midi_learning_vims( vv, widget, message, (widget == NULL ? 0 : 2) );
}
void vj_midi_learning_vims_complex( void *vv, char *widget, int id, int first , int extra)
{
char message[100];
snprintf( message, sizeof(message), "%03d:%d",id, first );
vj_midi_learning_vims( vv, widget, message, extra );
}
void vj_midi_learning_vims_msg( void *vv, char *widget, int id, int arg )
{
char message[100];
snprintf(message, sizeof(message), "%03d:%d;",id, arg );
vj_midi_learning_vims( vv, widget, message, 0 );
}
void vj_midi_learning_vims_msg2(void *vv, char *widget, int id, int arg, int b )
{
char message[100];
snprintf(message,sizeof(message), "%03d:%d %d;", id, arg,b );
vj_midi_learning_vims( vv, widget, message, 0 );
}
void vj_midi_learning_vims_fx( void *vv, int widget, int id, int a, int b, int c, int extra )
{
char message[100];
char wid[100];
snprintf(message,sizeof(message), "%03d:%d %d %d", id, a,b,c );
snprintf(wid, sizeof(wid),"slider_p%d", widget );
vj_midi_learning_vims( vv, wid, message, extra );
}
static void queue_vims_event( vmidi_t *v, int *data )
{
char key[32];
if( v->learn )
{
veejay_memcpy( v->learn_event, data, sizeof(v->learn_event ));
vj_msg(VEEJAY_MSG_INFO, "MIDI %x:%x,%x -> ?", v->learn_event[0],v->learn_event[1],
v->learn_event[2]);
return;
}
snprintf(key,sizeof(key), "%03d%03d", data[0],data[1] );
dvims_t *d = NULL;
int error = vevo_property_get( v->vims, key, 0, &d);
if( error == VEVO_NO_ERROR )
{
if( d->extra )
{ //@ argument is dynamic
double min = 0.0;
double max = 0.0;
double tmp = 0.0;
double val = 0.0;
switch(d->extra)
{
case 1: //slider
{
GtkAdjustment *a = gtk_range_get_adjustment( GTK_RANGE(
glade_xml_get_widget_( v->mw, d->widget ) ) );
min = a->lower;
max = a->upper;
}
break;
case 2: //spinbox
gtk_spin_button_get_range( GTK_SPIN_BUTTON(
glade_xml_get_widget_( v->mw, d->widget)), &min, &max);
break;
}
if( data[0] == SND_SEQ_EVENT_PITCHBEND )
{
tmp = 16384.0 / max;
val = data[2] + 8192;
if( val > 0 )
val = val / tmp;
}
else if( data[0] == SND_SEQ_EVENT_CONTROLLER || data[0] == SND_SEQ_EVENT_KEYPRESS )
{
tmp = 127.0 / max;
val = data[2];
if( val > 0 )
val = val / tmp;
} else {
return;
}
char vims_msg[255];
snprintf(vims_msg,sizeof(vims_msg), "%s %d;", d->msg, (int) val );
msg_vims( vims_msg );
vj_msg(VEEJAY_MSG_INFO, "MIDI %x:%x, %x -> vims %s", data[0], data[1],data[2], vims_msg);
}
else
{
msg_vims( d->msg );
vj_msg(VEEJAY_MSG_INFO, "MIDI %x: %x,%x -> vims %s", data[0],data[1],data[2], d->msg);
}
}
else
{
vj_msg(VEEJAY_MSG_ERROR, "No vims event for MIDI %x:%x,%x found",
data[0],data[1],data[2]);
}
}
static void vj_midi_action( vmidi_t *v )
{
snd_seq_event_t *ev;
int data[4] = { 0,0,0,0};
snd_seq_event_input( v->sequencer, &ev );
data[0] = ev->type;
switch( ev->type )
{
/* controller: channel <0-N>, <modwheel 0-127> */
case SND_SEQ_EVENT_CONTROLLER:
data[1] = ev->data.control.channel;
data[2] = ev->data.control.value;
break;
case SND_SEQ_EVENT_PITCHBEND:
data[1] = ev->data.control.channel;
data[2] = ev->data.control.value;
break;
case SND_SEQ_EVENT_NOTEON:
data[2] = ev->data.control.channel;
data[1] = ev->data.note.note;
break;
case SND_SEQ_EVENT_NOTEOFF:
data[2] = ev->data.control.channel;
data[1] = ev->data.note.note;
break;
case SND_SEQ_EVENT_KEYPRESS:
data[1] = ev->data.control.channel;
data[2] = ev->data.note.velocity;
break;
default:
break;
}
queue_vims_event( v, data );
snd_seq_free_event( ev );
}
int vj_midi_handle_events(void *vv)
{
vmidi_t *v = (vmidi_t*) vv;
if(!v->active) return 0;
if( poll( v->pfd, v->npfd, 0 ) > 0 )
{
//@ snd_event_input_pending doesnt work
// while( snd_seq_event_input_pending( v->sequencer, 0 ) > 0 )
vj_midi_action( v );
return 1;
}
return 0;
}
void *vj_midi_new(void *mw)
{
vmidi_t *v = (vmidi_t*) vj_calloc(sizeof(vmidi_t));
int portid = 0;
if( snd_seq_open( &(v->sequencer), "hw", SND_SEQ_OPEN_DUPLEX, 0 ) < 0 )
{
veejay_msg(0, "Error opening ALSA sequencer");
return v;
}
snd_seq_set_client_name( v->sequencer, "Veejay" );
if( (portid = snd_seq_create_simple_port( v->sequencer, "Veejay",
SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE ,
SND_SEQ_PORT_TYPE_APPLICATION )) < 0 )
{
veejay_msg(0, "Error creating sequencer port");
return v;
}
v->npfd = snd_seq_poll_descriptors_count( v->sequencer, POLLIN );
if( v->npfd <= 0 )
{
veejay_msg(0,"Unable to poll in from sequencer");
return v;
}
v->pfd = (struct pollfd *) vj_calloc( v->npfd * sizeof( struct pollfd ));
v->mw = mw;
v->learn = 0;
v->vims = vpn(VEVO_ANONYMOUS_PORT);
v->active = 1;
snd_seq_poll_descriptors( v->sequencer, v->pfd, v->npfd, POLLIN );
veejay_msg(VEEJAY_MSG_INFO, "MIDI listener active");
return (void*) v;
}

View File

@@ -0,0 +1,41 @@
/* Gveejay Reloaded - graphical interface for VeeJay
* (C) 2002-2007 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.
*/
#ifndef VMIDI_H
#define VMIDI_H
void *vj_midi_new(void *mw);
int vj_midi_handle_events(void *vv);
void vj_midi_play(void *vv );
void vj_midi_learn( void *vv );
void vj_midi_load(void *vv, const char *filename);
void vj_midi_save(void *vv, const char *filename);
void vj_midi_learning_vims( void *vv, char *widget, char *msg, int extra );
void vj_midi_learning_vims_simple( void *vv, char *widget, int id );
void vj_midi_learning_vims_complex( void *vv, char *widget, int id, int first , int extra );
void vj_midi_learning_vims_fx( void *vv, int widget, int id, int a, int b, int c, int extra );
void vj_midi_learning_vims_msg2(void *vv, char *widget, int id, int arg, int b );
void vj_midi_learning_vims_msg( void *vv, char *widget, int id, int arg );
void vj_midi_learning_vims_spin( void *vv, char *widget, int id );
#endif

View File

@@ -0,0 +1,358 @@
/***************************************************************************
cellrendererspin.c
------------------
begin : Tue Oct 21 2003
copyright : (C) 2003 by Tim-Philipp M<>ller
email : t.i.m at orange dot 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 is a dirty 15-minute hack that tries to
* make editable cells with spin buttons instead
* of the text entry widget.
*
* Modify how you please. At the moment you need
* to hook up your own cell data function to make
* sure that the number of digits is the same in
* editing mode as it is in non-editing mode.
*
* The parameters passed to _new() should probably
* be properties, and probably we don't need most
* of them anyway. Also, it would be good if there
* was a better method to ensure that the number
* of digits is the same without this.
*
* Maybe one should just rip out the whole _render
* stuff from GtkCellRendererText and make a
* whole new specialised GtkCellRenderFloat
* or something.
*
* If anyone ever completes this code to sth useful,
* or achieves sth similar in another way, or has
* any comments on it, please drop me a mail.
*/
#include "cellrendererspin.h"
#include <gtk/gtkadjustment.h>
#include <gtk/gtkspinbutton.h>
#include <stdlib.h>
#define GUI_CELL_RENDERER_SPIN_PATH "gui-cell-renderer-spin-path"
#define GUI_CELL_RENDERER_SPIN_INFO "gui-cell-renderer-spin-info"
/* Some boring function declarations: GObject type system stuff */
static void gui_cell_renderer_spin_init (GuiCellRendererSpin *cellspin);
static void gui_cell_renderer_spin_class_init (GuiCellRendererSpinClass *klass);
static void gui_cell_renderer_spin_finalize (GObject *gobject);
static gpointer parent_class;
static GtkCellEditable *gui_cell_renderer_spin_start_editing (GtkCellRenderer *cell,
GdkEvent *event,
GtkWidget *widget,
const gchar *path,
GdkRectangle *background_area,
GdkRectangle *cell_area,
GtkCellRendererState flags);
struct _GCRSpinInfo
{
gulong focus_out_id;
};
typedef struct _GCRSpinInfo GCRSpinInfo;
/***************************************************************************
*
* gui_cell_renderer_spin_get_type
*
* Here we register our type with the GObject type system if we
* haven't done so yet. Everything else is done in the callbacks.
*
***************************************************************************/
GType
gui_cell_renderer_spin_get_type (void)
{
static GType cell_spin_type = 0;
if (cell_spin_type)
return cell_spin_type;
if (1)
{
static const GTypeInfo cell_spin_info =
{
sizeof (GuiCellRendererSpinClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gui_cell_renderer_spin_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GuiCellRendererSpin),
0, /* n_preallocs */
(GInstanceInitFunc) gui_cell_renderer_spin_init,
};
/* Derive from GtkCellRenderer */
cell_spin_type = g_type_register_static (GTK_TYPE_CELL_RENDERER_TEXT,
"GuiCellRendererSpin",
&cell_spin_info,
0);
}
return cell_spin_type;
}
/***************************************************************************
*
* gui_cell_renderer_spin_init
*
* Set some default properties of the parent (GtkCellRendererText).
*
***************************************************************************/
static void
gui_cell_renderer_spin_init (GuiCellRendererSpin *cellrendererspin)
{
return;
}
/***************************************************************************
*
* gui_cell_renderer_spin_class_init:
*
***************************************************************************/
static void
gui_cell_renderer_spin_class_init (GuiCellRendererSpinClass *klass)
{
GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(klass);
GObjectClass *object_class = G_OBJECT_CLASS(klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gui_cell_renderer_spin_finalize;
/* Override the cell renderer's edit-related methods */
cell_class->start_editing = gui_cell_renderer_spin_start_editing;
}
/***************************************************************************
*
* gui_cell_renderer_spin_finalize: free any resources here
*
***************************************************************************/
static void
gui_cell_renderer_spin_finalize (GObject *object)
{
/*
GuiCellRendererSpin *cellrendererspin = GUI_CELL_RENDERER_SPIN(object);
*/
/* Free any dynamically allocated resources here */
/* chain up to parent class to make sure
* they release all their memory as well */
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
/***************************************************************************
*
* gui_cell_renderer_spin_new
*
* return a new cell renderer instance
* (all the parameters should really be properties)
*
* Not sure which of all these values are really
* relevant for the spin button - needs checking!
*
***************************************************************************/
GtkCellRenderer *
gui_cell_renderer_spin_new (gdouble lower,
gdouble upper,
gdouble step_inc,
gdouble page_inc,
gdouble page_size,
gdouble climb_rate,
guint digits)
{
GtkCellRenderer *cell;
GuiCellRendererSpin *spincell;
cell = g_object_new(GUI_TYPE_CELL_RENDERER_SPIN, NULL);
spincell = GUI_CELL_RENDERER_SPIN(cell);
spincell->lower = lower;
spincell->upper = upper;
spincell->step_inc = step_inc;
spincell->page_inc = page_inc;
spincell->page_size = page_size;
spincell->climb_rate = climb_rate;
spincell->digits = digits;
return cell;
}
/***************************************************************************
*
* gui_cell_renderer_spin_editing_done
*
***************************************************************************/
static void
gui_cell_renderer_spin_editing_done (GtkCellEditable *spinbutton,
gpointer data)
{
const gchar *path;
const gchar *new_text;
GCRSpinInfo *info;
info = g_object_get_data (G_OBJECT (data), GUI_CELL_RENDERER_SPIN_INFO);
if (info->focus_out_id > 0)
{
g_signal_handler_disconnect (spinbutton, info->focus_out_id);
info->focus_out_id = 0;
}
if (GTK_ENTRY(spinbutton)->editing_canceled)
return;
path = g_object_get_data (G_OBJECT (spinbutton), GUI_CELL_RENDERER_SPIN_PATH);
new_text = gtk_entry_get_text (GTK_ENTRY(spinbutton));
g_signal_emit_by_name(data, "edited", path, new_text);
}
/***************************************************************************
*
* gui_cell_renderer_spin_focus_out_event
*
***************************************************************************/
static gboolean
gui_cell_renderer_spin_focus_out_event (GtkWidget *spinbutton,
GdkEvent *event,
gpointer data)
{
gui_cell_renderer_spin_editing_done (GTK_CELL_EDITABLE (spinbutton), data);
/* entry needs focus-out-event */
return FALSE;
}
/***************************************************************************
*
* gui_cell_renderer_spin_start_editing
*
***************************************************************************/
static gboolean
onButtonPress (GtkWidget *spinbutton, GdkEventButton *bevent, gpointer data)
{
if ((bevent->button == 1 && bevent->type == GDK_2BUTTON_PRESS) || bevent->type == GDK_3BUTTON_PRESS)
{
g_print ("double or triple click caught and ignored.\n");
return TRUE; /* don't invoke other handlers */
}
return FALSE;
}
/***************************************************************************
*
* gui_cell_renderer_spin_start_editing
*
***************************************************************************/
static GtkCellEditable *
gui_cell_renderer_spin_start_editing (GtkCellRenderer *cell,
GdkEvent *event,
GtkWidget *widget,
const gchar *path,
GdkRectangle *background_area,
GdkRectangle *cell_area,
GtkCellRendererState flags)
{
GtkCellRendererText *celltext;
GuiCellRendererSpin *spincell;
GtkAdjustment *adj;
GtkWidget *spinbutton;
GCRSpinInfo *info;
gdouble curval = 0.0;
celltext = GTK_CELL_RENDERER_TEXT(cell);
spincell = GUI_CELL_RENDERER_SPIN(cell);
/* If the cell isn't editable we return NULL. */
if (celltext->editable == FALSE)
return NULL;
spinbutton = g_object_new (GTK_TYPE_SPIN_BUTTON, "has_frame", FALSE, "numeric", TRUE, NULL);
/* dirty */
if (celltext->text)
curval = atof(celltext->text);
adj = GTK_ADJUSTMENT(gtk_adjustment_new(curval,
spincell->lower,
spincell->upper,
spincell->step_inc,
spincell->page_inc,
spincell->page_size));
gtk_spin_button_configure(GTK_SPIN_BUTTON(spinbutton), adj, spincell->climb_rate, spincell->digits);
g_object_set_data_full (G_OBJECT(spinbutton), GUI_CELL_RENDERER_SPIN_PATH, g_strdup (path), g_free);
gtk_editable_select_region (GTK_EDITABLE (spinbutton), 0, -1);
gtk_widget_show (spinbutton);
g_signal_connect (spinbutton, "editing_done",
G_CALLBACK (gui_cell_renderer_spin_editing_done),
celltext);
/* hack trying to catch the quite annoying effect
* a double click has while editing */
g_signal_connect (spinbutton, "button_press_event",
G_CALLBACK (onButtonPress),
NULL);
info = g_new0(GCRSpinInfo, 1);
info->focus_out_id = g_signal_connect (spinbutton, "focus_out_event",
G_CALLBACK (gui_cell_renderer_spin_focus_out_event),
celltext);
g_object_set_data_full (G_OBJECT (cell), GUI_CELL_RENDERER_SPIN_INFO, info, g_free);
return GTK_CELL_EDITABLE (spinbutton);
}

View File

@@ -0,0 +1,68 @@
/***************************************************************************
cellrendererspin.h
------------------
begin : Tue Oct 21 2003
copyright : (C) 2003 by Tim-Philipp M<>ller
email : t.i.m at orange dot 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. *
* *
***************************************************************************/
#ifndef _cellrendererspin_h_included_
#define _cellrendererspin_h_included_
#include <gtk/gtkcellrenderertext.h>
/* Some boilerplate GObject type check and type cast macros */
#define GUI_TYPE_CELL_RENDERER_SPIN (gui_cell_renderer_spin_get_type())
#define GUI_CELL_RENDERER_SPIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GUI_TYPE_CELL_RENDERER_SPIN, GuiCellRendererSpin))
#define GUI_CELL_RENDERER_SPIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GUI_TYPE_CELL_RENDERER_SPIN, GuiCellRendererSpinClass))
#define GUI_IS_CELL_RENDERER_SPIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GUI_TYPE_CELL_RENDERER_SPIN))
#define GUI_IS_CELL_RENDERER_SPIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GUI_TYPE_CELL_RENDERER_SPIN))
#define GUI_CELL_RENDERER_SPIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GUI_TYPE_CELL_RENDERER_SPIN, GuiCellRendererSpinClass))
typedef struct _GuiCellRendererSpin GuiCellRendererSpin;
typedef struct _GuiCellRendererSpinClass GuiCellRendererSpinClass;
struct _GuiCellRendererSpin
{
GtkCellRendererText parent;
gdouble lower;
gdouble upper;
gdouble step_inc;
gdouble page_inc;
gdouble page_size;
gdouble climb_rate;
guint digits;
};
struct _GuiCellRendererSpinClass
{
GtkCellRendererTextClass parent_class;
};
GType gui_cell_renderer_spin_get_type (void);
GtkCellRenderer *gui_cell_renderer_spin_new (gdouble lower,
gdouble upper,
gdouble step_inc,
gdouble page_inc,
gdouble page_size,
gdouble climb_rate,
guint digits);
#endif /* _spinbar_renderer_h_included_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,141 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2000 Red Hat, Inc.
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_COLOR_SELECTION_H__
#define __GTK_COLOR_SELECTION_H__
// bad hack ... this parts are taken from different Header-Files of the gtk-sources
// that are normally needed for compiling the colorselection dialog
#define P_(String) (String)
#define _
#include <gtk/gtkdialog.h>
#include <gtk/gtkvbox.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GTK_TYPE_COLOR_SELECTION (gtk_color_selection_get_type ())
#define GTK_COLOR_SELECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_COLOR_SELECTION, GtkColorSelection))
#define GTK_COLOR_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_COLOR_SELECTION, GtkColorSelectionClass))
#define GTK_IS_COLOR_SELECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_COLOR_SELECTION))
#define GTK_IS_COLOR_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_COLOR_SELECTION))
#define GTK_COLOR_SELECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_COLOR_SELECTION, GtkColorSelectionClass))
typedef struct _GtkColorSelection GtkColorSelection;
typedef struct _GtkColorSelectionClass GtkColorSelectionClass;
typedef void (* GtkColorSelectionChangePaletteFunc) (const GdkColor *colors,
gint n_colors);
typedef void (* GtkColorSelectionChangePaletteWithScreenFunc) (GdkScreen *screen,
const GdkColor *colors,
gint n_colors);
struct _GtkColorSelection
{
GtkVBox parent_instance;
/* < private_data > */
gpointer private_data;
};
struct _GtkColorSelectionClass
{
GtkVBoxClass parent_class;
void (*color_changed) (GtkColorSelection *color_selection);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
};
/* ColorSelection */
GType gtk_color_selection_get_type (void) G_GNUC_CONST;
GtkWidget *gtk_color_selection_new (void);
gboolean gtk_color_selection_get_has_opacity_control (GtkColorSelection *colorsel);
void gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel,
gboolean has_opacity);
gboolean gtk_color_selection_get_has_palette (GtkColorSelection *colorsel);
void gtk_color_selection_set_has_palette (GtkColorSelection *colorsel,
gboolean has_palette);
void gtk_color_selection_set_current_color (GtkColorSelection *colorsel,
const GdkColor *color);
void gtk_color_selection_set_current_alpha (GtkColorSelection *colorsel,
guint16 alpha);
void gtk_color_selection_get_current_color (GtkColorSelection *colorsel,
GdkColor *color);
guint16 gtk_color_selection_get_current_alpha (GtkColorSelection *colorsel);
void gtk_color_selection_set_previous_color (GtkColorSelection *colorsel,
const GdkColor *color);
void gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel,
guint16 alpha);
void gtk_color_selection_get_previous_color (GtkColorSelection *colorsel,
GdkColor *color);
guint16 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel);
gboolean gtk_color_selection_is_adjusting (GtkColorSelection *colorsel);
gboolean gtk_color_selection_palette_from_string (const gchar *str,
GdkColor **colors,
gint *n_colors);
gchar* gtk_color_selection_palette_to_string (const GdkColor *colors,
gint n_colors);
#ifndef GTK_DISABLE_DEPRECATED
#ifndef GDK_MULTIHEAD_SAFE
GtkColorSelectionChangePaletteFunc gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func);
#endif
#endif
GtkColorSelectionChangePaletteWithScreenFunc gtk_color_selection_set_change_palette_with_screen_hook (GtkColorSelectionChangePaletteWithScreenFunc func);
#ifndef GTK_DISABLE_DEPRECATED
/* Deprecated calls: */
void gtk_color_selection_set_color (GtkColorSelection *colorsel,
gdouble *color);
void gtk_color_selection_get_color (GtkColorSelection *colorsel,
gdouble *color);
void gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
GtkUpdateType policy);
#endif /* GTK_DISABLE_DEPRECATED */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GTK_COLOR_SELECTION_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
/* HSV color selector for GTK+
*
* Copyright (C) 1999 The Free Software Foundation
*
* Authors: Simon Budig <Simon.Budig@unix-ag.org> (original code)
* Federico Mena-Quintero <federico@gimp.org> (cleanup for GTK+)
* Jonathan Blandford <jrb@redhat.com> (cleanup for GTK+)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_HSV_H__
#define __GTK_HSV_H__
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include <gtk/gtkcontainer.h>
#ifdef __cplusplus
extern "C" {
#endif
#define GTK_TYPE_HSV (gtk_hsv_get_type ())
#define GTK_HSV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_HSV, GtkHSV))
#define GTK_HSV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_HSV, GtkHSVClass))
#define GTK_IS_HSV(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_HSV))
#define GTK_IS_HSV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_HSV))
#define GTK_HSV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_HSV, GtkHSVClass))
typedef struct _GtkHSV GtkHSV;
typedef struct _GtkHSVClass GtkHSVClass;
struct _GtkHSV
{
GtkWidget parent_instance;
/* Private data */
gpointer priv;
};
struct _GtkHSVClass
{
GtkWidgetClass parent_class;
/* Notification signals */
void (*changed) (GtkHSV *hsv);
/* Keybindings */
void (* move) (GtkHSV *hsv,
GtkDirectionType type);
};
GType gtk_hsv_get_type (void) G_GNUC_CONST;
GtkWidget* gtk_hsv_new (void);
void gtk_hsv_set_color (GtkHSV *hsv,
double h,
double s,
double v);
void gtk_hsv_get_color (GtkHSV *hsv,
gdouble *h,
gdouble *s,
gdouble *v);
void gtk_hsv_set_metrics (GtkHSV *hsv,
gint size,
gint ring_width);
void gtk_hsv_get_metrics (GtkHSV *hsv,
gint *size,
gint *ring_width);
gboolean gtk_hsv_is_adjusting (GtkHSV *hsv);
void gtk_hsv_to_rgb (gdouble h,
gdouble s,
gdouble v,
gdouble *r,
gdouble *g,
gdouble *b);
void gtk_rgb_to_hsv (gdouble r,
gdouble g,
gdouble b,
gdouble *h,
gdouble *s,
gdouble *v);
#ifdef __cplusplus
}
#endif
#endif /* __GTK_HSV_H__ */

View File

@@ -0,0 +1,569 @@
/* gAlan - Graphical Audio Language
* Copyright (C) 1999 Tony Garnock-Jones
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <math.h>
#include <stdio.h>
#include <gtk/gtkmain.h>
#include <gtk/gtksignal.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "gtkknob.h"
#ifndef M_PI
# define M_PI 3.14159265358979323846 /* pi */
#endif
#define SCROLL_DELAY_LENGTH 300
#define KNOB_SIZE 32
#define STATE_IDLE 0
#define STATE_PRESSED 1
#define STATE_DRAGGING 2
/* Forward declarations */
static void gtk_knob_class_init(GtkKnobClass *klass);
static void gtk_knob_init(GtkKnob *knob);
static void gtk_knob_destroy(GtkObject *object);
static void gtk_knob_realize(GtkWidget *widget);
static void gtk_knob_size_request(GtkWidget *widget, GtkRequisition *requisition);
static void gtk_knob_size_allocate(GtkWidget *widget, GtkAllocation *allocation);
static gint gtk_knob_expose(GtkWidget *widget, GdkEventExpose *event);
static gint gtk_knob_button_press(GtkWidget *widget, GdkEventButton *event);
static gint gtk_knob_button_release(GtkWidget *widget, GdkEventButton *event);
static gint gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event);
static gint gtk_knob_timer(GtkKnob *knob);
static void gtk_knob_update_mouse_update(GtkKnob *knob);
static void gtk_knob_update_mouse(GtkKnob *knob, gint x, gint y);
static void gtk_knob_update_mouse_abs(GtkKnob *knob, gint x, gint y);
static void gtk_knob_update(GtkKnob *knob);
static void gtk_knob_adjustment_changed(GtkAdjustment *adjustment, gpointer data);
static void gtk_knob_adjustment_value_changed(GtkAdjustment *adjustment, gpointer data);
/* Local data */
static GtkWidgetClass *parent_class = NULL;
static GList *animation = NULL;
static GList *get_anim_list( char *name ) {
GError *err = NULL;
GdkPixbuf *animation;
GList *retval = NULL;
int x, w;
fprintf(stderr, "Load pixpbuf %s\n", name );
animation = gdk_pixbuf_new_from_file( name, &err );
w = gdk_pixbuf_get_width( animation );
for(x=0; x<w; x+=KNOB_SIZE ) {
GdkPixbuf *pixbuf = gdk_pixbuf_new_subpixbuf( animation, x, 0, KNOB_SIZE, KNOB_SIZE );
retval = g_list_append( retval, pixbuf );
}
return retval;
}
void free_anim_list( GList *anim_list )
{
// g_list_foreach( anim_list, gdk_pixbuf_unref );
}
guint gtk_knob_get_type(void) {
static guint knob_type = 0;
if (!knob_type) {
GtkTypeInfo knob_info = {
"GtkKnob",
sizeof (GtkKnob),
sizeof (GtkKnobClass),
(GtkClassInitFunc) gtk_knob_class_init,
(GtkObjectInitFunc) gtk_knob_init,
NULL,
NULL,
};
knob_type = gtk_type_unique(gtk_widget_get_type(), &knob_info);
}
return knob_type;
}
static void gtk_knob_class_init (GtkKnobClass *class) {
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
// animation = get_anim_list( knob->path );
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
parent_class = gtk_type_class(gtk_widget_get_type());
object_class->destroy = gtk_knob_destroy;
widget_class->realize = gtk_knob_realize;
widget_class->expose_event = gtk_knob_expose;
widget_class->size_request = gtk_knob_size_request;
widget_class->size_allocate = gtk_knob_size_allocate;
widget_class->button_press_event = gtk_knob_button_press;
widget_class->button_release_event = gtk_knob_button_release;
widget_class->motion_notify_event = gtk_knob_motion_notify;
}
static void gtk_knob_init (GtkKnob *knob) {
knob->policy = GTK_UPDATE_CONTINUOUS;
knob->state = STATE_IDLE;
knob->saved_x = knob->saved_y = 0;
knob->timer = 0;
knob->pixbuf = NULL;
knob->anim_list = animation;
knob->old_value = 0.0;
knob->old_lower = 0.0;
knob->old_upper = 0.0;
knob->adjustment = NULL;
}
GtkWidget *gtk_knob_new(GtkAdjustment *adjustment, const char *path) {
GtkKnob *knob;
knob = gtk_type_new(gtk_knob_get_type());
knob->path = g_strdup( path );
animation = get_anim_list( knob->path );
if (!adjustment)
adjustment = (GtkAdjustment*) gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
gtk_knob_set_adjustment(knob, adjustment);
return GTK_WIDGET(knob);
}
static void gtk_knob_destroy(GtkObject *object) {
GtkKnob *knob;
g_return_if_fail(object != NULL);
g_return_if_fail(GTK_IS_KNOB(object));
knob = GTK_KNOB(object);
if (knob->adjustment) {
gtk_object_unref(GTK_OBJECT(knob->adjustment));
knob->adjustment = NULL;
}
if (knob->pixbuf) {
gdk_pixbuf_unref(knob->pixbuf);
knob->pixbuf = NULL;
}
if (GTK_OBJECT_CLASS(parent_class)->destroy)
(*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
}
GtkAdjustment* gtk_knob_get_adjustment(GtkKnob *knob) {
g_return_val_if_fail(knob != NULL, NULL);
g_return_val_if_fail(GTK_IS_KNOB(knob), NULL);
return knob->adjustment;
}
void gtk_knob_set_update_policy(GtkKnob *knob, GtkUpdateType policy) {
g_return_if_fail (knob != NULL);
g_return_if_fail (GTK_IS_KNOB (knob));
knob->policy = policy;
}
void gtk_knob_set_adjustment(GtkKnob *knob, GtkAdjustment *adjustment) {
g_return_if_fail (knob != NULL);
g_return_if_fail (GTK_IS_KNOB (knob));
if (knob->adjustment) {
gtk_signal_disconnect_by_data(GTK_OBJECT(knob->adjustment), (gpointer)knob);
gtk_object_unref(GTK_OBJECT(knob->adjustment));
}
knob->adjustment = adjustment;
gtk_object_ref(GTK_OBJECT(knob->adjustment));
gtk_object_sink(GTK_OBJECT( knob->adjustment ) );
gtk_signal_connect(GTK_OBJECT(adjustment), "changed",
GTK_SIGNAL_FUNC(gtk_knob_adjustment_changed), (gpointer) knob);
gtk_signal_connect(GTK_OBJECT(adjustment), "value_changed",
GTK_SIGNAL_FUNC(gtk_knob_adjustment_value_changed), (gpointer) knob);
knob->old_value = adjustment->value;
knob->old_lower = adjustment->lower;
knob->old_upper = adjustment->upper;
gtk_knob_update(knob);
}
static void gtk_knob_realize(GtkWidget *widget) {
GtkKnob *knob;
GdkWindowAttr attributes;
gint attributes_mask;
g_return_if_fail(widget != NULL);
g_return_if_fail(GTK_IS_KNOB(widget));
GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
knob = GTK_KNOB(widget);
attributes.x = widget->allocation.x;
attributes.y = widget->allocation.y;
attributes.width = widget->allocation.width;
attributes.height = widget->allocation.height;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.window_type = GDK_WINDOW_CHILD;
attributes.event_mask =
gtk_widget_get_events (widget) |
GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
GDK_POINTER_MOTION_HINT_MASK;
attributes.visual = gtk_widget_get_visual(widget);
attributes.colormap = gtk_widget_get_colormap(widget);
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
widget->style = gtk_style_attach(widget->parent->style, widget->window);
gdk_window_set_user_data(widget->window, widget);
gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);
}
static void gtk_knob_size_request (GtkWidget *widget, GtkRequisition *requisition) {
requisition->width = KNOB_SIZE;
requisition->height = KNOB_SIZE;
}
static void gtk_knob_size_allocate (GtkWidget *widget, GtkAllocation *allocation) {
GtkKnob *knob;
g_return_if_fail(widget != NULL);
g_return_if_fail(GTK_IS_KNOB(widget));
g_return_if_fail(allocation != NULL);
widget->allocation = *allocation;
knob = GTK_KNOB(widget);
if (GTK_WIDGET_REALIZED(widget)) {
gdk_window_move_resize(widget->window,
allocation->x, allocation->y,
allocation->width, allocation->height);
}
}
static gint gtk_knob_expose(GtkWidget *widget, GdkEventExpose *event) {
GtkKnob *knob;
gfloat dx, dy;
GList *framelist;
g_return_val_if_fail(widget != NULL, FALSE);
g_return_val_if_fail(GTK_IS_KNOB(widget), FALSE);
g_return_val_if_fail(event != NULL, FALSE);
if (event->count > 0)
return FALSE;
knob = GTK_KNOB(widget);
gdk_window_clear_area(widget->window, 0, 0, widget->allocation.width, widget->allocation.height);
dx = knob->adjustment->value - knob->adjustment->lower;
dy = knob->adjustment->upper - knob->adjustment->lower;
framelist = knob->anim_list;
if (dy != 0) {
GdkPixbuf *pixbuf;
dx = MIN(MAX(dx / dy, 0), 1);
//dx = (1-dx) * (g_list_length( framelist )-0.5) * 0.75 + 0.125 * g_list_length( framelist );
dx = (dx) * (g_list_length( framelist ) - 1 );
pixbuf = g_list_nth_data( framelist, (int) dx);
gdk_pixbuf_render_to_drawable_alpha( pixbuf, widget->window,
0, 0, 0, 0, gdk_pixbuf_get_width( pixbuf ), gdk_pixbuf_get_height( pixbuf ), GDK_PIXBUF_ALPHA_FULL, 0, 0,0,0 );
}
return FALSE;
}
static gint gtk_knob_button_press(GtkWidget *widget, GdkEventButton *event) {
GtkKnob *knob;
g_return_val_if_fail(widget != NULL, FALSE);
g_return_val_if_fail(GTK_IS_KNOB(widget), FALSE);
g_return_val_if_fail(event != NULL, FALSE);
knob = GTK_KNOB(widget);
switch (knob->state) {
case STATE_IDLE:
switch (event->button) {
#if 0
case 3:
gtk_knob_update_mouse_abs(knob, event->x, event->y);
/* FALL THROUGH */
#endif
case 1:
case 3:
gtk_grab_add(widget);
knob->state = STATE_PRESSED;
knob->saved_x = event->x;
knob->saved_y = event->y;
break;
default:
break;
}
break;
default:
break;
}
return FALSE;
}
static gint gtk_knob_button_release(GtkWidget *widget, GdkEventButton *event) {
GtkKnob *knob;
g_return_val_if_fail(widget != NULL, FALSE);
g_return_val_if_fail(GTK_IS_KNOB(widget), FALSE);
g_return_val_if_fail(event != NULL, FALSE);
knob = GTK_KNOB(widget);
switch (knob->state) {
case STATE_PRESSED:
gtk_grab_remove(widget);
knob->state = STATE_IDLE;
switch (event->button) {
case 1:
knob->adjustment->value -= knob->adjustment->page_increment;
gtk_signal_emit_by_name(GTK_OBJECT(knob->adjustment), "value_changed");
break;
case 3:
knob->adjustment->value += knob->adjustment->page_increment;
gtk_signal_emit_by_name(GTK_OBJECT(knob->adjustment), "value_changed");
break;
default:
break;
}
break;
case STATE_DRAGGING:
gtk_grab_remove(widget);
knob->state = STATE_IDLE;
if (knob->policy != GTK_UPDATE_CONTINUOUS && knob->old_value != knob->adjustment->value)
gtk_signal_emit_by_name(GTK_OBJECT(knob->adjustment), "value_changed");
break;
default:
break;
}
return FALSE;
}
static gint gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
GtkKnob *knob;
GdkModifierType mods;
gint x, y;
g_return_val_if_fail(widget != NULL, FALSE);
g_return_val_if_fail(GTK_IS_KNOB(widget), FALSE);
g_return_val_if_fail(event != NULL, FALSE);
knob = GTK_KNOB(widget);
x = event->x;
y = event->y;
if (event->is_hint || (event->window != widget->window))
gdk_window_get_pointer(widget->window, &x, &y, &mods);
switch (knob->state) {
case STATE_PRESSED:
knob->state = STATE_DRAGGING;
/* fall through */
case STATE_DRAGGING:
if (mods & GDK_BUTTON1_MASK) {
gtk_knob_update_mouse(knob, x, y);
return TRUE;
} else if (mods & GDK_BUTTON3_MASK) {
gtk_knob_update_mouse_abs(knob, x, y);
return TRUE;
}
break;
default:
break;
}
return FALSE;
}
static gint gtk_knob_timer(GtkKnob *knob) {
g_return_val_if_fail(knob != NULL, FALSE);
g_return_val_if_fail(GTK_IS_KNOB(knob), FALSE);
if (knob->policy == GTK_UPDATE_DELAYED)
gtk_signal_emit_by_name(GTK_OBJECT(knob->adjustment), "value_changed");
return FALSE; /* don't keep running this timer */
}
static void gtk_knob_update_mouse_update(GtkKnob *knob) {
if (knob->policy == GTK_UPDATE_CONTINUOUS)
gtk_signal_emit_by_name(GTK_OBJECT(knob->adjustment), "value_changed");
else {
gtk_widget_draw(GTK_WIDGET(knob), NULL);
if (knob->policy == GTK_UPDATE_DELAYED) {
if (knob->timer)
gtk_timeout_remove(knob->timer);
knob->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH, (GtkFunction) gtk_knob_timer,
(gpointer) knob);
}
}
}
static void gtk_knob_update_mouse(GtkKnob *knob, gint x, gint y) {
gfloat old_value;
gfloat dv;
g_return_if_fail(knob != NULL);
g_return_if_fail(GTK_IS_KNOB(knob));
old_value = knob->adjustment->value;
dv = (knob->saved_y - y) * knob->adjustment->step_increment;
knob->saved_x = x;
knob->saved_y = y;
knob->adjustment->value += dv;
if (knob->adjustment->value != old_value)
gtk_knob_update_mouse_update(knob);
}
static void gtk_knob_update_mouse_abs(GtkKnob *knob, gint x, gint y) {
gfloat old_value;
gdouble angle;
g_return_if_fail(knob != NULL);
g_return_if_fail(GTK_IS_KNOB(knob));
old_value = knob->adjustment->value;
x -= KNOB_SIZE>>1;
y -= KNOB_SIZE>>1;
y = -y; /* inverted cartesian graphics coordinate system */
angle = atan2(y, x) / M_PI;
if (angle < -0.5)
angle += 2;
angle = -(2.0/3.0) * (angle - 1.25); /* map [1.25pi, -0.25pi] onto [0, 1] */
angle *= knob->adjustment->upper - knob->adjustment->lower;
angle += knob->adjustment->lower;
knob->adjustment->value = angle;
if (knob->adjustment->value != old_value)
gtk_knob_update_mouse_update(knob);
}
static void gtk_knob_update(GtkKnob *knob) {
gfloat new_value;
g_return_if_fail(knob != NULL);
g_return_if_fail(GTK_IS_KNOB (knob));
new_value = knob->adjustment->value;
if (new_value < knob->adjustment->lower)
new_value = knob->adjustment->lower;
if (new_value > knob->adjustment->upper)
new_value = knob->adjustment->upper;
if (new_value != knob->adjustment->value) {
knob->adjustment->value = new_value;
gtk_signal_emit_by_name(GTK_OBJECT(knob->adjustment), "value_changed");
}
gtk_widget_draw(GTK_WIDGET(knob), NULL);
}
static void gtk_knob_adjustment_changed(GtkAdjustment *adjustment, gpointer data) {
GtkKnob *knob;
g_return_if_fail(adjustment != NULL);
g_return_if_fail(data != NULL);
knob = GTK_KNOB(data);
if ((knob->old_value != adjustment->value) ||
(knob->old_lower != adjustment->lower) ||
(knob->old_upper != adjustment->upper)) {
gtk_knob_update (knob);
knob->old_value = adjustment->value;
knob->old_lower = adjustment->lower;
knob->old_upper = adjustment->upper;
}
}
static void gtk_knob_adjustment_value_changed (GtkAdjustment *adjustment, gpointer data) {
GtkKnob *knob;
g_return_if_fail(adjustment != NULL);
g_return_if_fail(data != NULL);
knob = GTK_KNOB(data);
if (knob->old_value != adjustment->value) {
gtk_knob_update (knob);
knob->old_value = adjustment->value;
}
}

View File

@@ -0,0 +1,86 @@
/* gAlan - Graphical Audio Language
* Copyright (C) 1999 Tony Garnock-Jones
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __GTK_KNOB_H__
#define __GTK_KNOB_H__
#include <gdk/gdk.h>
#include <gtk/gtkadjustment.h>
#include <gtk/gtkwidget.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PIXMAPDIRIFY(filename) \
(SITE_PKGDATA_DIR G_DIR_SEPARATOR_S "pixmaps" G_DIR_SEPARATOR_S filename)
#define GTK_KNOB(obj) GTK_CHECK_CAST(obj, gtk_knob_get_type(), GtkKnob)
#define GTK_KNOB_CLASS(klass) GTK_CHECK_CLASS_CAST(klass, gtk_knob_get_type(), GtkKnobClass)
#define GTK_IS_KNOB(obj) GTK_CHECK_TYPE(obj, gtk_knob_get_type())
typedef struct _GtkKnob GtkKnob;
typedef struct _GtkKnobClass GtkKnobClass;
struct _GtkKnob {
GtkWidget widget;
/* update policy (GTK_UPDATE_[CONTINUOUS/DELAYED/DISCONTINUOUS]) */
guint policy : 2;
/* State of widget (to do with user interaction) */
guint8 state;
gint saved_x, saved_y;
/* ID of update timer, or 0 if none */
guint32 timer;
/* Pixmap for knob */
GdkPixbuf *pixbuf;
/* Animation for knob... from animated gif */
GList *anim_list;
/* Old values from adjustment stored so we know when something changes */
gfloat old_value;
gfloat old_lower;
gfloat old_upper;
/* The adjustment object that stores the data for this knob */
GtkAdjustment *adjustment;
char *path;
};
struct _GtkKnobClass
{
GtkWidgetClass parent_class;
};
extern GtkWidget *gtk_knob_new(GtkAdjustment *adjustment, const char *path);
extern guint gtk_knob_get_type(void);
extern GtkAdjustment *gtk_knob_get_adjustment(GtkKnob *knob);
extern void gtk_knob_set_update_policy(GtkKnob *knob, GtkUpdateType policy);
extern void gtk_knob_set_adjustment(GtkKnob *knob, GtkAdjustment *adjustment);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,848 @@
/* veejay - Linux VeeJay
* (C) 2002-2004 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.
*/
/*
Implements a new slider type widget with selection markers
*/
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <gtkcairo.h>
#include <gtk/gtk.h>
#include "gtktimeselection.h"
enum
{
POS_CHANGED,
IN_CHANGED,
OUT_CHANGED,
BIND_CHANGED,
CLEAR_CHANGED,
SELECTION_CHANGED_SIGNAL,
LAST_SIGNAL
};
enum
{
MIN = 1,
MAX = 2,
POS = 3,
LENGTH = 4,
IN_POINT = 5,
OUT_POINT = 6,
SEL = 7,
BIND = 8,
CLEARED = 9,
};
typedef enum {
MOUSE_OUTSIDE,
MOUSE_STEPPER,
MOUSE_SELECTION,
MOUSE_WIDGET /* inside widget but not in any of the above */
} mouse_location;
/* Slider with 2 bars
*/
typedef enum TimelineAction
{
action_none = 0,
action_in_point,
action_out_point,
action_pos,
action_atomic,
} TimelineAction;
#define POINT_IN_RECT(xcoord, ycoord, rect) \
((xcoord) >= (rect).x && \
(xcoord) < ((rect).x + (rect).width) && \
(ycoord) >= (rect).y && \
(ycoord) < ((rect).y + (rect).height))
struct _TimelineSelection
{
GtkCairo cr;
GtkWidget *widget;
gdouble min;
gdouble max;
gdouble value;
gdouble frame_num;
gdouble num_video_frames;
gdouble in;
gdouble out;
gboolean bind;
gint grab_button;
TimelineAction action;
mouse_location grab_location;
mouse_location current_location;
GdkRectangle stepper;
GdkRectangle selection;
gboolean has_stepper;
gboolean clear;
gdouble stepper_size; /* size of triangle */
gdouble stepper_draw_size;
gdouble stepper_length; /* length from top to bottom */
gint step_size; /* step frames 1,2,4,8,16, ... */
gdouble frame_width;
gdouble frame_height;
gdouble font_line;
gboolean has_selection; /* use in/out points for selection */
gdouble move_x;
};
static void get_property( GObject *object,
guint id, GValue *value , GParamSpec *pspec );
static void set_property (GObject *object,
guint id, GValue * value, GParamSpec *pspec);
static gboolean event_press (GtkWidget *widget, GdkEventButton *bev, gpointer user_data);
static gboolean event_release (GtkWidget *widget, GdkEventButton *bev, gpointer user_data);
static gboolean event_motion (GtkWidget *widget, GdkEventMotion *mev, gpointer user_data);
static void timeline_class_init( TimelineSelectionClass *class );
static void timeline_init(TimelineSelection *te );
static void paint(GtkWidget *widget, cairo_t *cr, gpointer user_data);
static GObjectClass *parent_class = NULL;
static gint timeline_signals[LAST_SIGNAL] = { 0 };
struct _TimelineSelectionClass
{
GtkCairoClass parent_class;
void (*pos_changed) (TimelineSelection *te);
void (*in_point_changed) (TimelineSelection *te);
void (*out_point_changed) (TimelineSelection *te);
void (*bind_toggled) (TimelineSelection *te);
void (*cleared) (TimelineSelection *te);
};
static void set_property (GObject *object,
guint id, GValue *value, GParamSpec *pspec)
{
TimelineSelection *te = TIMELINE_SELECTION(object);
switch(id)
{
case MIN:
if(te->min != g_value_get_double(value))
{
te->min = g_value_get_double(value);
}
break;
case MAX:
if(te->max != g_value_get_double(value))
{
te->min = g_value_get_double(value);
}
break;
case POS:
if(te->frame_num != g_value_get_double(value))
{
te->frame_num = g_value_get_double(value);
}
break;
case LENGTH:
if(te->num_video_frames != g_value_get_double(value))
{
te->num_video_frames = g_value_get_double(value);
}
break;
case IN_POINT:
if(te->in != g_value_get_double(value))
{
te->in = g_value_get_double(value);
}
break;
case OUT_POINT:
if(te->out != g_value_get_double(value))
{
te->out = g_value_get_double(value);
}
break;
case SEL:
if(te->has_selection != g_value_get_boolean(value))
{
te->has_selection = g_value_get_boolean(value);
}
break;
case BIND:
if(te->bind != g_value_get_boolean(value))
{
te->bind = g_value_get_boolean(value);
}
break;
case CLEARED:
if(te->clear != g_value_get_boolean(value))
{
te->clear = g_value_get_boolean(value);
}
break;
default:
g_assert(FALSE);
break;
}
gtk_widget_queue_draw( GTK_WIDGET( te ));
}
static void get_property( GObject *object,
guint id, GValue *value , GParamSpec *pspec )
{
TimelineSelection *te = TIMELINE_SELECTION(object);
switch( id )
{
case MIN: g_value_set_double( value, te->min );break;
case MAX: g_value_set_double( value, te->max );break;
case POS: g_value_set_double( value, te->frame_num ); break;
case LENGTH: g_value_set_double( value, te->num_video_frames ); break;
case IN_POINT: g_value_set_double( value, te->in ); break;
case OUT_POINT: g_value_set_double( value, te->out ); break;
case SEL: g_value_set_boolean(value, te->has_selection) ; break;
case BIND: g_value_set_boolean(value, te->bind ); break;
case CLEARED: g_value_set_boolean(value,te->clear );break;
}
}
static void finalize (GObject *object)
{
parent_class->finalize( object );
}
static void timeline_class_init( TimelineSelectionClass *class )
{
GObjectClass *gobject_class;
gobject_class = G_OBJECT_CLASS( class );
parent_class = g_type_class_peek( GTK_TYPE_CAIRO );
gobject_class->finalize = finalize;
gobject_class->get_property = get_property;
gobject_class->set_property = set_property;
g_object_class_install_property( gobject_class,
MIN,
g_param_spec_double( "min",
"left", "left", 0.0, 1.0, 0.0, G_PARAM_READWRITE ));
g_object_class_install_property( gobject_class,
MAX,
g_param_spec_double( "max",
"right", "right", 0.0, 1.0, 1.0, G_PARAM_READWRITE ));
g_object_class_install_property( gobject_class,
POS,
g_param_spec_double( "pos",
"current position", "current position", 0.0,9999999.0, 0.0,
G_PARAM_READWRITE ));
g_object_class_install_property( gobject_class,
LENGTH,
g_param_spec_double( "length",
"Length (in frames)", "Length (in frames) ",0.0,9999999.0, 1.0,
G_PARAM_READWRITE ));
g_object_class_install_property( gobject_class,
IN_POINT,
g_param_spec_double( "in",
"In point", "(in frames) ",0.0,1.0, 0.0,
G_PARAM_READWRITE ));
g_object_class_install_property( gobject_class,
OUT_POINT,
g_param_spec_double( "out",
"Out point", "(in frames) ",0.0,1.0, 1.0,
G_PARAM_READWRITE ));
g_object_class_install_property( gobject_class,
SEL,
g_param_spec_boolean( "selection",
"Marker", "(in frames) ",FALSE,
G_PARAM_READWRITE ));
g_object_class_install_property( gobject_class,
BIND,
g_param_spec_boolean( "bind", "Bind marker", "Bind In/Out points", FALSE, G_PARAM_READWRITE));
g_object_class_install_property( gobject_class,
CLEARED,
g_param_spec_boolean( "clear", "Clear marker", "Clear in/out points", FALSE, G_PARAM_READWRITE ));
timeline_signals[ SELECTION_CHANGED_SIGNAL ] =
g_signal_new( "selection_changed",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,0,NULL,NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 , NULL );
timeline_signals[ POS_CHANGED ] =
g_signal_new( "pos_changed",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET( TimelineSelectionClass, pos_changed ),
NULL,NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0, NULL);
timeline_signals[ IN_CHANGED ] =
g_signal_new( "in_point_changed",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET( TimelineSelectionClass, in_point_changed ),
NULL,NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0, NULL);
timeline_signals[ OUT_CHANGED ] =
g_signal_new( "out_point_changed",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET( TimelineSelectionClass, out_point_changed ),
NULL,NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0, NULL);
timeline_signals[ CLEAR_CHANGED ] =
g_signal_new( "cleared", G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET( TimelineSelectionClass, cleared ),
NULL,NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0, NULL );
timeline_signals[ BIND_CHANGED ] =
g_signal_new( "bind_toggled",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET( TimelineSelectionClass, bind_toggled ),
NULL,NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0, NULL );
}
static int default_theme_ = 1;
void timeline_theme_colors( int inverse )
{
default_theme_ = inverse;
}
static void timeline_init( TimelineSelection *te )
{
te->min = 0.0;
te->max = 0.0;
te->action = action_none;
te->in = 0.0;
te->out = 1.0;
te->num_video_frames = 1.0;
te->frame_num = 0.0;
te->grab_location = MOUSE_OUTSIDE;
te->current_location = MOUSE_OUTSIDE;
te->grab_button = 0;
te->has_stepper = TRUE;
te->has_selection = FALSE;
te->stepper_size = 16; // 8 x 8 pixels
te->stepper_draw_size = 12;
te->stepper_length = 0;
te->frame_height = 10;
te->font_line = 12;
te->move_x = 0;
}
GType timeline_get_type(void)
{
static GType gtype = 0;
if(!gtype)
{
static const GTypeInfo ginfo = {
sizeof( TimelineSelectionClass),
NULL,
NULL,
(GClassInitFunc) timeline_class_init,
NULL,
NULL,
sizeof(TimelineSelection),
0,
(GInstanceInitFunc) timeline_init,
NULL
};
gtype = g_type_register_static( GTK_TYPE_CAIRO, "Timeline", &ginfo, 0 );
}
return gtype;
}
gdouble timeline_get_in_point( TimelineSelection *te )
{
gdouble result = 0.0;
g_object_get( G_OBJECT(te), "in", &result, NULL );
return result;
}
gdouble timeline_get_out_point( TimelineSelection *te )
{
gdouble result = 0.0;
g_object_get( G_OBJECT(te), "out", &result, NULL );
return result;
}
gboolean timeline_get_selection( TimelineSelection *te )
{
gboolean result = FALSE;
g_object_get( G_OBJECT(te), "selection", &result, NULL );
return result;
}
gboolean timeline_get_bind( TimelineSelection *te )
{
gboolean result = FALSE;
g_object_get( G_OBJECT(te), "bind", &result, NULL );
return result;
}
void timeline_set_bind(GtkWidget *widget, gboolean active)
{
TimelineSelection *te = TIMELINE_SELECTION(widget);
g_object_set( G_OBJECT(te), "bind", active, NULL );
g_signal_emit( te->widget, timeline_signals[BIND_CHANGED], 0);
}
void timeline_set_out_point( GtkWidget *widget, gdouble pos )
{
TimelineSelection *te = TIMELINE_SELECTION(widget);
if( pos < 0.0 ) pos = 0.0; else if (pos > 1.0 ) pos = 1.0;
g_object_set( G_OBJECT(te), "out", pos, NULL );
g_signal_emit(te->widget, timeline_signals[OUT_CHANGED], 0);
gtk_widget_queue_draw( GTK_WIDGET(te->widget) );
}
void timeline_clear_points( GtkWidget *widget )
{
gboolean cleared = TRUE;
gdouble pos = 0.0;
gdouble pos2 = 1.0;
TimelineSelection *te = TIMELINE_SELECTION(widget);
g_object_set( G_OBJECT(te), "clear", cleared, NULL );
g_object_set( G_OBJECT(te), "in", pos, NULL );
g_object_set( G_OBJECT(te), "out", pos2, NULL );
g_signal_emit(te->widget, timeline_signals[CLEAR_CHANGED], 0 );
gtk_widget_queue_draw(GTK_WIDGET(te->widget) );
}
void timeline_set_in_point( GtkWidget *widget, gdouble pos )
{
TimelineSelection *te = TIMELINE_SELECTION(widget);
if( pos < 0.0 ) pos = 0.0; else if (pos > 1.0 ) pos = 1.0;
g_object_set( G_OBJECT(te), "in", pos, NULL );
g_signal_emit(te->widget, timeline_signals[IN_CHANGED], 0);
gtk_widget_queue_draw( GTK_WIDGET(te->widget) );
}
void timeline_set_selection( GtkWidget *widget, gboolean active)
{
TimelineSelection *te = TIMELINE_SELECTION(widget);
g_object_set( G_OBJECT(te), "selection", active, NULL );
gtk_widget_queue_draw( GTK_WIDGET(te->widget) );
}
void timeline_set_length( GtkWidget *widget, gdouble length, gdouble pos)
{
TimelineSelection *te = TIMELINE_SELECTION( widget );
if( pos < 0.0 ) pos = 0.0;
g_object_set( G_OBJECT(te), "length", length, NULL );
timeline_set_pos( GTK_WIDGET(te->widget), pos );
}
void timeline_set_pos( GtkWidget *widget,gdouble pos)
{
TimelineSelection *te = TIMELINE_SELECTION( widget );
if( pos < 0.0 ) pos = 0.0;
g_object_set( G_OBJECT(te), "pos", pos, NULL );
g_signal_emit( te->widget, timeline_signals[POS_CHANGED], 0);
gtk_widget_queue_draw( GTK_WIDGET(te->widget) );
}
gdouble timeline_get_pos( TimelineSelection *te )
{
gdouble result = 0.0;
g_object_get( G_OBJECT(te), "pos", &result, NULL );
return result;
}
gdouble timeline_get_length( TimelineSelection *te )
{
gdouble result = 0.0;
g_object_get( G_OBJECT(te), "length", &result, NULL );
return result;
}
static void move_selection( GtkWidget *widget, gdouble x, gdouble width )
{
TimelineSelection *te = TIMELINE_SELECTION( widget );
gdouble dx3 = (0.5 * (te->out - te->in)) * width;
gdouble dx1 = x - dx3;
gdouble dx2 = x + dx3;
te->in = (1.0/width) * dx1;
te->out = (1.0/width ) * dx2;
timeline_set_out_point(widget, te->out );
timeline_set_in_point(widget, te->in );
te->move_x = x;
}
static gboolean event_press(GtkWidget *widget, GdkEventButton *ev, gpointer user_data)
{
TimelineSelection *te = TIMELINE_SELECTION( widget );
gdouble width = widget->allocation.width;
te->grab_button = ev->button;
te->current_location = MOUSE_WIDGET;
if( ev->type == GDK_2BUTTON_PRESS && te->grab_button == 1 )
{
timeline_clear_points( widget );
return FALSE;
}
if(te->grab_button == 1 && POINT_IN_RECT( ev->x, ev->y, te->stepper ) )
{
if(te->has_stepper)
{
te->current_location = MOUSE_STEPPER;
te->action = action_pos;
}
return FALSE;
}
if(te->grab_button == 1 && te->has_selection)
{
if( POINT_IN_RECT( ev->x, ev->y, te->selection ) && te->bind )
{
te->current_location = MOUSE_SELECTION;
}
if(!te->bind)
{
gdouble val = (1.0 / width) * ev->x;
timeline_set_in_point( widget, val );
}
}
else if(te->grab_button == 3 && te->has_selection )
{
if( POINT_IN_RECT( ev->x, ev->y, te->selection ) && te->bind )
{
te->current_location = MOUSE_SELECTION;
}
if(!te->bind)
{
gdouble val = (1.0/width) * ev->x;
timeline_set_out_point( widget, val );
}
}
else if(te->grab_button == 2 && te->has_selection)
{
gint dx = ev->x;
gint dy = ev->y;
if( POINT_IN_RECT( dx, dy, te->selection ) )
{
timeline_set_bind( widget, (te->bind ? FALSE: TRUE ));
te->move_x = (gdouble) ev->x;
}
}
gtk_widget_queue_draw( widget );
return FALSE;
}
static gboolean event_release (GtkWidget *widget, GdkEventButton *ev, gpointer user_data)
{
TimelineSelection *te = TIMELINE_SELECTION (widget);
te->action = action_none;
te->current_location = MOUSE_WIDGET;
// te->grab_button = 0;
// te->move_x = 0;
return FALSE;
}
static gboolean
event_motion (GtkWidget *widget, GdkEventMotion *ev, gpointer user_data)
{
TimelineSelection *te = TIMELINE_SELECTION (widget);
gdouble width = (gdouble) widget->allocation.width;
gint x,y;
GdkModifierType state;
gdk_window_get_pointer( ev->window, &x,&y,&state );
if( te->has_stepper && te->current_location == MOUSE_STEPPER && ev->state & GDK_BUTTON1_MASK)
{
gdouble rel_pos = ((gdouble)ev->x / width) * te->num_video_frames;
gdouble new_pos = (gdouble) ((gint) rel_pos );
timeline_set_pos( widget, new_pos );
return FALSE;
}
if( te->has_selection && te->current_location != MOUSE_STEPPER)
{
if(!te->bind)
{
gdouble gx = (1.0 / width) * x;
if(te->grab_button == 1 && ev->state & GDK_BUTTON1_MASK)
timeline_set_in_point(widget, gx );
else if(te->grab_button == 3 && ev->state & GDK_BUTTON3_MASK)
timeline_set_out_point( widget, gx );
}
}
if(te->has_selection && te->bind && te->grab_button == 2 )
move_selection( widget, x, width );
gtk_widget_queue_draw( widget );
return FALSE;
}
/* draw a rounded rectangle */
void
cairo_rectangle_round (cairo_t * cr,
double x0,
double y0, double width, double height, double radius)
{
double x1, y1;
x1 = x0 + width;
y1 = y0 + height;
if (width <= 0.001 || height <= 0.001)
return;
if (width / 2 < radius)
{
if (height / 2 < radius)
{
cairo_move_to (cr, x0, (y0 + y1) / 2);
cairo_curve_to (cr, x0, y0, x0, y0, (x0 + x1) / 2, y0);
cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1) / 2);
cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0) / 2, y1);
cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1) / 2);
}
else
{
cairo_move_to (cr, x0, y0 + radius);
cairo_curve_to (cr, x0, y0, x0, y0, (x0 + x1) / 2, y0);
cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
cairo_line_to (cr, x1, y1 - radius);
cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0) / 2, y1);
cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - radius);
}
}
else
{
if (height / 2 < radius)
{
cairo_move_to (cr, x0, (y0 + y1) / 2);
cairo_curve_to (cr, x0, y0, x0, y0, x0 + radius, y0);
cairo_line_to (cr, x1 - radius, y0);
cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1) / 2);
cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
cairo_line_to (cr, x0 + radius, y1);
cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1) / 2);
}
else
{
cairo_move_to (cr, x0, y0 + radius);
cairo_curve_to (cr, x0, y0, x0, y0, x0 + radius, y0);
cairo_line_to (cr, x1 - radius, y0);
cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
cairo_line_to (cr, x1, y1 - radius);
cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
cairo_line_to (cr, x0 + radius, y1);
cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - radius);
}
}
cairo_close_path (cr);
}
static void paint (GtkWidget *widget, cairo_t * cr, gpointer user_data)
{
TimelineSelection *te = TIMELINE_SELECTION( widget );
double width = widget->allocation.width;
double height = widget->allocation.height;
gdouble marker_width = width/ te->num_video_frames;
// gdouble marker_height = height / te->num_video_frames;
gdouble marker_height = te->frame_height;
te->frame_width = marker_width;
cairo_save(cr);
cairo_identity_matrix(cr);
/* Draw frames*/
/* Drawing many boxes cause CPU hog .. */
/*
cairo_set_source_rgba( cr, 0.0, 0.0, 0.0, 0.2 );
for(i =0; i < te->num_video_frames; i ++ )
{
double x1 = marker_width * i;
double x2 = x1 + frame_width;
cairo_rectangle_round(cr, x1, height - te->stepper_size, frame_width, marker_height, 4);
}
cairo_stroke(cr); */
// cairo_fill(cr);
/* Draw stepper */
if( te->has_stepper )
{
cairo_set_source_rgba( cr, 1.0,0.0,0.0,1.0);
double x1 = marker_width * te->frame_num;
te->stepper.x = x1 - 8;
te->stepper.y = 0;
te->stepper.width = te->stepper_size + 8;
te->stepper.height = te->stepper_size + 2;
// cairo_set_line_width( cr, 0.16 );
cairo_move_to( cr, x1 - te->stepper_draw_size, 0.0 * height );
cairo_rel_line_to( cr, te->stepper_draw_size, te->stepper_draw_size );
cairo_rel_line_to( cr, te->stepper_draw_size, -te->stepper_draw_size );
cairo_rel_line_to( cr, -2.0 * te->stepper_draw_size, 0 );
cairo_set_line_join( cr, CAIRO_LINE_JOIN_MITER);
cairo_move_to(cr, x1, te->stepper_draw_size );
cairo_rel_line_to( cr, 0.0, te->stepper_length );
cairo_stroke(cr);
//cairo_fill_preserve(cr);
if( te->grab_button == 1 && te->current_location == MOUSE_STEPPER )
{
cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_BOLD );
cairo_move_to(cr, x1 + (te->stepper_size * 0.5),te->font_line );
gchar text[40];
sprintf(text, "%d", (gint)te->frame_num );
cairo_text_path( cr, text );
cairo_set_font_size( cr, 0.2 );
double v = ( default_theme_ ? 1.0 : 0.0 );
cairo_set_source_rgba( cr, v,v,v,0.7 );
cairo_fill(cr);
}
//cairo_fill_preserve(cr);
}
/* Draw selection */
if( te->has_selection )
{
gdouble in = te->in * width;
gdouble out = te->out * width;
gdouble v = (default_theme_ ? 1.0: 0.0);
/* If user is editing in_point */
if( te->grab_button == 1 && te->current_location != MOUSE_STEPPER )
{
gdouble f = te->in * te->num_video_frames;
cairo_set_source_rgba( cr, 0.0, v,v,0.3 );
cairo_move_to( cr, in, 0.0 );
cairo_rel_line_to( cr, 0.0 , te->stepper_length );
cairo_stroke(cr);
cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_BOLD );
cairo_move_to(cr, in , te->font_line );
gchar text[40];
sprintf(text, "%d",(gint) f );
cairo_text_path( cr, text );
cairo_set_font_size( cr, 0.2 );
cairo_set_source_rgba( cr, v,v,v,0.7 );
cairo_fill(cr);
}
if( te->grab_button == 3 && te->current_location != MOUSE_STEPPER )
{
gdouble f = te->out * te->num_video_frames;
cairo_set_source_rgba( cr, 0.0, v,v,0.3 );
cairo_move_to( cr, out , 0.0 );
cairo_rel_line_to( cr, 0.0 , te->stepper_length );
cairo_stroke(cr);
cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_BOLD );
cairo_move_to(cr, out ,te->font_line );
gchar text[40];
sprintf(text, "%d", (gint) f );
cairo_text_path( cr, text );
cairo_set_font_size( cr, 0.2 );
cairo_set_source_rgba( cr, v,v,v,0.7 );
cairo_fill(cr);
}
cairo_set_source_rgba( cr, v, v, v, 0.3 );
cairo_rectangle_round(cr, in,
0.095 * height,
(out - in),
marker_height,
10);
te->selection.x = in;
te->selection.y = 0;
te->selection.width = out;
te->selection.height = te->font_line;
cairo_fill_preserve(cr);
}
cairo_restore(cr);
}
GtkWidget *timeline_new(void)
{
GtkWidget *widget = GTK_WIDGET( g_object_new( timeline_get_type(), NULL ));
TimelineSelection *te = TIMELINE_SELECTION( widget );
gtk_widget_set_size_request(widget, 200,16 );
gtk_widget_set_events( widget,
GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_POINTER_MOTION_MASK |
GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK |
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
GDK_BUTTON3_MOTION_MASK | GDK_2BUTTON_PRESS );
g_signal_connect( G_OBJECT(widget), "paint", G_CALLBACK(paint), NULL );
g_signal_connect( G_OBJECT(widget), "motion_notify_event",
G_CALLBACK(event_motion), NULL );
g_signal_connect( G_OBJECT(widget), "button_press_event",
G_CALLBACK(event_press), NULL );
g_signal_connect( G_OBJECT(widget), "button_release_event",
G_CALLBACK(event_release), NULL );
te->widget = widget;
return widget;
}

View File

@@ -0,0 +1,68 @@
/* veejay - Linux VeeJay
* (C) 2002-2004 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.
*/
#ifndef GTKTIMESELECTION_H
#define GTKTIMESELECTION_H
#include <gtk/gtk.h>
#include <gtk/gtkvbox.h>
#ifdef __cplusplus
extern "C"
{
#endif
#define TIMELINE_SELECTION(obj) GTK_CHECK_CAST(obj, timeline_get_type(), TimelineSelection )
#define TIMELINE_SELECTION_CLASS(klass) GTK_CHECK_CLASS_CAST( klass, timeline_get_type(), TimelineSelectionClass )
#define IS_TIMELINE_SELECTION(obj) GTK_CHECK_TYPE( obj, timeline_get_type() )
typedef struct _TimelineSelection TimelineSelection;
typedef struct _TimelineSelectionClass TimelineSelectionClass;
GtkType timeline_get_type (void);
GtkWidget* timeline_new (void);
gdouble timeline_get_length (TimelineSelection *te);
gdouble timeline_get_pos (TimelineSelection *te);
gdouble timeline_get_in_point (TimelineSelection *te );
gdouble timeline_get_out_point (TimelineSelection *te );
gboolean timeline_get_selection (TimelineSelection *te );
gboolean timeline_get_bind (TimelineSelection *te );
void timeline_set_pos (GtkWidget *widget, gdouble pos );
void timeline_set_in_point (GtkWidget *widget, gdouble pos);
void timeline_set_out_point (GtkWidget *widget, gdouble pos);
void timeline_set_length (GtkWidget *widget, gdouble length, gdouble pos);
void timeline_set_bind (GtkWidget *widget, gboolean active);
void timeline_clear_points( GtkWidget *widget );
void timeline_set_selection( GtkWidget *widget, gboolean active);
void timeline_theme_colors( int inverse );
#ifdef __cplusplus
}
#endif
#endif