1e8fc4975SFrançois Revol<?php 2e8fc4975SFrançois Revol 3e8fc4975SFrançois Revol/* 4e8fc4975SFrançois Revol * haiku.php - an online Haiku demo using qemu and vnc. 5e8fc4975SFrançois Revol * Copyright 2007, Francois Revol, revol@free.fr. 6e8fc4975SFrançois Revol */ 7e8fc4975SFrançois Revol 8664c8b6dSFrançois Revol// parts inspired by the Free Live OS Zoo 9664c8b6dSFrançois Revol// http://www.oszoo.org/wiki/index.php/Free_Live_OS_Zoo 10664c8b6dSFrançois Revol 11664c8b6dSFrançois Revol 12e8fc4975SFrançois Revol// relative path to the vnc java applet jar 13e8fc4975SFrançois Revol// you must *copy* (apache doesn't seem to like symlinks) it there. 14e8fc4975SFrançois Revol 15e8fc4975SFrançois Revol// on debian, apt-get install vnc-java will put them in 16e8fc4975SFrançois Revol// /usr/share/vnc-java 17e8fc4975SFrançois Revol//define("VNCJAVA_PATH", "vnc-java"); 18e8fc4975SFrançois Revol//define("VNCJAR", "vncviewer.jar"); 19e8fc4975SFrançois Revol//define("VNCCLASS", "vncviewer.class"); 20e8fc4975SFrançois Revol 21e8fc4975SFrançois Revol// to use the tightvnc applet instead (supports > 8bpp): 22e8fc4975SFrançois Revol// on debian, apt-get install tightvnc-java will put them in 23e8fc4975SFrançois Revol// /usr/share/tightvnc-java 24e8fc4975SFrançois Revoldefine("VNCJAVA_PATH", "tightvnc-java"); 25e8fc4975SFrançois Revoldefine("VNCJAR", "VncViewer.jar"); 26e8fc4975SFrançois Revoldefine("VNCCLASS", "VncViewer.class"); 27e8fc4975SFrançois Revol 28e8fc4975SFrançois Revol// maximum count of qemu instances. 29*91054f1dSFrançois Revoldefine("MAX_QEMUS", 2); 30e8fc4975SFrançois Revol 31e8fc4975SFrançois Revol// size of the java applet, must match the default resolution of the image. 3252a7cf96SFrançois Revol//define("APPLET_WIDTH", "800"); 3352a7cf96SFrançois Revol//define("APPLET_HEIGHT", "600"); 3452a7cf96SFrançois Revoldefine("APPLET_WIDTH", "1024"); 3552a7cf96SFrançois Revoldefine("APPLET_HEIGHT", "768"); 36e8fc4975SFrançois Revol// vnc protocol base port. 37e8fc4975SFrançois Revoldefine("VNCPORTBASE", 5900); 38e8fc4975SFrançois Revol 39664c8b6dSFrançois Revol// base port for audio streams 40f0cbfcafSFrançois Revol//define("AUDIOPORTBASE", 8080); 41f0cbfcafSFrançois Revoldefine("AUDIOPORTBASE", (VNCPORTBASE + MAX_QEMUS)); 42f0cbfcafSFrançois Revol 43f0cbfcafSFrançois Revol// base port for serial output 44f0cbfcafSFrançois Revol//define("SERIALPORTBASE", 9000); 45f0cbfcafSFrançois Revoldefine("SERIALPORTBASE", (VNCPORTBASE + MAX_QEMUS * 2)); 46664c8b6dSFrançois Revol 47e8fc4975SFrançois Revol// timeout before the demo session is killed, as argument to /bin/sleep 484720c31bSFrançois Revoldefine("SESSION_TIMEOUT", "20m"); 49e8fc4975SFrançois Revol 50e8fc4975SFrançois Revol// path to qemu binary 51c6f50a6aSFrançois Revoldefine("QEMU_BASE", "/usr/local"); 52c6f50a6aSFrançois Revoldefine("QEMU_BIN", QEMU_BASE . "/bin/qemu"); 53c6f50a6aSFrançois Revoldefine("QEMU_KEYMAPS", QEMU_BASE . "/share/qemu/keymaps"); 54e8fc4975SFrançois Revol// default arguments: no network, emulate tablet, readonly image file. 554720c31bSFrançois Revoldefine("QEMU_ARGS", "" 56d2bef01cSFrançois Revol ."-daemonize " /* detach from stdin */ 57d2bef01cSFrançois Revol ."-localtime " /* not UTC */ 58d2bef01cSFrançois Revol ."-name 'Haiku Online Demo' " 594720c31bSFrançois Revol ."-monitor /dev/null " 604720c31bSFrançois Revol ."-serial none " 614720c31bSFrançois Revol ."-parallel none " 624720c31bSFrançois Revol ." -net none " 634720c31bSFrançois Revol ."-usbdevice wacom-tablet " 644720c31bSFrançois Revol ."-vga vmware " 654720c31bSFrançois Revol ."-snapshot"); 66d2bef01cSFrançois Revol 67e8fc4975SFrançois Revol// absolute path to the image. 688ad2eabaSFrançois Revoldefine("QEMU_IMAGE_PATH","/home/revol/haiku/trunk/generated.x86/haiku.image"); 698ad2eabaSFrançois Revol// qemu 0.8.2 needs "", qemu 0.9.1 needs ":" 708ad2eabaSFrançois Revoldefine("QEMU_VNC_PREFIX", ":"); 71e8fc4975SFrançois Revol 72e8fc4975SFrançois Revol// name of session and pid files in /tmp 73e8fc4975SFrançois Revoldefine("QEMU_SESSFILE_TMPL", "qemu-haiku-session-"); 74e8fc4975SFrançois Revoldefine("QEMU_PIDFILE_TMPL", "qemu-haiku-pid-"); 75e8fc4975SFrançois Revol// name of session variable holding the qemu slot; not yet used correctly 76e8fc4975SFrançois Revoldefine("QEMU_IDX_VAR", "QEMU_HAIKU_SESSION_VAR"); 77e8fc4975SFrançois Revol 78f0cbfcafSFrançois Revol 79f0cbfcafSFrançois Revol// uncomment if you want to pass your Sonix webcam device through 80f0cbfcafSFrançois Revol// migth need to update VID:PID 81f0cbfcafSFrançois Revol//define("QEMU_USB_PASSTHROUGH", "-usbdevice host:0c45:6005"); 82f0cbfcafSFrançois Revol 83f0cbfcafSFrançois Revol 844720c31bSFrançois Revoldefine("BGCOLOR", "#336698"); 854720c31bSFrançois Revol 86f0cbfcafSFrançois Revol 874720c31bSFrançois Revol$vnckeymap = "en-us"; 884720c31bSFrançois Revol 89f0cbfcafSFrançois Revol$cpucount = 1; 90f0cbfcafSFrançois Revol 914720c31bSFrançois Revol// statics 924720c31bSFrançois Revol$count = $_SESSION['compteur']; 934720c31bSFrançois Revol//$count = $GLOBALS['compteur']; 944720c31bSFrançois Revol$closing = 0; 954720c31bSFrançois Revol$do_kill = 0; 964720c31bSFrançois Revol$do_run = 0; 974720c31bSFrançois Revol 984720c31bSFrançois Revol// parse args 994720c31bSFrançois Revolif (isset($_GET['close'])) 1004720c31bSFrançois Revol $closing = 1; 1014720c31bSFrançois Revol 1024720c31bSFrançois Revolif (isset($_GET['kill'])) 1034720c31bSFrançois Revol $do_kill = 1; 1044720c31bSFrançois Revol 1054720c31bSFrançois Revolif (isset($_GET['run'])) 1064720c31bSFrançois Revol $do_run = 1; 1074720c31bSFrançois Revol 1084720c31bSFrançois Revolif (isset($_GET['frame'])) {} 1094720c31bSFrançois Revol 110e8fc4975SFrançois Revolsession_start(); 111e8fc4975SFrançois Revol 1124720c31bSFrançois Revol//echo "do_run: " . $do_run . "<br>\n"; 1134720c31bSFrançois Revol//echo "do_kill: " . $do_kill . "<br>\n"; 114e8fc4975SFrançois Revol 115e8fc4975SFrançois Revol?> 116f0cbfcafSFrançois Revol<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 117e8fc4975SFrançois Revol<head> 118f0cbfcafSFrançois Revol<meta name="robots" content="noindex, nofollow, noarchive" /> 119cdbd6446SFrançois Revol<title>Haiku Online Demo</title> 120d2bef01cSFrançois Revol<link rel="shortcut icon" href="http://www.haiku-os.org/themes/shijin/favicon.ico" type="image/x-icon" /> 1214720c31bSFrançois Revol<style type="text/css"> 1224720c31bSFrançois Revol<!-- 1234720c31bSFrançois Revol /* basic style */ 1244720c31bSFrançois Revolbody { background-color: <?php echo BGCOLOR; ?>; } 1254720c31bSFrançois Revola:link { color:orange; } 1264720c31bSFrançois Revola:visited { color:darkorange; } 1274720c31bSFrançois Revola:hover { color:pink; } 1284720c31bSFrançois Revol.haiku_online_form { color: white; } 1294720c31bSFrançois Revol.haiku_online_disabled { color: grey; } 1304720c31bSFrançois Revol.haiku_online_out { color: white; } 1314720c31bSFrançois Revol.haiku_online_debug { color: orange; } 1324720c31bSFrançois Revol.haiku_online_error { color: red; font-weight: bold; } 1334720c31bSFrançois Revol.haiku_online_applet { background-color: <?php echo BGCOLOR; ?>; } 1344720c31bSFrançois Revol--> 1354720c31bSFrançois Revol</style> 136f0cbfcafSFrançois Revol<script type="text/javascript"> 137e8fc4975SFrançois Revolfunction onPageUnload() { 138e8fc4975SFrançois Revol //window.open("<?php echo $_SERVER["SCRIPT_NAME"] . "?close"; ?>", "closing", "width=100,height=30,location=no,menubar=no,toolbar=no,scrollbars=no"); 139e8fc4975SFrançois Revol} 140e8fc4975SFrançois Revol</script> 141f0cbfcafSFrançois Revol</head> 142e8fc4975SFrançois Revol<?php 143e8fc4975SFrançois Revol 144e8fc4975SFrançois Revol 1454720c31bSFrançois Revolif ($closing == 1) 146e8fc4975SFrançois Revol echo "<body>"; 1474720c31bSFrançois Revolelse 148e8fc4975SFrançois Revol echo "<body onunload=\"onPageUnload();\">"; 149e8fc4975SFrançois Revol 1504720c31bSFrançois Revolfunction out($str) 1514720c31bSFrançois Revol{ 1524720c31bSFrançois Revol echo "<div class=\"haiku_online_out\">$str</div>\n"; 1534720c31bSFrançois Revol ob_flush(); 1544720c31bSFrançois Revol flush(); 1554720c31bSFrançois Revol} 1564720c31bSFrançois Revol 157e8fc4975SFrançois Revolfunction dbg($str) 158e8fc4975SFrançois Revol{ 1594720c31bSFrançois Revol echo "<div class=\"haiku_online_debug\">$str</div>\n"; 1604720c31bSFrançois Revol ob_flush(); 1614720c31bSFrançois Revol flush(); 162e8fc4975SFrançois Revol} 163e8fc4975SFrançois Revol 164e8fc4975SFrançois Revolfunction err($str) 165e8fc4975SFrançois Revol{ 1664720c31bSFrançois Revol echo "<div class=\"haiku_online_error\">$str</div>\n"; 1674720c31bSFrançois Revol ob_flush(); 1684720c31bSFrançois Revol flush(); 169e8fc4975SFrançois Revol} 170e8fc4975SFrançois Revol 171e8fc4975SFrançois Revolfunction make_qemu_sessionfile_name($idx) 172e8fc4975SFrançois Revol{ 173e8fc4975SFrançois Revol return "/tmp/" . QEMU_SESSFILE_TMPL . $idx; 174e8fc4975SFrançois Revol} 175e8fc4975SFrançois Revol 176e8fc4975SFrançois Revolfunction make_qemu_pidfile_name($idx) 177e8fc4975SFrançois Revol{ 178e8fc4975SFrançois Revol return "/tmp/" . QEMU_PIDFILE_TMPL . $idx; 179e8fc4975SFrançois Revol} 180e8fc4975SFrançois Revol 181e8fc4975SFrançois Revolfunction find_qemu_slot() 182e8fc4975SFrançois Revol{ 183e8fc4975SFrançois Revol for ($idx = 0; $idx < MAX_QEMUS; $idx++) { 184e8fc4975SFrançois Revol $pidfile = make_qemu_pidfile_name($idx); 185e8fc4975SFrançois Revol $sessfile = make_qemu_sessionfile_name($idx); 186e8fc4975SFrançois Revol dbg("checking \"$pidfile\", \"$sessfile\"..."); 187e8fc4975SFrançois Revol if (!file_exists($pidfile) && !file_exists($sessfile)) { 188e8fc4975SFrançois Revol file_put_contents($sessfile, session_id()); 189e8fc4975SFrançois Revol $sid = file_get_contents($sessfile); 190e8fc4975SFrançois Revol if ($sid != session_id()) 191e8fc4975SFrançois Revol continue; 192e8fc4975SFrançois Revol $_SESSION[QEMU_IDX_VAR] = $idx; 193e8fc4975SFrançois Revol return $idx; 194e8fc4975SFrançois Revol } 195e8fc4975SFrançois Revol } 196e8fc4975SFrançois Revol return -1; 197e8fc4975SFrançois Revol} 198e8fc4975SFrançois Revol 1994720c31bSFrançois Revolfunction total_qemu_slots() 2004720c31bSFrançois Revol{ 2014720c31bSFrançois Revol return MAX_QEMUS; 2024720c31bSFrançois Revol} 2034720c31bSFrançois Revol 2044720c31bSFrançois Revol 2054720c31bSFrançois Revolfunction available_qemu_slots() 2064720c31bSFrançois Revol{ 2074720c31bSFrançois Revol $count = 0; 2084720c31bSFrançois Revol for ($idx = 0; $idx < MAX_QEMUS; $idx++) { 2094720c31bSFrançois Revol $pidfile = make_qemu_pidfile_name($idx); 2104720c31bSFrançois Revol $sessfile = make_qemu_sessionfile_name($idx); 2114720c31bSFrançois Revol //dbg("checking \"$pidfile\", \"$sessfile\"..."); 2124720c31bSFrançois Revol if (!file_exists($pidfile) && !file_exists($sessfile)) 2134720c31bSFrançois Revol $count++; 2144720c31bSFrançois Revol } 2154720c31bSFrançois Revol return $count; 2164720c31bSFrançois Revol} 2174720c31bSFrançois Revol 218e8fc4975SFrançois Revolfunction qemu_slot() 219e8fc4975SFrançois Revol{ 220e8fc4975SFrançois Revol return $_SESSION[QEMU_IDX_VAR]; 221e8fc4975SFrançois Revol} 222e8fc4975SFrançois Revol 223664c8b6dSFrançois Revolfunction audio_port() 224664c8b6dSFrançois Revol{ 225664c8b6dSFrançois Revol return AUDIOPORTBASE + qemu_slot(); 226664c8b6dSFrançois Revol} 227664c8b6dSFrançois Revol 228e8fc4975SFrançois Revolfunction vnc_display() 229e8fc4975SFrançois Revol{ 230e8fc4975SFrançois Revol return qemu_slot(); 231e8fc4975SFrançois Revol} 232e8fc4975SFrançois Revol 233e8fc4975SFrançois Revolfunction vnc_port() 234e8fc4975SFrançois Revol{ 235e8fc4975SFrançois Revol return VNCPORTBASE + vnc_display(); 236e8fc4975SFrançois Revol} 237e8fc4975SFrançois Revol 2384720c31bSFrançois Revolfunction vnc_addr_display() 2394720c31bSFrançois Revol{ 240d2bef01cSFrançois Revol return $_SERVER['HTTP_HOST'] . ":" . vnc_display(); 2414720c31bSFrançois Revol} 2424720c31bSFrançois Revol 2434720c31bSFrançois Revolfunction vnc_url() 2444720c31bSFrançois Revol{ 2454720c31bSFrançois Revol return "vnc://" . vnc_addr_display(); 2464720c31bSFrançois Revol} 2474720c31bSFrançois Revol 248e8fc4975SFrançois Revolfunction is_my_session_valid() 249e8fc4975SFrançois Revol{ 250e8fc4975SFrançois Revol if (!isset($_SESSION[QEMU_IDX_VAR])) 251e8fc4975SFrançois Revol return 0; 252e8fc4975SFrançois Revol $idx = $_SESSION[QEMU_IDX_VAR]; 253e8fc4975SFrançois Revol $sessfile = make_qemu_sessionfile_name($idx); 254e8fc4975SFrançois Revol if (!file_exists($sessfile)) 255e8fc4975SFrançois Revol return 0; 256e8fc4975SFrançois Revol $qemusession=file_get_contents($sessfile); 257e8fc4975SFrançois Revol // has expired 258e8fc4975SFrançois Revol if ($qemusession != session_id()) { 259e8fc4975SFrançois Revol return 0; 260e8fc4975SFrançois Revol } 261e8fc4975SFrançois Revol return 1; 262e8fc4975SFrançois Revol} 263e8fc4975SFrançois Revol 264e8fc4975SFrançois Revol 2654720c31bSFrançois Revolfunction list_keymaps() 2664720c31bSFrançois Revol{ 2674720c31bSFrançois Revol $bads = array('.', '..', 'common', 'modifiers'); 2684720c31bSFrançois Revol $keymaps = scandir(QEMU_KEYMAPS); 2694720c31bSFrançois Revol foreach ($keymaps as $key => $map) { 2704720c31bSFrançois Revol if (in_array($map, $bads)) 2714720c31bSFrançois Revol unset($keymaps[$key]); 2724720c31bSFrançois Revol } 2734720c31bSFrançois Revol return $keymaps; 2744720c31bSFrançois Revol} 2754720c31bSFrançois Revol 2764720c31bSFrançois Revol 2774720c31bSFrançois Revolfunction in_keymaps($keymap) 2784720c31bSFrançois Revol{ 2794720c31bSFrançois Revol $keymaps = list_keymaps(); 2804720c31bSFrançois Revol 2814720c31bSFrançois Revol if ($keymap == "") 2824720c31bSFrançois Revol return false; 2834720c31bSFrançois Revol if (in_array($keymap, $keymaps)) 2844720c31bSFrançois Revol return true; 2854720c31bSFrançois Revol 2864720c31bSFrançois Revol return false; 2874720c31bSFrançois Revol} 288c6f50a6aSFrançois Revol 289c6f50a6aSFrançois Revol 290c6f50a6aSFrançois Revolfunction probe_keymap() 291c6f50a6aSFrançois Revol{ 292c6f50a6aSFrançois Revol global $vnckeymap; 2934720c31bSFrançois Revol if (is_string($_GET['keymap']) && in_keymaps($_GET['keymap'])) 2944720c31bSFrançois Revol { 2954720c31bSFrançois Revol $vnckeymap = $_GET['keymap']; 2964720c31bSFrançois Revol dbg("Overriden keymap '" . $vnckeymap . "' in arguments."); 2974720c31bSFrançois Revol return; 2984720c31bSFrançois Revol } 299c6f50a6aSFrançois Revol // if the browser advertised a prefered lang... 300c6f50a6aSFrançois Revol if (!isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) 301c6f50a6aSFrançois Revol return; 302c6f50a6aSFrançois Revol $langs = $_SERVER["HTTP_ACCEPT_LANGUAGE"]; 303c6f50a6aSFrançois Revol $langs = ereg_replace(";q=[^,]*", "", $langs); 304c6f50a6aSFrançois Revol $langs = str_replace(" ", "", $langs); 305c6f50a6aSFrançois Revol $langs = split(",", $langs); 306c6f50a6aSFrançois Revol //print_r($langs); 307c6f50a6aSFrançois Revol //print_r($keymaps); 308c6f50a6aSFrançois Revol foreach($langs as $lang) 309c6f50a6aSFrançois Revol { 3104720c31bSFrançois Revol if (in_keymaps($lang)) 311c6f50a6aSFrançois Revol { 3124720c31bSFrançois Revol $vnckeymap = $lang; 313664c8b6dSFrançois Revol dbg("Detected keymap '" . $vnckeymap . 314664c8b6dSFrançois Revol "' from browser headers."); 315c6f50a6aSFrançois Revol return; 316c6f50a6aSFrançois Revol } 317c6f50a6aSFrançois Revol } 318c6f50a6aSFrançois Revol} 3194720c31bSFrançois Revol 3204720c31bSFrançois Revol 321f0cbfcafSFrançois Revolfunction probe_options_form() 322f0cbfcafSFrançois Revol{ 323f0cbfcafSFrançois Revol global $cpucount; 324f0cbfcafSFrançois Revol $cpucount = 1; 325f0cbfcafSFrançois Revol if (isset($_GET['cpucount'])) 326f0cbfcafSFrançois Revol $cpucount = (int)$_GET['cpucount']; 327f0cbfcafSFrançois Revol $cpucount = max(min($cpucount, 8), 1); 328f0cbfcafSFrançois Revol //dbg("cpucount $cpucount"); 329f0cbfcafSFrançois Revol $cpucount = 1; // force for now 330f0cbfcafSFrançois Revol} 331f0cbfcafSFrançois Revol 332f0cbfcafSFrançois Revol 3334720c31bSFrançois Revolfunction output_options_form() 3344720c31bSFrançois Revol{ 3354720c31bSFrançois Revol global $vnckeymap; 3364720c31bSFrançois Revol $idx = qemu_slot(); 3374720c31bSFrançois Revol echo "<form method=\"get\" action=\"" . $_SERVER['PHP_SELF'] . "\">"; 3384720c31bSFrançois Revol echo "<table border=\"0\" class=\"haiku_online_form\">\n"; 339d2bef01cSFrançois Revol 340f0cbfcafSFrançois Revol $keymaps = list_keymaps(); 341d2bef01cSFrançois Revol echo "<tr>\n<td align=\"right\">\n"; 3424720c31bSFrançois Revol echo "Select your keymap:"; 343d2bef01cSFrançois Revol echo "</td>\n<td>\n"; 3444720c31bSFrançois Revol echo "<select name=\"keymap\">"; 3454720c31bSFrançois Revol foreach ($keymaps as $keymap) { 346f0cbfcafSFrançois Revol echo "<option value=\"$keymap\" "; 3474720c31bSFrançois Revol if ($keymap == $vnckeymap) 348f0cbfcafSFrançois Revol echo "selected=\"selected\" "; 3494720c31bSFrançois Revol echo ">$keymap</option>"; 3504720c31bSFrançois Revol //echo "<option name=\"keymap\" "; 3514720c31bSFrançois Revol //echo "value=\"$keymap\">" . locale_get_display_name($keymap); 3524720c31bSFrançois Revol //echo "</option>"; 3534720c31bSFrançois Revol } 3544720c31bSFrançois Revol echo "</select>"; 355d2bef01cSFrançois Revol echo "</td>\n</tr>\n"; 3564720c31bSFrançois Revol 357f0cbfcafSFrançois Revol 3584720c31bSFrançois Revol $modes = array("1024x768"/*, "800x600"*/); 3594720c31bSFrançois Revol echo "<tr "; 3604720c31bSFrançois Revol if (count($modes) < 2) 3614720c31bSFrançois Revol echo "class=\"haiku_online_disabled\""; 3624720c31bSFrançois Revol echo ">\n"; 3634720c31bSFrançois Revol echo "<td align=\"right\">\n"; 3644720c31bSFrançois Revol echo "Select display size:"; 365d2bef01cSFrançois Revol echo "</td>\n<td>\n"; 3664720c31bSFrançois Revol echo "<select name=\"videomode\" "; 3674720c31bSFrançois Revol if (count($modes) < 2) 368f0cbfcafSFrançois Revol echo "disabled=\"disabled\""; 3694720c31bSFrançois Revol echo ">"; 3704720c31bSFrançois Revol foreach ($modes as $mode) { 371f0cbfcafSFrançois Revol echo "<option value=\"$mode\" "; 3724720c31bSFrançois Revol if ($mode == $videomode) 373f0cbfcafSFrançois Revol echo "selected=\"selected\" "; 3744720c31bSFrançois Revol echo ">$mode</option>"; 3754720c31bSFrançois Revol } 3764720c31bSFrançois Revol echo "</select>"; 377d2bef01cSFrançois Revol echo "</td>\n</tr>\n"; 3784720c31bSFrançois Revol 379f0cbfcafSFrançois Revol 380f0cbfcafSFrançois Revol $maxcpus = 8; 381f0cbfcafSFrançois Revol echo "<tr "; 382f0cbfcafSFrançois Revol if (!$enable_cpus) 383f0cbfcafSFrançois Revol echo "class=\"haiku_online_disabled\""; 384f0cbfcafSFrançois Revol echo ">\n"; 385f0cbfcafSFrançois Revol echo "<td align=\"right\">\n"; 386f0cbfcafSFrançois Revol echo "Select cpu count:"; 387f0cbfcafSFrançois Revol echo "</td>\n<td>\n"; 388f0cbfcafSFrançois Revol echo "<select name=\"cpucount\" "; 389f0cbfcafSFrançois Revol if (!$enable_cpus) 390f0cbfcafSFrançois Revol echo "disabled=\"disabled\""; 391f0cbfcafSFrançois Revol echo ">"; 392f0cbfcafSFrançois Revol for ($ncpu = 1; $ncpu <= $maxcpus; $ncpu++) { 393f0cbfcafSFrançois Revol echo "<option value=\"$ncpu\" "; 394f0cbfcafSFrançois Revol if ($ncpu == 1) 395f0cbfcafSFrançois Revol echo "selected=\"selected\" "; 396f0cbfcafSFrançois Revol echo ">$ncpu</option>"; 397f0cbfcafSFrançois Revol } 398f0cbfcafSFrançois Revol echo "</select>"; 399f0cbfcafSFrançois Revol echo "</td>\n</tr>\n"; 400f0cbfcafSFrançois Revol 401f0cbfcafSFrançois Revol 402f0cbfcafSFrançois Revol $enable_sound = 0; 4034720c31bSFrançois Revol echo "<tr "; 4044720c31bSFrançois Revol if (!$enable_sound) 4054720c31bSFrançois Revol echo "class=\"haiku_online_disabled\""; 4064720c31bSFrançois Revol echo ">\n"; 4074720c31bSFrançois Revol echo "<td align=\"right\">\n"; 408d2bef01cSFrançois Revol echo "Check to enable sound:"; 409d2bef01cSFrançois Revol echo "</td>\n<td>\n"; 410d2bef01cSFrançois Revol echo "<input type=\"checkbox\" name=\"sound\" id=\"sound_cb\" "; 411f0cbfcafSFrançois Revol echo "value=\"1\" "; 412664c8b6dSFrançois Revol if ($enable_sound) { 413*91054f1dSFrançois Revol echo "checked=\"checked\" /"; 414f0cbfcafSFrançois Revol } else 415f0cbfcafSFrançois Revol echo "disabled=\"disabled\" /"; 416*91054f1dSFrançois Revol echo "><label for=\"sound_cb\">Sound</label>"; 417d2bef01cSFrançois Revol echo "</td>\n</tr>\n"; 418d2bef01cSFrançois Revol 419f0cbfcafSFrançois Revol $enable_serial = 1; 420f0cbfcafSFrançois Revol echo "<tr "; 421f0cbfcafSFrançois Revol if (!$enable_serial) 422f0cbfcafSFrançois Revol echo "class=\"haiku_online_disabled\""; 423f0cbfcafSFrançois Revol echo ">\n"; 424f0cbfcafSFrançois Revol echo "<td align=\"right\">\n"; 425f0cbfcafSFrançois Revol echo "Check to enable serial output:"; 426f0cbfcafSFrançois Revol echo "</td>\n<td>\n"; 427f0cbfcafSFrançois Revol echo "<input type=\"checkbox\" name=\"serial\" id=\"serial_cb\" "; 428f0cbfcafSFrançois Revol echo "value=\"1\" "/*"disabled "*/; 429f0cbfcafSFrançois Revol if ($enable_serial) { 430f0cbfcafSFrançois Revol //echo "checked "; 431*91054f1dSFrançois Revol } 432*91054f1dSFrançois Revol echo "/><label for=\"serial_cb\">Serial</label>"; 433f0cbfcafSFrançois Revol echo "</td>\n</tr>\n"; 434f0cbfcafSFrançois Revol 435f0cbfcafSFrançois Revol if (defined("QEMU_USB_PASSTHROUGH")) { 436f0cbfcafSFrançois Revol 437f0cbfcafSFrançois Revol $enable_webcam = 1; 438f0cbfcafSFrançois Revol echo "<tr "; 439f0cbfcafSFrançois Revol if (!$enable_webcam) 440f0cbfcafSFrançois Revol echo "class=\"haiku_online_disabled\""; 441f0cbfcafSFrançois Revol echo ">\n"; 442f0cbfcafSFrançois Revol echo "<td align=\"right\">\n"; 443f0cbfcafSFrançois Revol echo "Check to enable webcam:"; 444f0cbfcafSFrançois Revol echo "</td>\n<td>\n"; 445f0cbfcafSFrançois Revol echo "<input type=\"checkbox\" name=\"webcam\" id=\"webcam_cb\" "; 446f0cbfcafSFrançois Revol echo "value=\"1\" "/*"disabled "*/; 447f0cbfcafSFrançois Revol if ($enable_webcam) { 448f0cbfcafSFrançois Revol //echo "checked "; 449*91054f1dSFrançois Revol } 450*91054f1dSFrançois Revol echo "/><label for=\"webcam_cb\">Webcam</label>"; 451f0cbfcafSFrançois Revol echo "</td>\n</tr>\n"; 452f0cbfcafSFrançois Revol } 453d2bef01cSFrançois Revol /* 454d2bef01cSFrançois Revol echo "<tr>\n<td align=\"right\">\n"; 4554720c31bSFrançois Revol //out("Click here to enable sound:"); 456d2bef01cSFrançois Revol echo "</td>\n<td>\n"; 457d2bef01cSFrançois Revol echo "</td>\n</tr>\n"; 458d2bef01cSFrançois Revol 459d2bef01cSFrançois Revol echo "<tr>\n<td align=\"right\">\n"; 460d2bef01cSFrançois Revol //out("Click here to enable sound:"); 461d2bef01cSFrançois Revol echo "</td>\n<td>\n"; 462d2bef01cSFrançois Revol echo "</td>\n</tr>\n"; 463d2bef01cSFrançois Revol */ 464d2bef01cSFrançois Revol 465d2bef01cSFrançois Revol echo "<tr>\n<td align=\"right\">\n"; 4664720c31bSFrançois Revol echo "Click here to start the session:"; 467d2bef01cSFrançois Revol echo "</td>\n<td>\n"; 4684720c31bSFrançois Revol echo "<input type=\"submit\" name=\"run\" "; 4694720c31bSFrançois Revol echo "value=\"Start!\" />"; 470d2bef01cSFrançois Revol echo "</td>\n</tr>\n"; 471d2bef01cSFrançois Revol 4724720c31bSFrançois Revol echo "</table>\n"; 4734720c31bSFrançois Revol echo "</form>\n"; 474664c8b6dSFrançois Revol out("NOTE: You will need a Java-enabled browser to display the VNC " . 475664c8b6dSFrançois Revol "Applet needed by this demo."); 4764720c31bSFrançois Revol out("You can however use instead an external <a " . 4774720c31bSFrançois Revol "href=\"http://fr.wikipedia.org/wiki/Virtual_Network_Computing\"" . 4784720c31bSFrançois Revol ">VNC viewer</a>."); 4794720c31bSFrançois Revol ob_flush(); 4804720c31bSFrançois Revol flush(); 4814720c31bSFrançois Revol} 4824720c31bSFrançois Revol 4834720c31bSFrançois Revolfunction output_kill_form() 4844720c31bSFrançois Revol{ 4854720c31bSFrançois Revol echo "<form method=\"get\" action=\"" . $_SERVER['PHP_SELF'] . "\">"; 4864720c31bSFrançois Revol echo "<table border=\"0\" class=\"haiku_online_form\">\n"; 4874720c31bSFrançois Revol echo "<tr>\n"; 4884720c31bSFrançois Revol echo "<td>\n"; 4894720c31bSFrançois Revol echo "Click here to kill the session:"; 4904720c31bSFrançois Revol echo "</td>\n"; 4914720c31bSFrançois Revol echo "<td>\n"; 4924720c31bSFrançois Revol echo "<input type=\"submit\" name=\"kill\" "; 4934720c31bSFrançois Revol echo "value=\"Terminate\"/>"; 4944720c31bSFrançois Revol echo "</td>\n"; 4954720c31bSFrançois Revol echo "</tr>\n"; 4964720c31bSFrançois Revol echo "</table>\n"; 4974720c31bSFrançois Revol echo "</form>\n"; 4984720c31bSFrançois Revol ob_flush(); 4994720c31bSFrançois Revol flush(); 500c6f50a6aSFrançois Revol} 501c6f50a6aSFrançois Revol 502c6f50a6aSFrançois Revol 503e8fc4975SFrançois Revolfunction start_qemu() 504e8fc4975SFrançois Revol{ 505c6f50a6aSFrançois Revol global $vnckeymap; 506f0cbfcafSFrançois Revol global $cpucount; 507e8fc4975SFrançois Revol $idx = find_qemu_slot(); 508e8fc4975SFrançois Revol if ($idx < 0) { 509e8fc4975SFrançois Revol err("No available qemu slot, please try later."); 510e8fc4975SFrançois Revol return $idx; 511e8fc4975SFrançois Revol } 512e8fc4975SFrançois Revol $pidfile = make_qemu_pidfile_name($idx); 513f0cbfcafSFrançois Revol $cmd = QEMU_BIN . " " . QEMU_ARGS; 514f0cbfcafSFrançois Revol if ($cpucount > 1) 515f0cbfcafSFrançois Revol $cmd .= " -smp " . $cpucount; 516f0cbfcafSFrançois Revol if (isset($_GET['serial'])) { 517f0cbfcafSFrançois Revol $cmd .= " -serial telnet::"; 518f0cbfcafSFrançois Revol $cmd .= (SERIALPORTBASE + qemu_slot()); 519f0cbfcafSFrançois Revol $cmd .= ",server,nowait,nodelay"; 520f0cbfcafSFrançois Revol } 521f0cbfcafSFrançois Revol if (isset($_GET['webcam']) && defined("QEMU_USB_PASSTHROUGH")) { 522f0cbfcafSFrançois Revol $cmd .= " " . QEMU_USB_PASSTHROUGH; 523f0cbfcafSFrançois Revol } 524f0cbfcafSFrançois Revol $cmd .= " -k " . $vnckeymap . 525664c8b6dSFrançois Revol " -vnc " . QEMU_VNC_PREFIX . vnc_display() . 526664c8b6dSFrançois Revol " -pidfile " . $pidfile . 527664c8b6dSFrançois Revol " " . QEMU_IMAGE_PATH; 528e8fc4975SFrançois Revol 529e8fc4975SFrançois Revol if (file_exists($pidfile)) 530e8fc4975SFrançois Revol unlink($pidfile); 531e8fc4975SFrançois Revol dbg("Starting <tt>" . $cmd . "</tt>..."); 532e8fc4975SFrançois Revol 533e8fc4975SFrançois Revol $descriptorspec = array( 534e8fc4975SFrançois Revol // 0 => array("pipe", "r"), // stdin 535e8fc4975SFrançois Revol // 1 => array("pipe", "w"), // stdout 536e8fc4975SFrançois Revol // 2 => array("pipe", "w") // stderr 537e8fc4975SFrançois Revol ); 538e8fc4975SFrançois Revol //$cmd="/bin/ls"; 539e8fc4975SFrançois Revol //passthru($cmd, $ret); 540e8fc4975SFrançois Revol //dbg("ret=$ret"); 541e8fc4975SFrançois Revol $cmd .= " &"; 542e8fc4975SFrançois Revol $process = proc_open($cmd, $descriptorspec, $pipes); 543e8fc4975SFrançois Revol sleep(1); 544e8fc4975SFrançois Revol proc_close($process); 545e8fc4975SFrançois Revol 546e8fc4975SFrançois Revol dbg("Started QEMU."); 547e8fc4975SFrançois Revol $sessfile = make_qemu_sessionfile_name($idx); 548664c8b6dSFrançois Revol $cmd = "(PID=`cat " . $pidfile . "`; " . 549664c8b6dSFrançois Revol "sleep " . SESSION_TIMEOUT . "; " . 550664c8b6dSFrançois Revol "kill -9 \$PID && " . 551664c8b6dSFrançois Revol "rm " . $pidfile . " " . $sessfile . ") &"; 552e8fc4975SFrançois Revol 553e8fc4975SFrançois Revol $process = proc_open($cmd, $descriptorspec, $wkpipes); 554e8fc4975SFrançois Revol sleep(1); 555e8fc4975SFrançois Revol proc_close($process); 556e8fc4975SFrançois Revol 557e8fc4975SFrançois Revol dbg("Started timed kill."); 558e8fc4975SFrançois Revol dbg("Ready for a " . SESSION_TIMEOUT . " session."); 559e8fc4975SFrançois Revol} 560e8fc4975SFrançois Revol 5614720c31bSFrançois Revolfunction stop_qemu() 5624720c31bSFrançois Revol{ 5634720c31bSFrançois Revol $qemuidx = qemu_slot(); 5644720c31bSFrançois Revol $pidfile = make_qemu_pidfile_name($qemuidx); 5654720c31bSFrançois Revol if (file_exists($pidfile)) { 5664720c31bSFrançois Revol $pid = file_get_contents($pidfile); 5674720c31bSFrançois Revol //out("PID:" . $pid); 5684720c31bSFrançois Revol system("/bin/kill -TERM " . $pid); 5694720c31bSFrançois Revol unlink($pidfile); 5704720c31bSFrançois Revol } 5714720c31bSFrançois Revol $sessionfile = make_qemu_sessionfile_name($qemuidx); 5724720c31bSFrançois Revol if (file_exists($sessionfile)) { 5734720c31bSFrançois Revol unlink($sessionfile); 5744720c31bSFrançois Revol } 5754720c31bSFrançois Revol unset($_SESSION[QEMU_IDX_VAR]); 5764720c31bSFrançois Revol 5774720c31bSFrançois Revol out("reloading..."); 5784720c31bSFrançois Revol sleep(1); 5794720c31bSFrançois Revol echo "<script>\n"; 5804720c31bSFrançois Revol echo "<!--\n"; 5814720c31bSFrançois Revol echo "window.location = \"" . $_SERVER['PHP_SELF'] . "\";\n"; 5824720c31bSFrançois Revol echo "//--></script>\n"; 5834720c31bSFrançois Revol out("Click <a href=\"" . $_SERVER['PHP_SELF'] . 5844720c31bSFrançois Revol "\">here</a> to reload the page."); 5854720c31bSFrançois Revol} 5864720c31bSFrançois Revol 5874720c31bSFrançois Revolfunction output_vnc_info() 5884720c31bSFrançois Revol{ 589664c8b6dSFrançois Revol out("You can use an external VNC client at " . 590664c8b6dSFrançois Revol "<a href=\"vnc://" . vnc_addr_display() . "\">" . 591664c8b6dSFrançois Revol "vnc://" . vnc_addr_display() . "</a> " . 5924720c31bSFrançois Revol "or enter <tt>" . vnc_addr_display() . "</tt> in your " . 593664c8b6dSFrançois Revol "<a href=\"http://fr.wikipedia.org/wiki/Virtual_Network_" . 594664c8b6dSFrançois Revol "Computing\"" . 595f0cbfcafSFrançois Revol ">VNC viewer</a>."); 596f0cbfcafSFrançois Revol //echo "<br />\n"; 5974720c31bSFrançois Revol} 598e8fc4975SFrançois Revol 599664c8b6dSFrançois Revolfunction output_audio_player_code($external_only=false) 600664c8b6dSFrançois Revol{ 601664c8b6dSFrançois Revol if (true) 602664c8b6dSFrançois Revol return; 603664c8b6dSFrançois Revol 604664c8b6dSFrançois Revol $port = audio_port(); 605664c8b6dSFrançois Revol $url = "http://" . $_SERVER['HTTP_HOST'] . ":$port/"; 606664c8b6dSFrançois Revol $icy = "icy://" . $_SERVER['HTTP_HOST'] . ":$port/"; 607664c8b6dSFrançois Revol if (!$external_only) { 608664c8b6dSFrançois Revol echo "<embed src=\"$url\" type=\"audio/mpeg\" "; 609664c8b6dSFrançois Revol echo "autoplay=\"true\" width=\"300\" height=\"50\" "; 610664c8b6dSFrançois Revol echo "controller=\"true\" align=\"right\">"; 611664c8b6dSFrançois Revol } 612664c8b6dSFrançois Revol out("You can use an external audio play at " . 613664c8b6dSFrançois Revol "<a href=\"$url\">$url</a> or <a href=\"$icy\">$icy</a>."); 614664c8b6dSFrançois Revol} 615664c8b6dSFrançois Revol 616664c8b6dSFrançois Revolfunction output_applet_code($external_only=false) 617e8fc4975SFrançois Revol{ 618e8fc4975SFrançois Revol $w = APPLET_WIDTH; 619e8fc4975SFrançois Revol $h = APPLET_HEIGHT; 620e8fc4975SFrançois Revol $port = vnc_port(); 621e8fc4975SFrançois Revol $vncjpath = VNCJAVA_PATH; 622e8fc4975SFrançois Revol $jar = VNCJAR; 623e8fc4975SFrançois Revol $class = VNCCLASS; 624664c8b6dSFrançois Revol if ($external_only) 625664c8b6dSFrançois Revol return; 626f0cbfcafSFrançois Revol echo "<a name=\"haiku_online_applet\"></a>"; 6274720c31bSFrançois Revol echo "<center>"; 6284720c31bSFrançois Revol echo "<applet code=$class codebase=\"$vncjpath/\" "; 6294720c31bSFrançois Revol echo "archive=\"$vncjpath/$jar\" width=$w height=$h "; 6304720c31bSFrançois Revol echo "bgcolor=\"#336698\">\n"; 6314720c31bSFrançois Revol //not needed 6324720c31bSFrançois Revol //echo "<param name=\"HOST\" value=\"$HTTP_HOST\">\n"; 6334720c31bSFrançois Revol echo "<param name=\"PORT\" value=\"$port\">\n"; 6344720c31bSFrançois Revol echo "<param name=\"PASSWORD\" value=\"\">\n"; 6354720c31bSFrançois Revol //echo "<param name=\"share desktop\" value=\"no\" />"; 6364720c31bSFrançois Revol echo "<param name=\"background-color\" value=\"#336698\">\n"; 6374720c31bSFrançois Revol echo "<param name=\"foreground-color\" value=\"#ffffff\">\n"; 6384720c31bSFrançois Revol //echo "<param name=\"background\" value=\"#336698\">\n"; 6394720c31bSFrançois Revol //echo "<param name=\"foreground\" value=\"#ffffff\">\n"; 6404720c31bSFrançois Revol echo "There should be a java applet here... "; 6414720c31bSFrançois Revol echo "make sure you have a JVM and it's enabled!<br />\n"; 6424720c31bSFrançois Revol echo "If you do not have Java you can use an external VNC "; 6434720c31bSFrançois Revol echo "client as described above.\n"; 6444720c31bSFrançois Revol 6454720c31bSFrançois Revol echo "</applet>\n"; 6464720c31bSFrançois Revol echo "</center>"; 6474720c31bSFrançois Revol ob_flush(); 6484720c31bSFrançois Revol flush(); 6494720c31bSFrançois Revol // scroll to the top of the applet 6504720c31bSFrançois Revol echo "<script>\n"; 6514720c31bSFrançois Revol echo "<!--\n"; 6524720c31bSFrançois Revol echo "window.location.hash = \"haiku_online_applet\";"; 6534720c31bSFrançois Revol echo "//--></script>\n"; 6544720c31bSFrançois Revol ob_flush(); 6554720c31bSFrançois Revol flush(); 656e8fc4975SFrançois Revol} 657e8fc4975SFrançois Revol 658f0cbfcafSFrançois Revolfunction output_serial_output_code($external_only=false) 659f0cbfcafSFrançois Revol{ 660f0cbfcafSFrançois Revol if (!isset($_GET['serial'])) 661f0cbfcafSFrançois Revol return; 662f0cbfcafSFrançois Revol 663f0cbfcafSFrançois Revol $url = "telnet://" . $_SERVER['HTTP_HOST'] . ":"; 664f0cbfcafSFrançois Revol $url .= (SERIALPORTBASE + qemu_slot()) . "/"; 665f0cbfcafSFrançois Revol out("You can get serial output at <a href=\"$url\">$url</a>"); 666f0cbfcafSFrançois Revol return; 667f0cbfcafSFrançois Revol 668f0cbfcafSFrançois Revol // not really http... 669f0cbfcafSFrançois Revol $url = "http://" . $_SERVER['HTTP_HOST'] . ":"; 670f0cbfcafSFrançois Revol $url .= (SERIALPORTBASE + qemu_slot()) . "/"; 671f0cbfcafSFrançois Revol echo "<center>"; 672f0cbfcafSFrançois Revol echo "<iframe src=\"$url/\" type=\"text/plain\" width=\"100%\" "; 673f0cbfcafSFrançois Revol echo "height=\"200\"></iframe>"; 674f0cbfcafSFrançois Revol echo "</center>"; 675f0cbfcafSFrançois Revol 676f0cbfcafSFrançois Revol} 677f0cbfcafSFrançois Revol 678f0cbfcafSFrançois Revolout("<div style=\"text-align:right;\">Available displays: " . 6794720c31bSFrançois Revol available_qemu_slots() . "/" . total_qemu_slots() . 6804720c31bSFrançois Revol "</div>"); 6814720c31bSFrançois Revol 6824720c31bSFrançois Revol 6834720c31bSFrançois Revolprobe_keymap(); 684f0cbfcafSFrançois Revolprobe_options_form(); 6854720c31bSFrançois Revol 686e8fc4975SFrançois Revoldbg("Checking if session is running..."); 687e8fc4975SFrançois Revol 6884720c31bSFrançois Revol$qemuidx = -1; 689c6f50a6aSFrançois Revol 690e8fc4975SFrançois Revolif (is_my_session_valid()) { 6914720c31bSFrançois Revol dbg("Session running."); 692e8fc4975SFrançois Revol $qemuidx = qemu_slot(); 6934720c31bSFrançois Revol if ($do_kill) { 694e8fc4975SFrançois Revol dbg("closing..."); 6954720c31bSFrançois Revol stop_qemu(); 696e8fc4975SFrançois Revol } 6974720c31bSFrançois Revol} else if (!$do_kill && $do_run) { 6984720c31bSFrançois Revol dbg("Need to start qemu."); 6994720c31bSFrançois Revol 7004720c31bSFrançois Revol $qemuidx = start_qemu(); 701f0cbfcafSFrançois Revol //out("Waiting for vnc server..."); 702f0cbfcafSFrançois Revol //sleep(5); 7034720c31bSFrançois Revol} 7044720c31bSFrançois Revol 7054720c31bSFrançois Revol 7064720c31bSFrançois Revolif ($qemuidx >= 0 && !$do_kill) { 7074720c31bSFrançois Revol output_kill_form(); 708f0cbfcafSFrançois Revol output_serial_output_code(); 709664c8b6dSFrançois Revol output_audio_player_code(); 7104720c31bSFrançois Revol output_vnc_info(); 711f0cbfcafSFrançois Revol out("Waiting for vnc server..."); 712f0cbfcafSFrançois Revol sleep(1); 7134720c31bSFrançois Revol output_applet_code(); 7144720c31bSFrançois Revol} else { 7154720c31bSFrançois Revol output_options_form(); 716e8fc4975SFrançois Revol} 717e8fc4975SFrançois Revol 718d2bef01cSFrançois Revol//phpinfo(); 719e8fc4975SFrançois Revol 720e8fc4975SFrançois Revol?> 721e8fc4975SFrançois Revol 722e8fc4975SFrançois Revol</body> 723e8fc4975SFrançois Revol</html> 724