📄 glav_main.c
字号:
/* 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.*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <gtk/gtk.h>#include "glav.h"#include <gdk/gdkkeysyms.h>#include <unistd.h>#include <mpegconsts.h>#include <mpegtimecode.h>#include <sys/time.h>#define PLAY_PROG "lavplay"#define LAVPLAY_VSTR "lavplay" LAVPLAY_VERSION /* Expected version info */static struct timeval time_when_pressed;static int number_of_skipped_frames;int verbose = 1;static GTK_xlav *gtk_xlav;static int inp_pipe;static int out_pipe;static int pid;static double fps;static int cur_pos, total_frames, cur_speed=1, old_speed=999999;static int slider_pause;static int slider_pos;static int ff_stat=0, fr_stat=0;static int ff_speed[4] = { 1, 3, 10, 30 };static int selection_start = -1;static int selection_end = -1;#define MAXINP 4096#define SAVE_ALL 1#define SAVE_SEL 2static int savetype = 0;static char inpbuff[MAXINP];static int inplen = 0;static int frame_skip_button_up = 1;static char frame_skip_char;static char timecode[64];char *selected_filename;GtkWidget *file_selector;static void skip_num_frames(int num) { char out[32]; sprintf(out,"s%d\n",cur_pos + num); write(out_pipe,out,strlen(out));}static void calc_timecode(int pos, int do_frames){ MPEG_timecode_t tc; mpeg_timecode(&tc, pos, mpeg_framerate_code(mpeg_conform_framerate(fps)), fps); if (!do_frames) tc.f=0; sprintf(timecode,"%2d:%2.2d:%2.2d:%2.2d",tc.h,tc.m,tc.s,tc.f);}static void store_filename(GtkFileSelection *selector, gpointer user_data) { char str[256]; const char *name; /* First easy fix, Bernhard */ selected_filename = (char*)gtk_file_selection_get_filename (GTK_FILE_SELECTION(file_selector)); name = selected_filename; if(name==0) return; switch(savetype) { case SAVE_ALL: sprintf(str,"wa %s\n",name); break; case SAVE_SEL: sprintf(str,"ws %d %d %s\n",selection_start,selection_end,name); break; } write(out_pipe,str,strlen(str)); printf("Wrote to %s\n",name);}static void create_file_selection(void) { /* Create the selector */ char label[32]; switch (savetype) { case SAVE_ALL: sprintf(label,"save all to file..."); break; case SAVE_SEL: sprintf(label,"save selected to file..."); break; default: printf("Error in create_file_selection\n"); return; break; } file_selector = gtk_file_selection_new(label); /* Next problem, Bernhard */ g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION (file_selector)->ok_button), "clicked", (GtkSignalFunc)store_filename, NULL); /* Ensure that the dialog box is destroyed when the user clicks a button. */ g_signal_connect_swapped(G_OBJECT (GTK_FILE_SELECTION(file_selector)->ok_button), "clicked", G_CALLBACK (gtk_widget_destroy), (gpointer) file_selector); g_signal_connect_swapped(G_OBJECT (GTK_FILE_SELECTION(file_selector)->cancel_button), "clicked", G_CALLBACK (gtk_widget_destroy), (gpointer) file_selector); /* Display that dialog */ gtk_widget_show (file_selector);}gint key_press_cb(GtkWidget * widget, GdkEventKey* event, gpointer data ){ int need_pause=FALSE; int n=1; switch (event->keyval) { case GDK_0:/* go to beginning of file */ write(out_pipe,"s0\n",3); /* go to beginning */ break; case GDK_9: /* go to end of file */ need_pause=TRUE; write(out_pipe,"s10000000\n",10); /* go to end */ break; case GDK_parenleft: /* mark start of selection */ case GDK_Home: g_signal_emit_by_name(G_OBJECT(gtk_xlav->BSSelStart),"clicked",(gpointer)1); break; case GDK_parenright: /* mark end of selection */ case GDK_End: g_signal_emit_by_name(G_OBJECT(gtk_xlav->BSSelEnd),"clicked",(gpointer)1); break; case GDK_bracketleft: /* skip to selected start */ g_signal_emit_by_name(G_OBJECT(gtk_xlav->BGotoSelStart),"clicked",(gpointer)1); break; case GDK_bracketright: /* skip to selected end */ g_signal_emit_by_name(G_OBJECT(gtk_xlav->BGotoSelEnd),"clicked",(gpointer)1); break; case GDK_a: /* Save all */ g_signal_emit_by_name(G_OBJECT(gtk_xlav->BSaveAll),"clicked",(gpointer)1); break; case GDK_v: /* Save */ g_signal_emit_by_name(G_OBJECT(gtk_xlav->BSaveSel),"clicked",(gpointer)1); break; case GDK_q: /* Exit */ g_signal_emit_by_name(G_OBJECT(gtk_xlav->Exit),"clicked",(gpointer)1); break; case GDK_l: /* some number of frames right */ case GDK_L: case GDK_Right: need_pause=TRUE; g_signal_stop_emission_by_name(G_OBJECT(gtk_xlav->xlav), "key_press_event"); n=1; if(event->state & GDK_CONTROL_MASK) { write(out_pipe,"s10000000\n",10); /* go to end */ break; } else if(event->state & GDK_MOD1_MASK) { n=50; } else if (event->state & GDK_SHIFT_MASK) { n=10; } skip_num_frames(n); break; case GDK_h: /* some number of frames left */ case GDK_H: case GDK_Left: g_signal_stop_emission_by_name(GTK_OBJECT(gtk_xlav->xlav), "key_press_event"); n=-1; if(event->state & GDK_CONTROL_MASK) { /* go to beginning */ write(out_pipe,"s0\n",3); /* go to beginning */ break; } else if(event->state & GDK_MOD1_MASK) { n=-50; } else if (event->state & GDK_SHIFT_MASK) { n=-10; } need_pause=TRUE; skip_num_frames(n); break; case GDK_w: /* (word) 15 frames right */ need_pause=TRUE; skip_num_frames(15); break; case GDK_b: /* (back) 15 frames left */ need_pause=TRUE; skip_num_frames(-15); break; case GDK_W: /* 30 frames right */ need_pause=TRUE; skip_num_frames(30); break; case GDK_B: /* 30 frames left */ need_pause=TRUE; skip_num_frames(-30); break; case GDK_c: /* clear selection */ g_signal_emit_by_name(G_OBJECT(gtk_xlav->BClearSel),"clicked",(gpointer)1); break; case GDK_x: /* cut selection */ case GDK_Delete: g_signal_emit_by_name(G_OBJECT(gtk_xlav->BECut),"clicked",(gpointer)1); break; case GDK_y: /* copy (yank) selection */ g_signal_emit_by_name(G_OBJECT(gtk_xlav->BECopy),"clicked",(gpointer)1); break; case GDK_p: /* paste selection */ case GDK_Insert: g_signal_emit_by_name(G_OBJECT(gtk_xlav->BEPaste),"clicked",(gpointer)1); break; case GDK_f: /* play (forward) */ g_signal_emit_by_name(G_OBJECT(gtk_xlav->play),"clicked",(gpointer)4); break; case GDK_F: /* fast forward */ g_signal_emit_by_name(G_OBJECT(gtk_xlav->ff),"clicked",(gpointer)5); break; case GDK_r: /* play reverse */ g_signal_emit_by_name(G_OBJECT(gtk_xlav->rew),"clicked",(gpointer)2); break; case GDK_R: /* fast reverse */ g_signal_emit_by_name(G_OBJECT(gtk_xlav->fr),"clicked",(gpointer)1); break; case GDK_s: /* stop */ case GDK_S: g_signal_emit_by_name(G_OBJECT(gtk_xlav->stop),"clicked",(gpointer)3); break; case GDK_1: /* go 5 seconds forward */ skip_num_frames(150); break; case GDK_2: /* go 10 seconds forward */ skip_num_frames(300); break; case GDK_3: /* go 15 seconds forward */ skip_num_frames(450); break; case GDK_4: /* go 20 seconds forward */ skip_num_frames(600); break; case GDK_5: /* go 25 seconds forward */ skip_num_frames(750); break; case GDK_6: /* go 30 seconds forward */ skip_num_frames(900); break; case GDK_exclam: /* go 5 seconds back */ skip_num_frames(-150); break; case GDK_at: /* go 10 seconds back */ skip_num_frames(-300); break; case GDK_numbersign: /* go 15 seconds back */ skip_num_frames(-450); break; case GDK_dollar: /* go 20 seconds back */ skip_num_frames(-600); break; case GDK_percent: /* go 25 seconds back */ skip_num_frames(-750); break; case GDK_asciicircum: /* a.k.a "carat" (shift-6 on us keyboards) */ skip_num_frames(-900); break; case GDK_Shift_L: /* just shift keys, eat them */ case GDK_Shift_R: break; default: break; } if (cur_speed!=0) { if (need_pause) { write(out_pipe,"p0\n",3); /* pause on all keys */ } } return 0;}static void quick_message(const char *message) { GtkWidget *dialog, *label, *okay_button; /* Create the widgets */ dialog = gtk_dialog_new(); label = gtk_label_new (message); okay_button = gtk_button_new_with_label("Okay"); /* Ensure that the dialog box is destroyed when the user clicks ok. */ g_signal_connect_swapped(G_OBJECT (okay_button), "clicked", G_CALLBACK (gtk_widget_destroy), G_OBJECT(dialog)); gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), okay_button); /* Add the label, and show everything we've added to the dialog. */ gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label); gtk_widget_show_all (dialog);}void dispatch_input(void){ /* A line starting with '-' should be ignored */ if(inpbuff[0]=='-') return; /* A line starting with '@' contains psoition information */ if(inpbuff[0]=='@') { int slider_new_pos; sscanf(inpbuff+1,"%lg/%d/%d/%d",&fps,&cur_pos,&total_frames,&cur_speed); calc_timecode(cur_pos,cur_speed==0); gtk_label_set_text(GTK_LABEL(gtk_xlav->Timer),timecode); /* fl_set_object_label(gtk_xlav->Timer,timecode); */ if(total_frames<1) total_frames=1; slider_new_pos = 10000 * cur_pos / total_frames; if (slider_pos != slider_new_pos) { slider_pos = slider_new_pos; slider_pause++; gtk_adjustment_set_value(GTK_ADJUSTMENT(gtk_xlav->timeslider), (double)slider_new_pos / 100.0); } if(cur_speed != old_speed) { char label[32]; if(cur_speed == 1) { gtk_label_set_text(GTK_LABEL(gtk_xlav->StatDisp),"Play >"); } else if(cur_speed == 0) { gtk_label_set_text(GTK_LABEL(gtk_xlav->StatDisp),"Pause"); } else if(cur_speed == -1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -