This snippet gives a general purpose example of how to 'blit' an icon to a point on the screen, in a low level manner. The Gtk2::Gdk::Window is the actual window on the screen after it is mapped. If you create one of these images, it will dissapear if the window is resized, or unmapped in any way. I suppose it could be useful for creating temporary markers on an image, etc. Not really useful, but educational if you want to understand the difference between the window as the X server sees it, and the Gtk2 program's window, and it shows how to include a base64 encoded image in a script.
#!/usr/bin/perl use warnings; use strict; use Glib qw/TRUE FALSE/; use Gtk2 '-init'; use MIME::Base64; my @rectangles; #global for storing icon locations my $window = Gtk2::Window->new('toplevel'); $window->set_title('Embed test'); $window ->signal_connect( 'destroy' => \&delete_event ); $window->set_border_width(10); $window->set_default_size(500,430); my $vbox = Gtk2::VBox->new( FALSE, 6 ); $window->add($vbox); $vbox->set_border_width(2); my $hbox= Gtk2::HBox->new( FALSE, 6 ); $vbox->pack_end($hbox,FALSE,FALSE,0); $hbox->set_border_width(2); $hbox->set_size_request(500,48); $vbox->pack_end (Gtk2::HSeparator->new, FALSE, FALSE, 0); my $button = Gtk2::Button->new_from_stock('gtk-quit'); $hbox->pack_end( $button, FALSE, FALSE, 0 ); $button->signal_connect( clicked => \&delete_event ); my $button1 = Gtk2::Button->new('Set BG'); $hbox->pack_end( $button1, FALSE, FALSE, 0 ); $button1->signal_connect( clicked => \&set_bg,'single'); my $button2 = Gtk2::Button->new('Set BGauto'); $hbox->pack_end( $button2, FALSE, FALSE, 0 ); $button2->signal_connect( clicked => \&set_bg,'auto' ); my $button0 = Gtk2::Button->new('Clear'); $hbox->pack_end( $button0, FALSE, FALSE, 0 ); $button0->signal_connect( clicked => \&set_clear ); my $vbox1 = Gtk2::VBox->new( 0, 5 ); $vbox->pack_end ($vbox1, TRUE, TRUE, 0); my $btn = Gtk2::Button->new_from_stock('gtk-quit'); $btn->signal_connect( 'clicked' => \&delete_event ); $window->show_all(); Gtk2->main; ##################################### sub delete_event { Gtk2->main_quit; return FALSE; } ############################################################### sub set_clear{ my $gdkwindow = $window->window; foreach my $rectangle(@rectangles){ $gdkwindow->invalidate_rect ($rectangle,0); } @rectangles = (); return FALSE; } ################################################################# sub set_bg{ my ($caller,$mode) = @_; print "mode->$mode\n"; my $bunny = get_bunny(); # this properly renders it my $pixbuf = do { my $loader = Gtk2::Gdk::PixbufLoader->new(); $loader->write( $bunny ); $loader->close(); $loader->get_pixbuf(); }; my ($x, $y) = ($pixbuf->get_width, $pixbuf->get_height); #print "$x $y\n"; #print 'rowstride->', $pixbuf->get_rowstride,"\n"; #set the new pixbuff in the window #the gdkwindow is the actual window on the screen my $gdkwindow = $window->window; #the gdkwindow children are buttons, not the packing boxes #the gdk window is the actual paintable surface on the screen, # the children are areas of different painting, so the packing #boxes are not gdk children, but the buttons are. my @clist = $gdkwindow->get_children; #print "@clist\n"; my $gdkwindowC = $clist[0]; #the first button is the exit my ($x0, $y0, $width0, $height0, $depth) = $gdkwindowC->get_geometry; print "geometry x0->$x0, y0->$y0, width->$width0, height->$height0, de +pth->$depth\n"; my ($drawable, $x_offset, $y_offset) = $gdkwindowC->get_internal_paint +_info; print "drawable->$drawable, x_offset->$x_offset, y_offset->$y_offset\n +\n"; my $gc = Gtk2::Gdk::GC->new ($gdkwindow, undef); #$pixbuf->render_to_drawable ($drawable, $gc, # $src_x, $src_y, $dest_x, $dest_y, $width, $height, $dither, $x_dit +her, $y_dither) if($mode eq 'single'){ $pixbuf->render_to_drawable($gdkwindow, $gc, 0,0,$x0,$y0,$x,$y,'normal',0,0); my $rectangle = Gtk2::Gdk::Rectangle->new ($x0, $y0, $x, $y); push @rectangles, $rectangle; }else{ for(1..10){ my $x1 = int rand $x0; my $y1 = int rand $y0; $pixbuf->render_to_drawable($gdkwindow, $gc, 0,0,$x1,$y1,$x,$y,'normal',0,0); my $rectangle = Gtk2::Gdk::Rectangle->new ($x1, $y1, $x, $y); push @rectangles, $rectangle; } } Gtk2->main_iteration while Gtk2->events_pending; return FALSE; } ################################################################# sub get_bunny{ return decode_base64( 'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAABmJLR0QA/wD/AP+gvaeTA +AAACXBI WXMAAAsSAAALEgHS3X78AAAAmElEQVRYw+1WQQ7AIAizxP9/mV121Gm0BZfYxNukKxSwlI +Pg75HG MrGALkykfHjPBKmf+tbIAad/0Ngp3CHGIrnvEoco7xFDTf6lGMIeH6YaBNVYrTEUKYfYUG +DW0bOI t2qrTjVYNXa2f9SDAqt97I1AlMFST9pOIbjEYRuKsSS4fUZydcqSQOTzVubq/w+QmmVWtm +IvFx08 tNghLUXwK/sAAAAASUVORK5CYII='); }