--- /dev/null
+#!/usr/bin/perl -w
+
+use strict;
+use utf8;
+
+use Gtk2 '-init';
+use Glib qw(TRUE FALSE);
+
+use SCX::Reader;
+
+my @controllers = (0, 0, 0, 0, 0, 0);
+
+my $builder = Gtk2::Builder->new;
+$builder->add_from_file('slotcarman.glade');
+
+my $window = $builder->get_object('slotcarman');
+
+$builder->connect_signals(undef);
+$window->show();
+
+sub quit {
+ Gtk2->main_quit;
+ return FALSE;
+}
+
+my $reader = SCX::Reader->new({
+ portname => '/dev/ttyUSB0',
+ logfile => 'log',
+ callback => \&do_packet,
+});
+
+sub scx_read {
+ my $event = shift;
+
+ $reader->read();
+ return TRUE;
+}
+
+Glib::IO->add_watch(fileno($reader->fh), 'in', \&scx_read, 1);
+
+Gtk2->main();
+
+sub do_packet {
+ my (@data) = @_;
+
+ if ($data[0] == 0xff) { # controller status
+ for my $controller (1..6) {
+ my $byte = $data[$controller];
+ next if defined $controllers[$controller-1]
+ && $controllers[$controller-1] == $byte;
+ $controllers[$controller-1] = $byte;
+
+ my $progressbar = $builder->get_object(
+ 'progressbar_controller'.$controller);
+ if ($byte == 0xaa) {
+ $progressbar->set_text('inactive');
+ $progressbar->set_fraction(0);
+ next;
+ }
+ my $light = !($byte & 0x20);
+ my $backbutton = !($byte & 0x10);
+ my $speed = $byte & 0x0f;
+
+ my $text = ($backbutton ? '+' : '') . $speed;
+ $progressbar->set_text($text);
+ $progressbar->set_fraction($speed / 12);
+ }
+ } elsif ($data[0] == 0xd6) { # fuel status
+ my @fuel = (0,
+ $data[1] >> 4, $data[1] & 0x0f,
+ $data[2] >> 4, $data[2] & 0x0f,
+ $data[3] >> 4, $data[3] & 0x0f,
+ );
+ for my $car (1..6) {
+ next if defined $controllers[$car-1]
+ &&$controllers[$car-1] == $fuel[$car];
+
+ my $progressbar = $builder->get_object(
+ 'progressbar_fuel'.$car);
+ $progressbar->set_fraction($fuel[$car]/8);
+ }
+ } else {
+ print "Unknown packet",
+ (map { sprintf(" %02x", $_) } @data), "\n";
+ }
+}
+
+__END__
+use Gtk2 '-init';
+
+my $window = Gtk2::Window->new('toplevel');
+$window->signal_connect(delete_event => sub { Gtk2->main_quit; return FALSE });
+$window->set_title("Slot Cars Manager");
+
+$window->set_border_width(10);
+
+my $button = Gtk2::Button->new("Button 1");
+$button->signal_connect(clicked => \&callback, 'button 1');
+
+my $box1 = Gtk2::HBox->new(FALSE, 0);
+$window->add($box1);
+$box1->pack_start($button, TRUE, TRUE, 0);
+
+$button->show;
+$button = Gtk2::Button->new("Button 2");
+$button->signal_connect(clicked => \&callback, 'button 2');
+$box1->pack_start($button, TRUE, TRUE, 0);
+
+$button->show;
+$box1->show;
+$window->show;
+
+Gtk2->main();
+
+
+sub callback
+{
+ my ($button, $data) = @_;
+
+ print "Hello again - $data was pressed\n";
+}
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="2.20"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkWindow" id="slotcarman">
+ <property name="title" translatable="yes">Slot Cars Race Manager</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkMenuBar" id="menubar1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkMenuItem" id="menuitem1">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="menu1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem1">
+ <property name="label">gtk-new</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem2">
+ <property name="label">gtk-open</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem3">
+ <property name="label">gtk-save</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem4">
+ <property name="label">gtk-save-as</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparatorMenuItem" id="separatormenuitem1">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem5">
+ <property name="label">gtk-quit</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="quit" swapped="no"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="menuitem2">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="label" translatable="yes">_Edit</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="menu2">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem6">
+ <property name="label">gtk-cut</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem7">
+ <property name="label">gtk-copy</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem8">
+ <property name="label">gtk-paste</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem9">
+ <property name="label">gtk-delete</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="menuitem3">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="label" translatable="yes">_View</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="menuitem4">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="menu3">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem10">
+ <property name="label">gtk-about</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="about" swapped="no"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">7</property>
+ <property name="n_columns">11</property>
+ <child>
+ <object class="GtkLabel" id="label_pos1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><span weight="ultrabold" size="large">1</span></property>
+ <property name="use_markup">True</property>
+ <property name="justify">right</property>
+ <property name="width_chars">1</property>
+ <property name="single_line_mode">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_pos2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><span weight="ultrabold" size="large">2</span></property>
+ <property name="use_markup">True</property>
+ <property name="justify">right</property>
+ <property name="width_chars">1</property>
+ <property name="single_line_mode">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_pos3">
+ <property name="visible">True</property>
+ <property name="yalign">0.50999999046325684</property>
+ <property name="label" translatable="yes"><span weight="ultrabold" size="large">3</span></property>
+ <property name="use_markup">True</property>
+ <property name="justify">right</property>
+ <property name="width_chars">1</property>
+ <property name="single_line_mode">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_pos4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><span weight="ultrabold" size="large">4</span></property>
+ <property name="use_markup">True</property>
+ <property name="justify">right</property>
+ <property name="width_chars">1</property>
+ <property name="single_line_mode">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_pos5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><span weight="ultrabold" size="large">5</span></property>
+ <property name="use_markup">True</property>
+ <property name="justify">right</property>
+ <property name="width_chars">1</property>
+ <property name="single_line_mode">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_pos6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><span weight="ultrabold" size="large">6</span></property>
+ <property name="use_markup">True</property>
+ <property name="justify">right</property>
+ <property name="width_chars">1</property>
+ <property name="single_line_mode">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_name1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Ivi</property>
+ <property name="ellipsize">end</property>
+ <property name="width_chars">25</property>
+ <property name="single_line_mode">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="progressbar_fuel1">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">10</property>
+ <property name="right_attach">11</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="progressbar_fuel2">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">10</property>
+ <property name="right_attach">11</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="progressbar_fuel3">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">10</property>
+ <property name="right_attach">11</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="progressbar_fuel4">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">10</property>
+ <property name="right_attach">11</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="progressbar_fuel5">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">10</property>
+ <property name="right_attach">11</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="progressbar_fuel6">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">10</property>
+ <property name="right_attach">11</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="progressbar_controller1">
+ <property name="visible">True</property>
+ <property name="orientation">bottom-to-top</property>
+ </object>
+ <packing>
+ <property name="left_attach">8</property>
+ <property name="right_attach">9</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="progressbar_controller2">
+ <property name="visible">True</property>
+ <property name="orientation">bottom-to-top</property>
+ </object>
+ <packing>
+ <property name="left_attach">8</property>
+ <property name="right_attach">9</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="progressbar_controller3">
+ <property name="visible">True</property>
+ <property name="orientation">bottom-to-top</property>
+ </object>
+ <packing>
+ <property name="left_attach">8</property>
+ <property name="right_attach">9</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="progressbar_controller4">
+ <property name="visible">True</property>
+ <property name="orientation">bottom-to-top</property>
+ </object>
+ <packing>
+ <property name="left_attach">8</property>
+ <property name="right_attach">9</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="progressbar_controller5">
+ <property name="visible">True</property>
+ <property name="orientation">bottom-to-top</property>
+ </object>
+ <packing>
+ <property name="left_attach">8</property>
+ <property name="right_attach">9</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="progressbar_controller6">
+ <property name="visible">True</property>
+ <property name="orientation">bottom-to-top</property>
+ </object>
+ <packing>
+ <property name="left_attach">8</property>
+ <property name="right_attach">9</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkStatusbar" id="statusbar1">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <property name="has_resize_grip">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>