[Esbox-commits] r929 - in branches/work_Ed: . org.maemo.esbox.vm org.maemo.esbox.vm/.settings org.maemo.esbox.vm/META-INF org.maemo.esbox.vm/about_files org.maemo.esbox.vm/conf org.maemo.esbox.vm/src org.maemo.esbox.vm/src/org org.maemo.esbox.vm/src/org/maemo org.maemo.esbox.vm/src/org/maemo/esbox org.maemo.esbox.vm/src/org/maemo/esbox/internal org.maemo.esbox.vm/src/org/maemo/esbox/internal/api org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/ui org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/ui/actions org.maemo.esbox.vm/src/org/maemo/esbox/vm org.maemo.esbox.vm/src/org/maemo/esbox/vm/core org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/preferences org.maemo.esbox.vm.qemu org.maemo.esbox.vm.qemu/.settings org.maemo.esbox.vm.qemu/META-INF org.maemo.esbox.vm.qemu/conf org.maemo.esbox.vm.qemu/src org.maemo.esbox.vm.qemu/src/_org org.maemo.esbox.vm.qemu/src/_org/maemo org.maemo.esbox.vm.qemu/src/_org/maemo/esbox org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/protocol org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/protocol/vm org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/protocol/vm/qemu org.maemo.esbox.vm.qemu/src/org org.maemo.esbox.vm.qemu/src/org/maemo org.maemo.esbox.vm.qemu/src/org/maemo/esbox org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/qemu

eswartz at garage.maemo.org eswartz at garage.maemo.org
Mon Nov 10 19:01:42 EET 2008


Author: eswartz
Date: 2008-11-10 19:01:41 +0200 (Mon, 10 Nov 2008)
New Revision: 929

Added:
   branches/work_Ed/org.maemo.esbox.vm.qemu/
   branches/work_Ed/org.maemo.esbox.vm.qemu/.classpath
   branches/work_Ed/org.maemo.esbox.vm.qemu/.project
   branches/work_Ed/org.maemo.esbox.vm.qemu/.settings/
   branches/work_Ed/org.maemo.esbox.vm.qemu/.settings/org.eclipse.jdt.core.prefs
   branches/work_Ed/org.maemo.esbox.vm.qemu/META-INF/
   branches/work_Ed/org.maemo.esbox.vm.qemu/META-INF/MANIFEST.MF
   branches/work_Ed/org.maemo.esbox.vm.qemu/build.properties
   branches/work_Ed/org.maemo.esbox.vm.qemu/conf/
   branches/work_Ed/org.maemo.esbox.vm.qemu/conf/qemu_prefs.xml
   branches/work_Ed/org.maemo.esbox.vm.qemu/plugin.xml
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/Activator.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuBuildMachineFactory.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuMachine.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuMachineController.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuPreferenceConstants.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/StockQemuConfiguration.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/BaseVirtualMachinePreferencePage.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/CorePreferenceConstants.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/StockQemuConfiguration.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/protocol/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/protocol/vm/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/protocol/vm/qemu/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/protocol/vm/qemu/IQemuConfiguration.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/Activator.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/BaseVirtualMachinePreferencePage.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/PreferenceQemuConfiguration.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuBuildMachineFactory.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachine.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachineController.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuPreferenceConstants.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuPreferencePage.java
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/qemu/
   branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/qemu/IQemuConfiguration.java
   branches/work_Ed/org.maemo.esbox.vm/
   branches/work_Ed/org.maemo.esbox.vm/.classpath
   branches/work_Ed/org.maemo.esbox.vm/.project
   branches/work_Ed/org.maemo.esbox.vm/.settings/
   branches/work_Ed/org.maemo.esbox.vm/.settings/org.eclipse.jdt.core.prefs
   branches/work_Ed/org.maemo.esbox.vm/META-INF/
   branches/work_Ed/org.maemo.esbox.vm/META-INF/MANIFEST.MF
   branches/work_Ed/org.maemo.esbox.vm/about.html
   branches/work_Ed/org.maemo.esbox.vm/about_files/
   branches/work_Ed/org.maemo.esbox.vm/about_files/epl-v10.html
   branches/work_Ed/org.maemo.esbox.vm/build.properties
   branches/work_Ed/org.maemo.esbox.vm/conf/
   branches/work_Ed/org.maemo.esbox.vm/conf/vm_prefs.xml
   branches/work_Ed/org.maemo.esbox.vm/plugin.xml
   branches/work_Ed/org.maemo.esbox.vm/src/
   branches/work_Ed/org.maemo.esbox.vm/src/org/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BasePreferenceVirtualMachineConfiguration.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/Activator.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/VirtualBuildMachineConfigurationHandler.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/ui/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/ui/actions/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/ui/actions/ValidateVirtualMachineCommand.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachine.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachineConfiguration.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachinePreferencePage.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/VirtualMachinePreferenceConstants.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/BaseVirtualMachinePreferencePage.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/SelectVirtualMachineDialog.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/preferences/
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/preferences/CommonVirtualMachineSettingsPreferencePage.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/preferences/VirtualMachineSelectionPreferencePage.java
Log:
Checkpoint for VM support.  Currently works OK in workspace but unit tests are flaky due to asynchronous acquisition of VMs and SDKs.


Property changes on: branches/work_Ed/org.maemo.esbox.vm
___________________________________________________________________
Name: svn:ignore
   + bin


Added: branches/work_Ed/org.maemo.esbox.vm/.classpath
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/.classpath	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/.classpath	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Added: branches/work_Ed/org.maemo.esbox.vm/.project
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/.project	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/.project	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.maemo.esbox.vm</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: branches/work_Ed/org.maemo.esbox.vm/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/.settings/org.eclipse.jdt.core.prefs	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/.settings/org.eclipse.jdt.core.prefs	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,7 @@
+#Wed Nov 05 11:12:19 CST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5

Added: branches/work_Ed/org.maemo.esbox.vm/META-INF/MANIFEST.MF
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/META-INF/MANIFEST.MF	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/META-INF/MANIFEST.MF	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,20 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: ESbox Virtual Machine Support Plug-in
+Bundle-SymbolicName: org.maemo.esbox.vm;singleton:=true
+Bundle-Version: 2.0.0.qualifier
+Bundle-Activator: org.maemo.esbox.internal.vm.Activator
+Bundle-Vendor: NOKIA
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.maemo.mica.common.core;bundle-version="2.0.0",
+ org.maemo.mica.common.ui;bundle-version="2.0.0",
+ org.maemo.mica.protocol.ssh;bundle-version="2.0.0",
+ org.maemo.esbox.scratchbox.core;bundle-version="2.0.0",
+ org.maemo.mica.maemosdk.core;bundle-version="2.0.0",
+ org.eclipse.ui.ide;bundle-version="3.4.1"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Export-Package: org.maemo.esbox.internal.api.vm.core,
+ org.maemo.esbox.vm.core,
+ org.maemo.esbox.vm.ui

Added: branches/work_Ed/org.maemo.esbox.vm/about.html
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/about.html	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/about.html	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,21 @@
+<h3>About This Content</h3>
+
+<h3>ESbox</h3>
+
+<p><a href="http://esbox.garage.maemo.org/" target="_blank">ESbox</a> 
+is an Eclipse plug-in that helps programmers to develop applications for 
+maemo platform on Scratchbox Apophis. It supports C/C++ and Python programming 
+languages. Maemo 4.x SDKs (and later) will be supported.
+</p>
+
+<h3>License</h3>
+
+<p>See <a href="about_files/epl-v10.html">Eclipse Public License Version 1.0 (&quot;EPL&quot;)</a>.
+</p>
+
+<h3>Applicable Licenses</h3>   
+   
+<p>ESbox has a set of open source templates to help the development of applications. Such templates are distributed
+under <a href="about_files/COPYING.LESSER">LGPL license.</a></p>
+
+<address> &copy; Copyright 2007-2008 INdT. All rights reserved. </address>

Added: branches/work_Ed/org.maemo.esbox.vm/about_files/epl-v10.html
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/about_files/epl-v10.html	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/about_files/epl-v10.html	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+  <o:Revision>2</o:Revision>
+  <o:TotalTime>3</o:TotalTime>
+  <o:Created>2004-03-05T23:03:00Z</o:Created>
+  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+  <o:Pages>4</o:Pages>
+  <o:Words>1626</o:Words>
+  <o:Characters>9270</o:Characters>
+   <o:Lines>77</o:Lines>
+  <o:Paragraphs>18</o:Paragraphs>
+  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+  <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+  <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+ at font-face
+	{font-family:Tahoma;
+	panose-1:2 11 6 4 3 5 4 4 2 4;
+	mso-font-charset:0;
+	mso-generic-font-family:swiss;
+	mso-font-pitch:variable;
+	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+	{mso-style-parent:"";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p
+	{margin-right:0in;
+	mso-margin-top-alt:auto;
+	mso-margin-bottom-alt:auto;
+	margin-left:0in;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+	{mso-style-name:"Balloon Text";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:8.0pt;
+	font-family:Tahoma;
+	mso-fareast-font-family:"Times New Roman";}
+ at page Section1
+	{size:8.5in 11.0in;
+	margin:1.0in 1.25in 1.0in 1.25in;
+	mso-header-margin:.5in;
+	mso-footer-margin:.5in;
+	mso-paper-source:0;}
+div.Section1
+	{page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor (&quot;Commercial
+Contributor&quot;) hereby agrees to defend and indemnify every other
+Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
+costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
+WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
\ No newline at end of file

Added: branches/work_Ed/org.maemo.esbox.vm/build.properties
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/build.properties	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/build.properties	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               about_files/,\
+               about.html

Added: branches/work_Ed/org.maemo.esbox.vm/conf/vm_prefs.xml
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/conf/vm_prefs.xml	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/conf/vm_prefs.xml	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+
+<properties>
+	<comment>This file contains the default settings for QEMU preferences; 
+	see the org.maemo.mica.common.core.preference_set_provider extension</comment>
+	
+	<entry key="VM_USER_NAME">maemo</entry>
+	<entry key="VM_USER_PASSWORD">maemo</entry>
+	<entry key="VM_SSH_TARGET_ADDR">127.0.0.1</entry>
+	<entry key="VM_SSH_TARGET_PORT">2222</entry>
+	<entry key="VM_SSH_HOST_ADDR">10.0.2.2</entry>
+	<entry key="VM_CIFS_TARGET_PORT">445</entry>
+	
+</properties>
\ No newline at end of file

Added: branches/work_Ed/org.maemo.esbox.vm/plugin.xml
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/plugin.xml	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/plugin.xml	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+  <extension
+         point="org.eclipse.ui.commands">
+      <command
+            categoryId="org.eclipse.ui.category.help"
+            defaultHandler="org.maemo.esbox.internal.vm.ui.actions.ValidateVirtualMachineCommand"
+            description="Validate launching and communication with ESbox virtual machine"
+            id="org.maemo.esbox.vm.validateVirtualMachineCommand"
+            name="Validate ESbox Virtual Machine">
+      </command>
+   </extension>
+   <extension
+         point="org.eclipse.ui.menus">
+      <menuContribution
+            locationURI="menu:help?after=additions">
+         <command
+               commandId="org.maemo.esbox.vm.validateVirtualMachineCommand"
+               mnemonic="V"
+               style="push"
+               tooltip="Run to ensure that the virtual machine build host is properly configured.">
+         </command>
+      </menuContribution>
+   </extension>
+   
+   <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            category="org.maemo.mica.common.ui.preferenceCategory.maemo"
+            class="org.maemo.esbox.vm.ui.preferences.VirtualMachineSelectionPreferencePage"
+            id="org.maemo.esbox.vm.preferencePage.virtualMachines"
+            name="Virtual Machines">
+      </page>
+   </extension>
+   <extension
+         point="org.eclipse.ui.startup">
+      <startup></startup>
+   </extension>   
+
+   <extension
+          point="org.maemo.mica.common.core.preference_set_provider">
+       <preferenceSetProvider
+             defaultsXMLFile="conf/vm_prefs.xml"
+             preferenceConstantsClass="org.maemo.esbox.vm.core.VirtualMachinePreferenceConstants"
+             preferenceMigratorClass="org.maemo.mica.internal.api.common.core.OldESboxPreferenceMigrator"
+             preferenceStoreBundle="org.maemo.esbox.vm"
+             version="1">
+       </preferenceSetProvider>
+    </extension>
+   
+</plugin>

Added: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BasePreferenceVirtualMachineConfiguration.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BasePreferenceVirtualMachineConfiguration.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BasePreferenceVirtualMachineConfiguration.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.api.vm.core;
+
+import org.maemo.esbox.vm.core.IVirtualMachineConfiguration;
+import org.maemo.esbox.vm.core.VirtualMachinePreferenceConstants;
+import org.maemo.mica.common.core.CorePreferenceManager;
+import org.maemo.mica.common.core.machine.ISharedFilesystemProvider;
+import org.maemo.mica.internal.api.common.core.machine.StockSharedFilesystemProvider;
+import org.maemo.mica.protocol.ssh.SSHConfiguration;
+
+/**
+ * Basic implementation of {@link IVirtualMachineConfiguration} that reads preferences.
+ * @author eswartz
+ *
+ */
+public abstract class BasePreferenceVirtualMachineConfiguration implements IVirtualMachineConfiguration {
+
+	protected String getPreference(String key) {
+		String value = CorePreferenceManager.getInstance().getRegisteredKeyValue(key);
+		return value;
+	}
+	
+	protected String getUserName() {
+		return getPreference(VirtualMachinePreferenceConstants.VM_USER_NAME); 
+	}
+
+	protected String getUserPassword() {
+		return getPreference(VirtualMachinePreferenceConstants.VM_USER_PASSWORD); 
+	}
+
+	protected String getTargetAddr() {
+		return getPreference(VirtualMachinePreferenceConstants.VM_SSH_TARGET_ADDR); 
+	}
+	
+	protected int getTargetPort() {
+		return Integer.parseInt(getPreference(VirtualMachinePreferenceConstants.VM_SSH_TARGET_PORT)); 
+	}
+
+	protected String getHostAddr() {
+		return getPreference(VirtualMachinePreferenceConstants.VM_SSH_HOST_ADDR); 
+	}
+
+	public int getCIFSPort() {
+		return Integer.parseInt(getPreference(VirtualMachinePreferenceConstants.VM_CIFS_TARGET_PORT)); 
+	}
+	
+	public SSHConfiguration getSSHConfiguration() {
+		SSHConfiguration sshConfiguration = new SSHConfiguration(
+				getTargetAddr(), getTargetPort(),
+				getHostAddr(), 22,
+				getUserName(), getUserPassword(),
+				10 /*timeout*/ 
+				);
+
+		return sshConfiguration;
+	}
+
+	public ISharedFilesystemProvider getSharedFilesystemProvider() {
+		return new StockSharedFilesystemProvider(getUserName());
+	}
+
+}

Added: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/Activator.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/Activator.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/Activator.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,146 @@
+package org.maemo.esbox.internal.vm;
+
+import com.nokia.cpp.internal.api.utils.ui.WorkbenchUtils;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IStartup;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.maemo.mica.common.core.ErrorLogger;
+import org.maemo.mica.common.core.machine.MachineRegistry;
+import org.osgi.framework.BundleContext;
+
+import java.io.*;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin implements IStartup {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.maemo.esbox.vm";
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * @param object
+	 * @param e
+	 * @return
+	 */
+	public static IStatus createErrorStatus(String msg, Throwable t) {
+		return new Status(IStatus.ERROR, PLUGIN_ID, msg, t);
+	}
+
+	/**
+	 * @param warning
+	 * @param format
+	 * @param e
+	 * @return
+	 */
+	public static IStatus createStatus(int severity, String msg,
+			Throwable t) {
+		return new Status(severity, PLUGIN_ID, msg, t);
+	}
+
+	/**
+	 * @param warning
+	 * @param string
+	 * @return
+	 */
+	public static IStatus createStatus(int severity, String string) {
+		return new Status(severity, PLUGIN_ID, string);
+	}
+	
+	/**
+	 * Return the error logger instance of this plug-in.
+	 * 
+	 * @return the error logger instance of this plug-in.
+	 */
+	public static ErrorLogger getErrorLogger() {
+		class CoreErrorLogger extends ErrorLogger {
+
+			@Override
+			public String getPluginID() {
+				return PLUGIN_ID;
+			}
+			@Override
+			public Plugin getPlugin() {
+				return Activator.getDefault();
+			}
+
+		}
+
+		return new CoreErrorLogger();
+	}
+
+	/**
+	 * Find a file relative to the plugin, either in a running
+	 * workspace or a standalone unit test (assumed to run relative
+	 * to a plugin)
+	 * @param path
+	 */
+	public static InputStream getPluginRelativeInputStream(String path) throws IOException {
+		if (getDefault() != null) {
+			return FileLocator.openStream(getDefault().getBundle(), new Path(path), false);
+		} else {
+			return new FileInputStream("../" + path);
+		}
+	}
+	
+	/**
+	 * Returns an image descriptor for the image file at the given
+	 * plug-in relative path.
+	 *
+	 * @param path the path
+	 * @return the image descriptor
+	 */
+	public static ImageDescriptor getImageDescriptor(String path) {
+		return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IStartup#earlyStartup()
+	 */
+	public void earlyStartup() {
+		// wire ourselves up to handle selecting the build machine
+		if (!WorkbenchUtils.isJUnitRunning()) {
+			MachineRegistry.getInstance().addBuildMachineConfigurationListener(
+					new VirtualBuildMachineConfigurationHandler());
+		}
+	}
+
+}

Added: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/VirtualBuildMachineConfigurationHandler.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/VirtualBuildMachineConfigurationHandler.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/VirtualBuildMachineConfigurationHandler.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.vm;
+
+import com.nokia.cpp.internal.api.utils.ui.WorkbenchUtils;
+
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+import org.maemo.esbox.vm.core.IVirtualMachine;
+import org.maemo.esbox.vm.ui.SelectVirtualMachineDialog;
+import org.maemo.mica.common.core.machine.*;
+
+/**
+ * This implementation handles the request for build machine configuration by
+ * popping up a dialog and leads the user to the 
+ * Maemo > Virtual Machines preference page.
+ * @author eswartz
+ *
+ */
+public class VirtualBuildMachineConfigurationHandler implements IBuildMachineConfigurationListener {
+
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.common.core.machine.IBuildMachineRequestListener#buildMachineConfigurationNeeded()
+	 */
+	public void buildMachineConfigurationNeeded() {
+		// see if any virtual machines at all are available
+		int vmCount = 0;
+		IBuildMachine[] buildMachines = MachineRegistry.getInstance().getAvailableBuildMachines();
+		for (IBuildMachine machine : buildMachines) {
+			if (machine instanceof IVirtualMachine) {
+				vmCount++;
+			}
+		}
+		
+		if (vmCount > 0) {
+			Display.getDefault().asyncExec(new Runnable() {
+	
+				public void run() {
+					// first, don't show this if we're already editing these prefs
+					SelectVirtualMachineDialog dialog = new SelectVirtualMachineDialog(
+							WorkbenchUtils.getActiveShell());
+					dialog.open();
+				}
+				
+			});
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.common.core.machine.IBuildMachineConfigurationListener#buildMachinesChanged()
+	 */
+	public void buildMachinesChanged() {
+		// no handling
+	}
+
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/VirtualBuildMachineConfigurationHandler.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/ui/actions/ValidateVirtualMachineCommand.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/ui/actions/ValidateVirtualMachineCommand.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/ui/actions/ValidateVirtualMachineCommand.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,311 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.vm.ui.actions;
+
+import org.eclipse.core.commands.*;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.console.MessageConsole;
+import org.maemo.esbox.scratchbox.core.sdk.IScratchboxSDKTarget;
+import org.maemo.esbox.scratchbox.core.sdk.ScratchboxSDKFacade;
+import org.maemo.esbox.vm.core.IVirtualMachine;
+import org.maemo.mica.common.core.*;
+import org.maemo.mica.common.core.machine.*;
+import org.maemo.mica.common.core.process.*;
+import org.maemo.mica.common.core.sdk.ISDKTarget;
+import org.maemo.mica.common.core.sdk.SDKFactory;
+
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat;
+
+/**
+ * @author eswartz
+ *
+ */
+public class ValidateVirtualMachineCommand extends AbstractHandler {
+
+	private Shell shell;
+
+	protected void fail(final String msg, final Object... param) {
+		Display.getDefault().syncExec(new Runnable() {
+
+			public void run() {
+				MessageDialog.openError(getShell(), "Validation Failure", MessageFormat.format(msg, param));
+			}
+			
+		});
+	}
+	
+	protected void info(final String msg, final Object... param) {
+		Display.getDefault().syncExec(new Runnable() {
+
+			public void run() {
+				MessageDialog.openInformation(getShell(), "Validation Information", MessageFormat.format(msg, param));
+			}
+			
+		});
+	}
+	
+	protected void warn(final String msg, final Object... param) {
+		Display.getDefault().syncExec(new Runnable() {
+
+			public void run() {
+				MessageDialog.openWarning(getShell(), "Validation Information", MessageFormat.format(msg, param));
+			}
+			
+		});
+	}
+	/**
+	 * @return
+	 */
+	protected Shell getShell() {
+		return shell;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		setupContext(event.getApplicationContext());
+		
+		// find a virtual machine
+		boolean found = false;
+		
+		IMachine[] machines = MachineRegistry.getInstance().getBuildMachines();
+		for (IMachine machine : machines) {
+			if (machine instanceof IVirtualMachine) {
+				runVirtualMachineTests(machine);
+				found = true;
+			}
+		}
+		
+		if (!found) {
+			if (Platform.getOS().equals(Platform.OS_WIN32))
+				fail("Cannot find a registered virtual build machine -- probably a build or packaging error.");
+			else
+				info("No virtual build machines used or needed on this platform.");
+			return null;
+		}
+
+		return null;
+	}
+
+	private Object runVirtualMachineTests(IMachine machine) {
+		if (!testVirtualMachineRunning(machine))
+			return null;
+
+		if (!testProcessLaunching(machine))
+			return null;
+		
+		if (!testBasicFileSystem(machine))
+			return null;
+		
+		// check the shared folder
+		// XXX: the specific directories are a hack and should be accessible through IMachine API
+		IFileStore localStore = EFS.getLocalFileSystem().getStore(new Path("c:/sources/shared/__testfile.txt"));
+		IFileStore remoteStore = machine.getFileSystemAccess().getFileStore(new Path("/home/devel/shared/__testfile.txt"));
+		
+		try {
+			localStore.delete(0, null);
+		} catch (CoreException e) {
+		}
+
+		// in case the filesystem is NOT shared, don't falsely detect a similar file on the VM's local filesystem
+		try {
+			remoteStore.delete(0, null);
+			remoteStore.fetchInfo();
+		} catch (CoreException e) {
+		}
+		
+		OutputStream os;
+		try {
+			os = localStore.openOutputStream(EFS.OVERWRITE, null);
+			os.write("Contents\n".getBytes());
+			Policy.close(os);
+		} catch (Exception e) {
+			fail("Could not create local test file ''{0}''.\n\nThis is a serious problem.",
+					localStore);
+			return null;
+		}
+		
+		// wait a little while for samba to notice, or else it looks like the file doesn't exist (:p !!!)
+		try {
+			Thread.sleep(1000);
+		} catch (InterruptedException e1) {
+		}
+		remoteStore = machine.getFileSystemAccess().getFileStore(new Path("/home/devel/shared/__testfile.txt"));
+		if (!remoteStore.fetchInfo().exists()) {
+			fail("Could not access {0} over SSH filesystem.\n\nThis file should be visible since we created it locally and this location\nis assumed to be shared at {1}.\n\nPlease log in to the machine and invoke ''sh mount_share.sh''.\n",
+					remoteStore, localStore);
+			return null;
+		}
+		
+		if (!testScratchboxTargets("/home/devel/shared/__testfile.txt"))
+			return null;
+		
+		try {
+			localStore.delete(0, null);
+		} catch (CoreException e) {
+		}
+		
+		info("Everything seems to work!");
+		return null;
+	}
+
+	/**
+	 * @param machine
+	 */
+	private boolean testVirtualMachineRunning(final IMachine machine) {
+		// make sure it's running
+		final IStatus[] statuses = { null };
+		ProgressMonitorDialog dialog = new ProgressMonitorDialog(null);
+		try {
+			dialog.run(true, true, new IRunnableWithProgress() {
+
+				public void run(IProgressMonitor monitor)
+						throws InvocationTargetException, InterruptedException {
+					statuses[0] = MachineManager.getInstance().acquireMachine(machine, null);
+				}
+				
+			});
+		} catch (InvocationTargetException e) {
+			fail(e.getMessage());
+		} catch (InterruptedException e) {
+			fail(e.getMessage());
+		}
+		IStatus status = statuses[0];
+		if (!status.isOK()) {
+			if (status.getSeverity() == IStatus.ERROR) {
+				fail("Failed to launch or revive the virtual build machine:\n{0}", status);
+				return false;
+			}
+			fail("The virtual build machine is not well, going to continue anyway...:\n{0}", status);
+		}
+		return true;
+	}
+
+	/**
+	 * @param machine
+	 */
+	private boolean testProcessLaunching(final IMachine machine) {
+		// check the process launcher
+		IProcessLauncherFactory processLauncherFactory = machine.getProcessLauncherFactory();
+		IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(processLauncherFactory, 
+				"ls " + machine.getUserHome());
+		MessageConsole console = CoreConsoleManager.getInstance().getConsole(true, null, "Virtual machine ~devel home directory listing");
+		
+		Process process;
+		try {
+			process = processLauncher.createProcess();
+		} catch (MicaException e) {
+			fail("Could not run ls on " + machine.getUserHome() + " directory.\nIf SSH connections to machine are failing, ensure the \nrun_linux_wait.bat script (in the plugin) has not been modified\nand that the virtual machine has booted properly:\n{0}", 
+					e);
+			return false;
+		}
+		processLauncher.redirectToConsole(console);
+		
+		try {
+			process.waitFor();
+		} catch (InterruptedException e) {
+					
+		}
+		
+		return true;
+	}
+
+	/**
+	 * @param machine
+	 */
+	private boolean testBasicFileSystem(final IMachine machine) {
+		// check the basic filesystem access
+		IFileStore store = machine.getFileSystemAccess().getFileStore(machine.getUserHome());
+		if (!store.fetchInfo().exists()) {
+			fail("Could not access ''{0}'' over SSH filesystem.\n\nThis is probably a serious problem because the home directory for this user should exist.",
+					store);
+			return false;
+		}
+		
+		// see if the workspace is visible on the machine
+		IPath remoteWorkspace = machine.getFileSystemMapping().convertHostToTargetPath(ResourcesPlugin.getWorkspace().getRoot().getLocation());
+		if (remoteWorkspace == null) {
+			// XXX TODO: need an API for finding the actual share points
+			warn("Could not access the workspace root on the build machine.\n\nThis will usually complicate new project creation.\n\nPlease place the workspace somewhere under\n'c:/sources/shared' for best results.");
+		}
+		return true;
+	}
+
+	/**
+	 * 
+	 */
+	private boolean testScratchboxTargets(String path) {
+		IFileStore remoteStore;
+		
+		SDKFactory.getInstance().waitForRefreshComplete(null);
+		IScratchboxSDKTarget[] sdkTargets = ScratchboxSDKFacade.getInstance().getScratchboxSDKTargets();
+		
+		if (sdkTargets.length == 0) {
+			info("Could not locate any scratchbox SDK targets in virtual build machine.\n\nRetrying ...");
+			
+			ProgressMonitorDialog dlg2 = new ProgressMonitorDialog(getShell());
+			try {
+				dlg2.run(false, true, new IRunnableWithProgress() {
+
+					public void run(IProgressMonitor monitor)
+							throws InvocationTargetException, InterruptedException {
+						SDKFactory.getInstance().refresh(true);
+					}
+					
+				});
+			} catch (Exception e) {
+				fail("Failed to refresh Scratchbox SDKS:\n{0}", e.getMessage());
+				return false;
+			}
+
+			sdkTargets = ScratchboxSDKFacade.getInstance().getScratchboxSDKTargets();
+			if (sdkTargets.length < 4) {
+				fail("Failed to find all the expected scratchbox targets (wanted at least four)... the build machine is probably misconfigured or broken.");
+				return false;
+			}
+		}
+
+		// make sure we can see the shared folder in all targets
+		for (ISDKTarget target : sdkTargets) {
+			// now test the file
+			remoteStore = target.getTargetFileSystemAccess().getFileStore(new Path(path));
+			if (!remoteStore.fetchInfo().exists()) {
+				fail("Could not access {0} inside scratchbox target {1}.\n\nThis file should be visible since it is shared and accessible from the user's home.\n\nEither there is a missing 'bind' mount making this folder visible to scratchbox,\nor something else is broken.",
+						remoteStore, target);
+				return false;
+			}
+		}
+		
+		return true;
+	}
+
+	/**
+	 * @param applicationContext
+	 */
+	private void setupContext(Object applicationContext) {
+		if (applicationContext instanceof IAdaptable) {
+			shell = (Shell) ((IAdaptable) applicationContext).getAdapter(Shell.class);
+		}
+	}
+
+}

Added: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachine.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachine.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachine.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.vm.core;
+
+import org.maemo.mica.common.core.machine.IMachine;
+
+
+/**
+ * A machine implementing this interface is a virtual machine.
+ * @author eswartz
+ *
+ */
+public interface IVirtualMachine extends IMachine {
+
+	/**
+	 * Create the UI for editing the preferences of this machine
+	 * inside a preference dialog.  
+	 * <p>
+	 * The composite's created control should set a GridLayoutData for its layout data.
+	 * <p>
+	 * Any changes should be  
+	 * @return new Composite
+	 */
+	IVirtualMachinePreferencePage createPreferencePage();
+	
+	/**
+	 * Get the configuration for the virtual machine.
+	 * @return IVirtualMachineConfiguration instance, never <code>null</code>
+	 */
+	IVirtualMachineConfiguration getConfiguration();
+}

Added: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachineConfiguration.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachineConfiguration.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachineConfiguration.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.vm.core;
+
+import org.maemo.mica.common.core.machine.ISharedFilesystemProvider;
+import org.maemo.mica.protocol.ssh.SSHConfiguration;
+
+/**
+ * This interface encapsulates the settings needed to launch and communicate with a virtual machine.
+ * It will be extended by a configuration specific to a VM.
+ * @author eswartz
+ *
+ */
+public interface IVirtualMachineConfiguration {
+
+	/** Get the OS this runs (Platform.OS_xxx) */
+	String getOS();
+	
+	/** Get the name (path + filename) of the program to launch. */
+	String getExecutable();
+
+	/** Get the SSH configuration.  This combines most of the other VM settings
+	 * (username, password, target addr/port, host addr).
+	 * This should have a valid user/password specified at all times. */
+	SSHConfiguration getSSHConfiguration();
+
+	/**
+	 * Get the shared filesystems
+	 */
+	ISharedFilesystemProvider getSharedFilesystemProvider();
+
+	/**
+	 * Get the port for CIFS (Samba/Windows shares) access
+	 * @return
+	 */
+	int getCIFSPort();
+}

Added: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachinePreferencePage.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachinePreferencePage.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachinePreferencePage.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.vm.core;
+
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.jface.preference.PreferencePage;
+
+/**
+ * This interface allows a pref page to be nested inside another.
+ * @author eswartz
+ *
+ */
+public interface IVirtualMachinePreferencePage extends IPreferencePage {
+
+	/** Tell if any changes were made to VM settings */
+	boolean anyChanges();
+	
+	/** Perform the 'Apply' action (the performOk() will never be called!). */
+	void performApply();
+	
+	/** Reset to defaults */
+	void performDefaults();
+
+	int getMessageType();
+
+	void setOwner(PreferencePage page);
+}

Added: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/VirtualMachinePreferenceConstants.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/VirtualMachinePreferenceConstants.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/VirtualMachinePreferenceConstants.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.vm.core;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.maemo.esbox.internal.vm.Activator;
+
+/**
+ * These constants define the stored preferences for common virtual machine
+ * settings.
+ * <p>
+ * These settings are not exposed to the CorePreferenceManager.  Use 
+ * {@link IVirtualMachine#getConfiguration()} instead.
+ * @author eswartz
+ *
+ */
+public class VirtualMachinePreferenceConstants {
+	public static final int VERSION_MAJOR = 1;
+	public static final int VERSION_MINOR = 0;
+	
+	/** Get the preference store that contains these preferences */
+	public static IPreferenceStore getPreferenceStore() {
+		return Activator.getDefault().getPreferenceStore();
+	}
+	
+	public static final String VM_USER_NAME = "VM_USER_NAME";
+	public static final String VM_USER_PASSWORD = "VM_USER_PASSWORD";
+	public static final String VM_SSH_TARGET_PORT = "VM_SSH_TARGET_PORT";
+	public static final String VM_SSH_TARGET_ADDR = "VM_SSH_TARGET_ADDR";
+	public static final String VM_SSH_HOST_ADDR = "VM_SSH_HOST_ADDR";
+	public static final String VM_CIFS_TARGET_PORT = "VM_CIFS_TARGET_PORT";
+	
+
+}

Added: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/BaseVirtualMachinePreferencePage.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/BaseVirtualMachinePreferencePage.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/BaseVirtualMachinePreferencePage.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.vm.ui;
+
+import org.eclipse.jface.preference.*;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.maemo.esbox.vm.core.IVirtualMachinePreferencePage;
+
+/**
+ * Base class for a preference page for a particular VM engine.
+ * @author eswartz
+ *
+ */
+public abstract class BaseVirtualMachinePreferencePage extends FieldEditorPreferencePage implements IVirtualMachinePreferencePage {
+
+	protected boolean anyChanges;
+	private PreferencePage owner;
+
+	/**
+	 * 
+	 */
+	public BaseVirtualMachinePreferencePage() {
+		super(GRID);
+		noDefaultAndApplyButton();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.FieldEditorPreferencePage#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+	 */
+	@Override
+	public void propertyChange(PropertyChangeEvent event) {
+		super.propertyChange(event);
+		anyChanges = true;
+	}
+	
+	public void setOwner(PreferencePage owner) {
+		this.owner = owner;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.DialogPage#setMessage(java.lang.String)
+	 */
+	@Override
+	public void setMessage(String newMessage) {
+		super.setMessage(newMessage);
+		owner.setMessage(newMessage);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.PreferencePage#setMessage(java.lang.String, int)
+	 */
+	@Override
+	public void setMessage(String newMessage, int newType) {
+		super.setMessage(newMessage, newType);
+		owner.setMessage(newMessage, newType);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.PreferencePage#setValid(boolean)
+	 */
+	@Override
+	public void setValid(boolean b) {
+		super.setValid(b);
+		owner.setValid(b);
+	}
+	
+	@Override
+	public void performApply() {
+		super.performApply();
+		anyChanges = false;
+	}
+
+	@Override
+	public void performDefaults() {
+		super.performDefaults();
+		anyChanges = false;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.FieldEditorPreferencePage#performOk()
+	 */
+	@Override
+	public boolean performOk() {
+		boolean ret = super.performOk();
+		if (ret)
+			anyChanges = false;
+		return ret;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.vm.core.IVirtualMachinePreferencePage#anyChanges()
+	 */
+	public boolean anyChanges() {
+		return anyChanges;
+	}
+
+}
\ No newline at end of file

Added: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/SelectVirtualMachineDialog.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/SelectVirtualMachineDialog.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/SelectVirtualMachineDialog.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.vm.ui;
+
+import org.eclipse.core.runtime.IProduct;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+import org.maemo.esbox.internal.vm.Activator;
+import org.maemo.mica.common.ui.IPreferenceConstants;
+
+/**
+ * This dialog tells the user that a build machine should be selected.
+ * @author eswartz
+ *
+ */
+public class SelectVirtualMachineDialog extends MessageDialogWithToggle {
+
+	public static final String VIRTUAL_MACHINE_PREFS_ID = Activator.PLUGIN_ID + ".preferencePage.virtualMachines";
+	
+	private static final String BUG_ME_NOT = "SelectBuildMachineDialog.BugMeNot";
+	/**
+	 * 
+	 */
+	public SelectVirtualMachineDialog(Shell shell) {
+		super(shell, "Select Virtual Machine", null,
+				// note: UI is added below to provide a hyperlink
+				getProductName() + " needs to know what machine to use to build and launch your code. \n\n"+
+				"Your system cannot directly launch scratchbox or maemo tools, so a virtual machine running 32-bit Linux/i386 must be used.\n\n"+
+				"Please configure the settings by clicking the link below.",
+				MessageDialog.INFORMATION,
+				new String[] { IDialogConstants.OK_LABEL },
+				0,
+				"Do not remind me again",
+				Activator.getDefault().getPreferenceStore().getBoolean(BUG_ME_NOT));
+	}
+	
+	/**
+	 * @return
+	 */
+	private static String getProductName() {
+		IProduct product = Platform.getProduct();
+		if (product != null)
+			return product.getName();
+		else
+			return "Eclipse";
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.IconAndMessageDialog#createMessageArea(org.eclipse.swt.widgets.Composite)
+	 */
+	@Override
+	protected Control createMessageArea(Composite composite) {
+		Composite msgArea = (Composite) super.createMessageArea(composite);
+		
+		// two-column layout...
+		new Label(msgArea, SWT.NONE);
+		
+		Link link = new Link(msgArea, SWT.NONE);
+		link.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
+		link.setText("<a href=\"link\">Go to Virtual Machine preferences...</a>");
+		
+		link.addSelectionListener(new SelectionAdapter() {
+			/* (non-Javadoc)
+			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+			 */
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				SelectVirtualMachineDialog.this.close();
+				PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(
+						getShell(), 
+						VIRTUAL_MACHINE_PREFS_ID,
+						new String[] { 
+								IPreferenceConstants.MAEMO_PREFERENCE_CATEGORY_ID,
+								VIRTUAL_MACHINE_PREFS_ID, 
+							},
+						null);
+				dialog.open();
+			}
+		});
+		return msgArea;
+	}
+	
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/SelectVirtualMachineDialog.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/preferences/CommonVirtualMachineSettingsPreferencePage.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/preferences/CommonVirtualMachineSettingsPreferencePage.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/preferences/CommonVirtualMachineSettingsPreferencePage.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.vm.ui.preferences;
+
+import org.eclipse.jface.preference.*;
+import org.eclipse.swt.widgets.Text;
+import org.maemo.esbox.vm.core.VirtualMachinePreferenceConstants;
+import org.maemo.esbox.vm.ui.BaseVirtualMachinePreferencePage;
+
+/**
+ * This page is included inside the {@link VirtualMachineSelectionPreferencePage}
+ * to configure settings shared between all VMs.
+ * @author eswartz
+ *
+ */
+public class CommonVirtualMachineSettingsPreferencePage extends BaseVirtualMachinePreferencePage {
+
+	private StringFieldEditor feUserName;
+	private StringFieldEditor feUserPassword;
+	private StringFieldEditor feSshTargetAddr;
+	private IntegerFieldEditor feSshTargetPort;
+	private StringFieldEditor feSshHostAddr;
+
+	public CommonVirtualMachineSettingsPreferencePage() {
+		super();
+		setPreferenceStore(VirtualMachinePreferenceConstants.getPreferenceStore());
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors()
+	 */
+	@Override
+	protected void createFieldEditors() {
+		Text text;
+		
+		feUserName = new StringFieldEditor(
+				VirtualMachinePreferenceConstants.VM_USER_NAME,
+				"User:",
+				32,
+				getFieldEditorParent());
+		addField(feUserName);
+		text = feUserName.getTextControl(getFieldEditorParent());
+		text.setToolTipText("The user under whose control processes are launched and files are accessed.  This user must be capable of 'sudo' for commands that require root privileges.");
+		
+		feUserPassword = new StringFieldEditor(
+				VirtualMachinePreferenceConstants.VM_USER_PASSWORD,
+				"Password:",
+				32,
+				getFieldEditorParent());
+		addField(feUserPassword);
+		text = feUserPassword.getTextControl(getFieldEditorParent());
+		text.setEchoChar('\u25CF'); // Black Circle
+		text.setToolTipText("Password for the user mentioned above.\nWARNING: this text is not encrypted in any way.");
+
+		feSshTargetAddr = new StringFieldEditor(
+				VirtualMachinePreferenceConstants.VM_SSH_TARGET_ADDR,
+				"Target address:",
+				64,
+				getFieldEditorParent());
+		addField(feSshTargetAddr);
+		text = feSshTargetAddr.getTextControl(getFieldEditorParent());
+		text.setToolTipText("Specify the address of the machine as seen from the host.\nThis may be localhost (127.0.0.1) if the machine shares a network with the host,\nbut be sure the SSH port is configured as well.");
+
+		feSshTargetPort = new IntegerFieldEditor(
+				VirtualMachinePreferenceConstants.VM_SSH_TARGET_PORT,
+				"Target SSH port:",
+				getFieldEditorParent(),
+				5);
+		addField(feSshTargetPort);
+		text = feSshTargetPort.getTextControl(getFieldEditorParent());
+		text.setToolTipText("Specify the SSH port visible in the machine.\nThis may be different from the port seen inside the machine,\nespecially if the port is redirected to be visible to the host.");
+
+		feSshHostAddr = new StringFieldEditor(
+				VirtualMachinePreferenceConstants.VM_SSH_HOST_ADDR,
+				"Host address:",
+				64,
+				getFieldEditorParent());
+		addField(feSshHostAddr);
+		text = feSshHostAddr.getTextControl(getFieldEditorParent());
+		text.setToolTipText("Specify the address of the host as seen from the machine.");
+
+		/*
+		feSshHostPort = new IntegerFieldEditor(
+				VirtualMachinePreferenceConstants.VM_SSH_HOST_PORT,
+				"Host SSH port:",
+				getFieldEditorParent(),
+				5);
+		text = feSshHostPort.getTextControl(getFieldEditorParent());
+		text.setToolTipText("Specify the SSH port visible in the machine.\nThis may be different from the port seen inside the machine,\nespecially if the port is redirected to be visible to the host.");
+		 */
+		
+	}
+
+}

Added: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/preferences/VirtualMachineSelectionPreferencePage.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/preferences/VirtualMachineSelectionPreferencePage.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/ui/preferences/VirtualMachineSelectionPreferencePage.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,393 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.vm.ui.preferences;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.maemo.esbox.vm.core.IVirtualMachine;
+import org.maemo.esbox.vm.core.IVirtualMachinePreferencePage;
+import org.maemo.mica.common.core.machine.IBuildMachine;
+import org.maemo.mica.common.core.machine.MachineRegistry;
+import org.maemo.mica.common.core.sdk.SDKFactory;
+
+import java.util.*;
+import java.util.List;
+
+/**
+ * Configure virtual machine preferences.  This allows the user to select which
+ * virtual machine engine to use (IVirtualMachine, which we currently assume is a singleton)
+ * and how to configure it (username, password, shared folders, etc, combined with
+ * the virtual machine's own configuration UI).
+ * @author eswartz
+ *
+ */
+public class VirtualMachineSelectionPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+
+	private static final String NONE_LABEL = "None";
+	private List<IVirtualMachine> availableVirtualMachines;
+	private IVirtualMachine originalSelectedMachine;
+	private IVirtualMachine selectedMachine;
+	private ComboViewer vmComboViewer;
+	private Group vmConfigComposite;
+	private StackLayout vmConfigStackLayout;
+	private Map<String, IVirtualMachinePreferencePage> vmConfigPages;
+	protected Map<String, IVirtualMachine> vmMap;
+	private Label noVmConfigUI;
+	private CommonVirtualMachineSettingsPreferencePage commonVirtualMachineSettings;
+	private Group commonSettingsGroup;
+	
+	/**
+	 * 
+	 */
+	public VirtualMachineSelectionPreferencePage() {
+		// see which build machines are VMs
+		availableVirtualMachines = new ArrayList<IVirtualMachine>();
+		IBuildMachine[] availableBuildMachines = MachineRegistry.getInstance().getAvailableBuildMachines();
+		for (IBuildMachine machine : availableBuildMachines) {
+			if (machine instanceof IVirtualMachine) {
+				availableVirtualMachines.add((IVirtualMachine) machine);
+			}
+		}
+		
+		// order the VMs by preference
+		Collections.sort(availableVirtualMachines, 
+			new Comparator<IVirtualMachine>() {
+
+				public int compare(IVirtualMachine o1, IVirtualMachine o2) {
+					int o1Rank = getRank(o1);
+					int o2Rank = getRank(o2);
+					return o1Rank - o2Rank;
+				}
+
+				private int getRank(IVirtualMachine o1) {
+					// XXX: HARDCODED preferential ordering of virtual machines
+					String name = o1.getName().toLowerCase();
+					if (name.contains("vmware"))
+						return 0;
+					if (name.contains("qemu"))
+						return 1;
+					if (name.contains("virtualbox"))
+						return 2;
+					return 999;
+				}
+			
+		});
+		
+		// autoselect the in-use VM if possible
+		IBuildMachine[] currentBuildMachines = MachineRegistry.getInstance().getCurrentBuildMachines();
+		for (IBuildMachine machine : currentBuildMachines) {
+			if (machine instanceof IVirtualMachine) {
+				originalSelectedMachine = selectedMachine = (IVirtualMachine) machine;
+				break;
+			}
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+	 */
+	@Override
+	protected Control createContents(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NONE);
+		composite.setLayout(new GridLayout());
+		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+		
+		createVirtualMachineSelectorUI(composite);
+		
+		createCommonSettingsUI(composite);
+		
+		if (selectedMachine != null)
+			vmComboViewer.setSelection(new StructuredSelection(selectedMachine.getName()));
+		else
+			vmComboViewer.setSelection(new StructuredSelection(NONE_LABEL));
+		return composite;
+	}
+
+	/**
+	 * @param parent
+	 */
+	private void createVirtualMachineSelectorUI(Composite parent) {
+		Composite selectorComposite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginWidth = layout.marginHeight = 0;
+		selectorComposite.setLayout(layout);
+		selectorComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+		
+		Composite comboAndLabel = new Composite(selectorComposite, SWT.NONE);
+		comboAndLabel.setLayout(new GridLayout(2, false));
+		comboAndLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		Label label = new Label(comboAndLabel, SWT.NONE);
+		label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+		label.setText("Virtual machine:");
+		
+		CCombo vmCombo = new CCombo(comboAndLabel, SWT.READ_ONLY | SWT.BORDER | SWT.SHADOW_OUT);
+		vmCombo.setBackground(selectorComposite.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+		
+		vmComboViewer = new ComboViewer(vmCombo);
+		vmComboViewer.getCCombo().setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
+	
+		vmConfigComposite = new Group(selectorComposite, SWT.NONE);
+		vmConfigComposite.setText("Selected machine options");
+		
+		vmConfigComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+		vmConfigStackLayout = new StackLayout();
+		vmConfigStackLayout.marginWidth = 6;
+		vmConfigStackLayout.marginHeight = 6;
+		vmConfigComposite.setLayout(vmConfigStackLayout);
+		
+		noVmConfigUI = new Label(vmConfigComposite, SWT.NONE);
+		noVmConfigUI.setLayoutData(new GridData(GridData.FILL_BOTH));
+		noVmConfigUI.setText("No configuration options");
+		
+		vmMap = new LinkedHashMap<String, IVirtualMachine>();
+		vmConfigPages = new LinkedHashMap<String, IVirtualMachinePreferencePage>();
+		
+		vmComboViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				String name = (String) ((IStructuredSelection) event.getSelection()).getFirstElement();
+				changeSelectedMachine(name);
+			}
+			
+		}) ;	
+		
+		vmComboViewer.setLabelProvider(new LabelProvider() {
+			/* (non-Javadoc)
+			 * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+			 */
+			@Override
+			public String getText(Object element) {
+				return element.toString();
+			}
+		});
+		
+		vmComboViewer.setContentProvider(new ArrayContentProvider());
+
+		// create the VM pref pages
+
+		// first, make a "none" entry
+		vmConfigPages.put(NONE_LABEL, null);
+		
+		// then add the pre-sorted entries
+		for (IVirtualMachine machine : availableVirtualMachines) {
+			IVirtualMachinePreferencePage page = machine.createPreferencePage();
+			vmConfigPages.put(machine.getName(), 
+					page);
+			page.setOwner(this);
+			vmMap.put(machine.getName(), machine);
+		}
+		
+		vmComboViewer.setInput(vmConfigPages.keySet());
+	}
+
+	/**
+	 * @param name
+	 */
+	protected void changeSelectedMachine(String name) {
+		IVirtualMachine machine = vmMap.get(name);
+		if (machine != null) {
+			IPreferencePage page = vmConfigPages.get(machine.getName());
+			if (page.getControl() == null)
+				page.createControl(vmConfigComposite);
+			vmConfigStackLayout.topControl = page.getControl();
+			selectedMachine = machine;
+			commonSettingsGroup.setVisible(true);
+		} else {
+			vmConfigStackLayout.topControl = noVmConfigUI;
+			selectedMachine = null;
+			commonSettingsGroup.setVisible(false);
+		}
+		vmConfigComposite.layout();
+		getShell().layout(true, true);
+	}
+
+	/**
+	 * @param parent
+	 */
+	private void createCommonSettingsUI(Composite parent) {
+		commonSettingsGroup = new Group(parent, SWT.NONE);
+		commonSettingsGroup.setLayout(new GridLayout());
+		commonSettingsGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
+		commonSettingsGroup.setText("Common options");
+		
+		commonVirtualMachineSettings = new CommonVirtualMachineSettingsPreferencePage();
+		commonVirtualMachineSettings.setOwner(this);
+		commonVirtualMachineSettings.createControl(commonSettingsGroup);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+	 */
+	public void init(IWorkbench workbench) {
+		// nothing to do
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+	 */
+	@Override
+	protected void performDefaults() {
+		commonVirtualMachineSettings.performDefaults();
+		
+		for (IVirtualMachinePreferencePage page : vmConfigPages.values()) {
+			if (page != null)
+				page.performDefaults();
+		}
+		super.performDefaults();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.PreferencePage#isValid()
+	 */
+	@Override
+	public boolean isValid() {
+		if (!super.isValid())
+			return false;
+		
+		if (!commonVirtualMachineSettings.isValid())
+			return false;
+		
+		for (IVirtualMachinePreferencePage page : vmConfigPages.values()) {
+			if (page != null && !page.isValid())
+				return false;
+		}
+		
+		return true;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.PreferencePage#performApply()
+	 */
+	@Override
+	protected void performApply() {
+		boolean changed = false;
+		for (IVirtualMachinePreferencePage page : vmConfigPages.values()) {
+			if (page != null) {
+				changed |= page.anyChanges();
+				page.performApply();
+			}
+		}
+		
+		if (commonVirtualMachineSettings.anyChanges()) {
+			changed = true;
+			commonVirtualMachineSettings.performApply();
+		}
+		
+		if (changed) {
+			// reset the build machines, since they were initialized from other prefs
+			MachineRegistry.getInstance().refreshBuildMachines();
+		}
+		
+		if (originalSelectedMachine != selectedMachine) {
+			MachineRegistry.getInstance().setCurrentBuildMachine((IBuildMachine) selectedMachine);
+			changed = true;
+		}
+		
+		// on a change, refresh the SDKs that depend on these machines
+		// XXX: assumption that only SDK factories care about build machines 
+		//if (changed) {
+		//	SDKFactory.getInstance().refresh(new NullProgressMonitor());
+		//}
+		
+		originalSelectedMachine = selectedMachine;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.DialogPage#getErrorMessage()
+	 */
+	/*
+	@Override
+	public String getErrorMessage() {
+		String errorMessage = super.getErrorMessage();
+		if (errorMessage != null)
+			return errorMessage;
+		errorMessage = commonVirtualMachineSettings.getErrorMessage();
+		if (errorMessage != null)
+			return errorMessage;
+		for (IVirtualMachinePreferencePage page : vmConfigPages.values()) {
+			if (page != null) {
+				errorMessage = page.getErrorMessage();
+				if (errorMessage != null)
+					return errorMessage;
+			}
+		}
+		return null;
+	}*/
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.DialogPage#getMessage()
+	 */
+	/*
+	@Override
+	public String getMessage() {
+		String message = super.getMessage();
+		if (message != null)
+			return message;
+		message = commonVirtualMachineSettings.getMessage();
+		if (message != null)
+			return message;
+		for (IVirtualMachinePreferencePage page : vmConfigPages.values()) {
+			if (page != null) {
+				message = page.getMessage();
+				if (message != null)
+					return message;
+			}
+		}
+		return null;
+	}*/
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.DialogPage#getMessageType()
+	 */
+	/*
+	@Override
+	public int getMessageType() {
+		int messageType = super.getMessageType();
+		if (messageType != NONE)
+			return messageType;
+		messageType = commonVirtualMachineSettings.getMessageType();
+		if (messageType != NONE)
+			return messageType;
+		for (IVirtualMachinePreferencePage page : vmConfigPages.values()) {
+			if (page != null) {
+				messageType = page.getMessageType();
+				if (messageType != NONE)
+					return messageType;
+			}
+		}
+		return NONE;
+	}
+	*/
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.PreferencePage#performOk()
+	 */
+	@Override
+	public boolean performOk() {
+		if (isValid()) {
+			performApply();
+			return true;
+		} else {
+			return false;
+		}
+	}
+	
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu
___________________________________________________________________
Name: svn:ignore
   + bin


Added: branches/work_Ed/org.maemo.esbox.vm.qemu/.classpath
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/.classpath	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/.classpath	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry excluding="_org/maemo/esbox/internal/protocol/vm/qemu/|_org/maemo/esbox/internal/vm/qemu/|_org/maemo/esbox/protocol/vm/qemu/" kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/.classpath
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/.project
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/.project	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/.project	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.maemo.esbox.vm.qemu</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/.project
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/.settings/org.eclipse.jdt.core.prefs	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/.settings/org.eclipse.jdt.core.prefs	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,7 @@
+#Fri Nov 07 15:03:51 CST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/.settings/org.eclipse.jdt.core.prefs
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/META-INF/MANIFEST.MF
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/META-INF/MANIFEST.MF	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/META-INF/MANIFEST.MF	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: ESbox Qemu Virtual Machine Plug-in
+Bundle-SymbolicName: org.maemo.esbox.vm.qemu;singleton:=true
+Bundle-Version: 2.0.0.qualifier
+Bundle-Activator: org.maemo.esbox.internal.vm.qemu.Activator
+Bundle-Vendor: NOKIA
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.maemo.mica.common.core;bundle-version="2.0.0",
+ org.maemo.mica.common.ui;bundle-version="2.0.0",
+ org.maemo.mica.protocol.ssh;bundle-version="2.0.0",
+ org.maemo.esbox.vm;bundle-version="2.0.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Export-Package: org.maemo.esbox.internal.vm.qemu;x-friends:="org.maemo.mica.protocol.tests,org.maemo.esbox.scratchbox.tests",
+ org.maemo.esbox.vm.qemu


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/META-INF/MANIFEST.MF
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/build.properties
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/build.properties	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/build.properties	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               about_files/,\
+               about.html


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/build.properties
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/conf/qemu_prefs.xml
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/conf/qemu_prefs.xml	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/conf/qemu_prefs.xml	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+
+<properties>
+	<comment>This file contains the default settings for QEMU preferences; 
+	see the org.maemo.mica.common.core.preference_set_provider extension</comment>
+	
+	<entry key="QEMU_INSTALL_PATH">c:/Program Files/QEMU</entry>
+	<entry key="QEMU_EXE_NAME">qemu.exe</entry>
+	<entry key="QEMU_MEMORY_SIZE">512</entry>
+	<entry key="QEMU_LAUNCH_PATTERN">"${QEMU}" -kernel-kqemu -hda "${DISK_PATH}" -usb -L "${INSTALL_PATH}" -m ${MEMORY} -redir tcp:${SSH_PORT}::22</entry>
+	<entry key="QEMU_DISK_IMAGE_PATH">c:/MaemoVMWare/MaemoSDK-0.8/maemo-sdk-0.8.vmdk</entry>
+	
+</properties>
\ No newline at end of file


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/conf/qemu_prefs.xml
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/plugin.xml
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/plugin.xml	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/plugin.xml	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension
+         point="org.maemo.mica.common.core.build_machine_factory">
+      <build_machine_factory
+            class="org.maemo.esbox.internal.vm.qemu.QemuBuildMachineFactory">
+      </build_machine_factory>
+   </extension>
+
+   <extension
+          point="org.maemo.mica.common.core.preference_set_provider">
+       <preferenceSetProvider
+             defaultsXMLFile="conf/qemu_prefs.xml"
+             preferenceConstantsClass="org.maemo.esbox.internal.vm.qemu.QemuPreferenceConstants"
+             preferenceMigratorClass="org.maemo.mica.internal.api.common.core.OldESboxPreferenceMigrator"
+             preferenceStoreBundle="org.maemo.esbox.vm.qemu"
+             version="1">
+       </preferenceSetProvider>
+    </extension>
+
+</plugin>


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/plugin.xml
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/Activator.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/Activator.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/Activator.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,131 @@
+package _org.maemo.esbox.internal.protocol.vm.qemu;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.maemo.mica.common.core.ErrorLogger;
+import org.osgi.framework.BundleContext;
+
+import java.io.*;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.maemo.mica.protocol.vm.qemu";
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * @param object
+	 * @param e
+	 * @return
+	 */
+	public static IStatus createErrorStatus(String msg, Throwable t) {
+		return new Status(IStatus.ERROR, PLUGIN_ID, msg, t);
+	}
+
+	/**
+	 * @param warning
+	 * @param format
+	 * @param e
+	 * @return
+	 */
+	public static IStatus createStatus(int severity, String msg,
+			Throwable t) {
+		return new Status(severity, PLUGIN_ID, msg, t);
+	}
+
+	/**
+	 * @param warning
+	 * @param string
+	 * @return
+	 */
+	public static IStatus createStatus(int severity, String string) {
+		return new Status(severity, PLUGIN_ID, string);
+	}
+	
+	/**
+	 * Return the error logger instance of this plug-in.
+	 * 
+	 * @return the error logger instance of this plug-in.
+	 */
+	public static ErrorLogger getErrorLogger() {
+		class CoreErrorLogger extends ErrorLogger {
+
+			@Override
+			public String getPluginID() {
+				return PLUGIN_ID;
+			}
+			@Override
+			public Plugin getPlugin() {
+				return Activator.getDefault();
+			}
+
+		}
+
+		return new CoreErrorLogger();
+	}
+
+	/**
+	 * Find a file relative to the plugin, either in a running
+	 * workspace or a standalone unit test (assumed to run relative
+	 * to a plugin)
+	 * @param path
+	 */
+	public static InputStream getPluginRelativeInputStream(String path) throws IOException {
+		if (getDefault() != null) {
+			return FileLocator.openStream(getDefault().getBundle(), new Path(path), false);
+		} else {
+			return new FileInputStream("../" + path);
+		}
+	}
+	
+	/**
+	 * Returns an image descriptor for the image file at the given
+	 * plug-in relative path.
+	 *
+	 * @param path the path
+	 * @return the image descriptor
+	 */
+	public static ImageDescriptor getImageDescriptor(String path) {
+		return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path);
+	}
+
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/Activator.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuBuildMachineFactory.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuBuildMachineFactory.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuBuildMachineFactory.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+package _org.maemo.esbox.internal.protocol.vm.qemu;
+
+import _org.maemo.esbox.internal.protocol.vm.qemu.StockQemuConfiguration;
+import _org.maemo.esbox.protocol.vm.qemu.IQemuConfiguration;
+
+import org.maemo.mica.common.core.machine.IBuildMachineFactory;
+import org.maemo.mica.internal.api.common.core.machine.IBuildMachineImpl;
+
+/**
+ * This factory creates virtual build machines hosted on QEMU.
+ * We support only one machine at a time.
+ * @author eswartz
+ *
+ */
+public class QemuBuildMachineFactory implements IBuildMachineFactory {
+
+	private IQemuConfiguration configuration;
+	
+	public QemuBuildMachineFactory() {
+		this.configuration = new StockQemuConfiguration();
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.common.core.machine.IMachineFactory#createMachine(java.lang.String)
+	 */
+	public synchronized IBuildMachineImpl[] createMachines() {
+		IBuildMachineImpl qemuMachine = new QemuMachine(configuration);
+		return new IBuildMachineImpl[] { qemuMachine };
+	}
+
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuBuildMachineFactory.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuMachine.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuMachine.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuMachine.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+package _org.maemo.esbox.internal.protocol.vm.qemu;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.maemo.mica.common.core.*;
+import org.maemo.mica.common.core.machine.*;
+import org.maemo.mica.common.core.process.*;
+import org.maemo.mica.common.ui.dialogs.DialogUtils;
+import org.maemo.mica.common.ui.dialogs.PasswordInputDialog;
+import org.maemo.mica.internal.api.common.core.machine.IBuildMachineImpl;
+import org.maemo.mica.internal.api.protocol.ssh.SSHMachineBackend;
+import org.maemo.mica.protocol.vm.qemu.IQemuConfiguration;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.MessageFormat;
+import java.util.Map;
+
+
+/**
+ * This is a build machine running under QEMU.
+ * @author eswartz
+ *
+ */
+public class QemuMachine extends SSHMachineBackend implements IVirtualMachine, IBuildMachineImpl {
+
+	public final static String ID = Activator.PLUGIN_ID + ".qemu_machine";
+	public final static String NAME = "QEMU Linux Virtual Machine";
+	
+	public QemuMachine(IQemuConfiguration configuration) {
+		super(ID, NAME, configuration.getOS(),
+				new QemuMachineController(configuration),
+				configuration.getSSHConfiguration(),
+				configuration.getSharedFilesystemProvider());
+	}
+	
+	/**
+	 * This method is called on the UI thread.  It should validate that
+	 * the shared filesystems are available, prompting the user for a password
+	 * and launching 'mount_share.sh' to mount them otherwise.
+	 * <p>
+	 * XXX: this must be rewritten at some point to handle shares which aren't handled by mount_share.sh!
+	 * @param subProgressMonitor 
+	 * @return Status of mount
+	 */
+	public IStatus validateSharedMounts(IProgressMonitor monitor) {
+
+		ISharedFilesystemProvider sharedFilesystemProvider = 
+			getSharedFilesystemProvider();
+		Map<IPath, IPath> sharedFolders = 
+			sharedFilesystemProvider.getSharedFolders();
+		
+		monitor.beginTask("Validating shared folders", sharedFolders.size() * 2);
+		
+		boolean neededMount = false;
+		
+		String fsTypePattern = "smbfs|cifs";
+		for (Map.Entry<IPath, IPath> entry : sharedFolders.entrySet()) {
+			if (!isPathMounted(entry.getValue(), fsTypePattern, null)) {
+				neededMount = true;
+				PasswordInputDialog dialog = new PasswordInputDialog(
+						DialogUtils.getShell(), 
+						"Password Required",
+						MessageFormat.format(
+								"Enter the password for user ''{0}'' to mount the share ''{1}'':",
+								MachineRegistry.getInstance().getLocalMachine().getUserName(),
+								entry.getKey()));
+				if (IDialogConstants.CANCEL_ID == dialog.open())
+					continue;
+				
+				// TODO: this assumes a certain script exists on the VM
+				try {
+					mountSharesWithPassword(dialog.getPassword());
+				} catch (MicaException e) {
+					return Activator.createErrorStatus(
+							MessageFormat.format(
+									"Could not mount ''{0}'' in {1}",
+									entry.getKey().toString(),
+									getName()), e);
+				}
+				
+				monitor.worked(1);
+				if (monitor.isCanceled())
+					return Policy.getCancelStatus(Activator.getDefault());
+			}
+		}
+		
+		// verify that the mounting succeeded
+		boolean allSharesMounted = true;
+		if (neededMount) {
+			for (Map.Entry<IPath, IPath> entry : sharedFolders.entrySet()) {
+				if (!isPathMounted(entry.getValue(), fsTypePattern, null)) {
+					allSharesMounted = false;
+				}
+				monitor.worked(1);
+				if (monitor.isCanceled())
+					return Policy.getCancelStatus(Activator.getDefault());
+			}
+		}
+		
+		monitor.done();
+		
+		if (!allSharesMounted) {
+			return Activator.createStatus(IStatus.WARNING, 
+					MessageFormat.format(
+							"Not all the known shares were mounted in {0}; builds may fail",
+							getName()));
+		}
+
+		return Status.OK_STATUS;
+	}
+	
+	/**
+	 * Run the 'mount_share.sh' script to mount shares.
+	 * @param password
+	 */
+	protected void mountSharesWithPassword(final String password) throws MicaException {
+		IProcessLauncherFactory processLauncherFactory = getProcessLauncherFactory();
+		final IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(processLauncherFactory,
+				getUserHome(),
+				CommandLineArguments.createFromVarArgs(
+						"sh",
+						"mount_share.sh"));
+		
+		processLauncher.usePTY(true);
+		final Process process = processLauncher.createProcess();
+		final MicaException[] exceptions = { null };
+		
+		Thread thread = new Thread("Send password to mount") {
+
+			/* (non-Javadoc)
+			 * @see java.lang.Thread#run()
+			 */
+			@Override
+			public void run() {
+				try {
+					/* this goes to a weird stream (somehow) so we can't read it,
+					 even though it shows up when we put stuff to the Console!
+					InputStream is = process.getInputStream();
+					int ch;
+					// read "Password:"
+					while ((ch = is.read()) != -1) {
+						if (ch == ':') {
+							break;
+						}
+					}
+					*/
+					
+					// send password
+					OutputStream os = process.getOutputStream();
+					os.write((password + "\n").getBytes());
+					os.close();
+
+					// now let the remaining output go to the Console
+					processLauncher.redirectToConsole(false, null, "Mounting shares");
+					try {
+						int exit = process.waitFor();
+						if (exit != 0) {
+							exceptions[0] = new MicaException("Mounting script did not succeed; check Console for errors");
+							return;
+						}
+					} catch (InterruptedException e) {
+					}
+					
+				} catch (IOException e) {
+					exceptions[0] = new MicaException("Failed to send password", e);
+					return;
+				}
+			}
+		};
+		thread.start();
+		
+		boolean timedOut = !JobUtils.waitForThread(thread, 10000, null);
+
+		process.destroy();
+		
+		if (!thread.isAlive()) {
+			if (exceptions[0] != null) {
+				throw exceptions[0];
+			}
+		}
+		if (timedOut) {
+			if (thread.isAlive())
+				thread.interrupt();
+			throw new MicaException("Timeout sending password");
+		}
+	}
+	
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuMachine.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuMachineController.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuMachineController.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuMachineController.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,481 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+package _org.maemo.esbox.internal.protocol.vm.qemu;
+
+
+import com.nokia.cpp.internal.api.utils.ui.WorkbenchUtils;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.maemo.mica.common.core.*;
+import org.maemo.mica.common.core.machine.*;
+import org.maemo.mica.common.core.process.*;
+import org.maemo.mica.internal.api.protocol.ssh.SSHMachineControllerBase;
+import org.maemo.mica.protocol.vm.qemu.IQemuConfiguration;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.Socket;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is the basic implementation of a QEMU machine
+ * @author eswartz
+ *
+ */
+public class QemuMachineController extends SSHMachineControllerBase {
+
+	/**
+	 * 
+	 */
+	private static final IStatus CANCEL_STATUS = Policy.getCancelStatus(Activator.getDefault());
+	/**
+	 * 
+	 */
+	static final String QEMU_LAUNCHER = "conf/run_linux_wait.bat";
+	/** thread and process are non-null if we launched QEMU ourselves */
+	Process launchedQemu;
+	/** thread and process are non-null if we launched QEMU ourselves */
+	QemuWatcherThread launchedQemuThread;
+	private IQemuConfiguration qemuConfiguration;
+	private boolean isValidating;
+	
+	class QemuWatcherThread extends Thread {
+		private IProcessLauncher launcher;
+		private ByteArrayOutputStream err;
+		private ByteArrayOutputStream out;
+		public QemuWatcherThread(IProcessLauncher launcher) {
+			this.launcher = launcher;
+			setDaemon(true);
+		}
+		public void run() {
+			// TODO: make this go to the console
+			
+			// wait for it
+			out = new ByteArrayOutputStream();
+			err = new ByteArrayOutputStream();
+			launcher.waitAndRead(out, err);
+			System.out.println(out);
+			System.out.println(err);
+		}
+	}
+	
+	public QemuMachineController(IQemuConfiguration configuration) {
+		super(configuration.getSSHConfiguration(), "QEMU");
+		this.qemuConfiguration = configuration;
+	}
+	
+	/**
+	 * @param processLauncher
+	 * @return
+	 */
+	MachineException processOutput(String message, QemuWatcherThread thread) {
+		return new MachineException(
+				MessageFormat.format("{0}\nCommand line: {1}\nstdout: {2}\nstderr: {3}",
+					message, 
+					CommandLineArguments.toCommandLine(thread.launcher.getLaunchCommandArguments()),
+					thread.out,
+					thread.err));
+	}
+
+	@Override
+	protected IStatus doStartMachine(IProgressMonitor monitor) throws MachineException {
+		// ensure we check again ASAP
+		scheduleProbe();
+		
+		try {
+			return doStartMachineImpl(monitor);
+		} finally {
+			// and check again whether we think it succeeded or not
+			scheduleProbe();
+		}
+	}
+
+	/**
+	 * @param monitor
+	 * @return
+	 * @throws MachineException
+	 */
+	private IStatus doStartMachineImpl(IProgressMonitor monitor)
+			throws MachineException {
+		final int PROBE_COUNT = 10;
+		
+		monitor.beginTask("Starting " + getName(), IProgressMonitor.UNKNOWN);
+		
+		// we're here due to an error state
+		if (launchedQemu != null) {
+			// kill the running one since there's no way to fix it
+			
+			launchedQemu.destroy();
+			launchedQemu = null;
+			fireMachineStateChanged();
+			monitor.worked(1);
+			if (monitor.isCanceled())
+				return CANCEL_STATUS;
+		}
+		
+		if (!HostUtils.isWindows()) {
+			throw new MachineException("Launching QEMU from Linux not implemented yet");
+		}
+		
+		String batchFile;
+		try {
+			URL url = FileLocator.find(Activator.getDefault().getBundle(),
+					new Path(QEMU_LAUNCHER),
+					null);
+			if (url == null) {
+				throw new MachineException("Cannot locate " + QEMU_LAUNCHER);	
+			}
+			batchFile = new Path(FileLocator.toFileURL(url).getPath()).toOSString();
+		} catch (IOException e1) {
+			throw new MachineException("Cannot extract " + QEMU_LAUNCHER, e1);
+		}
+		
+		/* XXX: can't use CommandLineArguments#createFromCommandLine() for DOS
+		String launchPattern = "cmd /c \"${BATCH_FILE}\" \"${QEMU}\" \"${BIOS_DIR}\" \"${DATA_DIR}\" ${SSH_PORT}";
+		
+		ShellTemplateSubstitutor substitutor = new ShellTemplateSubstitutor();
+		substitutor.define("BATCH_FILE", batchFile);
+		substitutor.define("QEMU", configuration.getExecutable());
+		substitutor.define("BIOS_DIR", configuration.getBiosPath());
+		substitutor.define("DATA_DIR", configuration.getDiskImagePath());
+		substitutor.define("SSH_PORT", "" + configuration.getSSHConfiguration().getPort());
+		
+		String commandString = substitutor.substitute(launchPattern);
+		System.out.println(commandString);
+		List<String> cmdLine = CommandLineArguments.createFromCommandLine(commandString);
+		 */
+		
+		monitor.setTaskName("Launching QEMU and waiting for startup...");
+		
+		List<String> cmdLine = new ArrayList<String>();
+		// add START to launch in background
+		cmdLine.add("cmd");
+		cmdLine.add("/c");
+		cmdLine.add(batchFile);
+	
+		cmdLine.add(qemuConfiguration.getExecutable());
+		cmdLine.add(qemuConfiguration.getBiosPath());
+		cmdLine.add(qemuConfiguration.getDiskImagePath());
+		cmdLine.add("" + qemuConfiguration.getSSHConfiguration().getTargetPort());
+		cmdLine.add("" + qemuConfiguration.getCIFSPort());
+		
+		String commandString = CommandLineArguments.toCommandLine(cmdLine);
+		System.out.println(commandString);
+		
+		IProcessLauncherFactory processLauncherFactory = new HostProcessLauncherFactory();
+		final IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(
+				processLauncherFactory, null, cmdLine);
+		try {
+			launchedQemu = processLauncher.createProcess();
+		} catch (MicaException e) {
+			throw new MachineException("Cannot launch qemu: " + CommandLineArguments.toCommandLine(cmdLine), e);
+		}
+		
+		launchedQemuThread = new QemuWatcherThread(processLauncher);
+		launchedQemuThread.start();
+		
+		long timeout = System.currentTimeMillis() + 300 * 1000;
+		while (true) {
+			if (!launchedQemuThread.isAlive()) {
+				throw processOutput("qemu launch failed", launchedQemuThread);
+			}
+			try {
+				launchedQemu.exitValue();
+				launchedQemuThread.interrupt();
+				throw processOutput("QEMU died", launchedQemuThread);
+			} catch (IllegalThreadStateException e) {
+				// still running
+			}
+			
+			for (int cnt = 0; cnt < PROBE_COUNT; cnt++) {
+				monitor.worked(1);
+				if (monitor.isCanceled())
+					return CANCEL_STATUS;
+
+				try {
+					Thread.sleep(100);
+				} catch (InterruptedException e) {
+					doStopMachine(monitor);
+					return CANCEL_STATUS;
+				}
+				
+				Display display = Display.getCurrent();
+				if (display != null) {
+					while (display.readAndDispatch()) ;
+				}
+			}
+			
+			// test the connection
+			scheduleProbe();
+			IStatus status = doProbeMachine(new SubProgressMonitor(monitor, 1));
+			if (status.isOK()) {
+				// XXX: do this more intelligently
+				// sshd starts a few moments before /etc/rc.local is run, 
+				// so kernel parameters like vdso might not be configured yet... 
+				// wait a few seconds more to avoid immediately invoking
+				// scratchbox commands and failing.
+				for (int cnt = 0; cnt < 50; cnt++) {
+					Display display = Display.getCurrent();
+					if (display != null) {
+						while (display.readAndDispatch()) ;
+					}
+					
+					monitor.worked(1);
+					if (monitor.isCanceled())
+						throw cancelled();
+
+					try {
+						Thread.sleep(100);
+					} catch (InterruptedException e) {
+						throw cancelled();
+					}
+				}
+				break;
+			}
+			
+			if (System.currentTimeMillis() >= timeout) {
+				throw processOutput("Timed out waiting for qemu startup", launchedQemuThread);
+			}
+		}
+		
+		fireMachineStateChanged();
+		
+		return Status.OK_STATUS;
+	}
+	
+	protected MachineException cancelled() {
+		return new MachineException(null, new CoreException(CANCEL_STATUS));
+	}
+
+	@Override
+	protected IStatus doStopMachine(IProgressMonitor monitor) throws MachineException {
+		IStatus status = super.doStopMachine(monitor);
+		if (!status.isOK())
+			return status;
+		
+		// only try halting if we created it
+		if (launchedQemuThread != null && launchedQemuThread.isAlive()) {
+			// make it halt
+			List<String> cmdLine = CommandLineArguments.createFromCommandLine(
+				"sudo -S halt now");
+			
+			IProcessLauncherFactory processLauncherFactory = getProcessLauncherFactory();
+			Process process;
+			try {
+				process = ProcessLauncherCreator.createProcessLauncher(processLauncherFactory,
+						null, cmdLine).createProcess();
+				try {
+					// send the password for sudo
+					process.getOutputStream().write(qemuConfiguration.getSSHConfiguration().getUserPassword().getBytes());
+					process.getOutputStream().write('\n');
+					process.getOutputStream().close();
+	
+					// this will return right away, it seems
+					process.waitFor();
+				} catch (InterruptedException e2) {
+					throw new MachineException("Aborted halting Linux host in QEMU", e2);
+				}
+			} catch (Exception e) {
+				throw new MachineException("Cannot stop processes in Linux host in QEMU", e);
+			}
+			
+			// probe until it's not responding
+			
+			long timeout = System.currentTimeMillis() + 60 * 1000;
+			while (true) {
+				for (int cnt = 0; cnt < 10; cnt++) {
+					try {
+						monitor.worked(1);
+						if (monitor.isCanceled())
+							return CANCEL_STATUS;
+
+						Thread.sleep(100);
+					} catch (InterruptedException e) {
+						// ignore
+					}
+					
+					while (Display.getCurrent().readAndDispatch()) ;
+				}
+				
+				// test the connection
+				scheduleProbe();
+				status = doProbeMachine(monitor);
+				if (!status.isOK()) {
+					// wait a LITTLE longer -- termination of ssh doesn't mean we have really shut down
+					for (int cnt = 0; cnt < 75; cnt++) {
+						monitor.worked(1);
+						if (monitor.isCanceled())
+							return CANCEL_STATUS;
+
+						try {
+							Thread.sleep(100);
+						} catch (InterruptedException e) {
+							doStopMachine(monitor);
+							return CANCEL_STATUS;
+						}
+						
+						while (Display.getCurrent().readAndDispatch()) ;
+					}
+					break;
+				}
+				
+				if (System.currentTimeMillis() >= timeout) {
+					throw processOutput("Timed out waiting for qemu shutdown", launchedQemuThread);
+				}
+			}
+			
+			// stop monitoring
+			launchedQemuThread.interrupt();
+			launchedQemuThread = null;
+			
+			// now, kill the process 
+			launchedQemu.destroy();
+			launchedQemu = null;
+			
+			fireMachineStateChanged();
+	
+			return Status.OK_STATUS;
+		} else {
+			return Activator.createStatus(IStatus.WARNING, 
+					"Not terminating QEMU session that this IDE did not create");
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.internal.common.core.machine.BaseMachineController#doAskUserToRepairMachine(org.eclipse.swt.widgets.Shell, org.eclipse.core.runtime.IStatus)
+	 */
+	@Override
+	protected Result doAskUserToRepairMachine(Shell shell, IStatus status) {
+		// see if QEMU *seems* to be running... i.e. something is listening on the SSH port
+		try {
+			Socket socket = new Socket(qemuConfiguration.getSSHConfiguration().getTargetIPAddress(),
+					qemuConfiguration.getSSHConfiguration().getTargetPort());
+			socket.close();
+			
+		
+			final boolean[] results = { false };
+			if (!WorkbenchUtils.isJUnitRunning()) {
+				Display.getDefault().syncExec(new Runnable() {
+		
+					public void run() {
+						results[0] = MessageDialog.openConfirm(null, "QEMU running?", 
+								MessageFormat.format(
+										"QEMU may still be running, but it seems to be halted or crashed\n"
+										+"(or something else owns the server socket {0}:{1}).\n\n"
+										+"Please kill it if necessary and select 'Ok' to retry.",
+										qemuConfiguration.getSSHConfiguration().getTargetIPAddress(), 
+										""+qemuConfiguration.getSSHConfiguration().getTargetPort()));
+					}
+					
+				});
+			}
+			
+			if (!results[0]) {
+				// canceled
+				return Result.ABORT;
+			}
+			return Result.RETRY;
+			
+		} catch (IOException e) {
+			// no one listening to the port, so probably qemu not running; ignore the error and keep trying
+			return Result.IGNORE;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.internal.common.core.machine.BaseMachineController#acquireMachine(org.maemo.mica.common.core.machine.IMachine, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	@Override
+	public IStatus acquireMachine(IMachine machine, IProgressMonitor monitor) {
+		monitor.beginTask("", 2);
+		
+		// re-check to be sure
+		scheduleProbe();
+		IStatus status = super.acquireMachine(machine, new SubProgressMonitor(monitor, 1));
+		if (!status.isOK())
+			return status;
+		
+		if (monitor.isCanceled())
+			return CANCEL_STATUS;
+		
+		// now, verify shared folders
+		QemuMachine qemuMachine = (QemuMachine) machine;
+		
+		status = qemuMachine.validateSharedMounts(new SubProgressMonitor(monitor, 1));
+
+		return status;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.internal.common.core.machine.BaseMachineController#probeMachine(org.maemo.mica.common.core.machine.IMachine, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	@Override
+	public IStatus probeMachine(final IMachine machine, final IProgressMonitor monitor) {
+		monitor.beginTask("", 2);
+		
+		// re-check if things might be fishy
+		try {
+			if (launchedQemu != null)
+				launchedQemu.exitValue();
+			scheduleProbe();
+		} catch (IllegalThreadStateException e) {
+			
+		}
+		
+		IStatus status = super.probeMachine(machine, new SubProgressMonitor(monitor, 1));
+		if (!status.isOK())
+			return status;
+		
+		if (monitor.isCanceled())
+			return CANCEL_STATUS;
+		
+		try {
+			// try to ensure mounts are shared, but don't sync on this here
+			if (!isValidating) {
+				isValidating = true;
+				Runnable runnable = new Runnable() {
+
+					public void run() {
+						try {
+							IStatus status = ((QemuMachine) machine).validateSharedMounts(
+									new SubProgressMonitor(monitor, 1));
+							if (!status.isOK()) {
+								Activator.getErrorLogger().logError(status.getMessage(), status.getException());
+							}
+						} finally {
+							isValidating = false;
+						}
+					}
+					
+				};
+				
+				// must do this asynchronously if we don't own the display;
+				// most likely the machine is owned by other thread
+				Display display = Display.getCurrent();
+				if (display == null)
+					Display.getDefault().asyncExec(runnable);
+				else
+					runnable.run();
+			}
+			
+			return Status.OK_STATUS;
+		} finally {
+			monitor.worked(1);
+			monitor.done();
+		}
+	}
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuMachineController.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuPreferenceConstants.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuPreferenceConstants.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuPreferenceConstants.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package _org.maemo.esbox.internal.protocol.vm.qemu;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * This class encapsulates the keys for preference constants for QEMU configuration.
+ * @author eswartz
+ *
+ */
+public class QemuPreferenceConstants {
+	public static final int VERSION_MAJOR = 1;
+	public static final int VERSION_MINOR = 0;
+	
+	/** Get the preference store that contains these preferences */
+	public static IPreferenceStore getPreferenceStore() {
+		return Activator.getDefault().getPreferenceStore();
+	}
+	
+	
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/QemuPreferenceConstants.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/StockQemuConfiguration.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/StockQemuConfiguration.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/StockQemuConfiguration.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+package _org.maemo.esbox.internal.protocol.vm.qemu;
+
+import org.eclipse.core.runtime.Platform;
+import org.maemo.mica.common.core.machine.ISharedFilesystemProvider;
+import org.maemo.mica.internal.api.common.core.machine.StockSharedFilesystemProvider;
+import org.maemo.mica.protocol.ssh.SSHConfiguration;
+import org.maemo.mica.protocol.vm.qemu.IQemuConfiguration;
+
+/**
+ * @author eswartz
+ *
+ */
+public class StockQemuConfiguration implements IQemuConfiguration {
+
+	
+	private SSHConfiguration sshConfiguration = new SSHConfiguration(
+			"127.0.0.1", 2222, 
+			"10.0.2.2", 22,
+			"devel", "qatest", 
+			10 /*timeout*/ 
+			);
+
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.common.core.machine.IQemuConfiguration#getOS()
+	 */
+	public String getOS() {
+		return Platform.OS_LINUX;
+	}
+	
+	/* (non-Javadoc)
+	 * @see testrse.IQemuConfiguration#getSSHConfiguration()
+	 */
+	public SSHConfiguration getSSHConfiguration() {
+		return sshConfiguration;
+	}
+
+	/* (non-Javadoc)
+	 * @see testrse.IQemuConfiguration#getBiosPath()
+	 */
+	public String getBiosPath() {
+		return "c:/Program Files/Qemu";
+	}
+
+	/* (non-Javadoc)
+	 * @see testrse.IQemuConfiguration#getDiskImagePath()
+	 */
+	public String getDiskImagePath() {
+		return "c:/Program Files/Nokia/Carbide for Maemo/vm";
+		//return "e:/qemu_vm";
+	}
+
+	/* (non-Javadoc)
+	 * @see testrse.IQemuConfiguration#getExecutable()
+	 */
+	public String getExecutable() {
+		return "c:/program files/qemu/qemu.exe";
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.common.core.machine.IQemuConfiguration#getUserName()
+	 */
+	public String getUserName() {
+		return sshConfiguration.getUserName();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.common.core.machine.IQemuConfiguration#getSharedFilesystemProvider()
+	 */
+	public ISharedFilesystemProvider getSharedFilesystemProvider() {
+		return new StockSharedFilesystemProvider(sshConfiguration.getUserName());
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.common.core.machine.IQemuConfiguration#getCIFSPort()
+	 */
+	public int getCIFSPort() {
+		return 4445;
+	}
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/protocol/vm/qemu/StockQemuConfiguration.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/BaseVirtualMachinePreferencePage.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/BaseVirtualMachinePreferencePage.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/BaseVirtualMachinePreferencePage.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package _org.maemo.esbox.internal.vm.qemu;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.maemo.esbox.vm.core.IVirtualMachinePreferencePage;
+
+/**
+ * @author eswartz
+ *
+ */
+public abstract class BaseVirtualMachinePreferencePage extends PreferencePage {
+
+	protected boolean anyChanges;
+
+	/**
+	 * 
+	 */
+	public BaseVirtualMachinePreferencePage() {
+		super();
+	}
+
+	/**
+	 * @param title
+	 */
+	public BaseVirtualMachinePreferencePage(String title) {
+		super(title);
+	}
+
+	/**
+	 * @param title
+	 * @param image
+	 */
+	public BaseVirtualMachinePreferencePage(String title, ImageDescriptor image) {
+		super(title, image);
+	}
+
+	@Override
+	public void performApply() {
+		anyChanges = false;
+	}
+
+	@Override
+	public void performDefaults() {
+		
+		super.performDefaults();
+	}
+
+}
\ No newline at end of file


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/BaseVirtualMachinePreferencePage.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/CorePreferenceConstants.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/CorePreferenceConstants.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/CorePreferenceConstants.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package _org.maemo.esbox.internal.vm.qemu;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.maemo.mica.internal.common.core.Activator;
+
+/**
+ * This class encapsulates the keys for preference constants defined by the core.
+ * @author eswartz
+ *
+ */
+public class CorePreferenceConstants {
+	public static final int VERSION_MAJOR = 17;
+	public static final int VERSION_MINOR = 0;
+	
+	/** Get the preference store that contains these preferences */
+	public static IPreferenceStore getPreferenceStore() {
+		return Activator.getDefault().getPreferenceStore();
+	}
+	
+	public static final String LOG_COMMANDS = "LOG_COMMANDS";
+	public static final String LOG_COMMANDS_PATH = "LOG_COMMANDS_PATH";
+	public static final String USER = "USER";
+	public static final String TERMINAL_COMMAND = "TERMINAL_COMMAND";
+	public static final String BUILD_MACHINE_URIS = "BUILD_MACHINE_URIS";
+	public static final String VIRTUAL_BUILD_MACHINE_ID = "VIRTUAL_BUILD_MACHINE_ID";
+	
+	/* OS-specific defaults accessors */
+	static final String LOG_COMMANDS_PATH_WIN32 = "LOG_COMMANDS_PATH_WIN32";
+	static final String LOG_COMMANDS_PATH_UNIX = "LOG_COMMANDS_PATH_UNIX";
+	
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/CorePreferenceConstants.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/StockQemuConfiguration.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/StockQemuConfiguration.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/StockQemuConfiguration.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+package _org.maemo.esbox.internal.vm.qemu;
+
+import org.eclipse.core.runtime.Platform;
+import org.maemo.esbox.vm.qemu.IQemuConfiguration;
+import org.maemo.mica.common.core.machine.ISharedFilesystemProvider;
+import org.maemo.mica.internal.api.common.core.machine.StockSharedFilesystemProvider;
+import org.maemo.mica.protocol.ssh.SSHConfiguration;
+
+/**
+ * This configuration corresponds to the maemovmware image.
+ * @author eswartz
+ *
+ */
+public class StockQemuConfiguration implements IQemuConfiguration {
+
+	
+	private SSHConfiguration sshConfiguration = new SSHConfiguration(
+			"127.0.0.1", 2222, 
+			"10.0.2.2", 22,
+			"devel", "qatest", 
+			10 /*timeout*/ 
+			);
+
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.common.core.machine.IQemuConfiguration#getOS()
+	 */
+	public String getOS() {
+		return Platform.OS_LINUX;
+	}
+	
+	/* (non-Javadoc)
+	 * @see testrse.IQemuConfiguration#getSSHConfiguration()
+	 */
+	public SSHConfiguration getSSHConfiguration() {
+		return sshConfiguration;
+	}
+
+	/* (non-Javadoc)
+	 * @see testrse.IQemuConfiguration#getBiosPath()
+	 */
+	public String getInstallPath() {
+		return "c:/Program Files/Qemu";
+	}
+
+	/* (non-Javadoc)
+	 * @see testrse.IQemuConfiguration#getDiskImagePath()
+	 */
+	public String getDiskImagePath() {
+		return "c:/Program Files/Nokia/Carbide for Maemo/vm";
+		//return "e:/qemu_vm";
+	}
+
+	/* (non-Javadoc)
+	 * @see testrse.IQemuConfiguration#getExecutable()
+	 */
+	public String getExecutable() {
+		return "c:/program files/qemu/qemu.exe";
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.common.core.machine.IQemuConfiguration#getUserName()
+	 */
+	public String getUserName() {
+		return sshConfiguration.getUserName();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.common.core.machine.IQemuConfiguration#getSharedFilesystemProvider()
+	 */
+	public ISharedFilesystemProvider getSharedFilesystemProvider() {
+		return new StockSharedFilesystemProvider(sshConfiguration.getUserName());
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.common.core.machine.IQemuConfiguration#getCIFSPort()
+	 */
+	public int getCIFSPort() {
+		return 4445;
+	}
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/internal/vm/qemu/StockQemuConfiguration.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/protocol/vm/qemu/IQemuConfiguration.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/protocol/vm/qemu/IQemuConfiguration.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/protocol/vm/qemu/IQemuConfiguration.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package _org.maemo.esbox.protocol.vm.qemu;
+
+import org.maemo.mica.common.core.machine.ISharedFilesystemProvider;
+import org.maemo.mica.protocol.ssh.SSHConfiguration;
+
+/**
+ * This interface, implemented by clients, provides settings needed
+ * to launch and communicate with a virtual machine using QEMU.
+ * <p>
+ * XXX Currently this is expected to return non-changing values.
+ * If values change, ensure that a listener is added so machines
+ * can respond to changes.
+ * @author eswartz
+ *
+ */
+public interface IQemuConfiguration {
+
+	/** Get the OS this runs (Platform.OS_xxx) */
+	String getOS();
+	
+	/** Get the name (path + filename) of the program to launch. */
+	String getExecutable();
+
+	/** Get the path of the BIOS files. */
+	String getBiosPath();
+
+	/** Get the base path of the disk images. */
+	String getDiskImagePath();
+	
+	/** Get the SSH configuration. */
+	SSHConfiguration getSSHConfiguration();
+
+	/**
+	 * Get the name of the primary user on this machine
+	 */
+	String getUserName();
+	
+	/**
+	 * Get the shared filesystems
+	 */
+	ISharedFilesystemProvider getSharedFilesystemProvider();
+
+	/**
+	 * Get the port for CIFS (Samba/Windows shares) access
+	 * @return
+	 */
+	int getCIFSPort();
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/_org/maemo/esbox/protocol/vm/qemu/IQemuConfiguration.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/Activator.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/Activator.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/Activator.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,131 @@
+package org.maemo.esbox.internal.vm.qemu;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.maemo.mica.common.core.ErrorLogger;
+import org.osgi.framework.BundleContext;
+
+import java.io.*;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.maemo.esbox.vm.qemu";
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * @param object
+	 * @param e
+	 * @return
+	 */
+	public static IStatus createErrorStatus(String msg, Throwable t) {
+		return new Status(IStatus.ERROR, PLUGIN_ID, msg, t);
+	}
+
+	/**
+	 * @param warning
+	 * @param format
+	 * @param e
+	 * @return
+	 */
+	public static IStatus createStatus(int severity, String msg,
+			Throwable t) {
+		return new Status(severity, PLUGIN_ID, msg, t);
+	}
+
+	/**
+	 * @param warning
+	 * @param string
+	 * @return
+	 */
+	public static IStatus createStatus(int severity, String string) {
+		return new Status(severity, PLUGIN_ID, string);
+	}
+	
+	/**
+	 * Return the error logger instance of this plug-in.
+	 * 
+	 * @return the error logger instance of this plug-in.
+	 */
+	public static ErrorLogger getErrorLogger() {
+		class CoreErrorLogger extends ErrorLogger {
+
+			@Override
+			public String getPluginID() {
+				return PLUGIN_ID;
+			}
+			@Override
+			public Plugin getPlugin() {
+				return Activator.getDefault();
+			}
+
+		}
+
+		return new CoreErrorLogger();
+	}
+
+	/**
+	 * Find a file relative to the plugin, either in a running
+	 * workspace or a standalone unit test (assumed to run relative
+	 * to a plugin)
+	 * @param path
+	 */
+	public static InputStream getPluginRelativeInputStream(String path) throws IOException {
+		if (getDefault() != null) {
+			return FileLocator.openStream(getDefault().getBundle(), new Path(path), false);
+		} else {
+			return new FileInputStream("../" + path);
+		}
+	}
+	
+	/**
+	 * Returns an image descriptor for the image file at the given
+	 * plug-in relative path.
+	 *
+	 * @param path the path
+	 * @return the image descriptor
+	 */
+	public static ImageDescriptor getImageDescriptor(String path) {
+		return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path);
+	}
+
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/Activator.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/BaseVirtualMachinePreferencePage.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/BaseVirtualMachinePreferencePage.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/BaseVirtualMachinePreferencePage.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.vm.qemu;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.maemo.esbox.vm.core.IVirtualMachinePreferencePage;
+
+/**
+ * @author eswartz
+ *
+ */
+public abstract class BaseVirtualMachinePreferencePage extends PreferencePage {
+
+	protected boolean anyChanges;
+
+	/**
+	 * 
+	 */
+	public BaseVirtualMachinePreferencePage() {
+		super();
+	}
+
+	/**
+	 * @param title
+	 */
+	public BaseVirtualMachinePreferencePage(String title) {
+		super(title);
+	}
+
+	/**
+	 * @param title
+	 * @param image
+	 */
+	public BaseVirtualMachinePreferencePage(String title, ImageDescriptor image) {
+		super(title, image);
+	}
+
+	@Override
+	public void performApply() {
+		anyChanges = false;
+	}
+
+	@Override
+	public void performDefaults() {
+		
+		super.performDefaults();
+	}
+
+}
\ No newline at end of file


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/BaseVirtualMachinePreferencePage.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/PreferenceQemuConfiguration.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/PreferenceQemuConfiguration.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/PreferenceQemuConfiguration.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+package org.maemo.esbox.internal.vm.qemu;
+
+import org.eclipse.core.runtime.Platform;
+import org.maemo.esbox.internal.api.vm.core.BasePreferenceVirtualMachineConfiguration;
+import org.maemo.esbox.vm.qemu.IQemuConfiguration;
+
+/**
+ * This configuration reads settings from the preference store (VirtualMachinePreferenceConstants,
+ * QemuPreferenceConstants).  The settings will change as the preferences change.
+ * @author eswartz
+ *
+ */
+public class PreferenceQemuConfiguration extends BasePreferenceVirtualMachineConfiguration implements IQemuConfiguration {
+	
+	public String getOS() {
+		return Platform.OS_LINUX;
+	}
+	
+
+	public String getInstallPath() {
+		return getPreference(QemuPreferenceConstants.QEMU_INSTALL_PATH);
+	}
+
+	public String getDiskImagePath() {
+		return getPreference(QemuPreferenceConstants.QEMU_DISK_IMAGE_PATH); 
+	}
+
+	public String getExecutable() {
+		return getPreference(QemuPreferenceConstants.QEMU_EXE_NAME); 
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.vm.qemu.IQemuConfiguration#getMemorySize()
+	 */
+	public int getMemorySize() {
+		return Integer.parseInt(getPreference(QemuPreferenceConstants.QEMU_MEMORY_SIZE));
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.vm.qemu.IQemuConfiguration#getCommandLaunchPattern()
+	 */
+	public String getCommandLaunchPattern() {
+		return getPreference(QemuPreferenceConstants.QEMU_LAUNCH_PATTERN); 
+	}
+
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/PreferenceQemuConfiguration.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuBuildMachineFactory.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuBuildMachineFactory.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuBuildMachineFactory.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+package org.maemo.esbox.internal.vm.qemu;
+
+import org.maemo.esbox.vm.qemu.IQemuConfiguration;
+import org.maemo.mica.common.core.machine.IBuildMachineFactory;
+import org.maemo.mica.internal.api.common.core.machine.IBuildMachineImpl;
+
+/**
+ * This factory creates virtual build machines hosted on QEMU.
+ * We support only one machine at a time.
+ * @author eswartz
+ *
+ */
+public class QemuBuildMachineFactory implements IBuildMachineFactory {
+
+	private IQemuConfiguration configuration;
+	
+	public QemuBuildMachineFactory() {
+		this.configuration = new PreferenceQemuConfiguration();
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.common.core.machine.IMachineFactory#createMachine(java.lang.String)
+	 */
+	public synchronized IBuildMachineImpl[] createMachines() {
+		IBuildMachineImpl qemuMachine = new QemuMachine(configuration);
+		return new IBuildMachineImpl[] { qemuMachine };
+	}
+
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuBuildMachineFactory.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachine.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachine.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachine.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+package org.maemo.esbox.internal.vm.qemu;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.maemo.esbox.vm.core.*;
+import org.maemo.esbox.vm.qemu.IQemuConfiguration;
+import org.maemo.mica.common.core.*;
+import org.maemo.mica.common.core.machine.*;
+import org.maemo.mica.common.core.process.*;
+import org.maemo.mica.common.ui.dialogs.DialogUtils;
+import org.maemo.mica.common.ui.dialogs.PasswordInputDialog;
+import org.maemo.mica.internal.api.common.core.machine.IBuildMachineImpl;
+import org.maemo.mica.internal.api.protocol.ssh.SSHMachineBackend;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.MessageFormat;
+import java.util.Map;
+
+
+/**
+ * This is a build machine running under QEMU.
+ * @author eswartz
+ *
+ */
+public class QemuMachine extends SSHMachineBackend implements IVirtualMachine, IBuildMachineImpl {
+
+	public final static String ID = Activator.PLUGIN_ID + ".qemu_machine";
+	public final static String NAME = "QEMU Linux Virtual Machine";
+	private IQemuConfiguration configuration;
+	
+	public QemuMachine(IQemuConfiguration configuration) {
+		super(ID, NAME, configuration.getOS(),
+				new QemuMachineController(configuration),
+				configuration.getSSHConfiguration(),
+				configuration.getSharedFilesystemProvider());
+		this.configuration = configuration; 
+	}
+	
+	/**
+	 * This method is called on the UI thread.  It should validate that
+	 * the shared filesystems are available, prompting the user for a password
+	 * and launching 'mount_share.sh' to mount them otherwise.
+	 * <p>
+	 * XXX: this must be rewritten at some point to handle shares which aren't handled by mount_share.sh!
+	 * @param subProgressMonitor 
+	 * @return Status of mount
+	 */
+	public IStatus validateSharedMounts(IProgressMonitor monitor) {
+
+		ISharedFilesystemProvider sharedFilesystemProvider = 
+			getSharedFilesystemProvider();
+		Map<IPath, IPath> sharedFolders = 
+			sharedFilesystemProvider.getSharedFolders();
+		
+		monitor.beginTask("Validating shared folders", sharedFolders.size() * 2);
+		
+		boolean neededMount = false;
+		
+		String fsTypePattern = "smbfs|cifs";
+		for (Map.Entry<IPath, IPath> entry : sharedFolders.entrySet()) {
+			if (!isPathMounted(entry.getValue(), fsTypePattern, null)) {
+				neededMount = true;
+				PasswordInputDialog dialog = new PasswordInputDialog(
+						DialogUtils.getShell(), 
+						"Password Required",
+						MessageFormat.format(
+								"Enter the password for user ''{0}'' to mount the share ''{1}'':",
+								MachineRegistry.getInstance().getLocalMachine().getUserName(),
+								entry.getKey()));
+				if (IDialogConstants.CANCEL_ID == dialog.open())
+					continue;
+				
+				// TODO: this assumes a certain script exists on the VM
+				try {
+					mountSharesWithPassword(dialog.getPassword());
+				} catch (MicaException e) {
+					return Activator.createErrorStatus(
+							MessageFormat.format(
+									"Could not mount ''{0}'' in {1}",
+									entry.getKey().toString(),
+									getName()), e);
+				}
+				
+				monitor.worked(1);
+				if (monitor.isCanceled())
+					return Policy.getCancelStatus(Activator.getDefault());
+			}
+		}
+		
+		// verify that the mounting succeeded
+		boolean allSharesMounted = true;
+		if (neededMount) {
+			for (Map.Entry<IPath, IPath> entry : sharedFolders.entrySet()) {
+				if (!isPathMounted(entry.getValue(), fsTypePattern, null)) {
+					allSharesMounted = false;
+				}
+				monitor.worked(1);
+				if (monitor.isCanceled())
+					return Policy.getCancelStatus(Activator.getDefault());
+			}
+		}
+		
+		monitor.done();
+		
+		if (!allSharesMounted) {
+			return Activator.createStatus(IStatus.WARNING, 
+					MessageFormat.format(
+							"Not all the known shares were mounted in {0}; builds may fail",
+							getName()));
+		}
+
+		return Status.OK_STATUS;
+	}
+	
+	/**
+	 * Run the 'mount_share.sh' script to mount shares.
+	 * @param password
+	 */
+	protected void mountSharesWithPassword(final String password) throws MicaException {
+		IProcessLauncherFactory processLauncherFactory = getProcessLauncherFactory();
+		final IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(processLauncherFactory,
+				getUserHome(),
+				CommandLineArguments.createFromVarArgs(
+						"sh",
+						"mount_share.sh"));
+		
+		processLauncher.usePTY(true);
+		final Process process = processLauncher.createProcess();
+		final MicaException[] exceptions = { null };
+		
+		Thread thread = new Thread("Send password to mount") {
+
+			/* (non-Javadoc)
+			 * @see java.lang.Thread#run()
+			 */
+			@Override
+			public void run() {
+				try {
+					/* this goes to a weird stream (somehow) so we can't read it,
+					 even though it shows up when we put stuff to the Console!
+					InputStream is = process.getInputStream();
+					int ch;
+					// read "Password:"
+					while ((ch = is.read()) != -1) {
+						if (ch == ':') {
+							break;
+						}
+					}
+					*/
+					
+					// send password
+					OutputStream os = process.getOutputStream();
+					os.write((password + "\n").getBytes());
+					os.close();
+
+					// now let the remaining output go to the Console
+					processLauncher.redirectToConsole(false, null, "Mounting shares");
+					try {
+						int exit = process.waitFor();
+						if (exit != 0) {
+							exceptions[0] = new MicaException("Mounting script did not succeed; check Console for errors");
+							return;
+						}
+					} catch (InterruptedException e) {
+					}
+					
+				} catch (IOException e) {
+					exceptions[0] = new MicaException("Failed to send password", e);
+					return;
+				}
+			}
+		};
+		thread.start();
+		
+		boolean timedOut = !JobUtils.waitForThread(thread, 10000, null);
+
+		process.destroy();
+		
+		if (!thread.isAlive()) {
+			if (exceptions[0] != null) {
+				throw exceptions[0];
+			}
+		}
+		if (timedOut) {
+			if (thread.isAlive())
+				thread.interrupt();
+			throw new MicaException("Timeout sending password");
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.vm.core.IVirtualMachine#createPreferencePage(org.eclipse.swt.widgets.Composite)
+	 */
+	public IVirtualMachinePreferencePage createPreferencePage() {
+		return new QemuPreferencePage();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.vm.core.IVirtualMachine#getConfiguration()
+	 */
+	public IVirtualMachineConfiguration getConfiguration() {
+		return configuration;
+	}
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachine.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachineController.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachineController.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachineController.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,455 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+package org.maemo.esbox.internal.vm.qemu;
+
+
+import com.nokia.cpp.internal.api.utils.ui.WorkbenchUtils;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.maemo.esbox.vm.qemu.IQemuConfiguration;
+import org.maemo.mica.common.core.*;
+import org.maemo.mica.common.core.machine.*;
+import org.maemo.mica.common.core.process.*;
+import org.maemo.mica.internal.api.protocol.ssh.SSHMachineControllerBase;
+import org.maemo.mica.protocol.ssh.SSHConfiguration;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.Socket;
+import java.text.MessageFormat;
+import java.util.List;
+
+/**
+ * This is the basic implementation of a QEMU machine
+ * @author eswartz
+ *
+ */
+public class QemuMachineController extends SSHMachineControllerBase {
+
+	private static final IStatus CANCEL_STATUS = Policy.getCancelStatus(Activator.getDefault());
+	
+	/** thread and process are non-null if we launched QEMU ourselves */
+	Process launchedQemu;
+	/** thread and process are non-null if we launched QEMU ourselves */
+	QemuWatcherThread launchedQemuThread;
+	
+	private IQemuConfiguration qemuConfiguration;
+	private boolean isValidating;
+	
+	class QemuWatcherThread extends Thread {
+		private IProcessLauncher launcher;
+		private ByteArrayOutputStream err;
+		private ByteArrayOutputStream out;
+		public QemuWatcherThread(IProcessLauncher launcher) {
+			this.launcher = launcher;
+			setDaemon(true);
+		}
+		public void run() {
+			// TODO: make this go to the console
+			
+			// wait for it
+			out = new ByteArrayOutputStream();
+			err = new ByteArrayOutputStream();
+			launcher.waitAndRead(out, err);
+			System.out.println(out);
+			System.out.println(err);
+		}
+	}
+	
+	public QemuMachineController(IQemuConfiguration configuration) {
+		super("QEMU");
+		this.qemuConfiguration = configuration;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.internal.api.protocol.ssh.SSHMachineControllerBase#getConfiguration()
+	 */
+	@Override
+	protected SSHConfiguration getConfiguration() {
+		return qemuConfiguration.getSSHConfiguration(); 
+	}
+	
+	/**
+	 * @param processLauncher
+	 * @return
+	 */
+	MachineException processOutput(String message, QemuWatcherThread thread) {
+		return new MachineException(
+				MessageFormat.format("{0}\nCommand line: {1}\nstdout: {2}\nstderr: {3}",
+					message, 
+					CommandLineArguments.toCommandLine(thread.launcher.getLaunchCommandArguments()),
+					thread.out,
+					thread.err));
+	}
+
+	@Override
+	protected IStatus doStartMachine(IProgressMonitor monitor) throws MachineException {
+		// ensure we check again ASAP
+		scheduleProbe();
+		
+		try {
+			return doStartMachineImpl(monitor);
+		} finally {
+			// and check again whether we think it succeeded or not
+			scheduleProbe();
+		}
+	}
+
+	/**
+	 * @param monitor
+	 * @return
+	 * @throws MachineException
+	 */
+	private IStatus doStartMachineImpl(IProgressMonitor monitor)
+			throws MachineException {
+		final int PROBE_COUNT = 10;
+		
+		monitor.beginTask("Starting " + getName(), IProgressMonitor.UNKNOWN);
+		
+		// we're here due to an error state
+		if (launchedQemu != null) {
+			// kill the running one since there's no way to fix it
+			
+			launchedQemu.destroy();
+			launchedQemu = null;
+			fireMachineStateChanged();
+			monitor.worked(1);
+			if (monitor.isCanceled())
+				return CANCEL_STATUS;
+		}
+		
+		monitor.setTaskName("Launching QEMU and waiting for startup...");
+		
+		String launchPattern = qemuConfiguration.getCommandLaunchPattern();
+		ShellTemplateSubstitutor substitutor = new ShellTemplateSubstitutor();
+		
+		IPath launchPath = new Path(qemuConfiguration.getExecutable());
+		if (!launchPath.isAbsolute())
+			launchPath = new Path(qemuConfiguration.getInstallPath()).append(launchPath);
+		substitutor.define("QEMU", launchPath.toOSString());
+		substitutor.define("DISK_PATH", new Path(qemuConfiguration.getDiskImagePath()).toPortableString());
+		substitutor.define("INSTALL_PATH", new Path(qemuConfiguration.getInstallPath()).toPortableString());
+		substitutor.define("MEMORY", "" + qemuConfiguration.getMemorySize());
+		substitutor.define("SSH_PORT", "" + qemuConfiguration.getSSHConfiguration().getTargetPort());
+		substitutor.define("CIFS_PORT", "" + qemuConfiguration.getCIFSPort());
+		
+		launchPattern = substitutor.substitute(launchPattern);
+		List<String> cmdLine = CommandLineArguments.createFromHostCommandLine(launchPattern);
+		
+		String commandString = CommandLineArguments.toCommandLine(cmdLine);
+		System.out.println(commandString);
+		
+		IProcessLauncherFactory processLauncherFactory = new HostProcessLauncherFactory();
+		final IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(
+				processLauncherFactory, null, cmdLine);
+		try {
+			launchedQemu = processLauncher.createProcess();
+		} catch (MicaException e) {
+			throw new MachineException("Cannot launch qemu: " + CommandLineArguments.toCommandLine(cmdLine), e);
+		}
+		
+		launchedQemuThread = new QemuWatcherThread(processLauncher);
+		launchedQemuThread.start();
+		
+		long timeout = System.currentTimeMillis() + 300 * 1000;
+		while (true) {
+			if (!launchedQemuThread.isAlive()) {
+				throw processOutput("qemu launch failed", launchedQemuThread);
+			}
+			try {
+				launchedQemu.exitValue();
+				launchedQemuThread.interrupt();
+				throw processOutput("QEMU died", launchedQemuThread);
+			} catch (IllegalThreadStateException e) {
+				// still running
+			}
+			
+			for (int cnt = 0; cnt < PROBE_COUNT; cnt++) {
+				monitor.worked(1);
+				if (monitor.isCanceled())
+					return CANCEL_STATUS;
+
+				try {
+					Thread.sleep(100);
+				} catch (InterruptedException e) {
+					doStopMachine(monitor);
+					return CANCEL_STATUS;
+				}
+				
+				Display display = Display.getCurrent();
+				if (display != null) {
+					while (display.readAndDispatch()) ;
+				}
+			}
+			
+			// test the connection
+			scheduleProbe();
+			IStatus status = doProbeMachine(new SubProgressMonitor(monitor, 1));
+			if (status.isOK()) {
+				// XXX: do this more intelligently
+				// sshd starts a few moments before /etc/rc.local is run, 
+				// so kernel parameters like vdso might not be configured yet... 
+				// wait a few seconds more to avoid immediately invoking
+				// scratchbox commands and failing.
+				for (int cnt = 0; cnt < 50; cnt++) {
+					Display display = Display.getCurrent();
+					if (display != null) {
+						while (display.readAndDispatch()) ;
+					}
+					
+					monitor.worked(1);
+					if (monitor.isCanceled())
+						throw cancelled();
+
+					try {
+						Thread.sleep(100);
+					} catch (InterruptedException e) {
+						throw cancelled();
+					}
+				}
+				break;
+			}
+			
+			if (System.currentTimeMillis() >= timeout) {
+				throw processOutput("Timed out waiting for qemu startup", launchedQemuThread);
+			}
+		}
+		
+		fireMachineStateChanged();
+		
+		return Status.OK_STATUS;
+	}
+	
+	protected MachineException cancelled() {
+		return new MachineException(null, new CoreException(CANCEL_STATUS));
+	}
+
+	@Override
+	protected IStatus doStopMachine(IProgressMonitor monitor) throws MachineException {
+		IStatus status = super.doStopMachine(monitor);
+		if (!status.isOK())
+			return status;
+		
+		// only try halting if we created it
+		if (launchedQemuThread != null && launchedQemuThread.isAlive()) {
+			// make it halt
+			List<String> cmdLine = CommandLineArguments.createFromCommandLine(
+				"sudo -S halt now");
+			
+			IProcessLauncherFactory processLauncherFactory = getProcessLauncherFactory();
+			Process process;
+			try {
+				process = ProcessLauncherCreator.createProcessLauncher(processLauncherFactory,
+						null, cmdLine).createProcess();
+				try {
+					// send the password for sudo
+					process.getOutputStream().write(qemuConfiguration.getSSHConfiguration().getUserPassword().getBytes());
+					process.getOutputStream().write('\n');
+					process.getOutputStream().close();
+	
+					// this will return right away, it seems
+					process.waitFor();
+				} catch (InterruptedException e2) {
+					throw new MachineException("Aborted halting Linux host in QEMU", e2);
+				}
+			} catch (Exception e) {
+				throw new MachineException("Cannot stop processes in Linux host in QEMU", e);
+			}
+			
+			// probe until it's not responding
+			
+			long timeout = System.currentTimeMillis() + 60 * 1000;
+			while (true) {
+				for (int cnt = 0; cnt < 10; cnt++) {
+					try {
+						monitor.worked(1);
+						if (monitor.isCanceled())
+							return CANCEL_STATUS;
+
+						Thread.sleep(100);
+					} catch (InterruptedException e) {
+						// ignore
+					}
+					
+					while (Display.getCurrent().readAndDispatch()) ;
+				}
+				
+				// test the connection
+				scheduleProbe();
+				status = doProbeMachine(monitor);
+				if (!status.isOK()) {
+					// wait a LITTLE longer -- termination of ssh doesn't mean we have really shut down
+					for (int cnt = 0; cnt < 75; cnt++) {
+						monitor.worked(1);
+						if (monitor.isCanceled())
+							return CANCEL_STATUS;
+
+						try {
+							Thread.sleep(100);
+						} catch (InterruptedException e) {
+							doStopMachine(monitor);
+							return CANCEL_STATUS;
+						}
+						
+						while (Display.getCurrent().readAndDispatch()) ;
+					}
+					break;
+				}
+				
+				if (System.currentTimeMillis() >= timeout) {
+					throw processOutput("Timed out waiting for qemu shutdown", launchedQemuThread);
+				}
+			}
+			
+			// stop monitoring
+			launchedQemuThread.interrupt();
+			launchedQemuThread = null;
+			
+			// now, kill the process 
+			launchedQemu.destroy();
+			launchedQemu = null;
+			
+			fireMachineStateChanged();
+	
+			return Status.OK_STATUS;
+		} else {
+			return Activator.createStatus(IStatus.WARNING, 
+					"Not terminating QEMU session that this IDE did not create");
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.internal.common.core.machine.BaseMachineController#doAskUserToRepairMachine(org.eclipse.swt.widgets.Shell, org.eclipse.core.runtime.IStatus)
+	 */
+	@Override
+	protected Result doAskUserToRepairMachine(Shell shell, IStatus status) {
+		// see if QEMU *seems* to be running... i.e. something is listening on the SSH port
+		try {
+			Socket socket = new Socket(qemuConfiguration.getSSHConfiguration().getTargetIPAddress(),
+					qemuConfiguration.getSSHConfiguration().getTargetPort());
+			socket.close();
+			
+		
+			final boolean[] results = { false };
+			if (!WorkbenchUtils.isJUnitRunning()) {
+				Display.getDefault().syncExec(new Runnable() {
+		
+					public void run() {
+						results[0] = MessageDialog.openConfirm(null, "QEMU running?", 
+								MessageFormat.format(
+										"QEMU may still be running, but it seems to be halted or crashed\n"
+										+"(or something else owns the server socket {0}:{1}).\n\n"
+										+"Please kill it if necessary and select 'Ok' to retry.",
+										qemuConfiguration.getSSHConfiguration().getTargetIPAddress(), 
+										""+qemuConfiguration.getSSHConfiguration().getTargetPort()));
+					}
+					
+				});
+			}
+			
+			if (!results[0]) {
+				// canceled
+				return Result.ABORT;
+			}
+			return Result.RETRY;
+			
+		} catch (IOException e) {
+			// no one listening to the port, so probably qemu not running; ignore the error and keep trying
+			return Result.IGNORE;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.internal.common.core.machine.BaseMachineController#acquireMachine(org.maemo.mica.common.core.machine.IMachine, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	@Override
+	public IStatus acquireMachine(IMachine machine, IProgressMonitor monitor) {
+		monitor.beginTask("", 2);
+		
+		// re-check to be sure
+		scheduleProbe();
+		IStatus status = super.acquireMachine(machine, new SubProgressMonitor(monitor, 1));
+		if (!status.isOK())
+			return status;
+		
+		if (monitor.isCanceled())
+			return CANCEL_STATUS;
+		
+		// now, verify shared folders
+		QemuMachine qemuMachine = (QemuMachine) machine;
+		
+		status = qemuMachine.validateSharedMounts(new SubProgressMonitor(monitor, 1));
+
+		return status;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.mica.internal.common.core.machine.BaseMachineController#probeMachine(org.maemo.mica.common.core.machine.IMachine, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	@Override
+	public IStatus probeMachine(final IMachine machine, final IProgressMonitor monitor) {
+		monitor.beginTask("", 2);
+		
+		// re-check if things might be fishy
+		try {
+			if (launchedQemu != null)
+				launchedQemu.exitValue();
+			scheduleProbe();
+		} catch (IllegalThreadStateException e) {
+			
+		}
+		
+		IStatus status = super.probeMachine(machine, new SubProgressMonitor(monitor, 1));
+		if (!status.isOK())
+			return status;
+		
+		if (monitor.isCanceled())
+			return CANCEL_STATUS;
+		
+		try {
+			// try to ensure mounts are shared, but don't sync on this here
+			if (!isValidating) {
+				isValidating = true;
+				Runnable runnable = new Runnable() {
+
+					public void run() {
+						try {
+							IStatus status = ((QemuMachine) machine).validateSharedMounts(
+									new SubProgressMonitor(monitor, 1));
+							if (!status.isOK()) {
+								Activator.getErrorLogger().logError(status.getMessage(), status.getException());
+							}
+						} finally {
+							isValidating = false;
+						}
+					}
+					
+				};
+				
+				// must do this asynchronously if we don't own the display;
+				// most likely the machine is owned by other thread
+				Display display = Display.getCurrent();
+				if (display == null)
+					Display.getDefault().asyncExec(runnable);
+				else
+					runnable.run();
+			}
+			
+			return Status.OK_STATUS;
+		} finally {
+			monitor.worked(1);
+			monitor.done();
+		}
+	}
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachineController.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuPreferenceConstants.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuPreferenceConstants.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuPreferenceConstants.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.vm.qemu;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.maemo.esbox.vm.core.IVirtualMachine;
+
+/**
+ * This class encapsulates the keys for preference constants for QEMU configuration.
+ * NOTE: use {@link IVirtualMachine#getConfiguration()} to access these, not 
+ * CorePreferenceManager.
+ * @author eswartz
+ *
+ */
+public class QemuPreferenceConstants {
+	public static final int VERSION_MAJOR = 1;
+	public static final int VERSION_MINOR = 0;
+	
+	/** Get the preference store that contains these preferences */
+	public static IPreferenceStore getPreferenceStore() {
+		return Activator.getDefault().getPreferenceStore();
+	}
+	
+	/** Directory where QEMU and its files are found */
+	public static final String QEMU_INSTALL_PATH = "QEMU_INSTALL_PATH";
+	public static final String QEMU_EXE_NAME = "QEMU_EXE_NAME";
+	public static final String QEMU_MEMORY_SIZE = "QEMU_MEMORY_SIZE";
+	public static final String QEMU_LAUNCH_PATTERN = "QEMU_LAUNCH_PATTERN";
+	public static final String QEMU_DISK_IMAGE_PATH = "QEMU_DISK_IMAGE_PATH";
+	
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuPreferenceConstants.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuPreferencePage.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuPreferencePage.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuPreferencePage.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.vm.qemu;
+
+import org.eclipse.jface.preference.*;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Text;
+import org.maemo.esbox.vm.ui.BaseVirtualMachinePreferencePage;
+
+/**
+ * Configure QEMU preferences.  This page is NOT registered at the top level
+ * of preference page UI but is nested inside the ESbox Build Machine preference UI.
+ * @author eswartz
+ *
+ */
+public class QemuPreferencePage extends BaseVirtualMachinePreferencePage {
+
+	private FileFieldEditor feDiskPath;
+	private DirectoryFieldEditor feQemuPath;
+	private StringFieldEditor feQemuExeName;
+	private StringFieldEditor feQemuLaunchPattern;
+	private IntegerFieldEditor feRamSize;
+
+	/**
+	 * 
+	 */
+	public QemuPreferencePage() {
+		setPreferenceStore(QemuPreferenceConstants.getPreferenceStore());
+		setOwner(this);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors()
+	 */
+	@Override
+	protected void createFieldEditors() {
+		Text text;
+		
+		feQemuPath = new DirectoryFieldEditor(
+				QemuPreferenceConstants.QEMU_INSTALL_PATH,
+				"QEMU installation directory:", getFieldEditorParent());
+		addField(feQemuPath);
+		text = feQemuPath.getTextControl(getFieldEditorParent()); 
+		text.setToolTipText(
+			"Specify the full path to a QEMU installation (see http://bellard.org/qemu/), where various *.bin files should be located.");
+		
+		feQemuExeName = new StringFieldEditor(
+				QemuPreferenceConstants.QEMU_EXE_NAME,
+				"QEMU executable:", getFieldEditorParent());
+		addField(feQemuExeName);
+		text = feQemuExeName.getTextControl(getFieldEditorParent()); 
+		text.setToolTipText(
+				"Specify the program to launch.  If the program lives in the installation directory or on the PATH, provide a bare filename.  Otherwise, provide a full path to qemu.exe.");
+		
+		feQemuLaunchPattern = new StringFieldEditor(
+				QemuPreferenceConstants.QEMU_LAUNCH_PATTERN,
+				"QEMU command pattern:",
+				getFieldEditorParent());
+		addField(feQemuLaunchPattern);
+		text = feQemuLaunchPattern.getTextControl(getFieldEditorParent());
+		text.setToolTipText(
+			"Specify the specific command pattern to use to launch the virtual machine.");
+
+		// make this string manageable -- we want it to be long but not to force other
+		// fields off the edge
+		int width;
+		GC gc = new GC(getFieldEditorParent().getShell());
+		width = gc.getAdvanceWidth('m') * 32;
+		gc.dispose();
+
+		GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
+		gridData.widthHint = width;
+		text.setLayoutData(
+				gridData);
+		
+		feRamSize = new IntegerFieldEditor(
+				QemuPreferenceConstants.QEMU_MEMORY_SIZE,
+				"Memory size (Mb):",
+				getFieldEditorParent(),
+				5);
+		addField(feRamSize);
+		text = feRamSize.getTextControl(getFieldEditorParent());
+		text.setToolTipText("Specify the size of RAM for the machine, in megabytes.  Note: at least 512 Mb is recommended.");
+		
+		feDiskPath = new FileFieldEditor(
+				QemuPreferenceConstants.QEMU_DISK_IMAGE_PATH,
+				"Primary disk image:", getFieldEditorParent());
+		addField(feDiskPath);
+		text = feDiskPath.getTextControl(getFieldEditorParent());
+		text.setToolTipText(
+			"Specify the full path to the primary disk image.  Valid disk images are named *.vmdk, *.img, etc.\nIf you want to use other images, add -hdb <image>, etc. options to the command pattern.");
+		
+	}
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuPreferencePage.java
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/qemu/IQemuConfiguration.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/qemu/IQemuConfiguration.java	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/qemu/IQemuConfiguration.java	2008-11-10 17:01:41 UTC (rev 929)
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.vm.qemu;
+
+import org.maemo.esbox.vm.core.IVirtualMachineConfiguration;
+
+/**
+ * This interface, implemented by clients, provides settings needed
+ * to launch and communicate with a virtual machine using QEMU.
+ * <p>
+ * The stock implementation for QEMU machines created by IBuildMachineProvider
+ * reads the corresponding settings dynamically from QemuPreferenceConstants.
+ * @author eswartz
+ *
+ */
+public interface IQemuConfiguration extends IVirtualMachineConfiguration {
+
+	/** Get the installation path. */
+	String getInstallPath();
+
+	/** Get the primary disk image path. */
+	String getDiskImagePath();
+	
+	/** Get the memory size in Mb. */
+	int getMemorySize();
+	
+	/** Get the command launch pattern.
+	 * @return a pattern suitable for ShellTemplateSubstitutor 
+	 */
+	String getCommandLaunchPattern();
+	
+	
+	
+}


Property changes on: branches/work_Ed/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/qemu/IQemuConfiguration.java
___________________________________________________________________
Name: svn:executable
   + *



More information about the Esbox-commits mailing list