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