| 1 |
10 |
dpavlin |
#!/usr/bin/perl -w #d |
| 2 |
4 |
dpavlin |
|
| 3 |
10 |
dpavlin |
# GUI front-end to jpegtran to rotate and flip jpegs without loss |
| 4 |
4 |
dpavlin |
# |
| 5 |
10 |
dpavlin |
# 2000-06-14 Dobrica Pavlinusic <dpavlin@rot13.org> |
| 6 |
4 |
dpavlin |
|
| 7 |
|
|
use Gtk; |
| 8 |
|
|
use strict; |
| 9 |
|
|
|
| 10 |
|
|
init Gtk; |
| 11 |
|
|
set_locale Gtk; |
| 12 |
|
|
|
| 13 |
10 |
dpavlin |
my $DEBUG = 1; |
| 14 |
|
|
sub pdebug { print STDERR @_,"\n" if ($DEBUG); } |
| 15 |
|
|
|
| 16 |
4 |
dpavlin |
my $false = 0; |
| 17 |
|
|
my $true = 1; |
| 18 |
|
|
|
| 19 |
10 |
dpavlin |
# $X[0](dir|filename|w|h|pix) |
| 20 |
|
|
my @X; |
| 21 |
4 |
dpavlin |
|
| 22 |
10 |
dpavlin |
my $xv_pic_dir=".xvpics"; |
| 23 |
|
|
#$xv_pic_dir="/mnt/f/tmp2/PICS/.xvpics" if ($DEBUG); |
| 24 |
4 |
dpavlin |
|
| 25 |
10 |
dpavlin |
if (! $ARGV[0] && !-d ".xvpics") { |
| 26 |
|
|
print "Usage: $0 [path to directory with pictures (in which is .xvpics dir)]\n"; |
| 27 |
|
|
exit 1; |
| 28 |
|
|
} |
| 29 |
4 |
dpavlin |
|
| 30 |
10 |
dpavlin |
$xv_pic_dir = $ARGV[0]."/.xvpics" if ($ARGV[0]); |
| 31 |
|
|
|
| 32 |
|
|
if (! -d $xv_pic_dir) { |
| 33 |
|
|
print "$xv_pic_dir is not directory!"; |
| 34 |
|
|
} |
| 35 |
|
|
|
| 36 |
|
|
#-------------------------------------------------------------------- |
| 37 |
|
|
# scan directory |
| 38 |
|
|
|
| 39 |
|
|
pdebug "reading dir $xv_pic_dir"; |
| 40 |
|
|
|
| 41 |
|
|
opendir(DIR, $xv_pic_dir) || die "can't opendir $xv_pic_dir: $!"; |
| 42 |
|
|
my @pic_filenames = grep { !/^\./ && -f "$xv_pic_dir/$_" } readdir(DIR); |
| 43 |
|
|
closedir(DIR); |
| 44 |
|
|
|
| 45 |
|
|
pdebug "found $#pic_filenames files in $xv_pic_dir"; |
| 46 |
|
|
|
| 47 |
|
|
my $dir=$xv_pic_dir; |
| 48 |
|
|
$dir=~s/\.xvpics//; |
| 49 |
|
|
|
| 50 |
|
|
foreach my $filename (@pic_filenames) { |
| 51 |
|
|
pdebug "gronk $filename"; |
| 52 |
|
|
my ($w,$h,$pix) = xvpic_read("$xv_pic_dir/$filename"); |
| 53 |
|
|
my (%tmp) = ( dir=>$dir, filename=>$filename, w=>$w, h=>$h, pix=>$pix ); |
| 54 |
|
|
push @X,\%tmp; |
| 55 |
|
|
} |
| 56 |
|
|
|
| 57 |
|
|
#-------------------------------------------------------------------- |
| 58 |
|
|
# read xvpic from disk |
| 59 |
|
|
# xvpic_read($filename) |
| 60 |
|
|
# returns: |
| 61 |
|
|
# ($w,$h,$xv_pix) |
| 62 |
|
|
|
| 63 |
|
|
sub xvpic_read { |
| 64 |
|
|
my ($xv_pic) = @_; |
| 65 |
|
|
|
| 66 |
|
|
my ($w,$h,$cols) = (0,0,0); |
| 67 |
|
|
|
| 68 |
|
|
open(XV,$xv_pic) || die "$xv_pic: $!"; |
| 69 |
|
|
my $l=<XV>; chomp $l; |
| 70 |
|
|
if ($l!~m/^P7 332$/) { |
| 71 |
|
|
warn "$xv_pic not XV thumbnail file ($l)"; |
| 72 |
|
|
return; |
| 73 |
4 |
dpavlin |
} |
| 74 |
10 |
dpavlin |
while(<XV>) { |
| 75 |
|
|
chomp; |
| 76 |
|
|
next if (/^#/); |
| 77 |
|
|
if (/^(\d+) (\d+) (\d+)$/) { |
| 78 |
|
|
($w,$h,$cols) = ($1,$2,$3); |
| 79 |
|
|
last; |
| 80 |
|
|
} |
| 81 |
|
|
warn "expected w,h,cols, got: $_"; |
| 82 |
|
|
} |
| 83 |
|
|
|
| 84 |
|
|
warn "$xv_pic number of colors is not 255 (strange)" if ($cols != 255); |
| 85 |
|
|
|
| 86 |
|
|
my $buf; # tmp buffer for read; |
| 87 |
|
|
|
| 88 |
|
|
# read pixels |
| 89 |
|
|
read XV,$buf,($w*$h); |
| 90 |
|
|
|
| 91 |
|
|
return ($w,$h,$buf); |
| 92 |
4 |
dpavlin |
} |
| 93 |
|
|
|
| 94 |
10 |
dpavlin |
#-------------------------------------------------------------------- |
| 95 |
|
|
# Generate 332 colour-cube colourmap |
| 96 |
4 |
dpavlin |
|
| 97 |
10 |
dpavlin |
sub generate_xpm_colmap { |
| 98 |
|
|
my @xpm_colmap; |
| 99 |
|
|
for (my $i=0; $i<256; $i++) { |
| 100 |
4 |
dpavlin |
|
| 101 |
10 |
dpavlin |
push(@xpm_colmap,sprintf ("%02x c #%02x%02x%02x",$i, |
| 102 |
|
|
(255*(($i&(7<<5))>>5))/7, |
| 103 |
|
|
(255*(($i&(7<<2))>>2))/7, |
| 104 |
|
|
(255*(($i&(3<<0))>>0))/3 |
| 105 |
|
|
)); |
| 106 |
|
|
} |
| 107 |
|
|
return @xpm_colmap; |
| 108 |
|
|
} |
| 109 |
4 |
dpavlin |
|
| 110 |
10 |
dpavlin |
#-------------------------------------------------------------------- |
| 111 |
|
|
# main |
| 112 |
|
|
|
| 113 |
|
|
my ($w,$h) = (0,0); |
| 114 |
|
|
my $xv_pix; |
| 115 |
|
|
my @xpm_colmap=generate_xpm_colmap(); |
| 116 |
|
|
|
| 117 |
|
|
#($w,$h,@xv_pix) = xvpic_read($xv_pic); |
| 118 |
|
|
my $xv_pic = $X[0]{filename}; |
| 119 |
|
|
$w = $X[0]{w}; |
| 120 |
|
|
$h = $X[0]{h}; |
| 121 |
|
|
$xv_pix = $X[0]{pix}; |
| 122 |
|
|
|
| 123 |
|
|
#-------------------------------------------------------------------- |
| 124 |
|
|
# make rotated pictures |
| 125 |
|
|
|
| 126 |
|
|
#sub make_rotated { |
| 127 |
|
|
# my ($w,$h,$xv_pix) |
| 128 |
|
|
|
| 129 |
4 |
dpavlin |
#/* width height ncolors chars_per_pixel */ |
| 130 |
10 |
dpavlin |
#my @xpm_0= ( "$w $h 256 2" ); |
| 131 |
4 |
dpavlin |
my @xpm_180= ( "$w $h 256 2" ); |
| 132 |
|
|
my @xpm_90= ( "$h $w 256 2" ); |
| 133 |
|
|
my @xpm_270= ( "$h $w 256 2" ); |
| 134 |
10 |
dpavlin |
my @xpm_h= ( "$w $h 256 2" ); |
| 135 |
|
|
my @xpm_v= ( "$w $h 256 2" ); |
| 136 |
4 |
dpavlin |
|
| 137 |
10 |
dpavlin |
#push @xpm_0,@xpm_colmap; |
| 138 |
4 |
dpavlin |
push @xpm_180,@xpm_colmap; |
| 139 |
|
|
push @xpm_90,@xpm_colmap; |
| 140 |
|
|
push @xpm_270,@xpm_colmap; |
| 141 |
10 |
dpavlin |
push @xpm_h,@xpm_colmap; |
| 142 |
|
|
push @xpm_v,@xpm_colmap; |
| 143 |
4 |
dpavlin |
|
| 144 |
|
|
my @pix_0; |
| 145 |
|
|
my @pix_180; |
| 146 |
|
|
my @pix_90; |
| 147 |
|
|
my @pix_270; |
| 148 |
10 |
dpavlin |
my @pix_h; |
| 149 |
|
|
my @pix_v; |
| 150 |
4 |
dpavlin |
|
| 151 |
10 |
dpavlin |
my @xv_pix=unpack("C*",$xv_pix); |
| 152 |
|
|
|
| 153 |
4 |
dpavlin |
for(my $y=0; $y<$h; $y++) { |
| 154 |
|
|
for (my $x=0; $x<$w; $x++) { |
| 155 |
|
|
if (defined($xv_pix[$y*$w+$x])) { |
| 156 |
|
|
$pix_0[$y*$w+$x] = sprintf("%02x",$xv_pix[$y*$w+$x]); |
| 157 |
10 |
dpavlin |
$pix_180[($h-$y-1)*$w+($w-$x-1)] = sprintf("%02x",$xv_pix[$y*$w+$x]); |
| 158 |
4 |
dpavlin |
$pix_270[($w-$x-1)*$h+$y] = sprintf("%02x",$xv_pix[$y*$w+$x]); |
| 159 |
|
|
$pix_90[$x*$h+$y] = sprintf("%02x",$xv_pix[$y*$w+$x]); |
| 160 |
10 |
dpavlin |
$pix_h[$y*$w+($w-$x-1)] = sprintf("%02x",$xv_pix[$y*$w+$x]); |
| 161 |
|
|
$pix_v[($h-$y-1)*$w+$x] = sprintf("%02x",$xv_pix[$y*$w+$x]); |
| 162 |
4 |
dpavlin |
} else { |
| 163 |
10 |
dpavlin |
warn "undef pixel $x,$y!\n"; |
| 164 |
4 |
dpavlin |
} |
| 165 |
|
|
} |
| 166 |
|
|
} |
| 167 |
|
|
|
| 168 |
|
|
|
| 169 |
|
|
# fill in pixels now |
| 170 |
|
|
|
| 171 |
|
|
my $tmp; |
| 172 |
|
|
|
| 173 |
|
|
# portrait |
| 174 |
|
|
my $lw=$w*2; |
| 175 |
10 |
dpavlin |
#$tmp=join('',@pix_0); while ($tmp=~s/^(.{$lw})//) { push(@xpm_0,$1); } |
| 176 |
4 |
dpavlin |
$tmp=join('',@pix_180); while ($tmp=~s/^(.{$lw})//) { push(@xpm_180,$1); } |
| 177 |
10 |
dpavlin |
$tmp=join('',@pix_v); while ($tmp=~s/^(.{$lw})//) { push(@xpm_v,$1); } |
| 178 |
|
|
$tmp=join('',@pix_h); while ($tmp=~s/^(.{$lw})//) { push(@xpm_h,$1); } |
| 179 |
4 |
dpavlin |
|
| 180 |
|
|
# landscape |
| 181 |
|
|
$lw=$h*2; |
| 182 |
|
|
$tmp=join('',@pix_90); while ($tmp=~s/^(.{$lw})//) { push(@xpm_90,$1); } |
| 183 |
|
|
$tmp=join('',@pix_270); while ($tmp=~s/^(.{$lw})//) { push(@xpm_270,$1); } |
| 184 |
|
|
|
| 185 |
10 |
dpavlin |
#-------------------------------------------------------------------- |
| 186 |
|
|
# GTK GUI |
| 187 |
|
|
|
| 188 |
4 |
dpavlin |
my $window; |
| 189 |
10 |
dpavlin |
my ($pixmapwid_0, $pixmapwid_180, $pixmapwid_90, $pixmapwid_270, $pixmapwid_v, $pixmapwid_h); |
| 190 |
|
|
my ($button_0, $button_180, $button_90, $button_270, $button_v, $button_h); |
| 191 |
|
|
my ($pixmap_0, $pixmap_180, $pixmap_90, $pixmap_270, $pixmap_v, $pixmap_h); |
| 192 |
4 |
dpavlin |
my $mask; |
| 193 |
|
|
my $style; |
| 194 |
|
|
|
| 195 |
|
|
$window = new Gtk::Window( "toplevel" ); |
| 196 |
|
|
$window->signal_connect( "delete_event", sub { Gtk->exit( 0 ); } ); |
| 197 |
|
|
$window->border_width( 10 ); |
| 198 |
10 |
dpavlin |
$window->set_title( "GTK jpegtran" ); |
| 199 |
|
|
$window->realize(); |
| 200 |
4 |
dpavlin |
|
| 201 |
|
|
# now for the pixmap from gdk |
| 202 |
|
|
$style = $window->get_style()->bg( 'normal' ); |
| 203 |
|
|
|
| 204 |
10 |
dpavlin |
#( $pixmap_0, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_0 ); |
| 205 |
|
|
# |
| 206 |
|
|
## a pixmap widget to contain the pixmap |
| 207 |
|
|
#$pixmapwid_0 = new Gtk::Pixmap( $pixmap_0, $mask ); |
| 208 |
|
|
#$pixmapwid_0->show(); |
| 209 |
|
|
# |
| 210 |
|
|
## a button to contain the pixmap widget |
| 211 |
|
|
#$button_0 = new Gtk::Button(); |
| 212 |
|
|
#$button_0->add( $pixmapwid_0 ); |
| 213 |
|
|
#$button_0->show(); |
| 214 |
|
|
##$button_0->signal_connect( "clicked", \&jpegtran, "-optimize" ); |
| 215 |
|
|
## make button_0 inactive |
| 216 |
|
|
#$button_0->set_sensitive( $false ); |
| 217 |
4 |
dpavlin |
|
| 218 |
|
|
# rotate 180 |
| 219 |
|
|
( $pixmap_180, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_180 ); |
| 220 |
|
|
|
| 221 |
|
|
$pixmapwid_180 = new Gtk::Pixmap( $pixmap_180, $mask ); |
| 222 |
|
|
$pixmapwid_180->show(); |
| 223 |
|
|
|
| 224 |
|
|
$button_180 = new Gtk::Button(); |
| 225 |
|
|
$button_180->add( $pixmapwid_180 ); |
| 226 |
|
|
$button_180->show(); |
| 227 |
10 |
dpavlin |
$button_180->signal_connect( "clicked", \&jpegtran, "-rotate 180" ); |
| 228 |
4 |
dpavlin |
|
| 229 |
|
|
# rotate 90 |
| 230 |
|
|
( $pixmap_90, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_90 ); |
| 231 |
|
|
$pixmapwid_90 = new Gtk::Pixmap( $pixmap_90, $mask ); |
| 232 |
|
|
$pixmapwid_90->show(); |
| 233 |
|
|
|
| 234 |
|
|
$button_90 = new Gtk::Button(); |
| 235 |
|
|
$button_90->add( $pixmapwid_90 ); |
| 236 |
|
|
$button_90->show(); |
| 237 |
10 |
dpavlin |
$button_90->signal_connect( "clicked", \&jpegtran, "-rotate 90" ); |
| 238 |
4 |
dpavlin |
|
| 239 |
|
|
# rotate 270 |
| 240 |
|
|
( $pixmap_270, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_270 ); |
| 241 |
|
|
$pixmapwid_270 = new Gtk::Pixmap( $pixmap_270, $mask ); |
| 242 |
|
|
$pixmapwid_270->show(); |
| 243 |
|
|
|
| 244 |
|
|
$button_270 = new Gtk::Button(); |
| 245 |
|
|
$button_270->add( $pixmapwid_270 ); |
| 246 |
|
|
$button_270->show(); |
| 247 |
10 |
dpavlin |
$button_270->signal_connect( "clicked", \&jpegtran, "-rotate 270" ); |
| 248 |
4 |
dpavlin |
|
| 249 |
10 |
dpavlin |
# rotate v |
| 250 |
|
|
( $pixmap_v, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_v ); |
| 251 |
|
|
$pixmapwid_v = new Gtk::Pixmap( $pixmap_v, $mask ); |
| 252 |
|
|
$pixmapwid_v->show(); |
| 253 |
|
|
|
| 254 |
|
|
$button_v = new Gtk::Button(); |
| 255 |
|
|
$button_v->add( $pixmapwid_v ); |
| 256 |
|
|
$button_v->show(); |
| 257 |
|
|
$button_v->signal_connect( "clicked", \&jpegtran, "-flip vertical" ); |
| 258 |
|
|
|
| 259 |
|
|
# rotate h |
| 260 |
|
|
( $pixmap_h, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_h ); |
| 261 |
|
|
$pixmapwid_h = new Gtk::Pixmap( $pixmap_h, $mask ); |
| 262 |
|
|
$pixmapwid_h->show(); |
| 263 |
|
|
|
| 264 |
|
|
$button_h = new Gtk::Button(); |
| 265 |
|
|
$button_h->add( $pixmapwid_h ); |
| 266 |
|
|
$button_h->show(); |
| 267 |
|
|
$button_h->signal_connect( "clicked", \&jpegtran, "-flip horizontal" ); |
| 268 |
|
|
|
| 269 |
4 |
dpavlin |
# pack, show, draw |
| 270 |
|
|
|
| 271 |
10 |
dpavlin |
my $hbox_top = new Gtk::HBox( $false, 0 ); |
| 272 |
|
|
my $hbox_mid = new Gtk::HBox( $true, 0 ); |
| 273 |
|
|
my $hbox_bot = new Gtk::HBox( $true, 0 ); |
| 274 |
4 |
dpavlin |
|
| 275 |
10 |
dpavlin |
|
| 276 |
|
|
#-------------------------------------------------------------------- |
| 277 |
|
|
# |
| 278 |
|
|
|
| 279 |
|
|
sub pix2xpm { |
| 280 |
|
|
my ($nr,$w,$h,$xv_pix) = @_; |
| 281 |
|
|
|
| 282 |
|
|
pdebug("pix2xpm w:$w h:$w pix:",length($xv_pix)); |
| 283 |
|
|
|
| 284 |
|
|
my @xpm=( "$w $h 256 2" ); |
| 285 |
|
|
push @xpm,@xpm_colmap; |
| 286 |
|
|
|
| 287 |
|
|
my @xv_pix=unpack("C*",$xv_pix); |
| 288 |
|
|
my $pix; |
| 289 |
|
|
|
| 290 |
|
|
for(my $i=0; $i<$#xv_pix; $i++) { |
| 291 |
|
|
$pix .= sprintf("%02x",$xv_pix[$i]); |
| 292 |
|
|
} |
| 293 |
|
|
my $lw=$w*2; |
| 294 |
|
|
while ($pix=~s/^(.{$lw})//) { push(@xpm,$1); } |
| 295 |
|
|
|
| 296 |
|
|
pdebug "pix2xpm retured ",length(join("",@xpm))," bytes, $#xpm lines"; |
| 297 |
|
|
return (\@xpm); |
| 298 |
|
|
} |
| 299 |
|
|
|
| 300 |
|
|
sub xpm_button { |
| 301 |
|
|
my ($nr) = @_; |
| 302 |
|
|
|
| 303 |
|
|
pdebug "xpm_button($nr): xpm/pix len: ", length $X[$nr]{xpm},"/",length $X[$nr]{pix}; |
| 304 |
|
|
|
| 305 |
|
|
( $X[$nr]{pixmap}, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @{$X[$nr]{xpm}} ); |
| 306 |
|
|
# ( $pixmap, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm( $window->window, $style, "test.xpm" ); |
| 307 |
|
|
$X[$nr]{pixmapwid} = new Gtk::Pixmap( $X[$nr]{pixmap}, $mask ); |
| 308 |
|
|
$X[$nr]{pixmapwid}->show(); |
| 309 |
|
|
|
| 310 |
|
|
$X[$nr]{button} = new Gtk::Button(); |
| 311 |
|
|
$X[$nr]{button}->add( $X[$nr]{pixmapwid} ); |
| 312 |
|
|
$X[$nr]{button}->show(); |
| 313 |
|
|
$X[$nr]{button}->signal_connect( "clicked", \&select_pic, $nr ); |
| 314 |
|
|
|
| 315 |
|
|
return ($X[$nr]{button}); |
| 316 |
|
|
} |
| 317 |
|
|
|
| 318 |
|
|
my $arr_l = create_arrow_button( 'left', 'in' ); |
| 319 |
|
|
$hbox_top->pack_start( $arr_l, $false, $false, 0 ); |
| 320 |
|
|
#$hbox_top->pack_start( $button_0, $false, $false, 0 ); |
| 321 |
|
|
|
| 322 |
|
|
|
| 323 |
|
|
for (my $i=0; $i<$#X; $i++) { |
| 324 |
|
|
#for (my $i=0; $i<0; $i++) { |
| 325 |
|
|
$X[$i]{xpm} = pix2xpm($i,$X[$i]{w},$X[$i]{h},$X[$i]{pix}); |
| 326 |
|
|
$X[$i]{button}=xpm_button($window, $i ); |
| 327 |
|
|
$hbox_top->pack_start( $X[$i]{button}, $false, $false, 0 ); |
| 328 |
|
|
} |
| 329 |
|
|
|
| 330 |
|
|
my $arr_r = create_arrow_button( 'right', 'in' ); |
| 331 |
|
|
$hbox_top->pack_start( $arr_r, $false, $false, 0 ); |
| 332 |
|
|
|
| 333 |
|
|
$hbox_mid->pack_start( $button_90, $false, $false, 0 ); |
| 334 |
|
|
$hbox_mid->pack_start( $button_180, $false, $false, 0 ); |
| 335 |
|
|
$hbox_mid->pack_start( $button_270, $false, $false, 0 ); |
| 336 |
|
|
|
| 337 |
|
|
$hbox_bot->pack_start( $button_v, $false, $false, 0 ); |
| 338 |
|
|
$hbox_bot->pack_start( $button_h, $false, $false, 0 ); |
| 339 |
|
|
|
| 340 |
|
|
$hbox_top->show(); |
| 341 |
|
|
$hbox_mid->show(); |
| 342 |
|
|
$hbox_bot->show(); |
| 343 |
|
|
|
| 344 |
|
|
sub create_arrow_button |
| 345 |
|
|
{ |
| 346 |
|
|
my ( $arrow_type, $shadow_type ) = @_; |
| 347 |
|
|
|
| 348 |
|
|
my $button; |
| 349 |
|
|
my $arrow; |
| 350 |
|
|
|
| 351 |
|
|
$button = new Gtk::Button(); |
| 352 |
|
|
$arrow = new Gtk::Arrow( $arrow_type, $shadow_type ); |
| 353 |
|
|
|
| 354 |
|
|
$button->add( $arrow ); |
| 355 |
|
|
$button->show(); |
| 356 |
|
|
$arrow->show(); |
| 357 |
|
|
|
| 358 |
|
|
return ( $button ); |
| 359 |
|
|
} |
| 360 |
|
|
|
| 361 |
|
|
|
| 362 |
|
|
my $hbox = new Gtk::HBox( $true, 0 ); |
| 363 |
|
|
my $filename_label = new Gtk::Label($xv_pic); |
| 364 |
|
|
$filename_label->show(); |
| 365 |
|
|
$hbox->pack_start( $filename_label, $false, $false, 0 ); |
| 366 |
4 |
dpavlin |
$hbox->show(); |
| 367 |
|
|
|
| 368 |
10 |
dpavlin |
my $hseparator = new Gtk::HSeparator(); |
| 369 |
|
|
$hseparator->show(); |
| 370 |
|
|
my $hseparator2 = new Gtk::HSeparator(); |
| 371 |
|
|
$hseparator2->show(); |
| 372 |
|
|
|
| 373 |
|
|
my $vbox = new Gtk::VBox( $false, 5 ); |
| 374 |
|
|
$vbox->pack_start( $hbox_top, $false, $false, 0 ); |
| 375 |
|
|
$vbox->pack_start( $hseparator, $false, $false, 0 ); |
| 376 |
|
|
$vbox->pack_start( $hbox, $false, $false, 0 ); |
| 377 |
|
|
$vbox->pack_start( $hseparator2, $false, $false, 0 ); |
| 378 |
|
|
$vbox->pack_start( $hbox_mid, $false, $false, 0 ); |
| 379 |
|
|
$vbox->pack_start( $hbox_bot, $false, $false, 0 ); |
| 380 |
|
|
$vbox->show(); |
| 381 |
|
|
|
| 382 |
|
|
$window->add($vbox); |
| 383 |
|
|
$window->show(); |
| 384 |
|
|
|
| 385 |
4 |
dpavlin |
main Gtk; |
| 386 |
|
|
exit( 0 ); |
| 387 |
|
|
|
| 388 |
10 |
dpavlin |
#-------------------------------------------------------------------- |
| 389 |
|
|
# call jpegtran command |
| 390 |
|
|
|
| 391 |
|
|
sub jpegtran { |
| 392 |
|
|
my ( $widget, $data ) = @_; |
| 393 |
|
|
print "jpegtran $data\n"; |
| 394 |
|
|
} |
| 395 |
|
|
|
| 396 |
|
|
#-------------------------------------------------------------------- |
| 397 |
|
|
# select picture |
| 398 |
|
|
|
| 399 |
|
|
sub select_pic { |
| 400 |
|
|
my ( $widget, $data ) = @_; |
| 401 |
|
|
my $xvpic=$X[$data]{filename}; |
| 402 |
|
|
print "picture selected: $data ($xvpic)\n"; |
| 403 |
|
|
$filename_label->set_text($xvpic); |
| 404 |
|
|
} |