Thread: Odds and ends
View Single Post
Posts: 235 | Thanked: 339 times | Joined on Nov 2010
#64
Originally Posted by Addison View Post
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 (inputfdchannelFALSENULL);
        
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 (0kp);
        
fclose (kp);
    }
}

static 
inline DBusGProxyget_mce_request_proxy (void)
{
    return 
dbus_g_proxy_new_for_name (systembusMCE_SERVICEMCE_REQUEST_PATHMCE_REQUEST_IF);
}

static 
gboolean is_tablet_locked (void)
{
    
gchar *lockmode NULL;
    
gboolean retval FALSE;
    
DBusGProxy *mcereqproxy get_mce_request_proxy();

    
dbus_g_proxy_call (mcereqproxyMCE_TKLOCK_MODE_GETNULLG_TYPE_INVALIDG_TYPE_STRING, &lockmodeG_TYPE_INVALID);
    
g_object_unref (mcereqproxy);
    if (!
lockmode)
        return 
FALSE;

    
retval g_strrstr (lockmodeMCE_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 (mcereqproxyMCE_DISPLAY_OFF_REQG_TYPE_INVALID);
    
g_object_unref (mcereqproxy);
}

static 
void begin_work (gboolean zoomin)
{
    
gchar cmdline[sizeof (SCRIPT_TO_RUN) + 10];
    
g_snprintf (cmdlinesizeof (cmdline), "%s %s"SCRIPT_TO_RUNzoomin "in" "out");
    
g_spawn_command_line_sync (cmdlineNULLNULLNULLNULL);
    
blank_screen();
}

static 
gboolean input_cb (GIOChannel *sourceGIOCondition conditiongpointer 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*) &evsizeof (struct input_event), &bytes_readNULL) == 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 *dispstategpointer data G_GNUC_UNUSED)
{
    if (!
g_str_equal (dispstateMCE_DISPLAY_ON_STRING) && is_tablet_locked())
    {
        
disable_kplock();
        
g_io_add_watch (inputfdchannelG_IO_IN G_IO_PRIinput_cbinputfdchannel);
    }
}

static 
void tklock_cb (DBusGProxy *proxy G_GNUC_UNUSED, const gchar *modegpointer data G_GNUC_UNUSED)
{
    if (
g_strrstr (modeMCE_TK_UNLOCKED))
    {
        
dbus_g_proxy_disconnect_signal (mceproxyMCE_DISPLAY_SIGG_CALLBACK (display_cb), NULL);
        
GSource *inputfd_watch g_main_context_find_source_by_user_data (NULLinputfdchannel);
        if (
inputfd_watch)
            
g_source_destroy (inputfd_watch);
    }
    else
    {
        
dbus_g_proxy_connect_signal (mceproxyMCE_DISPLAY_SIGG_CALLBACK (display_cb), NULLNULL);
    }
}

int main (void)
{
    
inputfd open (INPUT_DEVO_RDONLY O_NONBLOCK);
    if (
inputfd == -1)
        return 
EXIT_FAILURE;
    
    
signal (SIGTERMsighandler);
    
signal (SIGINTsighandler);
    
signal (SIGQUITsighandler);

    
g_type_init();    
    
systembus dbus_g_bus_get (DBUS_BUS_SYSTEMNULL);
    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 (inputfdchannelG_IO_FLAG_NONBLOCKNULL);
    
g_io_channel_set_encoding (inputfdchannelNULLNULL);

    
mceproxy dbus_g_proxy_new_for_name (systembusMCE_SERVICEMCE_SIGNAL_PATHMCE_SIGNAL_IF);
    
dbus_g_proxy_add_signal (mceproxyMCE_DISPLAY_SIGG_TYPE_STRINGG_TYPE_INVALID);
    
dbus_g_proxy_add_signal (mceproxyMCE_TKLOCK_MODE_SIGG_TYPE_STRINGG_TYPE_INVALID);
    
dbus_g_proxy_connect_signal (mceproxyMCE_TKLOCK_MODE_SIGG_CALLBACK (tklock_cb), NULLNULL);
    
    
loopy g_main_loop_new (NULLFALSE);
    
g_main_loop_run (loopy);

    return 
EXIT_SUCCESS;

 

The Following User Says Thank You to jstokes For This Useful Post: