php-gtk2 ends with an error under linux
| From: | xxoes | Date: | Mon, 13 Feb 2006 07:55:19 +0000 |
| Subject: | php-gtk2 ends with an error under linux | ||
| Groups: | php.gtk.dev | ||
| Request: | Send a blank email to php-gtk-dev+get-2407@lists.php.net to get a copy of this message | ||
This application run perfect under win2k || winXP but not linux
The Application is a little bit complex,
the error happened on $this->pixmaps->draw_rectangle
and the message is:
This probably reflects a bug in the program.
The error was 'BadMatch (invalid parameter attributes)'.
(Details: serial 173 error_code 8 request_code 70 minor_code 0)
(Note to programmers: normally, X errors are reported asynchronously;
that is, you will receive the error a while after causing it.
To debug your program, run it with the --sync command line
option to change this behavior. You can then get a meaningful
backtrace from your debugger if you break on the gdk_x_error() function.)
When i comment out "$this->pixmaps->draw_rectangle" the app is working a time long.
The first part is only for debuging:
<?PHP
dl("php_gtk2.so");
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush(1);
function ticks() {
$res = debug_backtrace();
if(@isset($res[1]))
$cur = $res[1];
else
$cur = $res[0];
if(!@isset($cur["file"]) || !@isset($cur["line"])) {
$cur["file"] = "??? ".$res[0]["file"];
$cur["line"] = "??? ".$res[0]["line"];
}
else {
$cur["line"] .= " => ".$res[0]["line"];
}
echo $cur["file"]."(".$cur["line"].")";
if(@isset($cur["class"])) {
echo $cur["class"].$cur["type"].$cur["function"]."(";
$args = "";
for($i=0;$i<count($cur["args"]);$i++) {
if($args != "") $args .= ",";
if(is_string($cur["args"][$i]))
$args .= "\"".addslashes($cur["args"][$i])."\"";
else if(is_object($cur["args"][$i]))
$args .= "(object)".get_class($cur["args"][$i]);
else
$args .= $cur["args"][$i];
}
echo $args.")";
}
else if($cur["function"] != "ticks") {
echo $cur["function"];
}
while(gtk::events_pending()) {gtk::main_iteration_do(1);}
echo "\r\n";
/*
for($i=0;$i<count($res);$i++) {
unset($res[$i]["object"]);
unset($res[$i]["args"]);
}
print_r($res);
*/
}
register_tick_function("ticks");
declare(ticks=1);
?>
Thats the application:
<?PHP
error_reporting(E_ALL | E_STRICT);
$break_loop = 0;
$tex_data = array();
class Fun extends GtkWindow {
protected $da;
protected $pixmap;
protected $pixmaps;
protected $gc;
protected $cmap;
protected $width;
protected $height;
protected $mx;
protected $my;
protected $mx_free;
protected $my_free;
protected $done;
protected $zoom = 2;
public $tex_data;
function __construct($parent = null) {
parent::__construct();
$this->width = (int)(gdk::screen_width()/$this->zoom);
$this->height = (int)(gdk::screen_height()/$this->zoom);
$this->connect_simple('destroy', array(&$this, 'quit'));
$this->set_title("Fun");
$this->set_position(Gtk::WIN_POS_NONE);
$this->set_default_size($this->width*$this->zoom, $this->height*$this->zoom);
$this->set_border_width(0);
$this->set_resizable(0);
$this->set_decorated(0);
$this->set_skip_taskbar_hint(1);
$this->set_skip_pager_hint(1);
$this->set_modal(1);
$this->__create_da();
$this->show_all();
$this->set_keep_above(1);
$this->set_uposition(0,0);
mt_srand((double)microtime());
$this->TexReset();
// gtk::timeout_add(1,array(&$this,"timer"));
}
function __create_da() {
$this->da = new GtkDrawingArea();
$this->da->set_size_request($this->width*$this->zoom, $this->height*$this->zoom);
$this->add($this->da);
$this->da->realize();
$this->da->connect('configure-event', array(&$this, 'configure_event'));
$this->da->connect('expose-event', array(&$this,'draw_it'));
$this->da->add_events(Gdk::POINTER_MOTION_MASK);
$this->da->connect('motion-notify-event', array(&$this, 'motion_notify_event'));
}
function gen_shape() {
// $this->shape_combine_mask($this->pixmaps,0,0);
}
function motion_notify_event($widget, $event) {
static $mouse = 0;
$mouse++;
if($mouse >= 2) {
global $break_loop;
// $break_loop = 1;
}
$max = 10;
$window = $event->window;
$x = (int)((int)$event->x_root/2)*2;
$y = (int)($event->y_root/2)*2;
$x = (int)($x/$this->zoom);
$y = (int)($y/$this->zoom);
$change = 0;
for($xi=$x-$max;$xi<$x+$max;$xi++) {
if($xi < 0 || $xi >= $this->width) continue;
for($yi=$y-$max;$yi<$y+$max;$yi++) {
if($yi < 0 || $yi >= $this->height) continue;
if(@isset($this->tex_data[$xi][$yi])) {
unset($this->tex_data[$xi][$yi]);
$this->pixmap->draw_rectangle($this->style->white_gc,
true, $xi*$this->zoom, $yi*$this->zoom,
$this->zoom,
$this->zoom);
// Here is an BUG ????
$this->pixmaps->draw_rectangle($this->style->black_gc,
true, $xi*$this->zoom, $yi*$this->zoom,
$this->zoom,
$this->zoom);
$change++;
}
}
}
if($change) {
$this->da->queue_draw_area($x-$max, $y-$max, $max*2, $max*2);
$this->gen_shape();
}
return(true);
}
function quit() {
global $break_loop;
echo "destroy <br />\r\n";
$this->destroy();
$break_loop = 1;
gtk::main_quit();
}
function configure_event($widget, $event) {
$this->pixmap = new GdkPixmap($widget->window,
$this->width*$this->zoom,
$this->height*$this->zoom,
-1);
$this->pixmaps = new GdkPixmap($widget->window,
$this->width*$this->zoom,
$this->height*$this->zoom,
1);
$this->pixmap->draw_rectangle($widget->style->white_gc,
true, 0, 0,
$this->width*$this->zoom,
$this->height*$this->zoom);
$this->gc = new GdkGc($this->da->window);
$this->cmap = $this->da->get_colormap();
return true;
}
function draw_it($widget, $event) {
$gc = new GdkGC($widget->window);
// BUG ???? PHP crashed with $widget->style->fg_gc
// $widget->window->draw_drawable($widget->style->fg_gc[$widget->state],
$widget->window->draw_drawable($gc,
$this->pixmap,
$event->area->x, $event->area->y,
$event->area->x, $event->area->y,
$event->area->width, $event->area->height);
return false;
}
function do_loop() {
// while(gtk::events_pending()) {gtk::main_iteration_do(0);}
}
function TexReset() {
global $tex_data;
$width = $this->width;
$height = $this->height;
$this->mx=(int)(rand()%($width/2))*2; // Pick A New Random X Position
$this->my=(int)(rand()%($height/2))*2; // Pick A New Random Y Position
$this->pixmap->draw_rectangle($this->style->white_gc,
true, 0, 0,
$this->width*$this->zoom,
$this->height*$this->zoom);
// Here is an BUG ????
$this->pixmaps->draw_rectangle($this->style->black_gc,
true, 0, 0,
$this->width*$this->zoom,
$this->height*$this->zoom);
if(count($tex_data) > 0) {
reset($tex_data);
while(list($key_x) = each($tex_data)) {
if($key_x >= $width) continue;
ksort($tex_data[$key_x]);
reset($tex_data[$key_x]);
while(list($key_y) = each($tex_data[$key_x])) {
if($key_y >= $height) continue;
$this->TexUpdate($key_x,$key_y);
}
$this->gen_shape();
$this->do_loop();
}
$this->gen_shape();
$this->do_loop();
}
else {
$this->tex_data = array();
}
$this->done = false;
}
function TexUpdate($dmx,$dmy) { // Update Pixel dmx, dmy On The Texture
$dmx = (int)$dmx;
$dmy = (int)$dmy;
if($dmx >= $this->width || $dmy >= $this->height) return;
$this->tex($dmx,$dmy,255); // Set Red Pixel To Full Bright
$dmx = $dmx*$this->zoom;
$dmy = $dmy*$this->zoom;
static $i_color = 0;
$i_color++;
if($i_color >= 256) $i_color = 0;
$i_color = mt_rand(0,255);
$color = $i_color*$i_color*$i_color;
$r = $color&255;
$g = ($color&65280)>>8;
$b = ($color&16711680)>>16;
// $gc = $this->style->black_gc;
$this->gc->set_foreground($this->cmap->alloc_color($r*256, $g*256, $b*256));
$gc = $this->gc;
$this->pixmap->draw_rectangle($gc,
true, $dmx, $dmy,
$this->zoom,
$this->zoom);
// Here is an BUG ????
$this->pixmaps->draw_rectangle($this->style->white_gc,
true, $dmx, $dmy,
$this->zoom,
$this->zoom);
$this->da->queue_draw_area($dmx, $dmy, $dmx+5, $dmy+5);
}
function tex($dmx,$dmy,$val = -1) {
if($val != -1) {
$this->tex_data[$dmx][$dmy]=$val;
}
if(@isset($this->tex_data[$dmx][$dmy]))
return($this->tex_data[$dmx][$dmy]);
else
return(0);
}
function TexMake() {
global $break_loop;
$width = $this->width;
$height = $this->height;
$mx = &$this->mx;
$my = &$this->my;
$tex_data = &$this->tex_data;
if($this->done) {
$this->TexReset();
}
// Check To Make Sure We Are Not Trapped (Nowhere Else To Move)
/*
if((($mx>($width-4) || $this->tex($mx+2,$my)==255)) &&
(($mx<2 || $this->tex($mx-2,$my)==255)) &&
(($my>($height-4) || $this->tex($mx,$my+2)==255)) &&
(($my<2 || $this->tex($mx,$my-2)==255))) {
do { // If We Are Trapped
$mx=(int)(rand()%($width/2))*2; // Pick A New Random X Position
$my=(int)(rand()%($height/2))*2; // Pick A New Random Y Position
$this->do_loop();
} while(!$break_loop && $this->tex($mx,$my)==0); // Keep Picking A Random Position Until We Find
} // One That Has Already Been Tagged (Safe Starting Point)
*/
static $no_found = 0;
{
$dir=(int)mt_rand(1,8)%4; // Pick A Random Direction
if(($dir==0) && ($mx<=($width-4))) { // If The Direction Is 0 (Right) And We Are Not At The Far Right
if($this->tex($mx+2,$my)==0) { // And If The Room To The Right Has Not Already Been Visited
$this->TexUpdate($mx+1,$my); // Update The Texture To Show Path Cut Out Between Rooms
$mx+=2; // Move To The Right (Room To The Right)
$no_found = 0;
}
else {
$no_found++;
}
}
else if(($dir==1) && ($my<=($height-4))) { // If The Direction Is 1 (Down) And We Are Not At The Bottom
if($this->tex($mx,$my+2)==0) { // And If The Room Below Has Not Already Been Visited
$this->TexUpdate($mx,$my+1); // Update The Texture To Show Path Cut Out Between Rooms
$my+=2; // Move Down (Room Below)
$no_found = 0;
}
else {
$no_found++;
}
}
else if(($dir==2) && ($mx>=2)) { // If The Direction Is 2 (Left) And We Are Not At The Far Left
if($this->tex($mx-2,$my)==0) { // And If The Room To The Left Has Not Already Been Visited
$this->TexUpdate($mx-1,$my); // Update The Texture To Show Path Cut Out Between Rooms
$mx-=2; // Move To The Left (Room To The Left)
$no_found = 0;
}
else {
$no_found++;
}
}
else if(($dir==3) && ($my>=2)) { // If The Direction Is 3 (Up) And We Are Not At The Top
if($this->tex($mx,$my-2)==0) { // And If The Room Above Has Not Already Been Visited
$this->TexUpdate($mx,$my-1); // Update The Texture To Show Path Cut Out Between Rooms
$my-=2; // Move Up (Room Above)
$no_found = 0;
}
else {
$no_found++;
}
}
if($no_found >= 20) {
$i = 0;
$no_found = 0;
while(!$break_loop && $this->tex($mx,$my)==255) { // If We Are Trapped
$i++;
/*
$mx=(int)(rand()%($width/2))*2; // Pick A New Random X Position
$my=(int)(rand()%($height/2))*2; // Pick A New Random Y Position
*/
if($i > 100 && !($i%1000)) {
if(!($i%1000)) {
if($this->get_done()) {
return;
}
$this->mx = $this->mx_free;
$this->my = $this->my_free;
break;
}
}
}; // Keep Picking A Random Position Until We Find
}
}
$this->TexUpdate($mx,$my);
$this->gen_shape();
}
function get_done_A() {
for($x=$this->mx;$x<$this->width;$x+=2) { // Loop Through All The Rooms
for($y=$this->my;$y<$this->height;$y+=2) { // On X And Y Axis
if($this->tex($x,$y)==0) { // If Current Texture Pixel (Room) Is Blank
$this->mx_free = $x;
$this->my_free = $y;
return(false); // We Have To Set done To False (Not Finished Yet)
}
}
}
return(true);
}
function get_done_B() {
for($x=$this->mx-2;$x>=0;$x-=2) { // Loop Through All The Rooms
for($y=$this->my-2;$y>=0;$y-=2) { // On X And Y Axis
if($this->tex($x,$y)==0) { // If Current Texture Pixel (Room) Is Blank
$this->mx_free = $x;
$this->my_free = $y;
return(false); // We Have To Set done To False (Not Finished Yet)
}
}
}
return(true);
}
function get_done_C() {
for($x=0;$x<$this->width;$x+=2) { // Loop Through All The Rooms
for($y=0;$y<$this->height;$y+=2) { // On X And Y Axis
if($this->tex($x,$y)==0) { // If Current Texture Pixel (Room) Is Blank
$this->mx_free = $x;
$this->my_free = $y;
return(false); // We Have To Set done To False (Not Finished Yet)
}
}
}
return(true);
}
function get_done() {
static $c = 0;
if(!$c) {
$c = 1;
if($this->get_done_A() && $this->get_done_B() && $this->get_done_C()) {
$this->done = true;
return(true);
}
}
else {
$c = 0;
if($this->get_done_B() && $this->get_done_A() && $this->get_done_C()) {
$this->done = true;
return(true);
}
}
return(false);
}
};
$fun = new Fun();
while(!$break_loop) {
$fun->do_loop();
if(!$break_loop) {
$fun->TexMake();
}
}
?>
(sorry for my english ;))
mfg xxoes