#!/usr/bin/perl # Christian Birchinger # # Hotkeys: # # up/down/left/right => Cursor Keys # CTRL => Source # Keypad 0 => Return # Space => Power # Escape => Exit use strict; use Socket; use Glib ':constants'; use Gtk2 '-init'; use Gtk2::Gdk::Keysyms; my $lirchost = "n900"; my $lirchostport = 8765; my $appname = "tvui"; # keyword => [ remote control, button ] my $codetable = { power => [ 'RM-ED006', 'power' ], source => [ 'RM-ED006', 'source' ], up => [ 'RM-ED006', 'up' ], down => [ 'RM-ED006', 'down' ], left => [ 'RM-ED006', 'left' ], right => [ 'RM-ED006', 'right' ], ok => [ 'RM-ED006', 'ok' ], return => [ 'RM-ED006-2', 'return' ], }; #========================================================================== $0 = $appname if ($^O eq 'linux'); # Setting $0 fails on FreeBSD and Windows #---[ LIrc remote connection ]--------------------------------------------- my $iaddr = inet_aton($lirchost) || abort("No such host: $lirchost"); my $paddr = sockaddr_in($lirchostport, $iaddr); my $proto = getprotobyname('tcp'); socket(SOCK, PF_INET, SOCK_STREAM, $proto) || abort("Unable to open socket: $!"); connect(SOCK, $paddr) || abort("Unable to Connect to ${lirchost}: $!"); # print join( "\n", send_lirc_string("list") ) . "\n"; #---[ GTK Main Window Content ]-------------------------------------------- Gtk2->init; my $window = Gtk2::Window->new( 'toplevel' ); $window->set_title ( $appname ); $window->set_position( 'mouse' ); my $vbox1 = Gtk2::VBox->new( 1, 6 ); $window->add($vbox1); $vbox1->set_border_width(2); #---[ first row of buttons ]---------------------------------------------- my $hbox1 = Gtk2::HBox->new( 1, 6 ); $vbox1->pack_start($hbox1,0,0,2); my $button1 = create_button('Power', 'gtk-execute', 'power'); $hbox1->pack_start( $button1, 0, 0, 0 ); my $button2 = create_button('Up', 'gtk-go-up', 'up'); $hbox1->pack_start( $button2, 0, 0, 0 ); my $button3 = create_button('Source', 'gtk-connect', 'source'); $hbox1->pack_start( $button3, 0, 0, 0 ); #-------------------------------------------------------------------------- #---[ second row of buttons ]---------------------------------------------- my $hbox2 = Gtk2::HBox->new( 1, 6 ); $vbox1->pack_start($hbox2,0,0,2); my $button4 = create_button('Left', 'gtk-go-back', 'left'); $hbox2->pack_start( $button4, 0, 0, 0 ); my $button5 = create_button('Ok', 'gtk-ok', 'ok'); $hbox2->pack_start( $button5, 0, 0, 0 ); my $button6 = create_button('Right', 'gtk-go-forward', 'right'); $hbox2->pack_start( $button6, 0, 0, 0 ); #-------------------------------------------------------------------------- #---[ third row of buttons ]----------------------------------------------- my $hbox3 = Gtk2::HBox->new( 1, 6 ); $vbox1->pack_start($hbox3,0,0,2); my $button7 = create_button('Return', 'gtk-undo', 'return'); $hbox3->pack_start( $button7, 0, 0, 0 ); my $button8 = create_button('Down', 'gtk-go-down', 'down'); $hbox3->pack_start( $button8, 0, 0, 0 ); my $button9 = create_button('Quit', 'gtk-quit', FALSE); $button9->signal_connect( clicked => \&quit_app ); $hbox3->pack_start( $button9, 0, 0, 0 ); #-------------------------------------------------------------------------- $window->signal_connect(delete_event => \&quit_app); $window->signal_connect(destroy => \&quit_app); $window->signal_connect (key_press_event => sub { my ($widget, $event) = @_; if ( $event->keyval == $Gtk2::Gdk::Keysyms{Up} ) { execute_remote('up') } elsif ( $event->keyval == $Gtk2::Gdk::Keysyms{Down} ) { execute_remote('down') } elsif ( $event->keyval == $Gtk2::Gdk::Keysyms{Right} ) { execute_remote('right'); } elsif ( $event->keyval == $Gtk2::Gdk::Keysyms{Left} ) { execute_remote('left') } elsif ( $event->keyval == $Gtk2::Gdk::Keysyms{Return} ) { execute_remote('ok') } elsif ( $event->keyval == $Gtk2::Gdk::Keysyms{KP_0} ) { execute_remote('return') } elsif ( $event->keyval == $Gtk2::Gdk::Keysyms{Control_R} ) { execute_remote('source') } elsif ( $event->keyval == $Gtk2::Gdk::Keysyms{space} ) { execute_remote('power') } elsif ( $event->keyval == $Gtk2::Gdk::Keysyms{Escape} ) { quit_app() } return 1; }); $window->show_all; Gtk2->main; #========================================================================== sub quit_app { print "$appname: Exiting normaly...\n"; close(SOCK); exit 0; } sub send_lirc_string { (my $cmd) = @_; my @result; my $line; send SOCK, $cmd . "\n", 0; until($line eq "END") { $line = ; chomp($line); push (@result, $line); } return @result; } sub execute_remote { my ($command) = @_; if ( $codetable->{$command} ){ send_remote( @{$codetable->{$command}} ); } else { print "$appname: WARNING: Unknown function \"$command\" requested.\n" } } sub send_remote { my ($remote, $command) = @_; my @result; print "send_remote: Pressing button \"$command\" on remote control \"$remote\"\n"; @result = send_lirc_string("send_once " . $remote . " " . $command); print join( "\n", @result ) . "\n"; } sub create_button { my ($label, $image, $execfunc) = @_; my $button = Gtk2::Button->new_with_label( $label ); $button->set_image( Gtk2::Image->new_from_stock( $image, 'button' ) ) if ($image); $button->signal_connect( clicked => sub{ execute_remote( $execfunc ) }) if ($execfunc); $button->can_focus(FALSE); $button->set_size_request(80, 32); return $button; } sub abort { my ($message) = @_; $message = "terminated." if (!$message); print STDERR "appname: ABORT: $message\n"; Gtk2->init; my $dialog = Gtk2::Dialog->new ("$appname error" , $window, 'destroy-with-parent', 'gtk-quit' => 'none'); my $label = Gtk2::Label->new ("$message"); my $vbox = Gtk2::VBox->new(0, 0); $vbox->set_border_width(10); $vbox->pack_start($label, 1, 1, 0); $dialog->get_content_area ()->add ($vbox); $dialog->signal_connect (response => sub { close(SOCK); exit 1; }); $dialog->show_all; Gtk2->main; }