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 8e8fc4975SFrançois Revol// relative path to the vnc java applet jar 9e8fc4975SFrançois Revol// you must *copy* (apache doesn't seem to like symlinks) it there. 10e8fc4975SFrançois Revol 11e8fc4975SFrançois Revol// on debian, apt-get install vnc-java will put them in 12e8fc4975SFrançois Revol// /usr/share/vnc-java 13e8fc4975SFrançois Revol//define("VNCJAVA_PATH", "vnc-java"); 14e8fc4975SFrançois Revol//define("VNCJAR", "vncviewer.jar"); 15e8fc4975SFrançois Revol//define("VNCCLASS", "vncviewer.class"); 16e8fc4975SFrançois Revol 17e8fc4975SFrançois Revol// to use the tightvnc applet instead (supports > 8bpp): 18e8fc4975SFrançois Revol// on debian, apt-get install tightvnc-java will put them in 19e8fc4975SFrançois Revol// /usr/share/tightvnc-java 20e8fc4975SFrançois Revoldefine("VNCJAVA_PATH", "tightvnc-java"); 21e8fc4975SFrançois Revoldefine("VNCJAR", "VncViewer.jar"); 22e8fc4975SFrançois Revoldefine("VNCCLASS", "VncViewer.class"); 23e8fc4975SFrançois Revol 24e8fc4975SFrançois Revol// maximum count of qemu instances. 25e8fc4975SFrançois Revoldefine("MAX_QEMUS", 8); 26e8fc4975SFrançois Revol 27e8fc4975SFrançois Revol// size of the java applet, must match the default resolution of the image. 2852a7cf96SFrançois Revol//define("APPLET_WIDTH", "800"); 2952a7cf96SFrançois Revol//define("APPLET_HEIGHT", "600"); 3052a7cf96SFrançois Revoldefine("APPLET_WIDTH", "1024"); 3152a7cf96SFrançois Revoldefine("APPLET_HEIGHT", "768"); 32e8fc4975SFrançois Revol// vnc protocol base port. 33e8fc4975SFrançois Revoldefine("VNCPORTBASE", 5900); 34e8fc4975SFrançois Revol 35e8fc4975SFrançois Revol// timeout before the demo session is killed, as argument to /bin/sleep 36*4720c31bSFrançois Revoldefine("SESSION_TIMEOUT", "20m"); 37e8fc4975SFrançois Revol 38e8fc4975SFrançois Revol// path to qemu binary 39c6f50a6aSFrançois Revoldefine("QEMU_BASE", "/usr/local"); 40c6f50a6aSFrançois Revoldefine("QEMU_BIN", QEMU_BASE . "/bin/qemu"); 41c6f50a6aSFrançois Revoldefine("QEMU_KEYMAPS", QEMU_BASE . "/share/qemu/keymaps"); 42e8fc4975SFrançois Revol// default arguments: no network, emulate tablet, readonly image file. 43*4720c31bSFrançois Revoldefine("QEMU_ARGS", "" 44*4720c31bSFrançois Revol ."-monitor /dev/null " 45*4720c31bSFrançois Revol ."-serial none " 46*4720c31bSFrançois Revol ."-parallel none " 47*4720c31bSFrançois Revol ." -net none " 48*4720c31bSFrançois Revol ."-usbdevice wacom-tablet " 49*4720c31bSFrançois Revol ."-vga vmware " 50*4720c31bSFrançois Revol ."-snapshot"); 51e8fc4975SFrançois Revol// absolute path to the image. 528ad2eabaSFrançois Revoldefine("QEMU_IMAGE_PATH","/home/revol/haiku/trunk/generated.x86/haiku.image"); 538ad2eabaSFrançois Revol// qemu 0.8.2 needs "", qemu 0.9.1 needs ":" 548ad2eabaSFrançois Revoldefine("QEMU_VNC_PREFIX", ":"); 55e8fc4975SFrançois Revol 56e8fc4975SFrançois Revol// name of session and pid files in /tmp 57e8fc4975SFrançois Revoldefine("QEMU_SESSFILE_TMPL", "qemu-haiku-session-"); 58e8fc4975SFrançois Revoldefine("QEMU_PIDFILE_TMPL", "qemu-haiku-pid-"); 59e8fc4975SFrançois Revol// name of session variable holding the qemu slot; not yet used correctly 60e8fc4975SFrançois Revoldefine("QEMU_IDX_VAR", "QEMU_HAIKU_SESSION_VAR"); 61e8fc4975SFrançois Revol 62*4720c31bSFrançois Revoldefine("BGCOLOR", "#336698"); 63*4720c31bSFrançois Revol 64*4720c31bSFrançois Revol$vnckeymap = "en-us"; 65*4720c31bSFrançois Revol 66*4720c31bSFrançois Revol// statics 67*4720c31bSFrançois Revol$count = $_SESSION['compteur']; 68*4720c31bSFrançois Revol//$count = $GLOBALS['compteur']; 69*4720c31bSFrançois Revol$closing = 0; 70*4720c31bSFrançois Revol$do_kill = 0; 71*4720c31bSFrançois Revol$do_run = 0; 72*4720c31bSFrançois Revol 73*4720c31bSFrançois Revol// parse args 74*4720c31bSFrançois Revolif (isset($_GET['close'])) 75*4720c31bSFrançois Revol $closing = 1; 76*4720c31bSFrançois Revol 77*4720c31bSFrançois Revolif (isset($_GET['kill'])) 78*4720c31bSFrançois Revol $do_kill = 1; 79*4720c31bSFrançois Revol 80*4720c31bSFrançois Revolif (isset($_GET['run'])) 81*4720c31bSFrançois Revol $do_run = 1; 82*4720c31bSFrançois Revol 83*4720c31bSFrançois Revolif (isset($_GET['frame'])) {} 84*4720c31bSFrançois Revol 85e8fc4975SFrançois Revolsession_start(); 86e8fc4975SFrançois Revol 87*4720c31bSFrançois Revol//echo "do_run: " . $do_run . "<br>\n"; 88*4720c31bSFrançois Revol//echo "do_kill: " . $do_kill . "<br>\n"; 89e8fc4975SFrançois Revol 90e8fc4975SFrançois Revol?> 91e8fc4975SFrançois Revol<html> 92e8fc4975SFrançois Revol<head> 93cdbd6446SFrançois Revol<meta name="robots" content="noindex, nofollow, noarchive"> 94cdbd6446SFrançois Revol<title>Haiku Online Demo</title> 95*4720c31bSFrançois Revol<style type="text/css"> 96*4720c31bSFrançois Revol<!-- 97*4720c31bSFrançois Revol /* basic style */ 98*4720c31bSFrançois Revolbody { background-color: <?php echo BGCOLOR; ?>; } 99*4720c31bSFrançois Revola:link { color:orange; } 100*4720c31bSFrançois Revola:visited { color:darkorange; } 101*4720c31bSFrançois Revola:hover { color:pink; } 102*4720c31bSFrançois Revol.haiku_online_form { color: white; } 103*4720c31bSFrançois Revol.haiku_online_disabled { color: grey; } 104*4720c31bSFrançois Revol.haiku_online_out { color: white; } 105*4720c31bSFrançois Revol.haiku_online_debug { color: orange; } 106*4720c31bSFrançois Revol.haiku_online_error { color: red; font-weight: bold; } 107*4720c31bSFrançois Revol.haiku_online_applet { background-color: <?php echo BGCOLOR; ?>; } 108*4720c31bSFrançois Revol--> 109*4720c31bSFrançois Revol</style> 110e8fc4975SFrançois Revol</head> 111e8fc4975SFrançois Revol<script> 112e8fc4975SFrançois Revolfunction onPageUnload() { 113e8fc4975SFrançois Revol //window.open("<?php echo $_SERVER["SCRIPT_NAME"] . "?close"; ?>", "closing", "width=100,height=30,location=no,menubar=no,toolbar=no,scrollbars=no"); 114e8fc4975SFrançois Revol} 115e8fc4975SFrançois Revol</script> 116e8fc4975SFrançois Revol<?php 117e8fc4975SFrançois Revol 118e8fc4975SFrançois Revol 119*4720c31bSFrançois Revolif ($closing == 1) 120e8fc4975SFrançois Revol echo "<body>"; 121*4720c31bSFrançois Revolelse 122e8fc4975SFrançois Revol echo "<body onunload=\"onPageUnload();\">"; 123e8fc4975SFrançois Revol 124*4720c31bSFrançois Revolfunction out($str) 125*4720c31bSFrançois Revol{ 126*4720c31bSFrançois Revol echo "<div class=\"haiku_online_out\">$str</div>\n"; 127*4720c31bSFrançois Revol ob_flush(); 128*4720c31bSFrançois Revol flush(); 129*4720c31bSFrançois Revol} 130*4720c31bSFrançois Revol 131e8fc4975SFrançois Revolfunction dbg($str) 132e8fc4975SFrançois Revol{ 133*4720c31bSFrançois Revol echo "<div class=\"haiku_online_debug\">$str</div>\n"; 134*4720c31bSFrançois Revol ob_flush(); 135*4720c31bSFrançois Revol flush(); 136e8fc4975SFrançois Revol} 137e8fc4975SFrançois Revol 138e8fc4975SFrançois Revolfunction err($str) 139e8fc4975SFrançois Revol{ 140*4720c31bSFrançois Revol echo "<div class=\"haiku_online_error\">$str</div>\n"; 141*4720c31bSFrançois Revol ob_flush(); 142*4720c31bSFrançois Revol flush(); 143e8fc4975SFrançois Revol} 144e8fc4975SFrançois Revol 145e8fc4975SFrançois Revolfunction make_qemu_sessionfile_name($idx) 146e8fc4975SFrançois Revol{ 147e8fc4975SFrançois Revol return "/tmp/" . QEMU_SESSFILE_TMPL . $idx; 148e8fc4975SFrançois Revol} 149e8fc4975SFrançois Revol 150e8fc4975SFrançois Revolfunction make_qemu_pidfile_name($idx) 151e8fc4975SFrançois Revol{ 152e8fc4975SFrançois Revol return "/tmp/" . QEMU_PIDFILE_TMPL . $idx; 153e8fc4975SFrançois Revol} 154e8fc4975SFrançois Revol 155e8fc4975SFrançois Revolfunction find_qemu_slot() 156e8fc4975SFrançois Revol{ 157e8fc4975SFrançois Revol for ($idx = 0; $idx < MAX_QEMUS; $idx++) { 158e8fc4975SFrançois Revol $pidfile = make_qemu_pidfile_name($idx); 159e8fc4975SFrançois Revol $sessfile = make_qemu_sessionfile_name($idx); 160e8fc4975SFrançois Revol dbg("checking \"$pidfile\", \"$sessfile\"..."); 161e8fc4975SFrançois Revol if (!file_exists($pidfile) && !file_exists($sessfile)) { 162e8fc4975SFrançois Revol file_put_contents($sessfile, session_id()); 163e8fc4975SFrançois Revol $sid = file_get_contents($sessfile); 164e8fc4975SFrançois Revol if ($sid != session_id()) 165e8fc4975SFrançois Revol continue; 166e8fc4975SFrançois Revol $_SESSION[QEMU_IDX_VAR] = $idx; 167e8fc4975SFrançois Revol return $idx; 168e8fc4975SFrançois Revol } 169e8fc4975SFrançois Revol } 170e8fc4975SFrançois Revol return -1; 171e8fc4975SFrançois Revol} 172e8fc4975SFrançois Revol 173*4720c31bSFrançois Revolfunction total_qemu_slots() 174*4720c31bSFrançois Revol{ 175*4720c31bSFrançois Revol return MAX_QEMUS; 176*4720c31bSFrançois Revol} 177*4720c31bSFrançois Revol 178*4720c31bSFrançois Revol 179*4720c31bSFrançois Revolfunction available_qemu_slots() 180*4720c31bSFrançois Revol{ 181*4720c31bSFrançois Revol $count = 0; 182*4720c31bSFrançois Revol for ($idx = 0; $idx < MAX_QEMUS; $idx++) { 183*4720c31bSFrançois Revol $pidfile = make_qemu_pidfile_name($idx); 184*4720c31bSFrançois Revol $sessfile = make_qemu_sessionfile_name($idx); 185*4720c31bSFrançois Revol //dbg("checking \"$pidfile\", \"$sessfile\"..."); 186*4720c31bSFrançois Revol if (!file_exists($pidfile) && !file_exists($sessfile)) 187*4720c31bSFrançois Revol $count++; 188*4720c31bSFrançois Revol } 189*4720c31bSFrançois Revol return $count; 190*4720c31bSFrançois Revol} 191*4720c31bSFrançois Revol 192e8fc4975SFrançois Revolfunction qemu_slot() 193e8fc4975SFrançois Revol{ 194e8fc4975SFrançois Revol return $_SESSION[QEMU_IDX_VAR]; 195e8fc4975SFrançois Revol} 196e8fc4975SFrançois Revol 197e8fc4975SFrançois Revolfunction vnc_display() 198e8fc4975SFrançois Revol{ 199e8fc4975SFrançois Revol return qemu_slot(); 200e8fc4975SFrançois Revol} 201e8fc4975SFrançois Revol 202e8fc4975SFrançois Revolfunction vnc_port() 203e8fc4975SFrançois Revol{ 204e8fc4975SFrançois Revol return VNCPORTBASE + vnc_display(); 205e8fc4975SFrançois Revol} 206e8fc4975SFrançois Revol 207*4720c31bSFrançois Revolfunction vnc_addr_display() 208*4720c31bSFrançois Revol{ 209*4720c31bSFrançois Revol return $_SERVER['SERVER_ADDR'] . ":" . vnc_display(); 210*4720c31bSFrançois Revol} 211*4720c31bSFrançois Revol 212*4720c31bSFrançois Revolfunction vnc_url() 213*4720c31bSFrançois Revol{ 214*4720c31bSFrançois Revol return "vnc://" . vnc_addr_display(); 215*4720c31bSFrançois Revol} 216*4720c31bSFrançois Revol 217e8fc4975SFrançois Revolfunction is_my_session_valid() 218e8fc4975SFrançois Revol{ 219e8fc4975SFrançois Revol if (!isset($_SESSION[QEMU_IDX_VAR])) 220e8fc4975SFrançois Revol return 0; 221e8fc4975SFrançois Revol $idx = $_SESSION[QEMU_IDX_VAR]; 222e8fc4975SFrançois Revol $sessfile = make_qemu_sessionfile_name($idx); 223e8fc4975SFrançois Revol if (!file_exists($sessfile)) 224e8fc4975SFrançois Revol return 0; 225e8fc4975SFrançois Revol $qemusession=file_get_contents($sessfile); 226e8fc4975SFrançois Revol // has expired 227e8fc4975SFrançois Revol if ($qemusession != session_id()) { 228e8fc4975SFrançois Revol return 0; 229e8fc4975SFrançois Revol } 230e8fc4975SFrançois Revol return 1; 231e8fc4975SFrançois Revol} 232e8fc4975SFrançois Revol 233e8fc4975SFrançois Revol 234*4720c31bSFrançois Revolfunction list_keymaps() 235*4720c31bSFrançois Revol{ 236*4720c31bSFrançois Revol $bads = array('.', '..', 'common', 'modifiers'); 237*4720c31bSFrançois Revol $keymaps = scandir(QEMU_KEYMAPS); 238*4720c31bSFrançois Revol foreach ($keymaps as $key => $map) { 239*4720c31bSFrançois Revol if (in_array($map, $bads)) 240*4720c31bSFrançois Revol unset($keymaps[$key]); 241*4720c31bSFrançois Revol } 242*4720c31bSFrançois Revol return $keymaps; 243*4720c31bSFrançois Revol} 244*4720c31bSFrançois Revol 245*4720c31bSFrançois Revol 246*4720c31bSFrançois Revolfunction in_keymaps($keymap) 247*4720c31bSFrançois Revol{ 248*4720c31bSFrançois Revol $keymaps = list_keymaps(); 249*4720c31bSFrançois Revol 250*4720c31bSFrançois Revol if ($keymap == "") 251*4720c31bSFrançois Revol return false; 252*4720c31bSFrançois Revol if (in_array($keymap, $keymaps)) 253*4720c31bSFrançois Revol return true; 254*4720c31bSFrançois Revol 255*4720c31bSFrançois Revol return false; 256*4720c31bSFrançois Revol} 257c6f50a6aSFrançois Revol 258c6f50a6aSFrançois Revol 259c6f50a6aSFrançois Revolfunction probe_keymap() 260c6f50a6aSFrançois Revol{ 261c6f50a6aSFrançois Revol global $vnckeymap; 262*4720c31bSFrançois Revol if (is_string($_GET['keymap']) && in_keymaps($_GET['keymap'])) 263*4720c31bSFrançois Revol { 264*4720c31bSFrançois Revol $vnckeymap = $_GET['keymap']; 265*4720c31bSFrançois Revol dbg("Overriden keymap '" . $vnckeymap . "' in arguments."); 266*4720c31bSFrançois Revol return; 267*4720c31bSFrançois Revol } 268c6f50a6aSFrançois Revol // if the browser advertised a prefered lang... 269c6f50a6aSFrançois Revol if (!isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) 270c6f50a6aSFrançois Revol return; 271c6f50a6aSFrançois Revol $langs = $_SERVER["HTTP_ACCEPT_LANGUAGE"]; 272c6f50a6aSFrançois Revol $langs = ereg_replace(";q=[^,]*", "", $langs); 273c6f50a6aSFrançois Revol $langs = str_replace(" ", "", $langs); 274c6f50a6aSFrançois Revol $langs = split(",", $langs); 275c6f50a6aSFrançois Revol //print_r($langs); 276c6f50a6aSFrançois Revol //print_r($keymaps); 277c6f50a6aSFrançois Revol foreach($langs as $lang) 278c6f50a6aSFrançois Revol { 279*4720c31bSFrançois Revol if (in_keymaps($lang)) 280c6f50a6aSFrançois Revol { 281*4720c31bSFrançois Revol $vnckeymap = $lang; 282*4720c31bSFrançois Revol dbg("Detected keymap '" . $vnckeymap . "' from browser headers."); 283c6f50a6aSFrançois Revol return; 284c6f50a6aSFrançois Revol } 285c6f50a6aSFrançois Revol } 286c6f50a6aSFrançois Revol} 287*4720c31bSFrançois Revol 288*4720c31bSFrançois Revol 289*4720c31bSFrançois Revolfunction output_options_form() 290*4720c31bSFrançois Revol{ 291*4720c31bSFrançois Revol global $vnckeymap; 292*4720c31bSFrançois Revol $idx = qemu_slot(); 293*4720c31bSFrançois Revol echo "<form method=\"get\" action=\"" . $_SERVER['PHP_SELF'] . "\">"; 294*4720c31bSFrançois Revol echo "<table border=\"0\" class=\"haiku_online_form\">\n"; 295*4720c31bSFrançois Revol echo "<tr>\n"; 296*4720c31bSFrançois Revol echo "<td align=\"right\">\n"; 297*4720c31bSFrançois Revol echo "Select your keymap:"; 298*4720c31bSFrançois Revol echo "</td>\n"; 299*4720c31bSFrançois Revol echo "<td>\n"; 300*4720c31bSFrançois Revol echo "<select name=\"keymap\">"; 301*4720c31bSFrançois Revol $keymaps = list_keymaps(); 302*4720c31bSFrançois Revol foreach ($keymaps as $keymap) { 303*4720c31bSFrançois Revol echo "<option name=\"keymap\" value=\"$keymap\" "; 304*4720c31bSFrançois Revol if ($keymap == $vnckeymap) 305*4720c31bSFrançois Revol echo "selected "; 306*4720c31bSFrançois Revol echo ">$keymap</option>"; 307*4720c31bSFrançois Revol //echo "<option name=\"keymap\" "; 308*4720c31bSFrançois Revol //echo "value=\"$keymap\">" . locale_get_display_name($keymap); 309*4720c31bSFrançois Revol //echo "</option>"; 310*4720c31bSFrançois Revol } 311*4720c31bSFrançois Revol echo "</select>"; 312*4720c31bSFrançois Revol echo "</td>\n"; 313*4720c31bSFrançois Revol echo "</tr>\n"; 314*4720c31bSFrançois Revol 315*4720c31bSFrançois Revol $modes = array("1024x768"/*, "800x600"*/); 316*4720c31bSFrançois Revol echo "<tr "; 317*4720c31bSFrançois Revol if (count($modes) < 2) 318*4720c31bSFrançois Revol echo "class=\"haiku_online_disabled\""; 319*4720c31bSFrançois Revol echo ">\n"; 320*4720c31bSFrançois Revol echo "<td align=\"right\">\n"; 321*4720c31bSFrançois Revol echo "Select display size:"; 322*4720c31bSFrançois Revol echo "</td>\n"; 323*4720c31bSFrançois Revol echo "<td>\n"; 324*4720c31bSFrançois Revol echo "<select name=\"videomode\" "; 325*4720c31bSFrançois Revol if (count($modes) < 2) 326*4720c31bSFrançois Revol echo "disabled"; 327*4720c31bSFrançois Revol echo ">"; 328*4720c31bSFrançois Revol 329*4720c31bSFrançois Revol foreach ($modes as $mode) { 330*4720c31bSFrançois Revol echo "<option name=\"videomode\" value=\"$mode\" "; 331*4720c31bSFrançois Revol if ($mode == $videomode) 332*4720c31bSFrançois Revol echo "selected "; 333*4720c31bSFrançois Revol echo ">$mode</option>"; 334*4720c31bSFrançois Revol } 335*4720c31bSFrançois Revol echo "</select>"; 336*4720c31bSFrançois Revol 337*4720c31bSFrançois Revol echo "</td>\n"; 338*4720c31bSFrançois Revol 339*4720c31bSFrançois Revol echo "</tr>\n"; 340*4720c31bSFrançois Revol echo "<tr "; 341*4720c31bSFrançois Revol if (!$enable_sound) 342*4720c31bSFrançois Revol echo "class=\"haiku_online_disabled\""; 343*4720c31bSFrançois Revol echo ">\n"; 344*4720c31bSFrançois Revol echo "<td align=\"right\">\n"; 345*4720c31bSFrançois Revol echo "Click here to enable sound:"; 346*4720c31bSFrançois Revol echo "</td>\n"; 347*4720c31bSFrançois Revol echo "<td>\n"; 348*4720c31bSFrançois Revol echo "<input type=\"checkbox\" name=\"sound\" "; 349*4720c31bSFrançois Revol echo "value=\"1\" disabled "; 350*4720c31bSFrançois Revol if ($enable_sound) 351*4720c31bSFrançois Revol echo "checked "; 352*4720c31bSFrançois Revol echo ">Sound</input>"; 353*4720c31bSFrançois Revol echo "</td>\n"; 354*4720c31bSFrançois Revol echo "</tr>\n"; 355*4720c31bSFrançois Revol echo "<tr>\n"; 356*4720c31bSFrançois Revol echo "<td align=\"right\">\n"; 357*4720c31bSFrançois Revol //out("Click here to enable sound:"); 358*4720c31bSFrançois Revol echo "</td>\n"; 359*4720c31bSFrançois Revol echo "<td>\n"; 360*4720c31bSFrançois Revol echo "</td>\n"; 361*4720c31bSFrançois Revol echo "</tr>\n"; 362*4720c31bSFrançois Revol echo "<tr>\n"; 363*4720c31bSFrançois Revol echo "<td align=\"right\">\n"; 364*4720c31bSFrançois Revol echo "Click here to start the session:"; 365*4720c31bSFrançois Revol echo "</td>\n"; 366*4720c31bSFrançois Revol echo "<td>\n"; 367*4720c31bSFrançois Revol echo "<input type=\"submit\" name=\"run\" "; 368*4720c31bSFrançois Revol echo "value=\"Start!\" />"; 369*4720c31bSFrançois Revol echo "</td>\n"; 370*4720c31bSFrançois Revol echo "</tr>\n"; 371*4720c31bSFrançois Revol echo "</table>\n"; 372*4720c31bSFrançois Revol echo "</form>\n"; 373*4720c31bSFrançois Revol out("NOTE: You will need a Java-enabled browser to display the VNC Applet needed by this demo."); 374*4720c31bSFrançois Revol out("You can however use instead an external <a " . 375*4720c31bSFrançois Revol "href=\"http://fr.wikipedia.org/wiki/Virtual_Network_Computing\"" . 376*4720c31bSFrançois Revol ">VNC viewer</a>."); 377*4720c31bSFrançois Revol ob_flush(); 378*4720c31bSFrançois Revol flush(); 379*4720c31bSFrançois Revol} 380*4720c31bSFrançois Revol 381*4720c31bSFrançois Revolfunction output_kill_form() 382*4720c31bSFrançois Revol{ 383*4720c31bSFrançois Revol echo "<form method=\"get\" action=\"" . $_SERVER['PHP_SELF'] . "\">"; 384*4720c31bSFrançois Revol echo "<table border=\"0\" class=\"haiku_online_form\">\n"; 385*4720c31bSFrançois Revol echo "<tr>\n"; 386*4720c31bSFrançois Revol echo "<td>\n"; 387*4720c31bSFrançois Revol echo "Click here to kill the session:"; 388*4720c31bSFrançois Revol echo "</td>\n"; 389*4720c31bSFrançois Revol echo "<td>\n"; 390*4720c31bSFrançois Revol echo "<input type=\"submit\" name=\"kill\" "; 391*4720c31bSFrançois Revol echo "value=\"Terminate\"/>"; 392*4720c31bSFrançois Revol echo "</td>\n"; 393*4720c31bSFrançois Revol echo "</tr>\n"; 394*4720c31bSFrançois Revol echo "</table>\n"; 395*4720c31bSFrançois Revol echo "</form>\n"; 396*4720c31bSFrançois Revol ob_flush(); 397*4720c31bSFrançois Revol flush(); 398c6f50a6aSFrançois Revol} 399c6f50a6aSFrançois Revol 400c6f50a6aSFrançois Revol 401e8fc4975SFrançois Revolfunction start_qemu() 402e8fc4975SFrançois Revol{ 403c6f50a6aSFrançois Revol global $vnckeymap; 404e8fc4975SFrançois Revol $idx = find_qemu_slot(); 405e8fc4975SFrançois Revol if ($idx < 0) { 406e8fc4975SFrançois Revol err("No available qemu slot, please try later."); 407e8fc4975SFrançois Revol return $idx; 408e8fc4975SFrançois Revol } 409e8fc4975SFrançois Revol $pidfile = make_qemu_pidfile_name($idx); 410c6f50a6aSFrançois Revol $cmd = QEMU_BIN . " " . QEMU_ARGS . " -k " . $vnckeymap . " -vnc " . QEMU_VNC_PREFIX . vnc_display() . " -pidfile " . $pidfile . " " . QEMU_IMAGE_PATH; 411e8fc4975SFrançois Revol 412e8fc4975SFrançois Revol if (file_exists($pidfile)) 413e8fc4975SFrançois Revol unlink($pidfile); 414e8fc4975SFrançois Revol dbg("Starting <tt>" . $cmd . "</tt>..."); 415e8fc4975SFrançois Revol 416e8fc4975SFrançois Revol $descriptorspec = array( 417e8fc4975SFrançois Revol // 0 => array("pipe", "r"), // stdin 418e8fc4975SFrançois Revol // 1 => array("pipe", "w"), // stdout 419e8fc4975SFrançois Revol // 2 => array("pipe", "w") // stderr 420e8fc4975SFrançois Revol ); 421e8fc4975SFrançois Revol //$cmd="/bin/ls"; 422e8fc4975SFrançois Revol //passthru($cmd, $ret); 423e8fc4975SFrançois Revol //dbg("ret=$ret"); 424e8fc4975SFrançois Revol $cmd .= " &"; 425e8fc4975SFrançois Revol $process = proc_open($cmd, $descriptorspec, $pipes); 426e8fc4975SFrançois Revol sleep(1); 427e8fc4975SFrançois Revol proc_close($process); 428e8fc4975SFrançois Revol 429e8fc4975SFrançois Revol dbg("Started QEMU."); 430e8fc4975SFrançois Revol $sessfile = make_qemu_sessionfile_name($idx); 431e8fc4975SFrançois Revol $cmd = "(sleep " . SESSION_TIMEOUT . "; kill -9 `cat " . $pidfile . "`; rm " . $pidfile . " " . $sessfile . ") &"; 432e8fc4975SFrançois Revol 433e8fc4975SFrançois Revol $process = proc_open($cmd, $descriptorspec, $wkpipes); 434e8fc4975SFrançois Revol sleep(1); 435e8fc4975SFrançois Revol proc_close($process); 436e8fc4975SFrançois Revol 437e8fc4975SFrançois Revol dbg("Started timed kill."); 438e8fc4975SFrançois Revol dbg("Ready for a " . SESSION_TIMEOUT . " session."); 439e8fc4975SFrançois Revol} 440e8fc4975SFrançois Revol 441*4720c31bSFrançois Revolfunction stop_qemu() 442*4720c31bSFrançois Revol{ 443*4720c31bSFrançois Revol $qemuidx = qemu_slot(); 444*4720c31bSFrançois Revol $pidfile = make_qemu_pidfile_name($qemuidx); 445*4720c31bSFrançois Revol if (file_exists($pidfile)) { 446*4720c31bSFrançois Revol $pid = file_get_contents($pidfile); 447*4720c31bSFrançois Revol //out("PID:" . $pid); 448*4720c31bSFrançois Revol system("/bin/kill -TERM " . $pid); 449*4720c31bSFrançois Revol unlink($pidfile); 450*4720c31bSFrançois Revol } 451*4720c31bSFrançois Revol $sessionfile = make_qemu_sessionfile_name($qemuidx); 452*4720c31bSFrançois Revol if (file_exists($sessionfile)) { 453*4720c31bSFrançois Revol unlink($sessionfile); 454*4720c31bSFrançois Revol } 455*4720c31bSFrançois Revol unset($_SESSION[QEMU_IDX_VAR]); 456*4720c31bSFrançois Revol 457*4720c31bSFrançois Revol out("reloading..."); 458*4720c31bSFrançois Revol sleep(1); 459*4720c31bSFrançois Revol echo "<script>\n"; 460*4720c31bSFrançois Revol echo "<!--\n"; 461*4720c31bSFrançois Revol echo "window.location = \"" . $_SERVER['PHP_SELF'] . "\";\n"; 462*4720c31bSFrançois Revol echo "//--></script>\n"; 463*4720c31bSFrançois Revol out("Click <a href=\"" . $_SERVER['PHP_SELF'] . 464*4720c31bSFrançois Revol "\">here</a> to reload the page."); 465*4720c31bSFrançois Revol} 466*4720c31bSFrançois Revol 467*4720c31bSFrançois Revolfunction output_vnc_info() 468*4720c31bSFrançois Revol{ 469*4720c31bSFrançois Revol out("You can use an external VNC client, click " . 470*4720c31bSFrançois Revol "<a href=\"vnc://" . vnc_addr_display() . "\">here</a> " . 471*4720c31bSFrançois Revol "or enter <tt>" . vnc_addr_display() . "</tt> in your " . 472*4720c31bSFrançois Revol "<a href=\"http://fr.wikipedia.org/wiki/Virtual_Network_Computing\"" . 473*4720c31bSFrançois Revol ">VNC viewer</a>.<br />"); 474*4720c31bSFrançois Revol} 475e8fc4975SFrançois Revol 476e8fc4975SFrançois Revolfunction output_applet_code() 477e8fc4975SFrançois Revol{ 478e8fc4975SFrançois Revol $w = APPLET_WIDTH; 479e8fc4975SFrançois Revol $h = APPLET_HEIGHT; 480e8fc4975SFrançois Revol $port = vnc_port(); 481e8fc4975SFrançois Revol $vncjpath = VNCJAVA_PATH; 482e8fc4975SFrançois Revol $jar = VNCJAR; 483e8fc4975SFrançois Revol $class = VNCCLASS; 484*4720c31bSFrançois Revol echo "<a name=\"haiku_online_applet\">"; 485*4720c31bSFrançois Revol echo "<center>"; 486*4720c31bSFrançois Revol echo "<applet code=$class codebase=\"$vncjpath/\" "; 487*4720c31bSFrançois Revol echo "archive=\"$vncjpath/$jar\" width=$w height=$h "; 488*4720c31bSFrançois Revol echo "bgcolor=\"#336698\">\n"; 489*4720c31bSFrançois Revol //not needed 490*4720c31bSFrançois Revol //echo "<param name=\"HOST\" value=\"$HTTP_HOST\">\n"; 491*4720c31bSFrançois Revol echo "<param name=\"PORT\" value=\"$port\">\n"; 492*4720c31bSFrançois Revol echo "<param name=\"PASSWORD\" value=\"\">\n"; 493*4720c31bSFrançois Revol //echo "<param name=\"share desktop\" value=\"no\" />"; 494*4720c31bSFrançois Revol echo "<param name=\"background-color\" value=\"#336698\">\n"; 495*4720c31bSFrançois Revol echo "<param name=\"foreground-color\" value=\"#ffffff\">\n"; 496*4720c31bSFrançois Revol //echo "<param name=\"background\" value=\"#336698\">\n"; 497*4720c31bSFrançois Revol //echo "<param name=\"foreground\" value=\"#ffffff\">\n"; 498*4720c31bSFrançois Revol echo "There should be a java applet here... "; 499*4720c31bSFrançois Revol echo "make sure you have a JVM and it's enabled!<br />\n"; 500*4720c31bSFrançois Revol echo "If you do not have Java you can use an external VNC "; 501*4720c31bSFrançois Revol echo "client as described above.\n"; 502*4720c31bSFrançois Revol 503*4720c31bSFrançois Revol echo "</applet>\n"; 504*4720c31bSFrançois Revol echo "</center>"; 505*4720c31bSFrançois Revol ob_flush(); 506*4720c31bSFrançois Revol flush(); 507*4720c31bSFrançois Revol // scroll to the top of the applet 508*4720c31bSFrançois Revol echo "<script>\n"; 509*4720c31bSFrançois Revol echo "<!--\n"; 510*4720c31bSFrançois Revol echo "window.location.hash = \"haiku_online_applet\";"; 511*4720c31bSFrançois Revol echo "//--></script>\n"; 512*4720c31bSFrançois Revol ob_flush(); 513*4720c31bSFrançois Revol flush(); 514e8fc4975SFrançois Revol} 515e8fc4975SFrançois Revol 516*4720c31bSFrançois Revolout("<div align\"right\">Available displays: " . 517*4720c31bSFrançois Revol available_qemu_slots() . "/" . total_qemu_slots() . 518*4720c31bSFrançois Revol "</div>"); 519*4720c31bSFrançois Revol 520*4720c31bSFrançois Revol 521*4720c31bSFrançois Revolprobe_keymap(); 522*4720c31bSFrançois Revol 523*4720c31bSFrançois Revol 524e8fc4975SFrançois Revoldbg("Checking if session is running..."); 525e8fc4975SFrançois Revol 526*4720c31bSFrançois Revol$qemuidx = -1; 527c6f50a6aSFrançois Revol 528e8fc4975SFrançois Revolif (is_my_session_valid()) { 529*4720c31bSFrançois Revol dbg("Session running."); 530e8fc4975SFrançois Revol $qemuidx = qemu_slot(); 531*4720c31bSFrançois Revol if ($do_kill) { 532e8fc4975SFrançois Revol dbg("closing..."); 533*4720c31bSFrançois Revol stop_qemu(); 534e8fc4975SFrançois Revol } 535*4720c31bSFrançois Revol} else if (!$do_kill && $do_run) { 536*4720c31bSFrançois Revol dbg("Need to start qemu."); 537*4720c31bSFrançois Revol 538*4720c31bSFrançois Revol $qemuidx = start_qemu(); 539*4720c31bSFrançois Revol out("Waiting for vnc server..."); 540*4720c31bSFrançois Revol sleep(5); 541*4720c31bSFrançois Revol} 542*4720c31bSFrançois Revol 543*4720c31bSFrançois Revol 544*4720c31bSFrançois Revolif ($qemuidx >= 0 && !$do_kill) { 545*4720c31bSFrançois Revol output_kill_form(); 546*4720c31bSFrançois Revol output_vnc_info(); 547*4720c31bSFrançois Revol echo "<br />\n"; 548*4720c31bSFrançois Revol output_applet_code(); 549*4720c31bSFrançois Revol} else { 550*4720c31bSFrançois Revol output_options_form(); 551e8fc4975SFrançois Revol} 552e8fc4975SFrançois Revol 553e8fc4975SFrançois Revol 554e8fc4975SFrançois Revol 555e8fc4975SFrançois Revol?> 556e8fc4975SFrançois Revol 557e8fc4975SFrançois Revol</body> 558e8fc4975SFrançois Revol</html> 559