#!/usr/bin/perl # # loST.pl-v0.04: # loST (logan's Shot Taker) is a simple Gtk-Perl app that will take a # (delayable) screenshot and make a small preview of it. # # Requirements: # Perl - http://www.perl.org/ --- tested with 5.6.1 # Gtk-Perl - http://www.gtkperl.org/ --- tested with 0.7008 # ImageMagick - http://www.imagemagick.org/ --- tested with 5.5.3 # # ChangeLog: # See the bottom of the script. # # Copyright (c) 2002 - 2003 Mike Hokenson # This application is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. use POSIX qw(:sys_wait_h _exit); use Gtk; use strict; my $false = 0; my $true = 1; # amount of time to wait before taking the screenshot. the spinner will default # to this value, so if you usually want to wait a few seconds... my $sleep_time = 0; # default path and filename: /home/buttercup/tmp/screenshot-1043115516.png # used YYYY-MM-DD before, but that could be annoying if you take a bunch of # screenshots in the same day (Cheetah ;)). my $screenshot = $ENV{'HOME'} . "/tmp/" . "screenshot-" . time . ".png"; # make a preview of the screenshot? my $make_prev = $true; # close the window after taking the screenshot? my $close_window = $true; # dimentions of the preview: 160x128, 320x256, etc: I can't seem to figure # out compression with png, the resulting preview is kindof large. :) my $prev_size = "160x128"; # take a screenshot of a selected window only my $window_only = $false; init Gtk; set_locale Gtk; my $window; my $vbox; my $hbox; my $frame; my $entry; my $adj; my $spinner; my $button; my $button_prev; my $tooltip; $window = new Gtk::Window("toplevel"); $window->set_title("loST (logan's Shot Taker)"); #$window->set_usize(350, 0); $window->border_width(5); $window->signal_connect("destroy", sub { Gtk->exit(0); }); $tooltip = new Gtk::Tooltips(); $vbox = new Gtk::VBox($false, 5); $window->add($vbox); $hbox = new Gtk::HBox($false, 5); $vbox->add($hbox); $frame = new Gtk::Frame("Screenshot:"); $frame->set_shadow_type("none"); $entry = new Gtk::Entry(1024); $entry->set_usize(275, 0); $entry->signal_connect("activate", \&do_screenshot); $entry->set_text($screenshot); $entry->select_region(0, length($screenshot)); #$entry->set_position(length($screenshot)); $frame->add($entry); $tooltip->set_tip($entry, "Location of screenshot.", ""); $hbox->add($frame); $entry->grab_focus(); $frame = new Gtk::Frame("Sleep:"); $frame->set_shadow_type("none"); $adj = new Gtk::Adjustment($sleep_time, 0, 60, 1, 15, 0); $spinner = new Gtk::SpinButton($adj, 0, 0); $spinner->set_wrap($true); $spinner->set_shadow_type("in"); $spinner->set_sensitive(!($window_only)); $adj->signal_connect("value_changed", \&sleep_spinner_changed, $spinner); $frame->add($spinner); $tooltip->set_tip($spinner, "Amount of time to wait before taking the screenshot.", ""); $hbox->add($frame); $frame = new Gtk::Frame(""); $frame->set_shadow_type("none"); $button_prev = new Gtk::CheckButton("Preview"); $button_prev->set_active(($make_prev == $true)); $button_prev->set_sensitive(!($window_only)); $button_prev->signal_connect("clicked", \&preview_toggled); $frame->add($button_prev); $tooltip->set_tip($button_prev, "Create a preview of the screenshot.", ""); $hbox->add($frame); $frame = new Gtk::Frame(""); $frame->set_shadow_type("none"); $button = new Gtk::CheckButton("Window"); $button->set_active(($window_only == $true)); $button->signal_connect("clicked", \&window_toggled); $frame->add($button); $tooltip->set_tip($button, "Take a screenshot of a selected window only.", ""); $hbox->add($frame); $frame = new Gtk::Frame(""); $frame->set_shadow_type("none"); $button = new Gtk::CheckButton("Close"); $button->set_active(($close_window == $true)); $button->signal_connect("clicked", \&close_toggled); $frame->add($button); $tooltip->set_tip($button, "Close before taking the screenshot.", ""); $hbox->add($frame); $hbox = new Gtk::HBox($true, 5); $vbox->add($hbox); $button = new Gtk::Button("Go"); $button->signal_connect("clicked", sub { do_screenshot($entry); }); $button->can_focus($false); $hbox->add($button); $button = new Gtk::Button("Cancel"); $button->signal_connect("clicked", sub { $window->destroy; }); $button->can_focus($false); $hbox->add($button); $window->show_all(); main Gtk; exit(0); sub sleep_spinner_changed { my ($adj, $spinner) = @_; $sleep_time = $spinner->get_value_as_int(); } sub preview_toggled { my $button = $_[0]; $make_prev = $button->active; $entry->grab_focus(); } sub window_toggled { my $button = $_[0]; my $file = $entry->get_chars; $window_only = $button->active; $spinner->set_sensitive(!($window_only)); $button_prev->set_sensitive(!($window_only)); my ($name, $ext) = split_name($file); if($window_only == $true) { $name .= "_window" . $ext; } else { $name =~ s/_window$//; $name .= $ext; } $entry->set_text($name); $entry->select_region(0, length($name)); $entry->grab_focus(); } sub close_toggled { my $button = $_[0]; $close_window = $button->active; $entry->grab_focus(); } sub split_name { my $file = $_[0]; return(undef, undef) unless(defined($file) && length($file)); my $index; $index = index($file, ".") if(($index = rindex($file, ".")) == -1); my $base = substr($file, 0, $index); my $type = substr($file, $index); return($base, $type); } sub do_screenshot { my $entry = $_[0]; my $file = $entry->get_chars; return unless($file); my $pid = fork(); die("fork: $!\n") if($pid < 0); if($pid == 0) { sleep($sleep_time); my $import; if($window_only) { $make_prev = $false; $import = "import"; } else { $import = "import -window root"; } open(IMPORT, "| $import $file") || die("open: import: $!\n"); close(IMPORT); _exit(0) unless($make_prev == $true); my ($prev, $ext) = split_name($file); $prev .= "_preview" . $ext; my $geom = Gtk::Gdk->screen_width() . "x" . Gtk::Gdk->screen_height(); my $conv = "convert -size $geom $file -resize $prev_size $prev"; open(CONVERT, "| $conv") || die("open: convert: $!\n"); close(CONVERT); _exit(0); } else { waitpid(-1, WNOHANG); } $window->destroy if($close_window == $true); } # --- ChangeLog --------------------------------------------------------------- # # 0.01 - 1/20/2003: # initial release. # # 0.02 - 1/20/2003: # added the ability to take a shot of a selected window only. # removed strftime in favor of 'time()' as part of the filename. # # 0.03 - 1/31/2003: # added the ability to toggle closing loST before taking the screenshot. # this would be useful if you want to take a bunch of screenshots for # a particular application. the screenshot name will NOT automatically # change when this is used, it's up to you to change it. # changed exit() to _exit() and added waitpid(). # # 0.04 - 2/7/2003: # minor changes to fork() related code. # # --- ChangeLog ---------------------------------------------------------------