xref: /haiku/3rdparty/mmu_man/onlinedemo/haiku.php (revision c6f50a6aa910dd97a67a5f5142b410f272fd4e5f)
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
36e8fc4975SFrançois Revoldefine("SESSION_TIMEOUT", "10m");
37e8fc4975SFrançois Revol
38e8fc4975SFrançois Revol// path to qemu binary
39*c6f50a6aSFrançois Revoldefine("QEMU_BASE", "/usr/local");
40*c6f50a6aSFrançois Revoldefine("QEMU_BIN", QEMU_BASE . "/bin/qemu");
41*c6f50a6aSFrançois Revoldefine("QEMU_KEYMAPS", QEMU_BASE . "/share/qemu/keymaps");
42e8fc4975SFrançois Revol// default arguments: no network, emulate tablet, readonly image file.
43*c6f50a6aSFrançois Revoldefine("QEMU_ARGS","-net none -usbdevice wacom-tablet -snapshot");
44e8fc4975SFrançois Revol// absolute path to the image.
458ad2eabaSFrançois Revoldefine("QEMU_IMAGE_PATH","/home/revol/haiku/trunk/generated.x86/haiku.image");
468ad2eabaSFrançois Revol// qemu 0.8.2 needs "", qemu 0.9.1 needs ":"
478ad2eabaSFrançois Revoldefine("QEMU_VNC_PREFIX", ":");
48e8fc4975SFrançois Revol
49e8fc4975SFrançois Revol// name of session and pid files in /tmp
50e8fc4975SFrançois Revoldefine("QEMU_SESSFILE_TMPL", "qemu-haiku-session-");
51e8fc4975SFrançois Revoldefine("QEMU_PIDFILE_TMPL", "qemu-haiku-pid-");
52e8fc4975SFrançois Revol// name of session variable holding the qemu slot; not yet used correctly
53e8fc4975SFrançois Revoldefine("QEMU_IDX_VAR", "QEMU_HAIKU_SESSION_VAR");
54e8fc4975SFrançois Revol
55e8fc4975SFrançois Revolsession_start();
56e8fc4975SFrançois Revol
57e8fc4975SFrançois Revolif (isset($_GET['frame'])) {
58e8fc4975SFrançois Revol}
59e8fc4975SFrançois Revol
60e8fc4975SFrançois Revol?>
61e8fc4975SFrançois Revol<html>
62e8fc4975SFrançois Revol<head>
63cdbd6446SFrançois Revol<meta name="robots" content="noindex, nofollow, noarchive">
64cdbd6446SFrançois Revol<title>Haiku Online Demo</title>
65e8fc4975SFrançois Revol</head>
66e8fc4975SFrançois Revol<script>
67e8fc4975SFrançois Revolfunction onPageUnload() {
68e8fc4975SFrançois Revol	//window.open("<?php echo $_SERVER["SCRIPT_NAME"] . "?close"; ?>", "closing", "width=100,height=30,location=no,menubar=no,toolbar=no,scrollbars=no");
69e8fc4975SFrançois Revol}
70e8fc4975SFrançois Revol</script>
71e8fc4975SFrançois Revol<?php
72e8fc4975SFrançois Revol
73*c6f50a6aSFrançois Revol$vnckeymap = "en-us";
74e8fc4975SFrançois Revol
75e8fc4975SFrançois Revol// statics
76e8fc4975SFrançois Revol
77e8fc4975SFrançois Revol$count = $_SESSION['compteur'];
78e8fc4975SFrançois Revol//$count = $GLOBALS['compteur'];
79e8fc4975SFrançois Revol$closing = 0;
80e8fc4975SFrançois Revolif (isset($_GET['close'])) {
81e8fc4975SFrançois Revol	$closing = 1;
82e8fc4975SFrançois Revol	echo "<body>";
83e8fc4975SFrançois Revol} else
84e8fc4975SFrançois Revol	echo "<body onunload=\"onPageUnload();\">";
85e8fc4975SFrançois Revol
86e8fc4975SFrançois Revolfunction dbg($str)
87e8fc4975SFrançois Revol{
88e8fc4975SFrançois Revol	echo "<div class=\"debug\">$str</div>\n";
89e8fc4975SFrançois Revol}
90e8fc4975SFrançois Revol
91e8fc4975SFrançois Revolfunction err($str)
92e8fc4975SFrançois Revol{
93e8fc4975SFrançois Revol	echo "<div class=\"error\">$str</div>\n";
94e8fc4975SFrançois Revol}
95e8fc4975SFrançois Revol
96e8fc4975SFrançois Revolfunction make_qemu_sessionfile_name($idx)
97e8fc4975SFrançois Revol{
98e8fc4975SFrançois Revol	return "/tmp/" . QEMU_SESSFILE_TMPL . $idx;
99e8fc4975SFrançois Revol}
100e8fc4975SFrançois Revol
101e8fc4975SFrançois Revolfunction make_qemu_pidfile_name($idx)
102e8fc4975SFrançois Revol{
103e8fc4975SFrançois Revol	return "/tmp/" . QEMU_PIDFILE_TMPL . $idx;
104e8fc4975SFrançois Revol}
105e8fc4975SFrançois Revol
106e8fc4975SFrançois Revolfunction find_qemu_slot()
107e8fc4975SFrançois Revol{
108e8fc4975SFrançois Revol	for ($idx = 0; $idx < MAX_QEMUS; $idx++) {
109e8fc4975SFrançois Revol		$pidfile = make_qemu_pidfile_name($idx);
110e8fc4975SFrançois Revol		$sessfile = make_qemu_sessionfile_name($idx);
111e8fc4975SFrançois Revol		dbg("checking \"$pidfile\", \"$sessfile\"...");
112e8fc4975SFrançois Revol		if (!file_exists($pidfile) && !file_exists($sessfile)) {
113e8fc4975SFrançois Revol			file_put_contents($sessfile, session_id());
114e8fc4975SFrançois Revol			$sid = file_get_contents($sessfile);
115e8fc4975SFrançois Revol			if ($sid != session_id())
116e8fc4975SFrançois Revol				continue;
117e8fc4975SFrançois Revol			$_SESSION[QEMU_IDX_VAR] = $idx;
118e8fc4975SFrançois Revol			return $idx;
119e8fc4975SFrançois Revol		}
120e8fc4975SFrançois Revol	}
121e8fc4975SFrançois Revol	return -1;
122e8fc4975SFrançois Revol}
123e8fc4975SFrançois Revol
124e8fc4975SFrançois Revolfunction qemu_slot()
125e8fc4975SFrançois Revol{
126e8fc4975SFrançois Revol	return $_SESSION[QEMU_IDX_VAR];
127e8fc4975SFrançois Revol}
128e8fc4975SFrançois Revol
129e8fc4975SFrançois Revolfunction vnc_display()
130e8fc4975SFrançois Revol{
131e8fc4975SFrançois Revol	return qemu_slot();
132e8fc4975SFrançois Revol}
133e8fc4975SFrançois Revol
134e8fc4975SFrançois Revolfunction vnc_port()
135e8fc4975SFrançois Revol{
136e8fc4975SFrançois Revol	return VNCPORTBASE + vnc_display();
137e8fc4975SFrançois Revol}
138e8fc4975SFrançois Revol
139e8fc4975SFrançois Revolfunction is_my_session_valid()
140e8fc4975SFrançois Revol{
141e8fc4975SFrançois Revol	if (!isset($_SESSION[QEMU_IDX_VAR]))
142e8fc4975SFrançois Revol		return 0;
143e8fc4975SFrançois Revol	$idx = $_SESSION[QEMU_IDX_VAR];
144e8fc4975SFrançois Revol	$sessfile = make_qemu_sessionfile_name($idx);
145e8fc4975SFrançois Revol	if (!file_exists($sessfile))
146e8fc4975SFrançois Revol		return 0;
147e8fc4975SFrançois Revol	$qemusession=file_get_contents($sessfile);
148e8fc4975SFrançois Revol	// has expired
149e8fc4975SFrançois Revol	if ($qemusession != session_id()) {
150e8fc4975SFrançois Revol		return 0;
151e8fc4975SFrançois Revol	}
152e8fc4975SFrançois Revol	return 1;
153e8fc4975SFrançois Revol}
154e8fc4975SFrançois Revol
155e8fc4975SFrançois Revol
156*c6f50a6aSFrançois Revol
157*c6f50a6aSFrançois Revol
158*c6f50a6aSFrançois Revolfunction probe_keymap()
159*c6f50a6aSFrançois Revol{
160*c6f50a6aSFrançois Revol	global $vnckeymap;
161*c6f50a6aSFrançois Revol	// if the browser advertised a prefered lang...
162*c6f50a6aSFrançois Revol	if (!isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]))
163*c6f50a6aSFrançois Revol		return;
164*c6f50a6aSFrançois Revol	$langs = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
165*c6f50a6aSFrançois Revol	$langs = ereg_replace(";q=[^,]*", "", $langs);
166*c6f50a6aSFrançois Revol	$langs = str_replace(" ", "", $langs);
167*c6f50a6aSFrançois Revol	$langs = split(",", $langs);
168*c6f50a6aSFrançois Revol	//print_r($langs);
169*c6f50a6aSFrançois Revol	$keymaps = scandir(QEMU_KEYMAPS);
170*c6f50a6aSFrançois Revol	//print_r($keymaps);
171*c6f50a6aSFrançois Revol	foreach($langs as $lang)
172*c6f50a6aSFrançois Revol	{
173*c6f50a6aSFrançois Revol		foreach($keymaps as $keymap)
174*c6f50a6aSFrançois Revol		{
175*c6f50a6aSFrançois Revol			if ($keymap == $lang)
176*c6f50a6aSFrançois Revol			{
177*c6f50a6aSFrançois Revol				dbg("Detected keymap '" . $keymap . "' from browser headers.");
178*c6f50a6aSFrançois Revol				$vnckeymap = $keymap;
179*c6f50a6aSFrançois Revol				return;
180*c6f50a6aSFrançois Revol			}
181*c6f50a6aSFrançois Revol		}
182*c6f50a6aSFrançois Revol	}
183*c6f50a6aSFrançois Revol}
184*c6f50a6aSFrançois Revol
185*c6f50a6aSFrançois Revol
186e8fc4975SFrançois Revolfunction start_qemu()
187e8fc4975SFrançois Revol{
188*c6f50a6aSFrançois Revol	global $vnckeymap;
189e8fc4975SFrançois Revol	$idx = find_qemu_slot();
190e8fc4975SFrançois Revol	if ($idx < 0) {
191e8fc4975SFrançois Revol		err("No available qemu slot, please try later.");
192e8fc4975SFrançois Revol		return $idx;
193e8fc4975SFrançois Revol	}
194e8fc4975SFrançois Revol	$pidfile = make_qemu_pidfile_name($idx);
195*c6f50a6aSFrançois Revol	$cmd = QEMU_BIN . " " . QEMU_ARGS . " -k " . $vnckeymap . " -vnc " . QEMU_VNC_PREFIX . vnc_display() . " -pidfile " . $pidfile . " " . QEMU_IMAGE_PATH;
196e8fc4975SFrançois Revol
197e8fc4975SFrançois Revol	if (file_exists($pidfile))
198e8fc4975SFrançois Revol		unlink($pidfile);
199e8fc4975SFrançois Revol	dbg("Starting <tt>" . $cmd . "</tt>...");
200e8fc4975SFrançois Revol
201e8fc4975SFrançois Revol	$descriptorspec = array(
202e8fc4975SFrançois Revol	//       0 => array("pipe", "r"),   // stdin
203e8fc4975SFrançois Revol	//       1 => array("pipe", "w"),  // stdout
204e8fc4975SFrançois Revol	//       2 => array("pipe", "w")   // stderr
205e8fc4975SFrançois Revol	);
206e8fc4975SFrançois Revol	//$cmd="/bin/ls";
207e8fc4975SFrançois Revol	//passthru($cmd, $ret);
208e8fc4975SFrançois Revol	//dbg("ret=$ret");
209e8fc4975SFrançois Revol	$cmd .= " &";
210e8fc4975SFrançois Revol	$process = proc_open($cmd, $descriptorspec, $pipes);
211e8fc4975SFrançois Revol	sleep(1);
212e8fc4975SFrançois Revol	proc_close($process);
213e8fc4975SFrançois Revol
214e8fc4975SFrançois Revol	dbg("Started QEMU.");
215e8fc4975SFrançois Revol	$sessfile = make_qemu_sessionfile_name($idx);
216e8fc4975SFrançois Revol	$cmd = "(sleep " . SESSION_TIMEOUT . "; kill -9 `cat " . $pidfile . "`; rm " . $pidfile . " " . $sessfile . ") &";
217e8fc4975SFrançois Revol
218e8fc4975SFrançois Revol	$process = proc_open($cmd, $descriptorspec, $wkpipes);
219e8fc4975SFrançois Revol	sleep(1);
220e8fc4975SFrançois Revol	proc_close($process);
221e8fc4975SFrançois Revol
222e8fc4975SFrançois Revol	dbg("Started timed kill.");
223e8fc4975SFrançois Revol	dbg("Ready for a " . SESSION_TIMEOUT . " session.");
224e8fc4975SFrançois Revol}
225e8fc4975SFrançois Revol
226e8fc4975SFrançois Revol
227e8fc4975SFrançois Revolfunction output_applet_code()
228e8fc4975SFrançois Revol{
229e8fc4975SFrançois Revol	$w = APPLET_WIDTH;
230e8fc4975SFrançois Revol	$h = APPLET_HEIGHT;
231e8fc4975SFrançois Revol	$port = vnc_port();
232e8fc4975SFrançois Revol	$vncjpath = VNCJAVA_PATH;
233e8fc4975SFrançois Revol	$jar = VNCJAR;
234e8fc4975SFrançois Revol	$class = VNCCLASS;
235e8fc4975SFrançois Revol	echo "<applet code=$class codebase=\"$vncjpath/\" archive=\"$vncjpath/$jar\" width=$w height=$h>
236e8fc4975SFrançois Revol	<param name=\"PORT\" value=\"$port\">
237e8fc4975SFrançois Revol	<!param name=\"HOST\" value=\"$HTTP_HOST\"><!-- no need -->
238e8fc4975SFrançois Revol	<param name=\"PORT\" value=\"$port\">
239e8fc4975SFrançois Revol	<param name=\"PASSWORD\" value=\"\">
240e8fc4975SFrançois Revol	There should be a java applet here... make sure you have a JVM and it's enabled!
241e8fc4975SFrançois Revol	</applet>";
242e8fc4975SFrançois Revol}
243e8fc4975SFrançois Revol
244e8fc4975SFrançois Revoldbg("Checking if session is running...");
245e8fc4975SFrançois Revol
246*c6f50a6aSFrançois Revol
247e8fc4975SFrançois Revolif (is_my_session_valid()) {
248e8fc4975SFrançois Revol	dbg("Session running");
249e8fc4975SFrançois Revol	$qemuidx = qemu_slot();
250e8fc4975SFrançois Revol} else if ($closing != 1) {
251e8fc4975SFrançois Revol	dbg("Need to start qemu");
252e8fc4975SFrançois Revol
253*c6f50a6aSFrançois Revol	probe_keymap();
254e8fc4975SFrançois Revol	$qemuidx = start_qemu();
255e8fc4975SFrançois Revol}
256e8fc4975SFrançois Revol
257e8fc4975SFrançois Revolif ($qemuidx >= 0) {
258e8fc4975SFrançois Revol	if ($closing) {
259e8fc4975SFrançois Revol		dbg("closing...");
260e8fc4975SFrançois Revol		unlink(make_qemu_sessionfile_name($qemuidx));
261e8fc4975SFrançois Revol		//unlink(make_qemu_sessionfile_name($qemuidx));
262e8fc4975SFrançois Revol		sleep(1);
263e8fc4975SFrançois Revol		//echo "<script> self.close(\"closing\"); </script>";
264e8fc4975SFrançois Revol	} else {
265e8fc4975SFrançois Revol		dbg("Waiting for vnc server...");
266e8fc4975SFrançois Revol		sleep(5);
267e8fc4975SFrançois Revol		output_applet_code();
268e8fc4975SFrançois Revol	}
269e8fc4975SFrançois Revol}
270e8fc4975SFrançois Revol
271e8fc4975SFrançois Revol
272e8fc4975SFrançois Revol
273e8fc4975SFrançois Revol?>
274e8fc4975SFrançois Revol
275e8fc4975SFrançois Revol</body>
276e8fc4975SFrançois Revol</html>
277