1<?php 2 3/* 4 * haiku.php - an online Haiku demo using qemu and vnc. 5 * 6 * Copyright 2007-2010, Francois Revol, revol@free.fr. 7 * Distributed under the terms of the MIT License. 8 */ 9 10// parts inspired by the Free Live OS Zoo 11// http://www.oszoo.org/wiki/index.php/Free_Live_OS_Zoo 12 13 14// include local configuration that possibly overrides defines below. 15if (file_exists('haiku.conf.php')) 16 include('haiku.conf.php'); 17 18 19// name of the page 20define("PAGE_TITLE", "Haiku Online Demo"); 21 22 23// relative path to the vnc java applet jar 24// you must *copy* (apache doesn't seem to like symlinks) it there. 25 26// on debian, apt-get install vnc-java will put them in 27// /usr/share/vnc-java 28//define("VNCJAVA_PATH", "vnc-java"); 29//define("VNCJAR", "vncviewer.jar"); 30//define("VNCCLASS", "vncviewer.class"); 31 32// to use the tightvnc applet instead (supports > 8bpp): 33// on debian, apt-get install tightvnc-java will put them in 34// /usr/share/tightvnc-java 35define("VNCJAVA_PATH", "tightvnc-java"); 36define("VNCJAR", "VncViewer.jar"); 37define("VNCCLASS", "VncViewer.class"); 38 39// do not show applet controls 40define("VNC_HIDE_CONTROLS", true); 41 42// generate and use (plain text) passwords 43// NOT IMPLEMENTED 44//define("VNC_USE_PASS", true); 45 46// maximum count of qemu instances. 47define("MAX_QEMUS", 2); 48 49// size of the java applet, must match the default resolution of the image. 50//define("APPLET_WIDTH", "800"); 51//define("APPLET_HEIGHT", "600"); 52define("APPLET_WIDTH", "1024"); 53define("APPLET_HEIGHT", "768"); 54// vnc protocol base port. 55define("VNCPORTBASE", 5900); 56 57// base port for audio streams 58//define("AUDIOPORTBASE", 8080); 59define("AUDIOPORTBASE", (VNCPORTBASE + MAX_QEMUS)); 60 61// base port for serial output 62//define("SERIALPORTBASE", 9000); 63define("SERIALPORTBASE", (VNCPORTBASE + MAX_QEMUS * 2)); 64 65// timeout before the demo session is killed, as argument to /bin/sleep 66define("SESSION_TIMEOUT", "20m"); 67 68// path to qemu binary 69define("QEMU_BASE", "/usr/local"); 70define("QEMU_BIN", QEMU_BASE . "/bin/qemu"); 71define("QEMU_KEYMAPS", QEMU_BASE . "/share/qemu/keymaps"); 72// default arguments: no network, emulate tablet, readonly image file. 73define("QEMU_ARGS", "" 74 ."-daemonize " /* detach from stdin */ 75 ."-localtime " /* not UTC */ 76 ."-name '" . addslashes(PAGE_TITLE) . "' " 77 ."-monitor /dev/null " 78 ."-serial none " 79 ."-parallel none " 80 ."-net none " 81 ."-usbdevice wacom-tablet " 82 //."-vga vmware " 83 ."-snapshot "); 84 85// absolute path to the image. 86define("QEMU_IMAGE_PATH", "/home/revol/haiku.image"); 87// BAD: let's one download the image 88//define("QEMU_IMAGE_PATH", dirname($_SERVER['SCRIPT_FILENAME']) . "/haiku.image"); 89 90// max number of cpus for the VM, not more than 8 91define("QEMU_MAX_CPUS", 1); 92 93// qemu 0.8.2 needs "", qemu 0.9.1 needs ":" 94define("QEMU_VNC_PREFIX", ":"); 95 96// name of session and pid files in /tmp 97define("QEMU_SESSFILE_TMPL", "qemu-haiku-session-"); 98define("QEMU_PIDFILE_TMPL", "qemu-haiku-pid-"); 99// name of session variable holding the qemu slot; not yet used correctly 100define("QEMU_IDX_VAR", "QEMU_HAIKU_SESSION_VAR"); 101 102 103// uncomment if you want to pass your Sonix webcam device through 104// migth need to update VID:PID 105// doesnt really work yet 106//define("QEMU_USB_PASSTHROUGH", "-usbdevice host:0c45:6005"); 107 108 109define("BGCOLOR", "#336698"); 110 111 112 113 114$vnckeymap = "en-us"; 115 116$cpucount = 1; 117 118// statics 119//$count = $_SESSION['compteur']; 120//$count = $GLOBALS['compteur']; 121$closing = 0; 122$do_kill = 0; 123$do_run = 0; 124 125function out($str) 126{ 127 echo "<div class=\"haiku_online_out\">$str</div>\n"; 128 ob_flush(); 129 flush(); 130} 131 132function dbg($str) 133{ 134 echo "<div class=\"haiku_online_debug\">$str</div>\n"; 135 ob_flush(); 136 flush(); 137} 138 139function err($str) 140{ 141 echo "<div class=\"haiku_online_error\">$str</div>\n"; 142 ob_flush(); 143 flush(); 144} 145 146function make_qemu_sessionfile_name($idx) 147{ 148 return "/tmp/" . QEMU_SESSFILE_TMPL . $idx; 149} 150 151function make_qemu_pidfile_name($idx) 152{ 153 return "/tmp/" . QEMU_PIDFILE_TMPL . $idx; 154} 155 156function find_qemu_slot() 157{ 158 for ($idx = 0; $idx < MAX_QEMUS; $idx++) { 159 $pidfile = make_qemu_pidfile_name($idx); 160 $sessfile = make_qemu_sessionfile_name($idx); 161 dbg("checking \"$pidfile\", \"$sessfile\"..."); 162 if (!file_exists($pidfile) && !file_exists($sessfile)) { 163 file_put_contents($sessfile, session_id()); 164 $sid = file_get_contents($sessfile); 165 if ($sid != session_id()) 166 continue; 167 $_SESSION[QEMU_IDX_VAR] = $idx; 168 return $idx; 169 } 170 } 171 return -1; 172} 173 174function total_qemu_slots() 175{ 176 return MAX_QEMUS; 177} 178 179 180function available_qemu_slots() 181{ 182 $count = 0; 183 for ($idx = 0; $idx < MAX_QEMUS; $idx++) { 184 $pidfile = make_qemu_pidfile_name($idx); 185 $sessfile = make_qemu_sessionfile_name($idx); 186 //dbg("checking \"$pidfile\", \"$sessfile\"..."); 187 if (!file_exists($pidfile) && !file_exists($sessfile)) 188 $count++; 189 } 190 return $count; 191} 192 193function qemu_slot() 194{ 195 return $_SESSION[QEMU_IDX_VAR]; 196} 197 198function audio_port() 199{ 200 return AUDIOPORTBASE + qemu_slot(); 201} 202 203function vnc_display() 204{ 205 return qemu_slot(); 206} 207 208function vnc_addr() 209{ 210 return $_SERVER['HTTP_HOST']; 211} 212 213function vnc_port() 214{ 215 return VNCPORTBASE + vnc_display(); 216} 217 218function vnc_addr_display() 219{ 220 return vnc_addr() . ":" . vnc_display(); 221} 222 223function vnc_url() 224{ 225 return "vnc://" . vnc_addr_display(); 226} 227 228function is_my_session_valid() 229{ 230 if (!isset($_SESSION[QEMU_IDX_VAR])) 231 return 0; 232 $idx = $_SESSION[QEMU_IDX_VAR]; 233 $sessfile = make_qemu_sessionfile_name($idx); 234 if (!file_exists($sessfile)) 235 return 0; 236 $qemusession=file_get_contents($sessfile); 237 // has expired 238 if ($qemusession != session_id()) { 239 return 0; 240 } 241 return 1; 242} 243 244 245function list_keymaps() 246{ 247 $bads = array('.', '..', 'common', 'modifiers'); 248 $keymaps = scandir(QEMU_KEYMAPS); 249 foreach ($keymaps as $key => $map) { 250 if (in_array($map, $bads)) 251 unset($keymaps[$key]); 252 } 253 return $keymaps; 254} 255 256 257function in_keymaps($keymap) 258{ 259 $keymaps = list_keymaps(); 260 261 if ($keymap == "") 262 return false; 263 if (in_array($keymap, $keymaps)) 264 return true; 265 266 return false; 267} 268 269 270function probe_keymap() 271{ 272 global $vnckeymap; 273 if (is_string($_GET['keymap']) && in_keymaps($_GET['keymap'])) 274 { 275 $vnckeymap = $_GET['keymap']; 276 dbg("Overriden keymap '" . $vnckeymap . "' in arguments."); 277 return; 278 } 279 // if the browser advertised a prefered lang... 280 if (!isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) 281 return; 282 $langs = $_SERVER["HTTP_ACCEPT_LANGUAGE"]; 283 $langs = ereg_replace(";q=[^,]*", "", $langs); 284 $langs = str_replace(" ", "", $langs); 285 $langs = split(",", $langs); 286 //print_r($langs); 287 //print_r($keymaps); 288 foreach($langs as $lang) 289 { 290 if (!in_keymaps($lang)) 291 $lang = ereg_replace("-.*", "", $lang); 292 if (in_keymaps($lang)) 293 { 294 $vnckeymap = $lang; 295 dbg("Detected keymap '" . $vnckeymap . 296 "' from browser headers."); 297 return; 298 } 299 } 300} 301 302 303function probe_options_form() 304{ 305 global $cpucount; 306 $cpucount = 1; 307 if (isset($_GET['cpucount'])) 308 $cpucount = (int)$_GET['cpucount']; 309 $cpucount = max(min($cpucount, QEMU_MAX_CPUS), 1); 310 //dbg("cpucount $cpucount"); 311} 312 313 314function output_options_form() 315{ 316 global $vnckeymap; 317 $idx = qemu_slot(); 318 echo "<form method=\"get\" action=\"" . $_SERVER['PHP_SELF'] . "\">"; 319 echo "<table border=\"0\" class=\"haiku_online_form\">\n"; 320 321 $keymaps = list_keymaps(); 322 echo "<tr>\n<td align=\"right\">\n"; 323 echo "Select your keymap:"; 324 echo "</td>\n<td>\n"; 325 echo "<select name=\"keymap\">"; 326 foreach ($keymaps as $keymap) { 327 echo "<option value=\"$keymap\" "; 328 if ($keymap == $vnckeymap) 329 echo "selected=\"selected\" "; 330 echo ">$keymap</option>"; 331 //echo "<option name=\"keymap\" "; 332 //echo "value=\"$keymap\">" . locale_get_display_name($keymap); 333 //echo "</option>"; 334 } 335 echo "</select>"; 336 echo "</td>\n</tr>\n"; 337 338 339 $modes = array("1024x768"/*, "800x600"*/); 340 echo "<tr "; 341 if (count($modes) < 2) 342 echo "class=\"haiku_online_disabled\""; 343 echo ">\n"; 344 echo "<td align=\"right\">\n"; 345 echo "Select display size:"; 346 echo "</td>\n<td>\n"; 347 echo "<select name=\"videomode\" "; 348 if (count($modes) < 2) 349 echo "disabled=\"disabled\""; 350 echo ">"; 351 foreach ($modes as $mode) { 352 echo "<option value=\"$mode\" "; 353 if ($mode == $videomode) 354 echo "selected=\"selected\" "; 355 echo ">$mode</option>"; 356 } 357 echo "</select>"; 358 echo "</td>\n</tr>\n"; 359 360 361 echo "<tr "; 362 if (QEMU_MAX_CPUS < 2) 363 echo "class=\"haiku_online_disabled\""; 364 echo ">\n"; 365 echo "<td align=\"right\">\n"; 366 echo "Select cpu count:"; 367 echo "</td>\n<td>\n"; 368 echo "<select name=\"cpucount\" "; 369 if (QEMU_MAX_CPUS < 2) 370 echo "disabled=\"disabled\""; 371 echo ">"; 372 for ($ncpu = 1; $ncpu <= QEMU_MAX_CPUS; $ncpu++) { 373 echo "<option value=\"$ncpu\" "; 374 if ($ncpu == 1) 375 echo "selected=\"selected\" "; 376 echo ">$ncpu</option>"; 377 } 378 echo "</select>"; 379 echo "</td>\n</tr>\n"; 380 381 382 $enable_sound = 1; 383 echo "<tr "; 384 if (!$enable_sound) 385 echo "class=\"haiku_online_disabled\""; 386 echo ">\n"; 387 echo "<td align=\"right\">\n"; 388 echo "Check to enable sound:"; 389 echo "</td>\n<td>\n"; 390 echo "<input type=\"checkbox\" name=\"sound\" id=\"sound_cb\" "; 391 echo "value=\"1\" "; 392 if ($enable_sound) { 393 //echo "checked=\"checked\" /"; 394 } else 395 echo "disabled=\"disabled\" /"; 396 echo "><label for=\"sound_cb\">Sound</label>"; 397 echo "</td>\n</tr>\n"; 398 399 $enable_serial = 1; 400 echo "<tr "; 401 if (!$enable_serial) 402 echo "class=\"haiku_online_disabled\""; 403 echo ">\n"; 404 echo "<td align=\"right\">\n"; 405 echo "Check to enable serial output:"; 406 echo "</td>\n<td>\n"; 407 echo "<input type=\"checkbox\" name=\"serial\" id=\"serial_cb\" "; 408 echo "value=\"1\" "/*"disabled "*/; 409 if ($enable_serial) { 410 //echo "checked "; 411 } 412 echo "/><label for=\"serial_cb\">Serial</label>"; 413 echo "</td>\n</tr>\n"; 414 415 if (defined("QEMU_USB_PASSTHROUGH")) { 416 417 $enable_webcam = 1; 418 echo "<tr "; 419 if (!$enable_webcam) 420 echo "class=\"haiku_online_disabled\""; 421 echo ">\n"; 422 echo "<td align=\"right\">\n"; 423 echo "Check to enable webcam:"; 424 echo "</td>\n<td>\n"; 425 echo "<input type=\"checkbox\" name=\"webcam\" id=\"webcam_cb\" "; 426 echo "value=\"1\" "/*"disabled "*/; 427 if ($enable_webcam) { 428 //echo "checked "; 429 } 430 echo "/><label for=\"webcam_cb\">Webcam</label>"; 431 echo "</td>\n</tr>\n"; 432 } 433 /* 434 echo "<tr>\n<td align=\"right\">\n"; 435 //out("Click here to enable sound:"); 436 echo "</td>\n<td>\n"; 437 echo "</td>\n</tr>\n"; 438 439 echo "<tr>\n<td align=\"right\">\n"; 440 //out("Click here to enable sound:"); 441 echo "</td>\n<td>\n"; 442 echo "</td>\n</tr>\n"; 443 */ 444 445 echo "<tr>\n<td align=\"right\">\n"; 446 echo "Click here to start the session:"; 447 echo "</td>\n<td>\n"; 448 echo "<input type=\"submit\" name=\"run\" "; 449 echo "value=\"Start!\" />"; 450 echo "</td>\n</tr>\n"; 451 452 echo "</table>\n"; 453 echo "</form>\n"; 454 out("NOTE: You will need a Java-enabled browser to display the VNC " . 455 "Applet needed by this demo."); 456 out("You can however use instead an external <a " . 457 "href=\"http://fr.wikipedia.org/wiki/Virtual_Network_Computing\"" . 458 ">VNC viewer</a>."); 459 ob_flush(); 460 flush(); 461} 462 463function output_kill_form() 464{ 465 echo "<form method=\"get\" action=\"" . $_SERVER['PHP_SELF'] . "\">"; 466 echo "<table border=\"0\" class=\"haiku_online_form\">\n"; 467 echo "<tr>\n"; 468 echo "<td>\n"; 469 echo "Click here to kill the session:"; 470 echo "</td>\n"; 471 echo "<td>\n"; 472 echo "<input type=\"submit\" name=\"kill\" "; 473 echo "value=\"Terminate\"/>"; 474 echo "</td>\n"; 475 echo "</tr>\n"; 476 echo "</table>\n"; 477 echo "</form>\n"; 478 ob_flush(); 479 flush(); 480} 481 482 483function start_qemu() 484{ 485 global $vnckeymap; 486 global $cpucount; 487 $idx = find_qemu_slot(); 488 if ($idx < 0) { 489 err("No available qemu slot, please try later."); 490 return $idx; 491 } 492 $pidfile = make_qemu_pidfile_name($idx); 493 $cmd = ''; 494 if (isset($_GET['sound'])) { 495 $cmd .= "QEMU_AUDIO_DRV=twolame "; 496 //$cmd .= "QEMU_TWOLAME_SAMPLES=" . 4096 . " "; 497 $cmd .= "QEMU_TWOLAME_PORT=" . audio_port() . " "; 498 } 499 $cmd .= QEMU_BIN . " " . QEMU_ARGS; 500 if ($cpucount > 1) 501 $cmd .= " -smp " . $cpucount; 502 if (isset($_GET['sound'])) { 503 $cmd .= " -soundhw hda"; 504 } 505 if (isset($_GET['serial'])) { 506 $cmd .= " -serial telnet::"; 507 $cmd .= (SERIALPORTBASE + qemu_slot()); 508 $cmd .= ",server,nowait,nodelay"; 509 } 510 if (isset($_GET['webcam']) && defined("QEMU_USB_PASSTHROUGH")) { 511 $cmd .= " " . QEMU_USB_PASSTHROUGH; 512 } 513 $cmd .= " -k " . $vnckeymap . 514 " -vnc " . QEMU_VNC_PREFIX . vnc_display() . 515 " -pidfile " . $pidfile . 516 " " . QEMU_IMAGE_PATH; 517 518 if (file_exists($pidfile)) 519 unlink($pidfile); 520 dbg("Starting <tt>" . $cmd . "</tt>..."); 521 522 $descriptorspec = array( 523 // 0 => array("pipe", "r"), // stdin 524 // 1 => array("pipe", "w"), // stdout 525 // 2 => array("pipe", "w") // stderr 526 ); 527 //$cmd="/bin/ls"; 528 //passthru($cmd, $ret); 529 //dbg("ret=$ret"); 530 $cmd .= " &"; 531 $process = proc_open($cmd, $descriptorspec, $pipes); 532 sleep(1); 533 proc_close($process); 534 535 dbg("Started QEMU."); 536 $sessfile = make_qemu_sessionfile_name($idx); 537 $cmd = "(PID=`cat " . $pidfile . "`; " . 538 "sleep " . SESSION_TIMEOUT . "; " . 539 "kill -9 \$PID && " . 540 "rm " . $pidfile . " " . $sessfile . ") &"; 541 542 $process = proc_open($cmd, $descriptorspec, $wkpipes); 543 sleep(1); 544 proc_close($process); 545 546 dbg("Started timed kill."); 547 dbg("Ready for a " . SESSION_TIMEOUT . " session."); 548} 549 550function stop_qemu() 551{ 552 $qemuidx = qemu_slot(); 553 $pidfile = make_qemu_pidfile_name($qemuidx); 554 if (file_exists($pidfile)) { 555 $pid = file_get_contents($pidfile); 556 //out("PID:" . $pid); 557 system("/bin/kill -TERM " . $pid); 558 unlink($pidfile); 559 } 560 $sessionfile = make_qemu_sessionfile_name($qemuidx); 561 if (file_exists($sessionfile)) { 562 unlink($sessionfile); 563 } 564 unset($_SESSION[QEMU_IDX_VAR]); 565 566 out("reloading..."); 567 sleep(1); 568 echo "<script>\n"; 569 echo "<!--\n"; 570 echo "window.location = \"" . $_SERVER['PHP_SELF'] . "\";\n"; 571 echo "//--></script>\n"; 572 out("Click <a href=\"" . $_SERVER['PHP_SELF'] . 573 "\">here</a> to reload the page."); 574} 575 576function output_vnc_info() 577{ 578 out("You can use an external VNC client at " . 579 "<a href=\"vnc://" . vnc_addr_display() . "\">" . 580 "vnc://" . vnc_addr_display() . "</a> " . 581 "or open <a href=\"" . $_SERVER['PHP_SELF'] . "?getfile=vncinfo&slot=" . vnc_display() . "\">this file</a>, " . 582 "or enter <tt>" . vnc_addr_display() . "</tt> in your " . 583 "<a href=\"http://fr.wikipedia.org/wiki/Virtual_Network_" . 584 "Computing\"" . 585 ">VNC viewer</a>."); 586 //echo "<br />\n"; 587} 588 589function output_vnc_info_file() 590{ 591 if (!is_my_session_valid()) 592 die("Bad request"); 593 594 header("Pragma: public"); 595 header("Expires: 0"); 596 header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 597 header("Content-type: application/x-vnc"); 598 header('Content-Disposition: attachment; filename="onlinedemo.vnc"'); 599 600 echo "[connection]\n"; 601 echo "host=" . vnc_addr() . "\n"; 602 echo "port=" . vnc_display() . "\n"; 603 if (defined('VNC_USE_PASS') && VNC_USE_PASS) 604 echo "password=" . $_SESSION['VNC_PASS'] . "\n"; 605 //echo "[options]\n"; 606 // cf. http://www.realvnc.com/pipermail/vnc-list/1999-December/011086.html 607 // cf. http://www.tek-tips.com/viewthread.cfm?qid=1173303&page=1 608 //echo "\n"; 609} 610 611function output_audio_player_code($external_only=false) 612{ 613 if (!isset($_GET['sound'])) 614 return; 615 616 $port = audio_port(); 617 $url = "http://" . $_SERVER['HTTP_HOST'] . ":$port/"; 618 $icy = "icy://" . $_SERVER['HTTP_HOST'] . ":$port/"; 619 $use_html5 = true; 620 621 if (!$external_only) { 622 if ($use_html5) { 623 echo "<audio autoplay=\"autoplay\" autobuffer=\"autobuffer\" controls=\"controls\">"; 624 echo "<source src=\"" . $url . "\" type=\"audio/mpeg\" />"; 625 } 626 if (!$use_html5) { 627 echo "<object type=\"audio/mpeg\" width=\"300\" height=\"50\">"; 628 echo "<param name=\"src\" value=\"" . $url . "\" />"; 629 echo "<param name=\"controller\" value=\"true\" />"; 630 echo "<param name=\"controls\" value=\"controlPanel\" />"; 631 echo "<param name=\"autoplay\" value=\"true\" />"; 632 echo "<param name=\"autostart\" value=\"1\" />"; 633 634 echo "<embed src=\"$url\" type=\"audio/mpeg\" "; 635 echo "autoplay=\"true\" width=\"300\" height=\"50\" "; 636 echo "controller=\"true\" align=\"right\" hidden=\"false\"></embed>"; 637 638 echo "</object>"; 639 } 640 if ($use_html5) { 641 echo "</audio>"; 642 } 643 } 644 out("You can use an external audio play at " . 645 "<a href=\"$url\">$url</a> or <a href=\"$icy\">$icy</a>, or use one of the playlists: " . 646 "<a href=\"" . $_SERVER['PHP_SELF'] . "?getfile=audiom3u\">[M3U]</a> " . 647 "<a href=\"" . $_SERVER['PHP_SELF'] . "?getfile=audiopls\">[PLS]</a>"); 648} 649 650function output_audio_player_file_m3u() 651{ 652 if (!is_my_session_valid()) 653 die("Bad request"); 654 655 header("Pragma: public"); 656 header("Expires: 0"); 657 header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 658 header("Content-type: audio/x-mpegurl"); 659 //header("Content-type: text/plain"); 660 header('Content-Disposition: attachment; filename="onlinedemo.m3u"'); 661 662 $port = audio_port(); 663 $url = "http://" . $_SERVER['HTTP_HOST'] . ":$port/"; 664 665 // cf. http://hanna.pyxidis.org/tech/m3u.html 666 echo "#EXTM3U\n"; 667 echo "#EXTINF:0," . PAGE_TITLE . "\n"; 668 echo "$url\n"; 669 //echo "\n"; 670} 671 672function output_audio_player_file_pls() 673{ 674 if (!is_my_session_valid()) 675 die("Bad request"); 676 677 header("Pragma: public"); 678 header("Expires: 0"); 679 header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 680 header("Content-type: audio/x-scpls"); 681 //header("Content-type: text/plain"); 682 header('Content-Disposition: attachment; filename="onlinedemo.pls"'); 683 684 $port = audio_port(); 685 $url = "http://" . $_SERVER['HTTP_HOST'] . ":$port/"; 686 687 echo "[playlist]\n"; 688 echo "numberofentries=1\n"; 689 echo "File1=$url\n"; 690 echo "Title1=" . PAGE_TITLE . "\n"; 691 echo "Length1=-1\n"; 692 echo "version=2\n"; 693 //echo "\n"; 694} 695 696function output_applet_code($external_only=false) 697{ 698 $w = APPLET_WIDTH; 699 $h = APPLET_HEIGHT; 700 $port = vnc_port(); 701 $vncjpath = VNCJAVA_PATH; 702 $jar = VNCJAR; 703 $class = VNCCLASS; 704 if ($external_only) 705 return; 706 echo "<a name=\"haiku_online_applet\"></a>"; 707 echo "<center>"; 708 echo "<applet code=$class codebase=\"$vncjpath/\" "; 709 echo "archive=\"$vncjpath/$jar\" width=$w height=$h "; 710 echo "bgcolor=\"#336698\">\n"; 711 //not needed 712 //echo "<param name=\"HOST\" value=\"$HTTP_HOST\">\n"; 713 echo "<param name=\"PORT\" value=\"$port\">\n"; 714 $pass = ''; 715 if (defined('VNC_USE_PASS') && VNC_USE_PASS) 716 $pass = $_SESSION['VNC_PASS']; 717 echo "<param name=\"PASSWORD\" value=\"" . $pass . "\">\n"; 718 if (defined("VNC_HIDE_CONTROLS") && VNC_HIDE_CONTROLS) 719 echo "<param name=\"Show controls\" value=\"No\">\n"; 720 //echo "<param name=\"share desktop\" value=\"no\" />"; 721 echo "<param name=\"background-color\" value=\"#336698\">\n"; 722 echo "<param name=\"foreground-color\" value=\"#ffffff\">\n"; 723 //echo "<param name=\"background\" value=\"#336698\">\n"; 724 //echo "<param name=\"foreground\" value=\"#ffffff\">\n"; 725 echo "There should be a java applet here... "; 726 echo "make sure you have a JVM and it's enabled!<br />\n"; 727 echo "If you do not have Java you can use an external VNC "; 728 echo "client as described above.\n"; 729 730 echo "</applet>\n"; 731 echo "</center>"; 732 ob_flush(); 733 flush(); 734 // scroll to the top of the applet 735 echo "<script>\n"; 736 echo "<!--\n"; 737 echo "scrollToAnchor(\"haiku_online_applet\");"; 738 echo "//--></script>\n"; 739 ob_flush(); 740 flush(); 741} 742 743function output_serial_output_code($external_only=false) 744{ 745 if (!isset($_GET['serial'])) 746 return; 747 748 $url = "telnet://" . $_SERVER['HTTP_HOST'] . ":"; 749 $url .= (SERIALPORTBASE + qemu_slot()) . "/"; 750 out("You can get serial output at <a href=\"$url\">$url</a>"); 751 return; 752 753 // not really http... 754 $url = "http://" . $_SERVER['HTTP_HOST'] . ":"; 755 $url .= (SERIALPORTBASE + qemu_slot()) . "/"; 756 echo "<center>"; 757 echo "<iframe src=\"$url/\" type=\"text/plain\" width=\"100%\" "; 758 echo "height=\"200\"></iframe>"; 759 echo "</center>"; 760 761} 762 763 764session_start(); 765 766// parse args 767 768// output redirections... 769if (isset($_GET['getfile'])) { 770 switch ($_GET['getfile']) { 771 case "vncinfo": 772 output_vnc_info_file(); 773 break; 774 case "audiom3u": 775 output_audio_player_file_m3u(); 776 break; 777 case "audiopls": 778 output_audio_player_file_pls(); 779 break; 780 default: 781 die("Bad request"); 782 } 783 die(); 784} 785 786if (isset($_GET['close'])) 787 $closing = 1; 788 789if (isset($_GET['kill'])) 790 $do_kill = 1; 791 792if (isset($_GET['run'])) 793 $do_run = 1; 794 795if (isset($_GET['frame'])) {} 796 797 798//echo "do_run: " . $do_run . "<br>\n"; 799//echo "do_kill: " . $do_kill . "<br>\n"; 800 801?> 802<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 803<head> 804<meta name="robots" content="noindex, nofollow, noarchive" /> 805<title><?php echo PAGE_TITLE; ?></title> 806<link rel="shortcut icon" href="http://www.haiku-os.org/sites/haiku-os.org/themes/shijin/favicon.ico" type="image/x-icon" /> 807<style type="text/css"> 808<!-- 809 /* basic style */ 810body { background-color: <?php echo BGCOLOR; ?>; } 811a:link { color:orange; } 812a:visited { color:darkorange; } 813a:hover { color:pink; } 814.haiku_online_form { color: white; } 815.haiku_online_disabled { color: grey; } 816.haiku_online_out { color: white; } 817.haiku_online_debug { color: orange; } 818.haiku_online_error { color: red; font-weight: bold; } 819.haiku_online_applet { background-color: <?php echo BGCOLOR; ?>; } 820--> 821</style> 822<script type="text/javascript"> 823function onPageUnload() { 824 //window.open("<?php echo $_SERVER["SCRIPT_NAME"] . "?close"; ?>", "closing", "width=100,height=30,location=no,menubar=no,toolbar=no,scrollbars=no"); 825} 826 827function scrollToAnchor(anchor) { 828 var a = document.anchors[anchor]; 829 if (a) { 830 if (a.scrollIntoView) 831 a.scrollIntoView(true); 832 else if (a.focus) 833 a.focus(); 834 } else 835 window.location.hash = anchor; 836} 837</script> 838</head> 839<?php 840 841 842if ($closing == 1) 843 echo "<body>"; 844else 845 echo "<body onunload=\"onPageUnload();\">"; 846 847 848out("<div style=\"text-align:right;\">Available displays: " . 849 available_qemu_slots() . "/" . total_qemu_slots() . 850 "</div>"); 851 852 853probe_keymap(); 854probe_options_form(); 855 856dbg("Checking if session is running..."); 857 858$qemuidx = -1; 859 860if (is_my_session_valid()) { 861 dbg("Session running."); 862 $qemuidx = qemu_slot(); 863 if ($do_kill) { 864 dbg("closing..."); 865 stop_qemu(); 866 } 867} else if (!$do_kill && $do_run) { 868 dbg("Need to start qemu."); 869 870 $qemuidx = start_qemu(); 871 //out("Waiting for vnc server..."); 872 //sleep(5); 873} 874 875 876if ($qemuidx >= 0 && !$do_kill) { 877 output_kill_form(); 878 output_serial_output_code(); 879 output_audio_player_code(); 880 output_vnc_info(); 881 out("Waiting for vnc server..."); 882 sleep(1); 883 output_applet_code(); 884} else { 885 output_options_form(); 886} 887 888//phpinfo(); 889 890?> 891 892</body> 893</html> 894