How to use two different computers with two differents OSes seemlessly
Posted by Christophe Robin in Archlinux, Uncategorized on March 8th, 2009
At home I have two computers, one on ArchLinux for work, and one under Vista for games. But switching between the two is really confusing when we’re a little tired, so I decided that I’d use only one soundcard, keyboard and mouse on the two computers…
I’m gonna explain you how to do this, in this tutorial I’ll use my windows box as the “master” as it has the best soundcard, keyboard and such of the two computers. Let’s starts:
Keyboard and Mouse
Keyboard and Mouse are probably the easiest part of this – Synergy is a small utility that allow you to share a mouse/keyboard between multiple computers, download the binary for windows and launch it, there set the computer as a server, and click configure. Set two screens, for the name use the hostnames of each computers, then create two links like in the following screenshot:
Don’t forget to create the two links ! Or when you’ll switch one the second computer, you will not be able to go back
Then on our archlinux box, do the following:
synergyc 192.168.xxx.xxx
That will launch the synergy client and connect to your server and voila, you can use only one keyboard/mouse between the two computers. Don’t forget to setup autostart in synergy on Windows, and add the client command in the Gnome Session Manager. Now it’s time to take care of the sound.
Using the sound over the network
Here is the hard part, setting up the sound over the network is a long task. First, download pulseaudio for windows here. Extract the thing in a folder like C:\pulseaudio then create a config file named default.pa containing the following:
load-module module-waveout
And put it in this folder. The first line tells pulseaudio to listen to all connections on the local network while the second line allow us to output sound. Next step is to double-click on pulseaudio.exe – Don’t paye attention to the warnings and go to C:\Users\<username> on Vista or C:\Document And Settings\<username> on previous windows then copy the .pulse-cookie here ( create by pulseaudio.exe ) to /etc/pulse-cookie on your linux box ( using WinSCP for example ). You can now add pulseaudio.exe to windows start ( there are lots of softs out there allowing it, just use whatever you want ) and we’re done with the windows box.
Now for our archlinux, we need to works on lots of things, let’s start on installing/configuring pulse:
Then add to your rc.conf
Avahi is needed for network communications in pulse. Now change our cookie modes:
cmod 0640 /etc/pulse-cookie
And finally setup pulseaudio by editing /etc/pulse/client.conf:
default-server = 192.168.xxx.xxx # change this to your windows box ip
We are now done with pulse itself. Don’t forget to add your users to the pulse-access group.
Let’s configure ALSA to use Pulse by editing /etc/asound.conf ( create it if it doesn’t exists ) and add the following lines:
type pulse
}
ctl.pulse {
type pulse
}
pcm.!default {
type pulse
}
ctl.!default {
type pulse
}
With all that, you should be ok, try launching mplayer using the -ao=alsa flag and you should hear the sound on your windows box
Spidermonkey in PECL
Posted by Christophe Robin in C, Code, PHP on February 24th, 2009
Today I finally released spidermonkey on PECL, you can find it here: http://pecl.php.net/package/spidermonkey/
The whole thing should work fine, I’m already working on several optimisations thanks to jorendorff from Mozilla on IRC. The next thing is to provide better error report, compilation/decompilation of scripts and more default functions for a bunch of things like Iterators and the like.
The last thing I added is a bunch of function applied to streams, here is an exemple:
$ctx = new JSContext();
/* provide fopen/fclose functions */
$ctx->registerFunction('fopen');
$ctx->registerFunction('fclose');
/* for output */
$ctx->registerFunction('printf');
Then in Javascript:
fd = fopen('somefile.txt', 'r')
while (line = fd.getline()) {
printf("%s\n", line)
}
fclose(fd)
Or
fd = fopen('somefile.txt', 'w')
/* here fd.SEEK_SET is the default value and is optional */
fd.seek(1024, fd.SEEK_SET)
fd.write("some text here :D")
fclose(fd)
Current status and API of spidermonkey
Posted by Christophe Robin in C, Code, PHP on February 21st, 2009
Spidermonkey had many features and changes done this week, so let’s look at what it can actually do, and what it can’t.
Features
- Execute Javascript ( well, of course it does
) - Register PHP functions to use in Javascript
- Assign PHP values in Javascript
- Register Classes in Javascript, allowing the user to instanciate them.
Just with those functionalities, you can already do a great deal of things with JS, and extend it really easily.
Conversion
When working with each others, Javascript convert is types to Zval ( PHP native type ) and vice-versa. Most types are successfully converted, but there are some exceptions:
- Javascript arrays are converted to stdClass due to the fact that they are stored as Objects by Spidermonkey.
- Javascript closures are not yet supported, but because PHP 5.3 support closures too, it should be done soon.
- Javascript regexp are not supported either, because there are no equivalents on the PHP side. In the end they’ll be converted to string.
Streams resources will soon have a prototype added by default with functions like read(), getline(), write(), etc…
Objects extending the Iterator abstract will also have a forEach function defined.
API
Here is the API:
/* evaluate javascript source code
*
* @param string $script A string containing the javascript source code
* @return mixed The last value in the global scope is returned to PHP
*/
public mixed evaluateScript(string $script);
/* register a function for use in javascript
*
* @param callback $callback A valid callback that will be called
* @param string $name The name under which the function will appear in Javascript,
* mandatory for closures and recommanded for array($obj, 'function')
*/
public void registerFunction(callback $callback [, string $name]):
/* register a class for use in javascript so that it can be instancied using "new"
*
* @param callback $class_name A valid class to export
* @param string $exported_name The name under which the class will appear
*/
public void registerClass(string $class_name [, string $exported_name])
/* register a variable for use in javascript
*
* @param string $name The name of the variable in Javascript
* @param mixed $value Value for the variable, objects and resources
* are passed by reference
*/
public void assign(string $name, mixed $value)
/* those function allow you to play with the version the engine is running
* it's not totally compatible and most versions will not be loaded by
* the engine, you can still have a try with the constants defined above */
public mixed setVersion(long $version)
public long getVersion()
public string getVersionString(long $version)
}
This is the current status at revision 38. Next revisions will be aimed at bug correction and error management. If you have any ideas for features, feel free to comments this post.
New feature for spidermonkey: registerClass()
Posted by Christophe Robin in C, Code, PHP on February 21st, 2009
As I explained in my previous blogpost, you can export objects to spidermonkey by using the assign() function on this object. While it’s enough for basic cases, It’s not enough for complex situations where Javascript need to create itself objects instances.
Solution
Tonight I worked on the solution named “registerClass()“. As examples are better than words, here is how it works:
$ctx = new JSContext();
/* register mysqli */
$ctx->registerClass('mysqli');
Then in your javascript source:
res = db.query('SELECT * FROM t1');
while (line = res.fetch_assoc())
{
// do something with line
}
As you can see, this function allow you to instanciate objects yourself in Javascript, providing more power and flexibility. This function will be available tomorrow morning in the SVN.
Bringing Javascript to the server using PHP * update *
Posted by Christophe Robin in C, Code, PHP on February 19th, 2009
I’ve been working for the last month on my first PHP extension since 2 years ago, a nice way to learn the new stuff Zend had in store for PHP 5.3. This extension is named SpiderMonkey, and embed the original engine made by Mozilla and available on most Linux distributions.
SpiderMonkey
SpiderMonkey is the Javascript engine used by Mozilla’s main products. It provide a nice C API for executing and interacting with Javascript. I base myself on the 1.7.0 version, which is the latest stable version. 1.8.0 is supposed to come soon but is still under development.
Usage
The API is straight-forward, a Javascript Runtime is first created, it’s a container for all “global” variables and Javascript Contexts. Contexts is the global scope where your program runs, all scripts executed on the same contexts will share the same global variables.
This part changed in rev. 38, see below
$rt = new JSRuntime();
/* Create a single context, most application will only use
* one context while a server ( like the pinetd httpd server )
* would create a context by request */
$ctx = $rt->createContext();
Since rev. 38, you don’t need to instanciate the JSRuntime anymore
* one context while a server ( like the pinetd httpd server )
* would create a context by request */
$ctx = new JSContext();
Once the context created, you’ll want to do two things:
- Assign values from PHP to JS
- Register functions from PHP to JS
For now, variables assigned from PHP are converted to a new Javascript variable and changing them in JS will not affect the original PHP value, while it’s supposed to be allowed later ( using a different function that will assign the variable as a reference and not a copy ), it’s already enough to provide $_GET, $_POST, $_FILES and the likes to JS. The only case where this change is for objects and resources, which keeps pointers to themselves thus allowing you to export a $dom variable containing a DOMDocument and acting on it by the mean of the object methods ( the object properties are not available ).
Exported functions are declared in the global scope.
Here is an exemple with mysqli:
$mysqli = new mysqli("host", "user", "pass", "db");
/* Allow Javascript to call sprintf under the name sprintf */
$ctx->registerFunction('sprintf', 'sprintf');
/* Provide our db connexion to Javascript */
$ctx->assign('db', $mysqli);
Then in Javascript you’d do:
* i'll stick with it in this sample */
res = db.query(sprintf('SELECT * FROM my_table WHERE field = %s', db.escape_string(dynamic_data)))
if (res) {
while (line = res.fetch_assoc())
{
printf("%s\n", line.field2);
}
}
Because this is based on PHP 5.3, you could also use closures in the assign function, allowing things like:
Allowing you to create a function foo() that echo “bar” when called.
Future
A lot of new features are already being implemented, here is a non-exhaustive list:
- Allowing to pass all variables as reference, allowing the Javascript to modify the PHP value
- Allow to register “classes” prototypes, like:
$ctx->registerClass('DOMDocument');
Then you could just do “var a = DOMDocument();” in Javascript to instanciate the object.
- Autoregister a prototype on some types of resources. A Stream resource could then be assigned in JS, and you could call stream.write, stream.read, etc…
How-to test ?
The whole source code is available on a public read-only SVN: https://ookoo.org/svn/pecl-spidermonkey. Be careful, you need PHP 5.3.0 beta 1 to compile it ( it will not even compile on PHP 5.2 ). There may be some issues when dealing with many objects so don’t use it for production purpose.
cd pecl-spidermonkey
phpize
./configure
make
./test.sh
Build complex SOAP requests and headers in PHP
Posted by Christophe Robin in Code, PHP on February 18th, 2009
When you’re writing PHP code for a company, you’ll need someday to write code that interact with a SOAP webservice. An exemple could be the Paypal SOAP API for ExpressCheckout. The original PHP API is terrible because of his handling of SOAP headers that doesn’t give the control we could want on an item.
The solution to this is to extend the original SoapClient using PHP:
{
public function __doRequest($request, $location,
$action, $version)
{
/* the $request element here contain the XML formatted request */
$dom = new DOMDocument();
$dom->loadXML($request);
/* now that you've loaded the request, you can easily add elements,
* replace them, etc...*/
/* save the modified request for __getLastRequest() */
$this->__last_request = $dom->saveXML();
/* then call the parent function to do the query */
$response = parent::__doRequest($this->__last_request,
$location, $action, $version);
/* $response contain the XML response returned by the webservice,
* you can also change it if needed, for exemple, in paypal I had to
* replace each occurences of the ebl:GetExpress...DetailsType
* by xsd:array because PHP would do some really weird things with
* it ( like referencing the parent, preventing access to child nodes )
* I do not store the response in __last_response because I want
* what was returned by the server, not what I changed :D */
return $response;
}
}
By doing that, you have a great deal of control on the request/responses coming from a SOAP webservices, the $location var contain the WS URL, the $action is the action called and $version is the SOAP version.
ArchLinux on the EEE 1000 *updated*
Posted by Christophe Robin in Archlinux on February 16th, 2009
2 weeks ago, I bought a shiny ASUS EEE PC 1000H, it looked big enough to do fun things, and the 160Go hard-drive of the Windows version was way better than what other versions could offer us. First thing I did was reinstall the whole thing under ArchLinux, my favorite linux distro.
I took the latest archboot, and within 30 minutes I was booting on my shell, archboot using the 2.6.28 kernel, most of the hardware was working, I plugged to the internet and started installing xorg, gnome and gdm. Most people are saying that GNOME on the EEE is useless because of the screen size, but with a little tweaking, you can get really nice results. Here is what I got after working for several hours:
Once gnome installed, I had somes issues with Fn-Keys preventing me to set the sound or luminosity without overlays bugs and such, to prevent this, install the “acpi-eee” package from aur, add eee to the DAEMONS variable in rc.conf and you’ll be ready to go.
So, now GNOME isn’t really pretty when just installed, so we’re gonna take care of that. First install the xf86-video-intel package from extra, then install compiz-fusion. You’ll need to add the following lines to the “Device” section of your xorg.conf file:
# ... normal config here
Option "MigrationHeuristic" "greedy"
Option "AccelMethod" "exa"
Option "ExaNoComposite" "false"
EndSection
Then add fusion-icon inside the Gnome Session Manager. You can now look on gnome-look.org for themes, I use the GNOME colors backgrounds and icons.
You should also look toward the “splashy” package, it adds a nice splash when booting arch and the themes are easily editable.
Update: Info about the wifi
Using the wifi is not something very hard, first plug your EEE using an ethernet cable, then with yaourt, fetch the aur package named rt2860 and install NetworkManager with the corresponding applet for your WM, and you should be ok.


