[xiph-cvs] cvs commit: snatch libsnatch.c snatch.pl x11.c

Monty xiphmont at xiph.org
Tue Nov 6 21:13:48 PST 2001



xiphmont    01/11/06 21:13:47

  Modified:    .        libsnatch.c snatch.pl x11.c
  Log:
  Bwah ha ha ha.  Almost there.

Revision  Changes    Path
1.6       +22 -6     snatch/libsnatch.c

Index: libsnatch.c
===================================================================
RCS file: /usr/local/cvsroot/snatch/libsnatch.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- libsnatch.c	2001/11/05 08:49:54	1.5
+++ libsnatch.c	2001/11/07 05:13:46	1.6
@@ -39,7 +39,7 @@
 
 static int    (*libc_open)(const char *,int,mode_t);
 static int    (*libc_connect)(int sockfd, const struct sockaddr *serv_addr,
-			   socklen_t addrlen);
+			      socklen_t addrlen);
 static int    (*libc_close)(int);
 static size_t (*libc_read)(int,void *,size_t);
 static size_t (*libc_write)(int,const void *,size_t);
@@ -180,6 +180,8 @@
     case 'P':
     case 'L':
     case 'O':
+    case 'F':
+    case 'D':
       ret=fread(&length,2,1,backchannel_fd);
       if(ret==1){
         if(length)buf=calloc(length+1,1);
@@ -202,6 +204,14 @@
             if(openfile)free(openfile);
             openfile=buf;
             break;
+	  case 'F':
+	    if(outfile)free(outfile);
+	    outfile=buf;
+	    break;
+	  case 'D':
+	    if(audioname)free(audioname);
+	    audioname=buf;
+	    break;
           }
       }
       break;
@@ -255,13 +265,13 @@
     xlib_xopen=get_me_symbol("XOpenDisplay");
 
     /* output path? */
-    outpath=getenv("SNATCH_OUTPUT_PATH");
+    outpath=strdup(getenv("SNATCH_OUTPUT_PATH"));
     if(!outpath){
       if(debug)
         fprintf(stderr,
                 "----env: SNATCH_OUTPUT_PATH\n"
                 "           not set. Using current working directory.\n");
-      outpath=".";
+      outpath=strdup(".");
     }else{
       if(debug)
         fprintf(stderr,
@@ -270,13 +280,13 @@
     }
 
     /* audio device? */
-    audioname=getenv("SNATCH_AUDIO_DEVICE");
+    audioname=strdup(getenv("SNATCH_AUDIO_DEVICE"));
     if(!audioname){
       if(debug)
         fprintf(stderr,
                 "----env: SNATCH_AUDIO_DEVICE\n"
                 "           not set. Using default (/dev/dsp*).\n");
-      audioname="/dev/dsp*";
+      audioname=strdup("/dev/dsp*");
     }else{
       if(debug)
         fprintf(stderr,
@@ -458,8 +468,14 @@
   initialize();
   return((*libc_fork)());
 }
+
+/* The audio device is subverted through open().  If we didn't care
+   about allowing a fake audio open() to 'succeed' even when the real
+   device is busy, then we could just watch for the ioctl(), grab the
+   fd() then, and not need to bother with any silly string matching.
+   However, we *do* care, so we do this the more complex, slightly
+   more error prone way. */
 
-/* The audio device is subverted through open() */
 int open(const char *pathname,int flags,...){
   va_list ap;
   int ret;

1.5       +697 -46   snatch/snatch.pl

Index: snatch.pl
===================================================================
RCS file: /usr/local/cvsroot/snatch/snatch.pl,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- snatch.pl	2001/11/05 07:04:08	1.4
+++ snatch.pl	2001/11/07 05:13:46	1.5
@@ -2,69 +2,720 @@
 
 use Socket;
 use Sys::Hostname;
+use Time::Local;
+use IPC::Open3;
+use File::Glob ':glob';
 use Tk;
-
+use Tk::Xrm;
 use Tk qw(exit); 
+
+my $HOME=$ENV{"HOME"};
+if(!defined($HOME)){
+    print "HOME environment variable not set.  Exiting.\n";
+    exit 1;
+}
 
-my $backchannel_socket="/tmp/snatch";
+$version="Snatch 20011106";
+$configdir=$HOME."/.snatch";
+$configfile=$configdir."/config.txt";
+$historyfile=$configdir."/history.txt";
+$logofile=$configdir."/logo.xpm";
+$libsnatch="/home/xiphmont/snatch/libsnatch.so";
+
+my $backchannel_socket="/tmp/snatch.$PID";
 my $uaddr=sockaddr_un($backchannel_socket);
 my $proto=getprotobyname('tcp');
+my $comm_ready=0;
+
+# default config
+$CONFIG{'REALPLAYER'}='{realplay,~/RealPlayer8/realplay}';
+$CONFIG{'OUPUT_PATH'}="$HOME";
+$CONFIG{'AUDIO_DEVICE'}="/dev/dsp*";
+$CONFIG{'AUDIO_MUTE'}='no';
+$CONFIG{'VIDEO_MUTE'}='no';
+$CONFIG{'MODE'}='active';
+$CONFIG{'OUTPUT'}=$HOME;
+$CONFIG{'DEBUG'}='no';
+
+if(! -e $configdir){
+    die $! unless mkdir $configdir, 0770;
+}
+
+
 
-my $username="e6dbvfc6";
-my $password="uwvdgjzy";
-my $openfile="/home/xiphmont/foo.ram";
-my $openloc="rtp://blah";
-
-my $playcode=join "",("Ks",pack ("S",4),"Kp",pack ("S",4));
-my $stopcode=join "",("Ks",pack ("S",4));
-my $exitcode=join "",("Kq",pack ("S",4));
-my $opencode=join "",("Ko",pack ("S",4));
-my $loccode=join "",("Kl",pack ("S",4));
-
-die $! unless socket(LISTEN_SOCK, PF_UNIX, SOCK_STREAM,0);
-unlink($backchannel_socket);
-die $! unless bind(LISTEN_SOCK,$uaddr);
-die $! unless listen(LISTEN_SOCK,SOMAXCONN);
-die $! unless accept(COMM_SOCK,LISTEN_SOCK);
-
-send_string("P",$password);
-send_string("U",$username);
-send_string("O",$openfile);
-send_string("L",$openloc);
-
-while(1){
-    $char=getc STDIN;
-    if($char eq "P"){
-	syswrite COMM_SOCK,$playcode;
-    }
-    if($char eq "S"){
-	syswrite COMM_SOCK,$stopcode;
-    }
-    if($char eq "O"){
-	syswrite COMM_SOCK,$opencode;
-    }
-    if($char eq "L"){
-	syswrite COMM_SOCK,$loccode;
-    }
-    if($char eq "Q"){
-	syswrite COMM_SOCK,$exitcode;
+$snatchxpm= <<'EOF';
+/* XPM */
+static char * snatch_xpm[] = {
+"36 27 25 1",
+" 	c None",
+".	c #060405",
+"+	c #8A8787",
+"@	c #8D1D27",
+"#	c #515052",
+"S	c #4F1314",
+"%	c #69272B",
+"&	c #AE5664",
+"*	c #D73138",
+"=	c #252524",
+"-	c #761922",
+";	c #2D0505",
+">	c #A53149",
+",	c #C8C8C8",
+"'	c #676768",
+")	c #F3F3F3",
+"!	c #A9A9A9",
+"~	c #7C5254",
+"{	c #F62F36",
+"]	c #9A9A99",
+"^	c #B32225",
+"/	c #261E24",
+"(	c #373736",
+"_	c #D7D7D7",
+":	c #797978",
+"   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%   ",
+" %S%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ",
+"%->%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%>-%",
+"S>;S----------------------------;@@%",
+"S>;*{{{{{{{{{{{******{{*{{{{{{{{-@>%",
+"S>;*{{{*^@--SSSSSSSSSSSSSS---@^{-->%",
+"S>;*{{-......................(.SS@>%",
+"S>;^{^...............(!/....:)..;->%",
+"S>;^{S..+!]=++!:.:!]#,)#'!]=!)!]/->%",
+"S>;^{;.:)'_+)]!)'_')+_,+)'_]_,:)#->%",
+"S>;@*..#))]')=!_#,,)#)],,./()'')/->%",
+"S>;@*;/:#])!).,,_!+)#)'_,(,:)(]_.->%",
+"S>;S at S.]__:++.!'!_!!(_]'__:#!.++.->%",
+"S>;-{^;........................S;->%",
+"S>;S{{{-......................@*;->%",
+"S>;S{{{{^;..................;^{*;->%",
+"S>;S{{{{{*S................S{{{^.->%",
+"S>;S{{{{{{{@..............@{{{{^.->%",
+"S>;S{{{{{{{{^;..........;^{{{{{^.->%",
+"S>;;{{{{{{{{{*S........-*{{{{{{^.->%",
+"S>;;***********^-S..S-^********@.->%",
+"S>;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;.->%",
+"S>;..............................->%",
+"S>;..............................@&~",
+"%-@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%>~+",
+" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%S% ",
+"   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%   "};
+EOF
+
+if(! -e $logofile){
+    die $! unless open LFILE, ">$logofile";
+    print LFILE $snatchxpm;
+    close LFILE;
+}
+
+# load the config/history
+if(-e $configfile){
+    die $! unless open CFILE, $configfile;
+    while(<CFILE>){
+	/^\s*([^=]+)=([^\n]*)/;
+	$CONFIG{$1}=$2;
     }
-    if($char eq "A"){
-	syswrite COMM_SOCK,'A';
+    close CFILE;
+}
+
+if(-e $historyfile){
+    die $! unless open HFILE, $historyfile;
+    while(<HFILE>){
+	push @TIMER, $_;
     }
-    if($char eq "I"){
-	syswrite COMM_SOCK,'I';
+    close HFILE;
+}
+
+print @ARGV;
+
+# build the UI
+my $toplevel=new MainWindow(-class=>'Snatch');
+my $Xname=$toplevel->Class;
+
+$toplevel->optionAdd("$Xname.background",  "#8e3740",20);
+$toplevel->optionAdd("$Xname.Panel.background",  "#8e3740",20);
+$toplevel->optionAdd("$Xname.Panel.foreground",  "#d0d0d0",20);
+$toplevel->optionAdd("$Xname.Panel.font",
+                     '-*-helvetica-bold-o-*-*-18-*-*-*-*-*-*-*',20);
+$toplevel->optionAdd("$Xname*Statuslabel.font",
+                     '-*-helvetica-bold-r-*-*-18-*-*-*-*-*-*-*',20);
+$toplevel->optionAdd("$Xname*Statuslabel.foreground", "#606060");
+$toplevel->optionAdd("$Xname*Status.font",
+                     '-*-helvetica-bold-r-*-*-18-*-*-*-*-*-*-*',20);
+
+$toplevel->optionAdd("$Xname*AlertDetail.font",
+                     '-*-helvetica-medium-r-*-*-10-*-*-*-*-*-*-*',20);
+
+
+$toplevel->optionAdd("$Xname*background",  "#d0d0d0",20);
+$toplevel->optionAdd("$Xname*foreground",  '#000000',20);
+$toplevel->optionAdd("$Xname*Tab*background",  "#a0a0a0",20);
+$toplevel->optionAdd("$Xname*Button*background",  "#f0d0b0",20);
+$toplevel->optionAdd("$Xname*Button*foreground",  '#000000',20);
+$toplevel->optionAdd("$Xname*activeBackground",  "#f0f0ff",20);
+$toplevel->optionAdd("$Xname*activeForeground",  '#0000a0',20);
+$toplevel->optionAdd("$Xname*borderWidth",         0,20);
+$toplevel->optionAdd("$Xname*activeBorderWidth",         1,20);
+$toplevel->optionAdd("$Xname*highlightThickness",         0,20);
+$toplevel->optionAdd("$Xname*padX",         2,20);
+$toplevel->optionAdd("$Xname*padY",         2,20);
+$toplevel->optionAdd("$Xname*relief",         'flat',20);
+$toplevel->optionAdd("$Xname*font",    
+                     '-*-helvetica-bold-r-*-*-12-*-*-*-*-*-*-*',20);
+$toplevel->optionAdd("$Xname*quit.font",    
+                     '-*-helvetica-bold-r-*-*-10-*-*-*-*-*-*-*',20);
+
+$toplevel->configure(-background=>$toplevel->optionGet("background",""));
+
+#$toplevel->resizable(FALSE,FALSE);
+my $xpm_snatch=$toplevel->Pixmap("_snatchlogo_xpm",-file=>$logofile);
+
+$window_shell=$toplevel->Label(Name=>"shell",borderwidth=>1,relief=>raised)->
+    place(-x=>10,-y=>36,-relwidth=>1.0,-relheight=>1.0,
+	  -width=>-20,-height=>-46,-anchor=>'nw');
+
+$window_setupbar=$toplevel->Button(-class=>Tab,Name=>"setup",text=>"configuration",
+				   borderwidth=>1,relief=>raised)->
+    place(-relx=>1.0,-anchor=>'se',-in=>$window_shell,-bordermode=>outside);
+$window_timerbar=$toplevel->Button(-class=>Tab,Name=>"timer",text=>"timer setup",
+				   borderwidth=>1,relief=>raised)->
+    place(-bordermode=>outside,-anchor=>'ne',-in=>$window_setupbar);
+
+$window_quit=$window_shell->Button(-class=>Tab,Name=>"quit",text=>"quit",
+				   -padx=>1,-pady=>1,
+				   relief=>'groove',borderwidth=>2)->
+    place(-x=>-1,-y=>-1,-relx=>1.0,-rely=>1.0,-anchor=>'se');
+
+$window_logo=$toplevel->
+    Label(Name=>"logo",-class=>"Panel",image=>$xpm_snatch,
+	  relief=>flat,borderwidth=>0)->
+    place(-x=>5,-y=>5,-anchor=>'nw');
+
+$window_version=$toplevel->
+    Label(Name=>"logo text",-class=>"Panel",text=>$version,
+	  relief=>flat,borderwidth=>0)->
+    place(-x=>5,-relx=>1.0,-rely=>1.0,-anchor=>'sw',-in=>$window_logo);
+
+
+$window_statuslabel=$window_shell->
+    Label(Name=>"statuslabel",-class=>"Statuslabel",text=>"Status: ",
+	  relief=>flat,borderwidth=>0)->
+    place(-x=>5,-y=>0,-rely=>.2,-relheight=>.4,-anchor=>'w');
+
+$window_status=$window_shell->
+    Label(Name=>"status",-class=>"Status",text=>"Starting...",
+	  relief=>flat,borderwidth=>0)->
+    place(-x=>5,-y=>0,-relx=>1.0,-relheight=>1.0,
+	  -anchor=>'nw',-in=>$window_statuslabel);
+
+$window_active=$window_shell->Button(Name=>"active",text=>"record all",
+				    state=>disabled,
+				   relief=>'groove',borderwidth=>2)->
+    place(-x=>5,-y=>0,-relx=>0.,-rely=>.55,-relwidth=>.33,
+	  -width=>-5,-anchor=>'w',-in=>$window_shell);
+
+$window_timer=$window_shell->Button(Name=>"timer",text=>"timed record",
+				    state=>disabled,
+				   relief=>'groove',borderwidth=>2)->
+    place(-x=>0,-y=>0,-relx=>.333,-rely=>.55,-relwidth=>.33,
+	  -width=>-0,-anchor=>'w',-in=>$window_shell);
+
+$window_inactive=$window_shell->Button(Name=>"inactive",text=>"record off",
+				    state=>disabled,
+				   relief=>'groove',borderwidth=>2)->
+    place(-x=>0,-y=>0,-relx=>.667,-rely=>.55,-relwidth=>.33,
+	  -width=>-5,-anchor=>'w',-in=>$window_shell);
+
+
+$window_mute=$window_shell->Label(Name=>"mute",text=>"mutes: ")->
+    place(-x=>5,-y=>0,-relx=>0.,-rely=>.85,
+	  -anchor=>'w',-in=>$window_shell);
+
+$window_amute=$window_shell->Button(Name=>"audio",text=>"audio",
+				    state=>disabled,
+				   relief=>'groove',borderwidth=>2)->
+    place(-x=>2,-relx=>1.0,-relheight=>1.0,-anchor=>'nw',-in=>$window_mute,
+	  -bordermode=>outside);
+
+$window_vmute=$window_shell->Button(Name=>"video",text=>"video",
+				    state=>disabled,
+				    relief=>'groove',borderwidth=>2)->
+    place(-x=>2,-relx=>1.0,-relheight=>1.0,-anchor=>'nw',-in=>$window_amute,
+	  -bordermode=>outside);
+
+$minwidth=
+    $window_logo->reqwidth()+
+    $window_version->reqwidth()+
+    $window_setupbar->reqwidth()+
+    $window_timerbar->reqwidth()+
+    30;
+$minheight=
+    $window_logo->reqheight()+
+    $window_statuslabel->reqheight()+
+    $window_mute->reqwidth()+
+    20;
+
+$toplevel->optionAdd("$Xname.geometry",    ($minwidth+20).'x'.$minheight,20);
+my$geometry=$toplevel->optionGet("geometry","");
+$toplevel->minsize($minwidth,$minheight);
+$toplevel->geometry($geometry);
+
+$toplevel->update();
+
+$window_quit->configure(-command=>[sub{Shutdown();}]);
+$window_amute->configure(-command=>[sub{Amute();}]);
+$window_vmute->configure(-command=>[sub{Vmute();}]);
+$window_active->configure(-command=>[sub{Robot_Active();}]);
+$window_timer->configure(-command=>[sub{Robot_Timer();}]);
+$window_inactive->configure(-command=>[sub{Robot_Inactive();}]);
+$window_setupbar->configure(-command=>[sub{Setup();}]);
+$window_timerbar->configure(-command=>[sub{Timer();}]);
+
+# bind socket
+BindSocket();
+
+# throw a realplayer process and 
+ThrowRealPlayer();
+
+# main loop 
+Tk::MainLoop();
+
+
+sub ThrowRealPlayer{
+    Status("Starting RealPlayer...");
+    # set up the environment
+
+    $ENV{"SNATCH_DEBUG"}=1;
+    $ENV{"LD_PRELOAD"}=$libsnatch;
+    $ENV{"SNATCH_COMM_SOCKET"}=$backchannel_socket;
+
+    my at list=bsd_glob("$CONFIG{'REALPLAYER'}",
+		     GLOB_TILDE|GLOB_ERR|GLOB_BRACE);
+    if(GLOB_ERROR || $#list<0){
+	Status("Failed to find RealPlayer!");
+	return;
+    }
+
+    die "pipe call failed unexpectedly: $!" unless pipe REAL_STDERR,WRITEH;
+    $realpid=open3("<&STDIN",">&STDOUT",">&WRITEH", at list[0]);
+    close WRITEH;
+
+    # a select loop until we have the socket accepted
+    my $rin = $win = $ein = '';
+    my $rout,$wout,$eout;
+    vec($rin,fileno(REAL_STDERR),1)=1;
+    vec($rin,fileno(LISTEN_SOCK),1)=1;
+    $ein=$rin | $win;
+
+    my $time=20;
+    my $stderr_output;
+
+    Status("Waiting for rendevous... [$time]");
+    while($time){
+	my($nfound,$timeleft)=select($rout=$rin, $wout=$win, $eout=$ein, 1);
+	if($nfound==0){
+	    $time--;
+	    Status("Waiting for rendevous... [$time]");
+	}else{
+	    if(vec($rout,fileno(REAL_STDERR),1)){
+		$bytes=sysread REAL_STDERR, my$scalar, 4096;
+		$stderr_output.=$scalar;
+		
+		if($bytes==0){
+		    Status("Rendevous failed.");
+
+		    Alert("RealPlayer didn't start successfully.  ".
+			  "Here's the complete debugging output of the ".
+			  "attempt:",
+			  $stderr_output);
+
+		    print "EOF on REAL_STDERR!\n";
+		    return;
+		}
+	    }
+	    if(vec($rout,fileno(LISTEN_SOCK),1)){
+		# socket has a request
+		$status=accept(COMM_SOCK,LISTEN_SOCK);
+		Status("libsnatch contacted");
+		$comm_ready=1;
+		$time=0;
+	    }
+	}
     }
-    if($char eq "T"){
-	syswrite COMM_SOCK,'T';
+
+
+    # configure
+    send_string("F",$CONFIG{'OUTPUT_PATH'});
+    send_string("D",$CONFIG{'AUDIO_DEVICE'});
+    Robot_Audio($global_audio_setting);
+    Robot_Video($global_video_setting);
+}
+
+sub BindSocket{
+    Status("Binding socket..");
+    die $! unless socket(LISTEN_SOCK, PF_UNIX, SOCK_STREAM,0);
+    unlink($backchannel_socket);
+    die $! unless bind(LISTEN_SOCK,$uaddr);
+    die $! unless listen(LISTEN_SOCK,SOMAXCONN);
+}
+
+sub ReleaseSocket{
+    $window_amute->configure(state=>disabled);
+    $window_vmute->configure(state=>disabled);
+
+    $comm_ready=0;
+    unlink($backchannel_socket);
+    close(LISTEN_SOCK);
+}
+
+sub AcceptSocket{
+    Status("Waiting for rendevous...");
+
+    eval{
+	local $SIG{ALRM} = sub { Status("Failed to rendevous"); };
+	alarm 15;
+	$status=accept(COMM_SOCK,LISTEN_SOCK);
+	alarm 0;
+	if($status){
+	    #enable the panel
+	    Status("libsnatch contacted");
+	    $comm_ready=1;
+	    $window_amute->configure(state=>active);
+	    $window_vmute->configure(state=>active);
+
+	    
+	}
     }
 }
 
+sub Shutdown{
+# save the config/history
+    ReleaseSocket();
+
+    die $! unless open CFILE, ">$configfile".".tmp";
+    foreach $key (keys %CONFIG){
+	print CFILE "$key=$CONFIG{$key}\n";
+    }
+    close CFILE;
+    die $! unless rename "$configfile".".tmp", $configfile;
+    
+    die $! unless open HFILE, ">$historyfile".".tmp";
+    foreach $line (@TIMER){
+	print HFILE "$line\n";
+    }
+    close HFILE;
+    die $! unless rename "$historyfile".".tmp", $historyfile;
+    
+  Tk::exit(0);
+}
+
+
 sub send_string{
     my($op,$code)=@_;
     syswrite COMM_SOCK,$op;
     syswrite COMM_SOCK, (pack 'S', length $code);
     syswrite COMM_SOCK, $code;
+}
+
+sub Robot_PlayLoc{
+    my($loc,$username,$password)=@_;
+    my $stopcode=join "",("Ks",pack ("S",4));
+    my $loccode=join "",("Kl",pack ("S",4));
+    
+    syswrite COMM_SOCK,$stopcode;
+
+    send_string("P",$password);
+    send_string("U",$username);
+    send_string("L",$openloc);
+
+    syswrite COMM_SOCK,$loccode;
+ 
+    # watch for bad password
+}
+
+sub Robot_PlayFile{
+    my($loc)=@_;
+    my $stopcode=join "",("Ks",pack ("S",4));
+    my $opencode=join "",("Ko",pack ("S",4));
+
+    syswrite COMM_SOCK,$stopcode;
+    send_string("O",$openfile);
+    syswrite COMM_SOCK,$opencode;
+}
+
+sub Robot_Stop{
+    my $stopcode=join "",("Ks",pack ("S",4));
+    syswrite COMM_SOCK,$playcode;
+}
+
+sub Robot_Exit{
+    my $exitcode=join "",("Kx",pack ("S",4));
+    syswrite COMM_SOCK,$playcode;
+    close COMM_SOCK;
+    Status("Waiting for RealPlayer exit...");
+    waitpid $realpid, 0
+}
+
+sub Robot_Active{
+    # clear out robot settings to avoid hopelessly confusing the user
+    send_string("U","");
+    send_string("P","");
+    send_string("O","");
+    send_string("L","");
+    syswrite COMM_SOCK,'A';
+    Amute($global_audio_setting);
+    Vmute($global_video_setting);
+    Status("Recording ACTIVE: Idle/Nominal");
+}
+
+sub Robot_Inctive{
+    send_string("U","");
+    send_string("P","");
+    send_string("O","");
+    send_string("L","");
+    Amute($global_audio_setting);
+    Vmute($global_video_setting);
+    syswrite COMM_SOCK,'I';
+    Status("Recording off");
+}
+
+sub Robot_Timer{
+    send_string("U","");
+    send_string("P","");
+    send_string("O","");
+    send_string("L","");
+    Amute($global_audio_setting);
+    Vmute($global_video_setting);
+    syswrite COMM_SOCK,'T';
+    Status("Inactive [Timer]");
+}
+
+sub Robot_Audio{
+    my($onoff)=@_;
+
+    if($onoff=~m/on/){
+	syswrite COMM_SOCK,'S';
+    }
+    if($onoff=~m/off/){
+	syswrite COMM_SOCK,'s';
+    }
+}
+
+sub Robot_Video{
+    my($onoff)=@_;
+
+    if($onoff=~m/on/){
+	syswrite COMM_SOCK,'V';
+    }
+    if($onoff=~m/off/){
+	syswrite COMM_SOCK,'v';
+    }
+}
+
+sub SplitTimerEntry{
+    my($line)=@_;
+
+# eg
+# 2001 11 05 1 12:25 300000 FAKEA FAKEV length:USERNAME length:PASSWORD length:FILE length:URL
+    $line=~/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\d+):(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(.*)/;
+    my $year=$1;
+    my $month=$2;
+    my $day=$3;
+    my $dayofweek=$4;
+    my $hour=$5;
+    my $minute=$6;
+    my $duration=$7;
+
+    my $audio=$8;
+    my $video=$9;
+
+    my $fields=$10;
+    
+    my $username;
+    my $password;
+    my $outfile;
+    my $url;
+
+    ($username,$fields)=LengthParse($fields);
+    ($password,$fields)=LengthParse($fields);
+    ($outfile,$fields)=LengthParse($fields);
+    ($url,$fields)=LengthParse($fields);
+
+    ($year,$month,$day,$dayofweek,$hour,$minute,$duration,$audio,$video,$username,
+     $password,$outfile,$url);
+}
+
+sub LengthParse{
+    my($line)=@_;
+    $line=~/(\d+):(.+)/;
+    $length=$1;
+    $rest=$2;
+
+    (substr($rest,0,$length),substr($rest,$length));
+}	
+
+sub MonthDays{
+    my($month,$year)=@_;
+    
+    if($month==2){
+	if($year % 4 !=0){
+	    28;
+	}elsif ($year % 400 == 0){
+	    29;
+	}elsif ($year % 100 == 0){
+	    28;
+	}else{
+	    29;
+	}
+    }else{
+	my @trans=(0,31,0,31,30,31,30,31,31,30,31,30,31);
+	$trans[$month];
+    }
+}
+
+sub TimerWhen{
+    my($try,$year,$month,$day,$dayofweek,$hour,$minute,$duration)=@_;
+
+    #overguard 
+    if($minute ne '*'){while($minute>=60){$minute-=60;
+					  $hour++if($hour ne '*');}};
+    if($hour ne '*'){while($hour>=24){$hour-=24;
+				      $day++ if($day ne '*');}};
+    if($day ne '*' && $month ne '*' && $year ne '*'){
+	while($month>12){$month-=12;$year++;};
+	while($day>MonthDays($month,$year)){
+	    $day-=MonthDays($month,$year);$month++;
+	    while($month>12){$month-=12;$year++;};
+	}
+    }
+    if($month ne '*'){while($month>12){$month-=12;
+				       $year++ if ($year ne '*')}};
+    
+    my $now=time();
+    my($nowsec,$nowmin,$nowhour,$nowday,$nowmonth,$nowyear)=localtime($now);    
+    $nowmon++;
+    $nowyear+=1900;
+
+    
+    # boundary cases in each...  rather than solving it exactly, we'll
+    # solve it empirically. Laziness as a virtue.
+    if($year eq '*'){
+	$try=TimerWhen($try,$nowyear-1,$month,$day,$dayofweek,
+		       $hour,$minute,$duration);
+	return $try if($try!=-1);
+	$try=TimerWhen($try,$nowyear,$month,$day,$dayofweek,
+		       $hour,$minute,$duration);
+	return $try if($try!=-1);
+	$try=TimerWhen($try,$nowyear+1,$month,$day,$dayofweek,
+		       $hour,$minute,$duration);
+	return $try if($try!=-1);
+    }elsif($month eq '*'){
+	for(my$i=1;$i<13;$i++){
+	    $try=TimerWhen($try,$year,$i,$day,$dayofweek,
+			   $hour,$minute,$duration);
+	    return $try if($try!=-1);
+	}
+    }elsif($day eq '*'){
+	# important to go for a weekday match */
+	for(my$i=1;$i<32;$i++){
+	    $try=TimerWhen($try,$year,$month,$i,$dayofweek,
+			   $hour,$minute,$duration);
+	    return $try if($try!=-1);
+	}
+    }elsif($hour eq "*"){
+	return $try;
+    }elsif($hour eq "*"){
+	return $try;
+    }elsif($duration eq "*"){
+	return $try;
+    }else{
+	my $start=timelocal(0,$minute,$hour,$day,$month-1,$year);
+	my $end=$start+$duration;
+	
+	# make sure day-of-month and day-of-week agree
+	if($dayofweek ne '*'){
+	    my($tsec,$tmin,$thour,$tday,$tmon,$tyear,$twday)=localtime($start);
+	    if($twday != $dayofweek){return $try};
+	}
+	
+	if($start>$now || $end>$now){
+	    if($try==-1 || $start<$try){
+		return $start;
+	    }
+	}
+    }
+    $try;
+}
+
+sub max{
+    my$val=shift @_;
+    while (defined(my$n=shift @_)){
+	$val=$n if($n>$val);
+    }
+    $val;
+}
+
+sub sortsub{
+    my($a,$b)=@_;
+    return $TIMER_TIMES[$a]-$TIMER_TIMES[$b];
+}
+
+sub TimerSort{
+    $count=0;
+    @TIMER_TIMES=(map {TimerWhen(-1,(SplitTimerEntry($_)))} @TIMER);
+    @TIMER_SORTED=sort sortsub, (map {$count++} @TIMER);
+}    
+
+sub Status{
+    $window_status->configure(text=>shift @_);
+    $toplevel->update();
+}
+
+sub Alert{
+    my($message,$detail)=@_;
+
+    if(defined($modal)){$modal->destroy()};
+
+    $modal=new MainWindow(-class=>"$Xname");
+    $modal->configure(-background=>$modal->optionGet("background",""));
+    
+    $modal_shell=$modal->Label(-class=>Alert,Name=>"shell",
+			       borderwidth=>1,relief=>raised)->
+				   place(-x=>4,-y=>4,-relwidth=>1.0,-relheight=>1.0,
+					 -width=>-8,-height=>-8,-anchor=>'nw');
+
+    $modal_exit=$modal_shell->
+	Button(-class=>Tab,Name=>"exit",text=>"X",
+	       -padx=>1,-pady=>1,relief=>'groove',borderwidth=>2)->
+		   place(-x=>-1,-y=>-1,-relx=>1.0,-rely=>1.0,-anchor=>'se');
+    
+    $modal_message=$modal_shell->
+	Label(text=>$message,-class=>"AlertText")->
+	    place(-x=>5,-y=>10);
+
+    $width=$modal_message->reqwidth();
+
+
+    $modal_detail=$modal_shell->
+	Message(text=>$detail,-class=>"AlertDetail",
+		-width=>($width-$modal_exit->reqwidth()))->
+	    place(-relx=>0,-y=>5,-rely=>1.0,-anchor=>'nw',
+		  -in=>$modal_message);
+
+    $width+=20;
+    $height=$modal_message->reqheight()+$modal_detail->reqheight()+25;
+
+    my$xx=$toplevel->rootx();
+    my$yy=$toplevel->rooty();
+    my$ww=$toplevel->width();
+    my$hh=$toplevel->height();
+
+    $x=$xx+$ww/2-$width/2;
+    $y=$yy+$hh/2-$height/2;
+    
+    $modal->geometry($width."x".$height."+".int($x)."+".int($y));
+    $modal->resizable(FALSE,FALSE);
+    $modal->transient($toplevel);
+    $modal_exit->configure(-command=>[sub{$modal->destroy();undef $modal}]);
 }
 
 

1.10      +3 -6      snatch/x11.c

Index: x11.c
===================================================================
RCS file: /usr/local/cvsroot/snatch/x11.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- x11.c	2001/11/05 16:58:03	1.9
+++ x11.c	2001/11/07 05:13:46	1.10
@@ -97,6 +97,8 @@
     XFree(children);
     id=parent_return;
   }
+  *root_x=x;
+  *root_y=y;
 }
 
 static void FakeKeycode(int keycode, int modmask, unsigned long window){
@@ -138,7 +140,6 @@
   int root_x,root_y;
 
   XGetGeometryRoot(window,&root_x,&root_y);
-
   memset(&event,0,sizeof(event));
   event.display=Xdisplay;
   event.type=4; /* button down */
@@ -505,7 +506,7 @@
   }
 
   /* watch for the open file window */
-  if(n>32 &&  !memcmp(data,"OpenFileDialogShell\0RCACoreAppShell\0",32)){
+  if(n>32 && !memcmp(data,"OpenFileDialogShell\0RCACoreAppShell\0",32)){
     fprintf(stderr,
             "    ...: RealPlayer popped open file dialog.\n");
     rpfile_shell=id;
@@ -574,10 +575,7 @@
     unsigned char *ptr=data;
     long i,j,k;
 
-    fprintf(stderr,"%d %d %d %d %d %d\n",x,y,width,height,rpplay_width,rpplay_height);
-
     if(x==0 && width==rpplay_width){
-      fprintf(stderr,"searching for screen...\n");
       if(y==0){
         play_blackupper=42;
         play_blacklower=-1;
@@ -610,7 +608,6 @@
            big black block */
         int test;
         
-	fprintf(stderr,"searching for logo...\n");
         for(test=play_blackupper;test<height+y;test++)
           if(test>=y)
             if(ptr[(test-y)*width*4+(width/2*4)+1]!=0)break;

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list