Techno Barje

FoobarFox : JSCtypes Putting Foobar Into Your Firefox!

FoobarFox

FoobarFox features

  • Retrieve currently playing song information into your Firefox
  • Automatically post to your twitter account all listening tracks
  • Search for information on wikipedia, myspace or google

FoobarFox prerequisites

install foofox@techno-barje.fr.xpi

foobarfox foobarfox


Real world JSCtypes usage

FoobarFox is not so usefull, it’s mainly a proof of concept for JSCtypes capabilities.
Let’s see how use JSCtypes to do fun things. You can copy paste this sample code into your JS Console while your foobar is playing something :

Components.utils.import("resource://gre/modules/ctypes.jsm");

/* Change the dll path if your main windows directory is not on C:\WINDOWS! */
var lib = ctypes.open("C:\\WINDOWS\\system32\\user32.dll");

/* Declare the signature of FindWindows function */
var findWindowEx = lib.declare("FindWindowW",
                               ctypes.stdcall_abi,
                               ctypes.int32_t,
                               ctypes.ustring,
                               ctypes.int32_t);

/* Search for Foobar windows by it's id */
/* this ID is often changing of value at each release :/ */
var win = findWindowEx("{DA7CD0DE-1602-45e6-89A1-C2CA151E008E}/1", 0);
if (!win)
  win = findWindowEx("{DA7CD0DE-1602-45e6-89A1-C2CA151E008E}", 0);
if (!win)
  win = findWindowEx("{97E27FAA-C0B3-4b8e-A693-ED7881E99FC1}", 0); 
if (!win)
  win = findWindowEx("{E7076D1C-A7BF-4f39-B771-BCBE88F2A2A8}", 0);

/* Define another signature of windows API function */
var getWindowText = lib.declare("GetWindowTextW",
                               ctypes.stdcall_abi,
                               ctypes.int32_t,
                               ctypes.int32_t,
                               ctypes.ustring,
                               ctypes.int32_t);

/* Fill the string buffer we give to JSCtypes call */
var text="";
var max_len = 100;
for(var i=0; i < max_len; i++)
  text+=" ";
var text_len = getWindowText(win,text,100);

/* Extract song information from foobar window title */
var m = text.match(/(.*) - (?:\[([^#]+)([^\]]+)\] |)(.*) \[foobar2000.*\]/);

var musicinfo = {
  artist : m[1],
  album : m[2],
  trackNumber : m[3],
  track : m[4]
};
alert(musicinfo.toSource());

JSCtypes current capabilities

As I said in my previous post, ctypes support in Firefox is limited and we can’t use struct. So we’re able to play only with libraries that wait string and int. You can even pass objects/structures, but only if they can be created by a function whose arguments support the same limitation. As you can see in the previous example, we’re able to retrieve a pointer to a HWND object with FindWindowEx because it only wait string arguments. After that we give this pointer to getWindowText as a ctypes.int32_t.

JSCtypes current limitations

Now, let’s see a C++ code that can’t be mapped into JSCtypes :

// Add a notification to the tray.
NOTIFYICONDATA nid = {0};

nid.cbSize         = sizeof(nid);
nid.uID            = 100;    
nid.uFlags         = NIF_ICON;
nid.hIcon          = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SAMPLEICON));

Shell_NotifyIcon(NIM_ADD, &nid);

source: msdn

In this case, we are neither able to create any NOTIFYICONDATA object, nor to set attributes on this structure.

For more information

  • JSCtypes api. But take care, this is a work in progress!
  • Bug 513788 - Revise js-facing API for js-ctypes.
  • Bug 429551 - add struct support to js-ctypes.

Comments