|Mex Reference Manual|
This section contains various nitty gritty explanations about how Media Explorer is put together.
Media Explorer is broadly based on a Model-View-Controller architecture.
Model: Media Explorer has a single root model (an instance of MexAggregateModel). A plugin loaded by Media Explorer's plugin manager can push models, each associated with a category (via MexModelInfo), into the root model. A model pushed by a plugin can be a simple MexModel or another MexAggregateModel.
View: The top-level view element is an MexExplorer instance. This is a horizontally-expanding, single-row MexResizingHBox, filled with MexColumns; a new column is added each time a new model is added to the explorer; the column title is set to the model's category. Focus moves between columns in response to UI events (e.g. key presses).
The columns are populated via the controller classes (see below).
Controller: A MexContentProxy instance (an implementation of MexProxy) is responsible for generating UI elements for each model. Each time a new model is added to the explorer, a new column is created, and an MxWidget generated and added to the column for each MexContent item in the model (currently hard-coded to a maximum of 10 items per column).
The default behaviour is for each content item to be represented by a MexContentBox. This is an expanding widget which displays one line of the content item's title, expanding on click to display the full title.
The class hierarchy diagramin the next section should help you identify how the classes mentioned above relate to each other; the API reference gives more detail about the specific methods supported by each class/interface.
The diagram below shows libmex's class hierarchy.
Media Explorer enables browsing, discovery and playback of media content; to do this, it needs to have media sources available. The Grilo framework for media discovery and browsing is used to provide those media sources.
Grilo provides a uniform API for accessing content and its metadata. Several Grilo plugins exist for adapting media for well-known sources (Vimeo, Flickr, YouTube etc.) so they can be presented via the Grilo API.
However, due to various licensing issues, these plugins are not enabled by default in Media Explorer. The only plugin which is enabled is grilo-tracker. This uses a Tracker service, running in the same environment as Media Explorer, to make media indexed by Tracker available through the Grilo API.
Tracker itself is a collection of data mining and indexing services, typically used for searching the local filesystem. By default Tracker comes with several indexing services called miners. The most widely used miner is the filesystem miner, responsible for indexing local files. Media Explorer makes use of the UPnP miner, if available, which additionally indexes UPnP servers.
The diagram below gives a high-level overview of the components involved:
The arrows between the nodes in the diagram represent media data from UPnP servers and the local filesystem being scanned, indexed and presented by higher-level components.
This section gives a few tips about how to check that everything is working properly in the content discovery stack.
Check tracker is indexing. You can follow the status of Tracker and its miners from the command line with:
The output should look something like this:
Store: 06 Apr 2011, 14:54:52: ✓ Idle Miners: 06 Apr 2011, 14:54:52: ✓ UPnP - Idle (ESMITH5-MOBL1: esmith5:) 06 Apr 2011, 14:54:52: ✓ File System - Idle 06 Apr 2011, 14:54:52: ✓ Applications - Idle Press Ctrl+C to end follow of Tracker state
Note that the UPnP miner is reporting the ID of a Windows laptop running Windows Media Center (which is UPnP compatible).
If a miner has an "X" against it, there may be something wrong with Tracker's configuration.
Check Tracker is indexing the right directories. If your local media aren't showing up in Media Explorer, it may be that they aren't being indexed by Tracker.
Check that Tracker is indexing directories where some media exists: see these instructions for configuring Tracker.
Check Grilo can browse your media. Tracker's directory settings might look right, but media may still not appear in Media Explorer. In this case, ensure that Tracker has actually indexed your media using the grilo-test-ui command. This runs a basic Grilo media browsing interface:
If your media files have been indexed, they should show up in this interface. If not, Grilo is probably failing to communicate with Tracker correctly.
Check detailed logs for Tracker, Grilo and GUPnP. If you haven't identified the issue by following the above steps, you can enable more verbose logging for the various Media Explorer components as follows:
Tracker. Set this environment variable:
This turns on all debug messages.
Grilo. Set this environment variable:
NB this produces a lot of messages; other less verbose debug levels are available (see the Grilo API docs).
GUPnP. Set this environment variable:
Media Explorer is designed to function as a netbook application or as a UX for a dedicated media centre distribution. This means that the UX is entirely usable without a mouse. However, it also means that it may be used with input devices other than a keyboard (such as a TV remote control). On top of this, the application may also run in environments where a full X environment is not available (for example, where the application is on a different GDL plane from the X server, as might happen when running on a processor like Intel's CE3100).
To this end, a small daemon called rebinder was designed to enable keys from a variety of input devices to be mapped consistently to the UX. The technical details of how this works are outlined below.
evdev. The "protocol" which reports events from the
kernel to userspace. At its core, this "protocol" is
reading a well-defined structure from a file descriptor
obtained by opening a
xorg-input-evdev. The Xorg input driver to feed X with evdev events.
lirc. Since the 2.6.36 kernel, lirc, a set of InfraRed device drivers, has been integrated into the mainline and lirc devices are exposed as evdev devices. This means that the issue of handling infra-red controls is now reduced to the issue of handling evdev devices. (Previously, binding key events would have involved handling IR devices and evdev devices separately.)
key code (keycode). A number assigned to the physical key. These days, on linux, these are defined in <linux/input.h> and are part of evdev key event structures.
key symbol (keysym). The logical symbol associated with the keycode. For instance, 'a' is associated with the keycode 38. On standard linux desktops, Xorg is responsible for the mapping between keycodes and keysyms.
libxkbcommon. This library provides control over the keyboard, extending the basic facilities available in X. The project has a public git repo.
Because Media Explorer is a media browser and player, it may be used in contexts outside the traditional netbook or laptop. This in turn means that users may want to control it with input devices beyond the standard mouse and keyboard, such as TV remote controls, for example:
keyboards, even ones with all those fancy "Internet keys"
remotes that are seen as USB HID devices
IR remotes exposed as evdev devices via in-kernel lirc
However, given the variety of input devices, a couple of issues arise:
Some Media Explorer actions (show more info. about some content, select some content etc.) naturally map to a a user's experience with modern TVs, DVD players, CD players, portable music players etc. In turn, a user can map those actions onto typical remote control keys (in the above case, onto Info and OK respectively).
However, these keys don't always have natural equivalents on a standard computer keyboard; but a user with a standard keyboard should still be able to control Media Explorer. So there needs to be some way to map actions (and their keys on a remote control) onto standard keyboard keys.
While remote controls are familiar to users, they bring a different set of issues when applied to a UX in a traditional Linux environment. Some of the keys on a TV remote, when pressed, produce events with keycodes greater than 255; however, these events are ignored by X, the window manager likely to be used on Linux. In some cases, remote control keys even produce keycodes which don't have any keysym under X.
In this case, these exotic keycodes need to be mapped onto keysyms which X does recognise.
rebinder solves these issues by:
Ensuring that a key press on an "exotic" key produces the same sort of event as its natural equivalent on a standard keyboard (where a natural equivalent exists). For example, rebinder makes a press on an OK key on a remote control appear to the application as a press on the Return key on a standard keyboard; similarly, the up/down/left/right keys on a remote are mapped to the keysyms for cursor keys on a standard keyboard.
Providing a configuration tool for mapping keys on an input device (keyboard, remote control) to actions in the application (info, home, back), where those actions don't have a "natural" key common to both remote controls and standard keyboards.
Redhat is working within the kernel/xorg-input-evdev/xorg to solve the whole remote issue in a better way. See this bug for details.
rebinder opens the evdev devices and listens directly to the kernel for events. Depending on the keycode associated with an event, rebinder has two ways of dealing with it:
Key events with a keycode < 255 are passed through to the standard X mechanism for handling.
For events with a keycode > 255, a new keysym for the event is determined by following one of two branches:
If the key has a natural mapping to a standard keyboard key (see above), the keysym associated with that standard key is used.
For a list of these natural mappings, see
in the Media Explorer source.
If there is no natural mapping for the key, a keysym to keycode binding from rebinder's configuration file is used instead (see below).
Note that the resulting keysym is actually a Clutter
keysym (though these are orthogonal to X keysyms): for
Once a new "rebound" keysym has been determined, it is sent to the X server via Xtest.
To ensure consistency when working on the Media Explorer
code, use the
MEX_KEY_* defines to
refer to the primary
navigation keys (up/down/left/right/ok/back/info/home);
mex-main.h for a full list of the
available defines. For all other keys, use
To launch the wizard to configure the Back, Home and Info buttons:
The bindings configuration file
a list of
Keysym=Keycode key-value pairs like
1 2 3 4
[bindings] Escape=9 Super_L=133 Menu=105
The configuration defines mappings from keycodes to keysyms for back (Escape), home (Super_L) and info (Menu). So, in the example above, a press on the key with keycode 9 will act like a press on the Esc key, sending an Escape keysym to X.
The mex-rebinder daemon handles
some of the events that X does not. To show debug messages
for this daemon, set the
environment variable to
all. Note that
you should restart mex-rebinder after
changing this environment variable, as it is a single-instance
When working with rebinder, you often also need to debug low-level events. The following tools can help with this:
evtest. This outputs raw events from the evdev drivers, which can be useful for working out if userland receives events from the kernel.
dmesg. Use this to see if an LIRC remote has been detected
by the kernel. If it has, there should be new
/dev/input/event%d devices and
some new raw events visible via evtest.
Note that it's likely that in-kernel LIRC devices aren't supported on MeeGo (needs to be verified).
xev. This can be used to watch events received by X.
Media Explorer plugins are packaged as standard shared-object libraries or modules. They are then installed into one of the plugin directories for Media Explorer, namely:
This is the main directory where most plugins are installed.
$HOME/.config on freedesktop.org
compliant distros (like MeeGo). Could be used for user-specific
the directory from where mex is
Responsibility for finding and loading plugins lies with the MexPluginManager, assigned as a member variables of the Media Explorer application. Plugin loading works like this:
mex creates a plugin manager (an instance of MexPluginManager).
The plugin manager looks for
.la files in the plugin
directories. (See above for details of where they
For each matching plugin file in those directories, the plugin manager does the following:
Loads the file via GModule.
Looks for a
symbol in the module's symbol table.
is found, the plugin manager creates an instance of the plugin
class and puts a reference to it into its plugin list. It
also emits a
Media Explorer responds to the plugin load (through a handler
attached to the
according to the type of plugin:
ModelProvider: The models provided by the plugin are added into Media Explorer's root model.
ToolProvider: The tool is added to the tool area of the interface; when the tool is activated, e.g. by a key press, the ClutterActor associated with the tool is presented. This actor can replace some or all of the Media Explorer UI with its own "sub-interface".
For example, the Media Explorer search plugin is a ToolProvider: when activated, it presents a "search page", with a text entry widget for entering a search string and an auto-suggest column. The search page replaces the other panels in the user interface.
ActionProvider: The actions provided by the plugin are added to Media Explorer's MexActionManager.
Actions are "things you can do to a piece of content". Media Explorer displays the actions for a piece of content when you press the information key while that content is highlighted. For example, Watch or Add to queue for a video, and View for a picture.
An ActionProvider plugin can add new actions to particular pieces of content. Each action is defined by an MexActionInfo object returned by the provider; this object specifies the MIME types for which an action is applicable, as well as the action itself (an instance of MxAction).
See the section about extending Media Explorer for more information on plugin development.