Re: Odds and ends
Quote:
Originally Posted by Addison
(Post 1085925)
Hey, there's one other thing I wanted to ask.
I love Xmms.
I also love how you can use the zoom in and out keys to change tracks.
The thing is, this doesn't work with the tablet locked so that the screen is turned off to save on battery life.
Is there any possible trick around this?
|
I wrote a hack, but unfortunately it doesn't work correctly: Sometimes, when locking, this program picks up spurious input events making the program think the zoom keys have been pressed, even when they haven't.
The idea behind this program (was supposed to be) is simple: If the zoom in/out keys are pressed are pressed while the tablet is locked and the display is dimmed/off, it will run /home/user/xmmskey and pass which zoom key was pressed by passing it as argv[1] (in a script, you can check if $1 = "in") and you could run xmmsctrl (available from free's debfarm repository) from this script.
If a resident Maemo 4 programmer (I don't know what I'm doing!) knows where I've messed up, I'll fix it, but it seems like auouymous is working on something anyway.
PHP Code:
/* Code taken from Austin Che's powerlaunch and fanoush's evkey */
/* gcc xmmskey.c $(pkg-config --cflags --libs glib-2.0 dbus-glib-1) -Wall -O2 -o xmmskey */
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <linux/input.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <dbus/dbus-glib.h>
#include <mce/dbus-names.h>
#include <mce/mode-names.h>
#define INPUT_DEV "/dev/input/event2"
#define KP_PATH "/sys/devices/platform/omap2_mcspi.1/spi1.0/disable_kp"
#define ZOOMIN_KC 65
#define ZOOMOUT_KC 66
#define SCRIPT_TO_RUN "/home/user/xmmskey"
static GMainLoop *loopy = NULL;
static gint inputfd = -1;
static GIOChannel *inputfdchannel = NULL;
static DBusGConnection *systembus = NULL;
static DBusGProxy *mceproxy = NULL;
static void sighandler (gint signo G_GNUC_UNUSED)
{
if (!inputfdchannel)
{
g_io_channel_shutdown (inputfdchannel, FALSE, NULL);
g_io_channel_unref (inputfdchannel);
inputfdchannel = NULL;
}
if (inputfd != -1)
{
close (inputfd);
inputfd = -1;
}
if (mceproxy)
{
g_object_unref (mceproxy);
mceproxy = NULL;
}
if (loopy)
{
g_main_loop_quit (loopy);
g_main_loop_unref (loopy);
loopy = NULL;
}
}
static void disable_kplock (void)
{
FILE *kp = g_fopen (KP_PATH, "w");
if (kp)
{
fputc (0, kp);
fclose (kp);
}
}
static inline DBusGProxy* get_mce_request_proxy (void)
{
return dbus_g_proxy_new_for_name (systembus, MCE_SERVICE, MCE_REQUEST_PATH, MCE_REQUEST_IF);
}
static gboolean is_tablet_locked (void)
{
gchar *lockmode = NULL;
gboolean retval = FALSE;
DBusGProxy *mcereqproxy = get_mce_request_proxy();
dbus_g_proxy_call (mcereqproxy, MCE_TKLOCK_MODE_GET, NULL, G_TYPE_INVALID, G_TYPE_STRING, &lockmode, G_TYPE_INVALID);
g_object_unref (mcereqproxy);
if (!lockmode)
return FALSE;
retval = g_strrstr (lockmode, MCE_TK_UNLOCKED) == NULL;
g_free (lockmode);
return retval;
}
static void blank_screen (void)
{
DBusGProxy *mcereqproxy = get_mce_request_proxy();
dbus_g_proxy_call_no_reply (mcereqproxy, MCE_DISPLAY_OFF_REQ, G_TYPE_INVALID);
g_object_unref (mcereqproxy);
}
static void begin_work (gboolean zoomin)
{
gchar cmdline[sizeof (SCRIPT_TO_RUN) + 10];
g_snprintf (cmdline, sizeof (cmdline), "%s %s", SCRIPT_TO_RUN, zoomin ? "in" : "out");
g_spawn_command_line_sync (cmdline, NULL, NULL, NULL, NULL);
blank_screen();
}
static gboolean input_cb (GIOChannel *source, GIOCondition condition, gpointer data G_GNUC_UNUSED)
{
if(condition & (G_IO_IN | G_IO_PRI))
{
struct input_event ev;
gsize bytes_read;
if (!is_tablet_locked())
return FALSE;
if (g_io_channel_read_chars (source, (gchar*) &ev, sizeof (struct input_event), &bytes_read, NULL) == G_IO_STATUS_NORMAL)
{
if (bytes_read != sizeof (struct input_event))
goto getmeout;
if (ev.type != EV_KEY)
goto getmeout;
if (ev.value != 0) /* Act only on key release */
goto getmeout;
if (ev.code == ZOOMIN_KC)
begin_work (TRUE);
else if (ev.code == ZOOMOUT_KC)
begin_work (FALSE);
}
}
getmeout:
return TRUE;
}
static void display_cb (DBusGProxy *proxy G_GNUC_UNUSED, const gchar *dispstate, gpointer data G_GNUC_UNUSED)
{
if (!g_str_equal (dispstate, MCE_DISPLAY_ON_STRING) && is_tablet_locked())
{
disable_kplock();
g_io_add_watch (inputfdchannel, G_IO_IN | G_IO_PRI, input_cb, inputfdchannel);
}
}
static void tklock_cb (DBusGProxy *proxy G_GNUC_UNUSED, const gchar *mode, gpointer data G_GNUC_UNUSED)
{
if (g_strrstr (mode, MCE_TK_UNLOCKED))
{
dbus_g_proxy_disconnect_signal (mceproxy, MCE_DISPLAY_SIG, G_CALLBACK (display_cb), NULL);
GSource *inputfd_watch = g_main_context_find_source_by_user_data (NULL, inputfdchannel);
if (inputfd_watch)
g_source_destroy (inputfd_watch);
}
else
{
dbus_g_proxy_connect_signal (mceproxy, MCE_DISPLAY_SIG, G_CALLBACK (display_cb), NULL, NULL);
}
}
int main (void)
{
inputfd = open (INPUT_DEV, O_RDONLY | O_NONBLOCK);
if (inputfd == -1)
return EXIT_FAILURE;
signal (SIGTERM, sighandler);
signal (SIGINT, sighandler);
signal (SIGQUIT, sighandler);
g_type_init();
systembus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
if (!systembus)
{
sighandler(0);
return EXIT_FAILURE;
}
inputfdchannel = g_io_channel_unix_new (inputfd);
if (!inputfdchannel)
{
sighandler(0);
return EXIT_FAILURE;
}
g_io_channel_set_flags (inputfdchannel, G_IO_FLAG_NONBLOCK, NULL);
g_io_channel_set_encoding (inputfdchannel, NULL, NULL);
mceproxy = dbus_g_proxy_new_for_name (systembus, MCE_SERVICE, MCE_SIGNAL_PATH, MCE_SIGNAL_IF);
dbus_g_proxy_add_signal (mceproxy, MCE_DISPLAY_SIG, G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_add_signal (mceproxy, MCE_TKLOCK_MODE_SIG, G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (mceproxy, MCE_TKLOCK_MODE_SIG, G_CALLBACK (tklock_cb), NULL, NULL);
loopy = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loopy);
return EXIT_SUCCESS;
}
|