@echo g++ -o $@ ydiff.C
@g++ $(CFLAGS) ydiff.C -o $@ $(LIBS)
+shdmp: shdmp.C
+ @g++ $(CFLAGS) shdmp.C -o $@
+
clean:
rm -rf $(OBJDIR)
rm -f shuttle_keys.h
if(debug) printf("ARender::run %d\n", __LINE__);
- if(vconsole->interrupt) interrupt = 1;
+ if( !interrupt ) interrupt = renderengine->interrupted;
+ if( !interrupt ) interrupt = renderengine->audio->get_interrupted();
+ if( !interrupt ) interrupt = vconsole->interrupt;
}
if(debug) printf("ARender::run %d\n", __LINE__);
else {
// Stop and restart
int command = cwindow->playback_engine->command->command;
- cwindow->playback_engine->transport_stop();
// Waiting for tracking to finish would make the restart position more
// accurate but it can't lock the window to stop tracking for some reason.
// Not waiting for tracking gives a faster response but restart position is
// only as accurate as the last tracking update.
- cwindow->playback_engine->interrupt_playback(0);
+ cwindow->playback_engine->transport_stop(0);
cwindow->playback_engine->next_command->realtime = 1;
cwindow->playback_engine->transport_command(command, change_type, edl, 0);
}
tracking_done = new Condition(1, "PlaybackEngine::tracking_done");
pause_lock = new Condition(0, "PlaybackEngine::pause_lock");
start_lock = new Condition(0, "PlaybackEngine::start_lock");
- input_lock = new Condition(1, "PlaybackEngine::input_lock");
- output_lock = new Condition(0, "PlaybackEngine::output_lock", 1);
+ input_lock = new Condition(1, "PlaybackEngine::input_lock");
+ output_lock = new Condition(0, "PlaybackEngine::output_lock", 1);
render_engine = 0;
debug = 0;
PlaybackEngine::~PlaybackEngine()
{
done = 1;
- transport_stop();
- interrupt_playback();
-
+ transport_stop(0);
Thread::join();
delete preferences;
delete_render_engine();
delete renderengine_lock;
delete command;
delete next_command;
- delete curr_command;
delete stop_command;
- delete input_lock;
- delete output_lock;
+ delete curr_command;
+ delete input_lock;
+ delete output_lock;
}
void PlaybackEngine::create_objects()
while( !done ) {
// Wait for current command to finish
output_lock->lock("PlaybackEngine::run");
+//printf("PlaybackEngine::run 0 %d\n", curr_command->command);
+ if( curr_command->command < 0 ) continue;
+// this covers a glitch that occurs when stop is asserted
+// when the render_engine starting, but not initialized
+ if( curr_command->command == STOP && render_engine )
+ render_engine->interrupt_playback();
wait_render_engine();
// Read the new command
input_lock->lock("PlaybackEngine::run");
- if( done ) return;
command->copy_from(curr_command);
+ curr_command->command = -1;
input_lock->unlock();
+ if( done ) break;
//printf("PlaybackEngine::run 1 %d\n", command->command);
switch( command->command ) {
// fall through
default:
is_playing_back = 1;
-
perform_change();
arm_render_engine();
start_render_engine();
break;
}
-
-
//printf("PlaybackEngine::run 100\n");
}
}
-void PlaybackEngine::stop_playback(int wait)
+void PlaybackEngine::stop_playback(int wait_tracking)
{
- transport_stop();
- interrupt_playback(wait);
+ transport_stop(wait_tracking);
renderengine_lock->lock("PlaybackEngine::stop_playback");
if(render_engine)
render_engine->wait_done();
// Resume or change direction
switch( curr_command ) {
default:
- transport_stop();
- interrupt_playback(wait_tracking);
+ transport_stop(wait_tracking);
do_resume = 1;
// fall through
case STOP:
}
if( do_stop ) {
- transport_stop();
- interrupt_playback(wait_tracking);
+ transport_stop(wait_tracking);
}
}
-int PlaybackEngine::transport_stop()
+int PlaybackEngine::transport_stop(int wait_tracking)
{
input_lock->lock("PlaybackEngine::transport_stop 1");
curr_command->copy_from(stop_command);
+ interrupt_playback(wait_tracking);
+//printf("send: %d (STOP)\n", STOP);
input_lock->unlock();
output_lock->unlock();
return 0;
}
curr_command->copy_from(next_command);
next_command->reset();
+//static const char *types[] = { "NONE",
+// "FRAME_FWD", "NORMAL_FWD", "FAST_FWD", "FRAME_REV", "NORMAL_REV", "FAST_REV",
+// "STOP", "PAUSE", "SLOW_FWD", "SLOW_REV", "REWIND", "GOTO_END", "CURRENT_FRAME",
+// "LAST_FRAME" };
+//printf("send= %d (%s)\n", command, types[command]);
input_lock->unlock();
output_lock->unlock();
return 0;
// Copy of main preferences
Preferences *preferences;
- int transport_stop();
+ int transport_stop(int wait_tracking);
int transport_command(int command, int change_type=CHANGE_NONE,
EDL *new_edl=0, int use_inout=0);
Condition *input_lock, *output_lock;
// active command
- TransportCommand *command, *stop_command;
- TransportCommand *curr_command, *next_command;
+ TransportCommand *command;
+// stop, next, queued commands
+ TransportCommand *stop_command, *next_command, *curr_command;
// Render engine
RenderEngine *render_engine;
if( !get_edl() ) return;
int command = engine->command->command;
// stop transport
- if( command != STOP && command != COMMAND_NONE &&
- command != SINGLE_FRAME_FWD && command != SINGLE_FRAME_REWIND ) {
- engine->transport_stop();
- engine->interrupt_playback(0);
- }
+ engine->stop_playback(0);
mwindow->gui->lock_window("PlayTransport::change_position");
mwindow->goto_position(position);
mwindow->gui->unlock_window();
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <error.h>
+#include <signal.h>
+#include <linux/input.h>
+
+input_event ev;
+
+int main(int ac, char **av)
+{
+ setbuf(stdout, 0);
+ if( ac < 2 ) { printf("usage: %s /dev/input/by-id/<device?>\n", av[0]); exit(1); }
+ int fd = open(av[1], O_RDONLY);
+ if( !fd ) { perror(av[1]); exit(1); }
+
+ for(;;) {
+ int ret = read(fd, &ev, sizeof(ev));
+ if( ret != sizeof(ev) ) {
+ if( ret < 0 ) perror("read event");
+ printf("bad read: %d\n", ret);
+ break;
+ }
+ printf("event: (%d, %d, 0x%x)\n", ev.type, ev.code, ev.value);
+ }
+
+ return 0;
+}
+
{
this->cin = cin;
this->name = cstrdup(nm);
- this->err = regcomp(&this->regex, re, REG_NOSUB);
- if( err ) {
- fprintf(stderr, "error compiling regex for [%s]: %s\n", name, re);
- char emsg[BCTEXTLEN];
- regerror(err, ®ex, emsg, sizeof(emsg));
- fprintf(stderr, "regerror: %s\n", emsg);
- }
}
TransName::~TransName()
{
delete [] name;
- regfree(®ex);
}
void Translation::init(int def)
wx = wy = 0;
jogvalue = 0xffff;
shuttlevalue = 0xffff;
- last_shuttle.tv_sec = 0;
- last_shuttle.tv_usec = 0;
- need_synthetic_shuttle = 0;
dev_name = 0;
done = -1;
if( translation ) {
switch( kjs ) {
default:
- case KJS_KEY_DOWN: ret = translation->key_down[index].first; break;
- case KJS_KEY_UP: ret = translation->key_up[index].first; break;
- case KJS_JOG: ret = translation->jog[index].first; break;
- case KJS_SHUTTLE: ret = translation->shuttles[index].first; break;
+ case KJS_KEY_DOWN: ret = translation->key_down[index].first; break;
+ case KJS_KEY_UP: ret = translation->key_up[index].first; break;
+ case KJS_JOG: ret = translation->jog[index].first; break;
+ case KJS_SHUTTLE: ret = translation->shuttles[index-S_7].first; break;
}
}
return ret;
fprintf(stderr, "shuttle(%d) out of range\n", value);
return;
}
- gettimeofday(&last_shuttle, 0);
- need_synthetic_shuttle = value != 0;
- if( value != shuttlevalue ) {
+ if( value != (int)shuttlevalue ) {
shuttlevalue = value;
- send_stroke_sequence(KJS_SHUTTLE, value+7);
+ send_stroke_sequence(KJS_SHUTTLE, value);
}
}
// event either!
void Shuttle::jog(unsigned int value)
{
- int direction;
- struct timeval now;
- struct timeval delta;
-
- // We should generate a synthetic event for the shuttle going
- // to the home position if we have not seen one recently
- if( need_synthetic_shuttle ) {
- gettimeofday( &now, 0 );
- timersub( &now, &last_shuttle, &delta );
-
- if( delta.tv_sec >= 1 || delta.tv_usec >= 5000 ) {
- shuttle(0);
- need_synthetic_shuttle = 0;
- }
- }
-
if( jogvalue != 0xffff ) {
value = value & 0xff;
- direction = ((value - jogvalue) & 0x80) ? -1 : 1;
+ int direction = ((value - jogvalue) & 0x80) ? -1 : 1;
+ int index = direction > 0 ? 1 : 0;
while( jogvalue != value ) {
// driver fails to send an event when jogvalue == 0
if( jogvalue != 0 ) {
- send_stroke_sequence(KJS_JOG, direction > 0 ? 1 : 0);
+ send_stroke_sequence(KJS_JOG, index);
}
jogvalue = (jogvalue + direction) & 0xff;
}
win_title[len] = 0;
XFree(list);
if( debug )
- printf("new focus: %08x\n", (unsigned)focus);
+ printf("new focus: %08x %s\n", (unsigned)focus, win_title);
}
else {
last_focused = 0;
if( tr->is_default ) return 1;
for( int i=0; i<tr->names.size(); ++i ) {
TransName *name = tr->names[i];
- if( name->cin != cin ) continue;
- if( regexec(&name->regex, win_title, 0, NULL, 0) )
- return 1;
+ if( name->cin == cin ) return 1;
}
}
tr = default_translation;
if( debug )
printf("new translation: %s\n", tr->name);
}
-//fprintf(stderr, "event: (%d, %d, 0x%x)\n", ev.type, ev.code, ev.value);
+// if( debug )
+// printf("event: (%d, %d, 0x%x)\n", ev.type, ev.code, ev.value);
switch( ev.type ) {
case EVENT_TYPE_DONE:
case EVENT_TYPE_ACTIVE_KEY:
}
}
while( ws(*cp) ) ++cp;
-// regex in TransName constructor
trans->names.append(new TransName(cin, name, cp));
- if( trans->names.last()->err ) { ret = 1; break; }
ret = fgets(cp=line,sizeof(line),fp) ? 0 : 1;
if( ret ) {
fprintf(stderr, "hit eof, no translation def for: %s\n",
#include <linux/input.h>
#include <sys/types.h>
-#include <regex.h>
// Copyright 2013 Eric Messick (FixedImagePhoto.com/Contact)
// reworked 2019 for cinelerra-gg by William Morrow (aka goodguy)
class TransName
{
public:
- int cin, err;
+ int cin;
const char *name;
- regex_t regex;
TransName(int cin, const char *nm, const char *re);
~TransName();
class Shuttle : public Thread
{
int fd;
- unsigned short jogvalue;
- int shuttlevalue;
- struct timeval last_shuttle;
- int need_synthetic_shuttle;
+ unsigned short jogvalue, shuttlevalue;
const char *dev_name;
Translation *default_translation;
Translations translations;
resume = 0;
toggle_audio = 0;
loop_play = 0;
+ displacement = 0;
speed = 0;
// Don't reset the change type for commands which don't perform the change
if(command != STOP) change_type = 0;
framerate_timer.update();
}
if(debug) printf("VRender::run %d done=%d\n", __LINE__, done);
- if( !interrupt )
- interrupt = renderengine->video->interrupt;
+ if( !interrupt ) interrupt = renderengine->interrupted;
+ if( !interrupt ) interrupt = renderengine->video->interrupt;
+ if( !interrupt ) interrupt = vconsole->interrupt;
}
TitleFont::TitleFont(TitleMain *client, TitleWindow *window, int x, int y)
: BC_PopupTextBox(window, &window->fonts, client->config.font,
- x, y, 240, 300, LISTBOX_ICON_LIST)
+ x, y, 300, 300, LISTBOX_ICON_LIST)
{
this->client = client;
this->window = window;
K3 "c" # Pro Only - Copy
K4 "v" # Pro Only - Paste
- S-7 REV_16 # Next 7 are reverse keys
+ S-7 REV_16 # Next 6 are reverse keys
S-6 REV_8 # the number on the end represents speed
S-5 REV_4 # number can be decimal up to 64
S-4 REV_2 # 2 means 2x or double speed
S-3 REV_1
- S-2 REV_0.5 # note 0.25 represents 1/4 speed
- S-1 REV_0.25
- S0 XK_KP_0 # Stop
- S1 FWD_0.25 # Next 7 are forward keys
- S2 FWD_0.5
+ S-2 REV_0.5 # note 0.5 represents 1/2 speed
+ S-1 XK_KP_0 # Because the Shuttle does not generate S0, have to use S1
+ S0 XK_KP_0 # Hardware does not generate S0
+ S1 XK_KP_0 # Because the Shuttle does not generate S0, have to use S1
+ S2 FWD_0.5 # Next 6 are forward keys
S3 FWD_1
S4 FWD_2
S5 FWD_4
K3 "c" # Pro Only - Copy
K4 "v" # Pro Only - Paste
- S-3 XK_KP_Add # Fast reverse
- S-2 XK_KP_6 # Play reverse
- S-1 XK_KP_5 # Slow reverse
- S0 XK_KP_0 # Stop
- S1 XK_KP_2 # Slow forward
- S2 XK_KP_3 # Play forward
- S3 XK_KP_Enter # Fast forward
+ S-7 REV_16
+ S-6 REV_8
+ S-5 REV_4
+ S-4 REV_2
+ S-3 REV_1
+ S-2 REV_0.5
+ S-1 XK_KP_0 # Because the Shuttle does not generate S0, have to use S1
+ S0 XK_KP_0 # Hardware does not generate S0
+ S1 XK_KP_0 # Because the Shuttle does not generate S0, have to use S1
+ S2 FWD_0.5
+ S3 FWD_1
+ S4 FWD_2
+ S5 FWD_4
+ S6 FWD_8
+ S7 FWD_16
JL XK_KP_4 # Frame reverse
JR XK_KP_1 # Frame forward
K2 XK_Home # Pro Only - Beginning
K3 "c" # Pro Only - Copy
K4 XK_End # Pro Only - End
-
- S-3 XK_KP_Add # Fast reverse
- S-2 XK_KP_6 # Play reverse
- S-1 XK_KP_5 # Slow reverse
- S0 XK_KP_0 # Stop
- S1 XK_KP_2 # Slow forward
- S2 XK_KP_3 # Play forward
- S3 XK_KP_Enter # Fast forward
+ S-7 REV_16
+ S-6 REV_8
+ S-5 REV_4
+ S-4 REV_2
+ S-3 REV_1
+ S-2 REV_0.5
+ S-1 XK_KP_0 # Because the Shuttle does not generate S0, have to use S1
+ S0 XK_KP_0 # Hardware does not generate S0
+ S1 XK_KP_0 # Because the Shuttle does not generate S0, have to use S1
+ S2 FWD_0.5
+ S3 FWD_1
+ S4 FWD_2
+ S5 FWD_4
+ S6 FWD_8
+ S7 FWD_16
+
JL XK_KP_4 # Frame reverse
JR XK_KP_1 # Frame forward