On Tue, 04 Sep 2007 16:42:22 +1000 Andrew Cowie <andrew@xxxxxxxxxxxxxxxxxxxxxxx> wrote: >We all "know" that some GtkWidgets have their own GdkWindows (ie >GtkButtons), and some do not (ie GtkLabels). At least, that's what the >documentation tells us. > >As I understand it, for GtkWidget* widget, > > widget->window > >is this GdkWindow*, if so assigned. > >++ > >I was working on writing a method to expose this in the Java bindings, >and was somewhat surprised to find that all the Widgets in my little >test app had the _same_ GdkWindow. Huh? >I really would have expected the GtkButton and GtkLabel to have >different GdkWindows. According to this, they're all writing to the same >one. > >{shrug} > >This is not a problem; I'm just not sure how to explain it (and in turn >document our binding of GdkWindow). My guess is either a) my app is too >simple, or b) GTK is doing something smart under the hood and the >original Xlib <-> GDK wrapping has long been superseded, perhaps by the >Cairo drawing layer. > >Have things evolved from when the original API documentation was >written, or am I just doing something really silly? Hi, I usually do Perl, and don't have time to convert this to c, but here is way to locate and change buttons. Even though they are all in the same window, you can get the children of the window, and write to their "paintable areas". #!/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, depth->$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_dither, $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+gvaeTAAAACXBI WXMAAAsSAAALEgHS3X78AAAAmElEQVRYw+1WQQ7AIAizxP9/mV121Gm0BZfYxNukKxSwlIPg75HG MrGALkykfHjPBKmf+tbIAad/0Ngp3CHGIrnvEoco7xFDTf6lGMIeH6YaBNVYrTEUKYfYUGDW0bOI t2qrTjVYNXa2f9SDAqt97I1AlMFST9pOIbjEYRuKsSS4fUZydcqSQOTzVubq/w+QmmVWtmIvFx08 tNghLUXwK/sAAAAASUVORK5CYII='); } __END__ zentara -- I'm not really a human, but I play one on earth. http://zentara.net/japh.html _______________________________________________ gtk-list mailing list gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list