summaryrefslogtreecommitdiffstats
path: root/perl-install/standalone/drakclock
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/standalone/drakclock')
-rwxr-xr-xperl-install/standalone/drakclock424
1 files changed, 424 insertions, 0 deletions
diff --git a/perl-install/standalone/drakclock b/perl-install/standalone/drakclock
new file mode 100755
index 000000000..359bc1d2b
--- /dev/null
+++ b/perl-install/standalone/drakclock
@@ -0,0 +1,424 @@
+#!/usr/bin/perl
+
+use strict;
+use lib qw(/usr/lib/libDrakX);
+use POSIX;
+use common;
+# i18n : IMPORTANT to get correct namespace (drakconf instead of libDrakX)
+BEGIN { unshift @::textdomains, 'drakconf' }
+use mygtk3 qw(gtknew);
+use ugtk3 qw(:all);
+use interactive;
+use standalone;
+use timezone;
+
+my $in = interactive->vnew('su');
+my $cairo;
+my ($midx, $midy, $radius);
+my ($dRadians_hour, $dRadians_min, $dRadians_sec);
+my $Radian;
+my $timer;
+my $first = 1;
+my $its_reset = 0;
+
+$ugtk3::wm_icon = "/usr/share/mcc/themes/default/time-mdk.png";
+
+my $ntpd = $timezone::ntp . 'd';
+my $ntpfile = '/etc/' . $timezone::ntp . '.conf';
+
+my $my_win = ugtk3->new(N("Date, Clock & Time Zone Settings"));
+
+$my_win->{window}->signal_connect(delete_event => sub { ugtk3->exit(0) });
+
+my $calendar = gtknew('Calendar');
+$calendar->signal_connect($_ => \&cal_changed) foreach 'month-changed', 'day-selected', 'day-selected-double-click', 'prev-month', 'next-month', 'prev-year', 'next-year';
+
+my $timezone = timezone::read();
+
+my $label_timezone = gtknew('Label', text => $timezone->{timezone} || N("not defined"));
+
+my $button_time = gtknew('Button', text => N("Change Time Zone"));
+my @timezones = eval { timezone::getTimeZones() };
+my $err = $@;
+$button_time->signal_connect(clicked => sub {
+ local $::isEmbedded = 0; # to prevent sub window embedding
+ if (my $tz = $in->ask_from_treelist(N("Timezone - DrakClock"), N("Which is your timezone?"), '/', \@timezones, $timezone->{timezone})) {
+ $timezone->{timezone} = $tz;
+ $timezone->{UTC} = $in->ask_yesorno(N("GMT - DrakClock"), N("Is your hardware clock set to GMT?"), $timezone->{UTC});
+ timezone::write($timezone);
+ $label_timezone->set_text($timezone->{timezone});
+ }
+ });
+if (!@timezones) {
+ warn "Failed to retrieve timezone list: $err\n";
+ $button_time->set_sensitive(0);
+}
+
+my $drawing_area;
+
+my $adjh = Gtk3::Adjustment->new(0.0, 0.0, 23.0, 1.0, 5.0, 0.0);
+my $adjm = Gtk3::Adjustment->new(0.0, 0.0, 59.0, 1.0, 5.0, 0.0);
+my $adjs = Gtk3::Adjustment->new(0.0, 0.0, 59.0, 1.0, 5.0, 0.0);
+
+my ($button_reset, $check_ntp, $hb_ntp, $combo_ntpserver, $ntp);
+my $mode = is_ntp_daemon_running();
+
+my (undef, undef, $h_old, $old_day, $old_month, $old_year) = localtime(time());
+
+my @image_size = (200, 200);
+
+$my_win->{window}->add(
+ gtknew('VBox', border_width => $::isEmbedded ? 0 : 5, children => [
+ 1, gtknew('HBox', children => [
+ 1, gtknew('VBox', children => [
+ 0, $calendar,
+ 1, gtknew('Frame', text => N("Network Time Protocol"), shadow_type => 'etched_in', child =>
+ gtknew('VBox', border_width => 5, children => [
+ 0, gtknew('Label', text => N("Your computer can synchronize its clock\n with a remote time server using NTP")),
+ 0, gtksignal_connect(gtkset_active($check_ntp = gtknew('CheckButton', text => N("Enable Network Time Protocol")), $mode), clicked => sub {
+ $mode = !$mode;
+ $hb_ntp->set_sensitive($mode);
+ if ($mode == 1 && !$in->do_pkgs->is_installed('ntp') && !$in->do_pkgs->is_installed('chrony')) {
+ install_ntp();
+ }
+ }),
+ 0, $hb_ntp = gtknew('HBox', border_width => 5, children => [
+ 0, gtknew('Label', text => N("Server:")),
+ 1, $combo_ntpserver = Gtk3::ComboBoxText->new
+ ])
+ ]))
+ ]),
+ 0, gtknew('VBox', children => [
+ 0, my $clock = gtknew('HBox', children => [
+ 0, $drawing_area = gtkset_size_request(Gtk3::DrawingArea->new, @image_size),
+ ]),
+ 0, my $time_box = gtknew('HBox', homogenous => 1, children => [
+ 0, my $spinner_h = Gtk3::SpinButton->new($adjh, 0, 0),
+ 0, my $spinner_m = Gtk3::SpinButton->new($adjm, 0, 0),
+ 0, my $spinner_s = Gtk3::SpinButton->new($adjs, 0, 0),
+ ]),
+ 1, gtknew('Frame', text => N("Timezone"), shadow_type => 'etched_in', child =>
+ gtknew('VBox', border_width => 5, children_tight => [
+ $label_timezone,
+ $button_time ])),
+ ]),
+ ]),
+ 0, create_okcancel(
+ my $w =
+ {
+ cancel_clicked => sub { ugtk3->exit(0) },
+ ok_clicked => sub {
+ my $need_date = 1;
+ any::disable_x_screensaver();
+ if ($check_ntp->get_active) {
+ my $choosed_serv = $combo_ntpserver->entry->get_text;
+ $choosed_serv =~ s/^[^:]+: (.+)/$1/;
+ if (!$choosed_serv) {
+ err_dialog(N("Error"), N("Please enter a valid NTP server address."));
+ return;
+ }
+ timezone::set_ntp_server($choosed_serv);
+ system('systemctl', 'enable', "$ntpd.service");
+ system('systemctl', 'stop', "$ntpd.service");
+ #verify that we have a valid hostname (thx sam)
+ $choosed_serv =~ s/[^-a-zA-Z0-9.]//g;
+ my $sync_ok;
+ if ($ntpd eq "chronyd") {
+ system('systemctl', 'start', "$ntpd.service");
+ # Wait up to 30s for sync
+ $sync_ok = !system('chronyc', 'waitsync', '30', '0.1');
+ system('systemctl', 'stop', "$ntpd.service") if !$sync_ok;
+ } else {
+ $sync_ok = !system('/usr/sbin/ntpd', '-gqc', '/dev/null', $choosed_serv);
+ system('systemctl', 'start', "$ntpd.service") if $sync_ok;
+ }
+ if ($sync_ok) {
+ update_time(); #- get the new time before updating the hwclock
+ $need_date = 0;
+ } else {
+ $in->ask_from_no_check({
+ title => N("Error"),
+ messages => N("Could not synchronize with %s.", $choosed_serv),
+ ok => N("Quit"),
+ cancel => N("Retry"),
+ }, []) or return;
+ }
+ } else {
+ if (is_ntp_daemon_running()) {
+ system('systemctl', 'stop', "$ntpd.service");
+ system('systemctl', 'disable', "$ntpd.service");
+ }
+ }
+ if ($need_date) {
+ my ($year, $month, $day) = $calendar->get_date;
+ $month++;
+ my ($hour, $min, $sec) = ($adjh->get_value, $adjm->get_value, $adjs->get_value);
+ system("date " .
+ join('', map { print_it0($_) } ($month, $day, $hour, $min, $year)) . '.' . print_it0($sec));
+ }
+ -e '/sbin/hwclock' and system('/sbin/hwclock', '--systohc');
+ any::enable_x_screensaver();
+ system(qw(dcop kicker Panel restart)) if $ENV{DESKTOP} eq 'kde';
+ ugtk3->exit(0);
+ },
+ },
+ undef, undef, '',
+ [ N("Reset"), sub {
+ $its_reset = 1;
+ $timer = Glib::Timeout->add(120, \&update_time);
+ Repaint(1);
+ $button_reset->set_sensitive(0);
+ $its_reset = 0;
+ } ]
+ ),
+ ])
+ );
+$button_reset = $w->{buttons}{N("Reset")};
+
+$time_box->set_direction('ltr');
+
+my $servers = get_server();
+$combo_ntpserver->set_popdown_strings(@$servers);
+if (-e $ntpfile && is_ntp_daemon_running()) {
+ $ntp = timezone::ntp_server();
+ $ntp and ntp_widget_state(1);
+ my $fullntp = $ntp;
+ my $short_ntp = $ntp;
+ #- strip digits from \d+.foo.pool.ntp.org
+ $short_ntp =~ s/^\d+\.//;
+ foreach (@$servers) {
+ /^[^:]+: \Q$short_ntp\E$/ and $fullntp = $_, last;
+ }
+ $combo_ntpserver->entry->set_text($fullntp);
+} else { ntp_widget_state(0) }
+
+my $pressed;
+$drawing_area->set_events(${ Gtk3::Gdk::EventMask->new([ 'button_press_mask', 'button_release_mask', "pointer_motion_mask" ]) });
+$drawing_area->signal_connect(draw => \&draw);
+
+$drawing_area->signal_connect(button_press_event => sub { $pressed = 1 });
+$drawing_area->signal_connect(button_release_event => sub { $first = 1; $pressed = 0 });
+$drawing_area->signal_connect(motion_notify_event => \&motion_event);
+
+$spinner_h->set_wrap(1);
+$spinner_h->signal_connect(activate => \&spinned);
+$spinner_h->signal_connect(button_release_event => \&spinned);
+$spinner_h->signal_connect(scroll_event => \&spinned);
+$spinner_h->signal_connect(changed => \&changed);
+
+$spinner_m->set_wrap(1);
+$spinner_m->signal_connect(activate => \&spinned);
+$spinner_m->signal_connect(scroll_event => \&spinned);
+$spinner_m->signal_connect(button_release_event => \&spinned);
+
+$spinner_s->set_wrap(1);
+$spinner_s->signal_connect(activate => \&spinned);
+$spinner_s->signal_connect(scroll_event => \&spinned);
+$spinner_s->signal_connect(button_release_event => \&spinned);
+
+gtkflush();
+
+my $is24 = $h_old > 12;
+$old_year += 1900;
+$calendar->select_month($old_month, $old_year);
+$calendar->select_day($old_day);
+$button_reset->set_sensitive(0);
+$timer = Glib::Timeout->add(120, \&update_time);
+
+$drawing_area->show;
+$my_win->{window}->show_all;
+$my_win->main;
+ugtk3->exit(0);
+
+sub ntp_widget_state {
+ my ($state) = @_;
+ $check_ntp->set_active($state);
+ $hb_ntp->set_sensitive($state);
+ $mode = $state;
+}
+sub install_ntp() {
+ $my_win->{window}->set_sensitive(0);
+ $in->do_pkgs->ensure_is_installed('chrony') or ntp_widget_state(0);
+ $my_win->{window}->set_sensitive(1);
+}
+sub is_ntp_daemon_running() {
+ !system("systemctl is-active $ntpd.service >/dev/null");
+}
+sub get_server() {
+ my $servs = timezone::ntp_servers();
+ [ map { "$servs->{$_}: $_" } sort { $servs->{$a} cmp $servs->{$b} || $a cmp $b } keys %$servs ];
+}
+sub update_time() {
+ my (undef, undef, undef, $mday, $mon, $year) = localtime(time());
+ return 1 if !$cairo;
+ $year += 1900;
+ my $old_its_reset = $its_reset;
+ $its_reset = 1;
+ $calendar->select_day($mday);
+ $calendar->select_month($mon, $year);
+ $its_reset = $old_its_reset;
+ Repaint(1);
+}
+
+sub cal_changed() {
+ if (!$its_reset && $timer) {
+ Glib::Source->remove($timer);
+ undef $timer;
+ }
+ $button_reset->set_sensitive(1);
+}
+
+sub changed() {
+ my $val = $adjh->get_value;
+ my $limit = ($is24 ? 18 : 6);
+ if (($limit > $val && $h_old > $limit && $h_old < ($is24 ? 24 : 12)) ||
+ ($limit < $val && $h_old < $limit && $val-$h_old != 12)) {
+ $is24 = !$is24;
+ }
+ $h_old = $val;
+}
+
+sub spinned() {
+ Glib::Source->remove($timer) if $timer;
+ undef $timer;
+ $button_reset->set_sensitive(1);
+ time_to_rad($adjs->get_value, $adjm->get_value, $adjh->get_value);
+ Repaint();
+ 0;
+}
+
+sub motion_event {
+ my ($widget, $event) = @_;
+ $pressed or return;
+ if ($first) {
+ Glib::Source->remove($timer) if $timer;
+ undef $timer;
+ $Radian = determine_radian($event->x, $event->y);
+ $button_reset->set_sensitive(1);
+ }
+
+ $$Radian = -atan2($event->x - $midx, $event->y - $midy) + $PI;
+
+ Repaint();
+ rad_to_time();
+ $first = 0;
+}
+
+sub determine_radian {
+ my ($x, $y) = @_;
+
+ my $res;
+ my $r;
+ foreach (\$dRadians_hour, \$dRadians_min, \$dRadians_sec) {
+ my $d = sqrt(($x - ($midx + 7/10 * $radius * sin($$_)))**2 + ($y - ($midy - 7/10 * $radius * cos($$_)))**2);
+ $res or $res = $d, $r = $_;
+ $d < $res and $res = $d, $r = $_;
+ }
+ $r;
+}
+
+sub draw {
+ my ($widget, $event) = @_;
+ $cairo = $event;
+ Repaint(undef, 1);
+ 0;
+}
+
+sub rad_to_time() {
+ $adjh->set_value(POSIX::floor($dRadians_hour * 6 / $PI) + ($is24 ? 12 : 0));
+ $adjm->set_value(POSIX::floor($dRadians_min*30/$PI));
+ $adjs->set_value(POSIX::floor($dRadians_sec*30/$PI));
+}
+
+sub time_to_rad {
+ my ($sec, $min, $hour) = @_;
+ $dRadians_hour = $hour % 12 * $PI / 6;
+ $dRadians_min = $min * $PI / 30;
+ $dRadians_sec = $sec * $PI / 30;
+ $adjh->set_value($hour);
+ $adjm->set_value($min);
+ $adjs->set_value($sec);
+}
+
+sub Repaint {
+ my ($o_update_time, $skip_redraw) = @_;
+ my ($sec, $min, $hour) = localtime(time());
+ time_to_rad($sec, $min, $hour) if $o_update_time;
+ ($midx, $midy) = ($drawing_area->get_allocated_width/2, $drawing_area->get_allocated_height/2);
+ $radius = ($midx < $midy ? $midx : $midy) - 10;
+ $drawing_area->set_margin_start($clock->get_allocated_width/2 - $midx);
+
+ $cairo->set_antialias('default');
+ DrawTicks();
+ DrawPoints();
+ DrawHour();
+ DrawMin();
+ DrawSec();
+ # Only redraw the clock if there are changes.
+ # This highly decreases the CPU usage.
+ $drawing_area->queue_draw unless $skip_redraw;
+ 1;
+}
+
+sub DrawSec() {
+ my $dRadians = $dRadians_sec;
+ $cairo->set_source_rgb(0.9, 0, 0);
+ $cairo->move_to($midx, $midy);
+ $cairo->line_to($midx + 85/100 * $radius * sin($dRadians), $midy - 85/100 * $radius * cos($dRadians));
+ $cairo->stroke;
+}
+
+sub DrawMin() {
+ my $dRadians = $dRadians_min;
+ $cairo->set_source_rgb(0.2, 0.2, 0.2);
+ $cairo->move_to($midx - 3/100 * $radius * sin($dRadians), $midy + 3/100 * $radius * cos($dRadians));
+ $cairo->line_to($midx - 3/100 * $radius * sin($dRadians+$PI/2), $midy + 3/100 * $radius * cos($dRadians+$PI/2));
+ $cairo->line_to($midx + 7/10 * $radius * sin($dRadians-0.03), $midy - 7/10 * $radius * cos($dRadians-0.03));
+ $cairo->line_to($midx + 8/10 * $radius * sin($dRadians), $midy - 8/10 * $radius * cos($dRadians));
+ $cairo->line_to($midx + 7/10 * $radius * sin($dRadians+0.03), $midy - 7/10 * $radius * cos($dRadians+0.03));
+ $cairo->line_to($midx + 3/100 * $radius * sin($dRadians+$PI/2), $midy - 3/100 * $radius * cos($dRadians+$PI/2));
+ $cairo->fill;
+}
+
+sub DrawHour() {
+ my $dRadians = $dRadians_hour + $dRadians_min / 12;
+ $cairo->set_source_rgb(0.2, 0.2, 0.2);
+ $cairo->move_to($midx - 4/100 * $radius * sin($dRadians), $midy + 4/100 * $radius * cos($dRadians));
+ $cairo->line_to($midx - 4/100 * $radius * sin($dRadians+$PI/2), $midy + 4/100 * $radius * cos($dRadians+$PI/2));
+ $cairo->line_to($midx + 5/10 * $radius * sin($dRadians-0.05), $midy - 5/10 * $radius * cos($dRadians-0.05));
+ $cairo->line_to($midx + 6/10 * $radius * sin($dRadians), $midy - 6/10 * $radius * cos($dRadians));
+ $cairo->line_to($midx + 5/10 * $radius * sin($dRadians+0.05), $midy - 5/10 * $radius * cos($dRadians+0.05));
+ $cairo->line_to($midx + 4/100 * $radius * sin($dRadians+$PI/2), $midy - 4/100 * $radius * cos($dRadians+$PI/2));
+ $cairo->fill;
+}
+
+sub DrawTicks() {
+ $cairo->set_source_rgb(1, 1, 1);
+ $cairo->new_sub_path;
+ $cairo->arc($midx, $midy, $radius, 0, 2 * $PI);
+ $cairo->fill_preserve;
+ $cairo->set_source_rgb(0, 0, 0);
+ $cairo->stroke;
+
+ foreach my $nHour (1..12) {
+ my $dRadians = $nHour * $PI / 6.0;
+ $cairo->move_to($midx + 9/10 * $radius * sin($dRadians),
+ $midy - 9/10 * $radius * cos($dRadians));
+ $cairo->line_to($midx + 1 * $radius * sin($dRadians),
+ $midy - 1 * $radius * cos($dRadians));
+ }
+ $cairo->stroke;
+}
+
+sub DrawPoints() {
+ $cairo->set_source_rgb(0, 0, 0);
+ foreach my $nMin (1..60) {
+ my $dRadians = $nMin * $PI / 30;
+ $cairo->move_to($midx + 95/100 * $radius * sin($dRadians), $midy - 95/100 * $radius * cos($dRadians));
+ $cairo->line_to($midx + 90/100 * $radius * sin($dRadians), $midy - 90/100 * $radius * cos($dRadians));
+ }
+ $cairo->stroke;
+}
+
+
+sub print_it0 { sprintf("%02d", $_[0]) }