Sunday, July 15, 2007

A victory

In following up on the compile error mentioned earlier, I found comments about trying to compile MythTV after installing a MythTV package. So, I shut down MythTV and moved the existing binaries and libraries out of the /usr/bin and /usr/lib directories, and then I recompiled (after making sure the configuration files were coded to /usr instead of /usr/local, since --prefix=/usr didn't seem to work as advertised). And the compile completed with zero errors.

After running make install on the newly-compiled binaries, I rebooted, and to my surprise and delight, MythTV came right up. Better still, all of the picoLCD's keys were behaving exactly as I had programmed them. Success!

So, just about all that's left is remote control. IR will be a long time coming, if I ever get it at all, because of the lack of an appropriate driver. I did install the MythWiFi plug-in for a web-based remote, which is probably my best hope for full remote control. But, when I click any button on the web remote, I get:

Warning: fsockopen() [function.fsockopen]: unable to connect to localhost:6546 in /var/www/remote/backend.php on line 115
ERROR: Connection refused (111)

The answer to this turned out to be a big "duh" moment -- Network Control must be enabled. Unfortunately, since I coded the LCD module to send "Key_Space" on the enter keypress instead of "Key_Enter" (because I was unsure of using "Key_Enter" vs. "Key_Return", I thought I was playing it safe), I had no way to navigate the config menus to enable that ("Space" doesn't activate the "Next" button). However, all was not lost -- since MythTV stores its configuration in a MySQL database, all I had to do was run the following query in MySQL:

update settings set data = '1' where value = 'NetworkControlEnabled';

A quick reboot (since exiting and restarting MythTV is also a little problematic with the keypad), and as if by magic, I can now control MythTV with a web browser.

Tuesday, July 10, 2007

Stubborn, isn't it?

I found another instance of the PREFIX directive, in the settings.pro file. The code around it would seem to indicate it defaults to /usr/local only if it's not already set; apparently configure --prefix=/usr doesn't set it to settings.pro's satisfaction. I set the prefix to /usr there as well, recompiled, linked to my libmythtv library, and finally, a successful boot.

Except it would seem that my code did not take effect. Down still sent a Key_Right.

Well, maybe the library isn't referenced, but compiled into the front end. Copy the compiled version of mythfrontend into place, reboot -- nope.

One last try. Maybe, just maybe, the fact that the old library was in /usr/lib at the time of compile of the programs caused confusion. I'll recompile.

While that's compiling, I'm going to take a look at the MythWifi plugin. Unless and until someone writes a lirc driver for the picoLCD (don't know if I will be able to), it'll be the closest thing we get to remote control. (And, if I can't get the front panel working, it'll be the only thing we get to control at all, barring hooking up an actual keyboard.)

Monday, July 9, 2007

The Mysterious Configuration

Quick post. I can't seem to find from where it's getting the /usr/local/bin path. I tried running ./configure --prefix=/usr (noting that the config file uses /usr/local if that isn't set), but that just wasn't good enough. Same problem (and associated errors in the log file) as before.

Sunday, July 8, 2007

Control Progress

After downloading the MythTV package from MythTV.org's Downloads page and compiling mythlcdserver, I discovered that KnoppMyth used a slightly newer version of the files (and resulting libraries). Wasted a lot of time there, but got the last stable release out of subversion (which, fortunately, was the same version used by KnoppMyth), and I am now able to compile MythTV modules with the correct library. Mostly. I am getting this error with mythtranscode/replex:

/usr/lib/libmythavcodec-0.20.1.so: undefined reference to `XvMCLoadQMatrix'
/usr/lib/libmythavcodec-0.20.1.so: undefined reference to `XvMCSyncSurface'
/usr/lib/libmythavcodec-0.20.1.so: undefined reference to `XvMCFlushSurface'
/usr/lib/libmythavcodec-0.20.1.so: undefined reference to `XvMCBeginSurface'
collect2: ld returned 1 exit status
make: *** [mythreplex] Error 1

But I intend to ignore it for now as it happens after mythlcdserver is compiled. (This is going to bug people searching for an answer to this problem and finding none. Sorry. Hopefully I'll find out more for a later post, because I'd like to solve this as well before I get desirous to compile and install a brand new release of MythTV.)

I made the following changes to mythlcdserver/lcdprocclient.cpp:

ChangedTo
lcd_keystring = gContext->GetSetting("LCDKeyString", "ABCDEF");lcd_keystring = gContext->GetSetting("LCDKeyString", "A B C D E F");
aString = "client_del_key " + expandString(old_keystring);aString = "client_del_key " + old_keystring;
aString = "client_add_key " + expandString(lcd_keystring);aString = "client_add_key " + lcd_keystring;

Judging from the expandString function, apparently lcdproc used to take single-character "keys", all concatenated in one string (i.e. "ABCDEF" representing six keys), whereas now it can use longer names, and the functions take a space-delimited list. My guess is that, in order to make MythTV compatible with old configuration values, they chose to stick to the single-character key designations and assume all configuration strings were such, and the expandString function puts a space between each character (if lcdproc is version 0.5 or higher). Some of the lcdproc drivers even have a provision for mapping their keys to a single-letter designation. The driver for picoLCD does not, though. So, my solution is to make mythlcdserver use key names instead of key letters, by simply removing the call to expandString and treating the LCDKeyString value as a space-delimited string.

So far, I've had a bit of success. When I compiled mythlcdserver with my changes and used a LCDKeyString value of "Plus Minus F1 F2 F3 F4 F5 Up Down Left Right Enter", I was actually able to control MythTV with the keypad. Sort of. The

+
key moved the menu selection up, and the
-
key selected the menu option. None of the other keys did anything (except after pressing all of them quickly to see if anything else would work, it stopped responding altogether; I suspect a bug in the picoLCD driver). When I changed the LCDKeyString value to "Up Down Left Right Enter", Up moved the cursor up and Down selected. So I have at least solved the problem of getting the keypad and the mythlcdserver program speaking the same language.

I have to say there is an annoyance that makes this whole process much more difficult, in that mythlcdserver doesn't work from the command line. Oh, it starts all right. Even connects to MythTV and gets status updates. It just can't connect to LCDd. I keep getting "connection refused" from LCDd, whether I run as mythtv or as root. Can't figure out the problem there.

The reading of the key press appears to be handled by the library libmyth, via lcddevice.cpp. It is under the same assumption that the LCDKeyString value represents a list of non-delimited, single-character keys. In fact, the translation is done by taking the key name reported (actually just the first character thereof), finding the position it matches in LCDKeyString, and using that position as a "magic number" translation to a key press. Using my edited code, the key press for "Up" would cause it to look for a "U", find it at position 0, and translate that as Key_Up. "Down" caused it to find a "D" at position 3, thereby sending Key_Right (which happens to select a menu option).

To "fix" this, I am rewriting the LCD::handleKeyPress function. It is, for the moment, quite simple:

void LCD::handleKeyPress(QString key_pressed) {
    int key = 0;

    if (key_pressed == "Up")
        key = Qt::Key_Up;
    else if (key_pressed == "Down")
        key = Qt::Key_Down;
    else if (key_pressed == "Left")
        key = Qt::Key_Left;
    else if (key_pressed == "Right")
        key = Qt::Key_Right;
    else if (key_pressed == "Enter")
        key = Qt::Key_Space;
    else if (key_pressed == "Plus")
        key = Qt::Key_Home;
    else if (key_pressed == "Minus")
        key = Qt::Key_End;
    else if (key_pressed == "F1")
        key = Qt::Key_F1;
    else if (key_pressed == "F2")
        key = Qt::Key_X;
    else if (key_pressed == "F3")
        key = Qt::Key_I;
    else if (key_pressed == "F4")
        key = Qt::Key_Escape;
    else if (key_pressed == "F5")
        key = Qt::Key_M;

    QApplication::postEvent(gContext->GetMainWindow(),
         new ExternalKeycodeEvent(key));
}

I think there is oodles of room for improvement. Some way to map keys would be ideal. I was kind of hoping I could use the keybindings table, maybe get the LCD module to report a key of, say, "LCD_UP", and have that text in the keybindings table to identify what action LCD_UP performs. Maybe if I have time, I'll work on that. Right now, I'll just keep my fingers crossed for a clean [enough] compile, install the library, and see if I managed to make this thing usable.

And... It's no good. The front end never appeared, and the LCD showed LCDd's default screen (0 clients). The mythfrontend.log file gave me a clue, though:

sh: /usr/local/bin/mythlcdserver: No such file or directory
[...]
Couldn't find theme Titivillus

The big clue is that I have mythlcdserver in /usr/bin/, not /usr/local/bin/. I'm going to hazard a guess that there is a path that gets compiled into the library that is different than the default KnoppMyth layout.

Friday, July 6, 2007

The Control Problem

Major stuck point here. If I use the picoLCD's usblcd utility program, I can see that the keypresses and IR signals are heard by the hardware. By examining the LCDd.conf file, I can see that lcdproc does have the ability to read keypresses. (Looking at the source code for the picoLCD driver for lcdproc, it only supports keypresses at the moment, not IR signals.) But for whatever reason, the keypresses are not getting through mythlcdserver to MythTV.

I'm not entirely sure who's to blame, but at the moment I'm suspecting the problem is with mythlcdserver attempting to bind to key events 'A', 'B', 'C', 'D', 'E', and 'F' where lcdproc (with the picoLCD driver) reports key events of 'Plus', 'Minus', 'F1', 'F2', 'F3', 'F4', 'F5', 'Left', 'Right', 'Up', 'Down', and 'Enter'. mythlcdserver also seems rather intent on using single-character keys only. I think I'll see what I can do about that.

If I'm right, then there may be an issue with trying to map LCD keys to MythTV commands. I really don't want the F1 key on the keypad to bring up Help. But one step at a time...

Monday, July 2, 2007

The Bling

The Mini-Box M300-LCD, as its name would imply, has an LCD module on its front -- specifically, a picoLCD module. The iMedia distribution already had the required drivers, but the KnoppMyth distribution did not. I installed the lcd4linux package through aptitude, but it did not have the picoLCD driver. I did download the source and was able to compile it with the picoLCD driver, and it worked great.

Of course, when I researched how to get MythTV to talk to it, I found that it already has a convenient application, mythlcdserver, to make good use of the display. And, it didn't work with lcd4linux, but lcdproc. I was avoiding using lcdproc, because the first hits I found searching for lcdproc and picoLCD indicated I would have to get the source code and patch it to use the picoLCD. The lcdproc hardware page had no sign of picoLCD. However, when I found the project page on freshmeat.net, the picoLCD driver was recently included. (Indeed, the lcdproc.org home page also has picoLCD in the text description of the most recent release; but I had missed that.)

I compiled and installed the LCDp daemon (which, for some reason, installs its configuration files to /usr/local/etc instead of /etc). With the curses driver active, I started the LCDp daemon, then tried running mythlcdserver. And nothing happened. I tried googling, but I couldn't find anyone else with this problem. Heck with it, I figured I'd reboot.

Interesting thing about LCDp. If the curses driver is active, then running it starts the server and locks the display, and apparently it doesn't daemonize. This is a problem when you have it running from init.d -- the boot process gets to that step, starts the curses display, and goes no farther. Unfortunately, I started it pretty early in the process (lcd4linux put its startup scripts at S20, so I mimicked this with my LCDp scripts), and sshd had not started yet. Oops. Curses, indeed. I went upstairs (since the MythTV box is now at home in the entertainment center) and grabbed a keyboard and that bootable USB key, booted, mounted the hard drive, edited the config file to use the picoLCD driver instead of the curses driver, and rebooted.

Since I had the keyboard attached at this point, instead of trying to run mythlcdserver from a command line, I went through MythTV's setup menu and enabled LCD there. And it worked just fine.

So now, MythTV talks to the picoLCD just fine. The next major steps are to get it to go the other way -- for the picoLCD to relate its keypresses, and hopefully the IR receiver, back to MythTV. Google hasn't helped so far...