123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <link title="Purple" rel="stylesheet" href="manual-purple.css"
- type="text/css">
- <link title="Minty" rel="alternate stylesheet" href=
- "manual-minty.css" type="text/css">
- <link title="Plain" rel="alternate stylesheet" href="manual.css"
- type="text/css">
- <title>Controlling openMSX from External Applications</title>
- </head>
- <body>
- <h1>Controlling openMSX from External Applications</h1>
- <h2>Introduction</h2>
- <p>The architecture of openMSX is that the main emulation code is all in a
- separate program, the main openMSX executable. Debugger GUI's, launcher
- GUI's, etc., can be external programs that control openMSX. This document
- explains you how you can control openMSX from your own application.</p>
- <div class="note">
- Note: This document was not written for normal end users, but only for
- developers who are interested in writing their own application that
- controls openMSX.
- </div>
- <div class="note">
- Disclaimer: it is possible that some update events are still missing and it
- is also possible that the structure of the replies and commands change. We
- will do our best to be backwards compatible, though.
- </div>
- <h2>Connecting</h2>
- <p>There are multiple ways to connect to openMSX. The first (and oldest) way
- is using a pipe. On Windows you can use a named pipe, on other systems you
- use <code>stdio</code>. To enable this, start openMSX like this:</p>
- <div class="commandline">
- openmsx -control stdio
- </div>
- <p>or for Windows:</p>
- <div class="commandline">
- openmsx -control pipe
- </div>
- <p>The second method is using a socket. Connecting on non-Windows systems
- goes with a UNIX domain socket. openMSX puts the socket in
- <code>/tmp/openmsx-<username>/socket.<pid></code>. The
- <code>/tmp/</code> dir can be overridden by environment variables
- <code>TMPDIR</code>, <code>TMP</code> or <code>TEMP</code> (in that order).
- </p>
- <p>On Windows (which does not support UNIX domain sockets), the socket is a
- normal TCP socket. The port number is random between 9938 and 9958. This is done
- to enforce applications to deal with multiple running openMSX processes. The
- port number will be put in the following text file:</p>
- <div class="commandline">
- %USERPROFILE%\Documents and Settings\<username>\Local Settings\Temp\openmsx-default\socket.<pid>
- </div>
- <p>or, when <code>%USERPROFILE%</code> does not exist:</p>
- <p>
- <code>%TMPDIR%\openmsx-default</code> or<br/>
- <code>%TMP%\openmsx-default</code> or<br/>
- <code>%TEMP%\openmsx-default</code> or as a last resort:<br/>
- <code>C:\WINDOWS\TEMP</code>
- </p>
- <p>After connecting, openMSX expects XML input on the channel and it will
- also give you output. This is explained in the next section.</p>
- <h2>Communication</h2>
- <p>
- After connecting, openMSX expects XML input on the channel (pipe or socket)
- and it will also give you output in XML format. The first output it gives is this:
- </p>
- <pre>
- <openmsx-output>
- </pre>
- <p>On non Windows systems you can easily try it out by just starting openMSX
- via the <code>stdio</code> method, like explained above. You give XML
- commands via the keyboard in the terminal and openMSX will print its
- responses on the terminal as well.
- </p>
- <p>This first output is the opening tag (<code><openmsx-output></code>).
- All messages that are normally printed on stdout in the
- terminal from which you start openMSX are in a <code><log></code> tag.
- The level can be "info" or "warning" and the message is in the text node
- itself.
- </p>
- <p>
- When you want to start communicating back, you <em>always</em> have to start
- with the opening tag first:
- </p>
- <div class="commandline">
- <openmsx-control>
- </div>
- <p> When starting openMSX with the <code>-control</code> option, it will not show a
- window: it starts with the 'none' renderer. So, a nice example (if you're
- still experimenting on the command line) would be to type this:</p>
- <div class="commandline">
- <command>set renderer SDL</command>
- </div>
- <p>
- With the <code><command></code> tag you can give any openMSX console
- command to openMSX. The commands are documented in the <a class="external"
- href="commands.html">Console Commands Reference</a>.
- </p>
- <p>
- Every <code><command></code> will result in a reply from openMSX. In
- the above case it will be:
- </p>
- <pre>
- <reply result="ok">SDL</reply>
- </pre>
- <p>
- The order is guaranteed, i.e. the replies will follow in the same order as in
- which you gave the commands to openMSX. In this reply example, you see that
- the command succeeded (result=ok) and it also gives you the actual result
- text that would also be printed on the console. In this case, the value of
- the renderer setting. When a command fails, you get something like this:
- </p>
- <pre>
- <command>biep</command>
- <reply result="nok">invalid command name "biep"
- </reply>
- </pre>
- <p>
- "biep" is not a valid command, and openMSX tells you this via a "nok" reply
- with the error message in the text node.
- </p>
- <p>
- The next important thing is events. When you use this interface to control
- openMSX, you want to know when things change. For this, you can enable events
- for certain event classes.
- </p>
- <p>An example:</p>
- <div class="commandline">
- <command>openmsx_update enable led</command>
- </div>
- <p>
- This command will enable updates about LED events. So, when a LED changes, you
- get messages like this:
- </p>
- <pre>
- <update type="led" machine="machine1" name="power">on</update>
- </pre>
- <p>
- So, when you get <update> tags, openMSX tells you that something
- changed. In this case, it is a LED update, for the machine with ID
- "machine1". The name of the LED is "power" and the value is in the text node:
- on.
- </p>
- <p>Here is a list of the currently available event types and when they are sent:</p>
- <table>
- <tr>
- <td><code>hardware</code></td>
- <td>hardware changes occurred, like a change of machine</td>
- </tr>
- <tr>
- <td><code>led</code></td>
- <td>LED status changed</td>
- </tr>
- <tr>
- <td><code>media</code></td>
- <td>media (disk images, cartridges, etc.) changed</td>
- </tr>
- <tr>
- <td><code>plug</code></td>
- <td>a pluggable got plugged or unplugged (empty value)</td>
- </tr>
- <tr>
- <td><code>setting</code></td>
- <td>the value of a setting changed</td>
- </tr>
- <tr>
- <td><code>setting-info</code></td>
- <td>the properties of a setting changed (e.g. number of options changed)</td>
- </tr>
- <tr>
- <td><code>status</code></td>
- <td>status changed, currently this is pause and debug break status</td>
- </tr>
- <tr>
- <td><code>extension</code></td>
- <td>extensions changed (add/remove)</td>
- </tr>
- <tr>
- <td><code>sounddevice</code></td>
- <td>sounddevices changed (add/remove)</td>
- </tr>
- <tr>
- <td><code>connector</code></td>
- <td>connectors changed (add/remove)</td>
- </tr>
- </table>
- <h3>Update Examples</h3>
- <p>Someone changed machines from Boosted MSX2 to Toshiba HX-10 at run time:</p>
- <pre>
- <update type="hardware" name="machine2">add</update>
- <update type="hardware" machine="machine2" name="carta">add</update>
- <update type="hardware" machine="machine2" name="cartb">add</update>
- <update type="hardware" machine="machine2" name="cassetteplayer">add</update>
- <update type="hardware" machine="machine1" name="diskb">remove</update>
- <update type="hardware" machine="machine1" name="diska">remove</update>
- <update type="hardware" machine="machine1" name="carta">remove</update>
- <update type="hardware" machine="machine1" name="cartb">remove</update>
- <update type="hardware" machine="machine1" name="cartc">remove</update>
- <update type="hardware" machine="machine1" name="cassetteplayer">remove</update>
- <update type="hardware" name="machine1">remove</update>
- <update type="hardware" name="machine2">select</update>
- </pre>
- <p>CAPS LED went to OFF:</p>
- <pre>
- <update type="led" machine="machine2" name="caps">off</update>
- </pre>
- <p>A tape was inserted in the cassetteplayer:</p>
- <pre>
- <update type="media" machine="machine2" name="cassetteplayer">/home/manuel/msx-soft/tapes/Zoids.zip</update>
- </pre>
- <p>The cassetteplayer got into play mode:</p>
- <pre>
- <update type="status" machine="machine2" name="cassetteplayer">play</update>
- </pre>
- <p>Someone plugged in a joystick:</p>
- <pre>
- <update type="plug" machine="machine2" name="joyporta">joystick1</update>
- </pre>
- <p>And unplugs it again:</p>
- <pre>
- <update type="plug" machine="machine2" name="joyporta"></update>
- </pre>
- <p>Someone set the maxframeskip setting to 12:</p>
- <pre>
- <update type="setting" name="maxframeskip">12</update>
- </pre>
- <p>openMSX got paused:</p>
- <pre>
- <update type="status" name="paused">true</update>
- </pre>
- <p>openMSX got into a debug break state:</p>
- <pre>
- <update type="status" machine="machine1" name="cpu">suspended</update>
- </pre>
- <p>openMSX got out of debug break state:</p>
- <pre>
- <update type="status" machine="machine1" name="cpu">running</update>
- </pre>
- <p>Someone inserted a Philips NMS-1205 Music Module:</p>
- <pre>
- <update type="sounddevice" machine="machine2" name="Philips NMS 1205 Music Module MSX-Audio 8-bit DAC">add</update>
- <update type="connector" machine="machine2" name="audiokeyboardport">add</update>
- <update type="sounddevice" machine="machine2" name="Philips NMS 1205 Music Module MSX-Audio DAC">add</update>
- <update type="sounddevice" machine="machine2" name="Philips NMS 1205 Music Module MSX-Audio">add</update>
- <update type="extension" machine="machine2" name="Philips_NMS_1205">add</update>
- </pre>
- <p>And with this, you should have all info that you need to make any external
- application that can control openMSX.</p>
- <p>More real world examples can be found here:</p>
- <ul>
- <li>in the Contrib directory of openMSX (openmsx-control*)</li>
- <li>in the code of the old openMSX Catapult (C++ via pipe)</li>
- <li>in the code of the new openMSX Catapult (Python, still via pipe)</li>
- <li>in the code of the openMSX GUI Debugger (C++ via socket)</li>
- </ul>
- </body>
- </html>
|