Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[HOWTO] Sony Vaio FS series FN keys
View unanswered posts
View posts from last 24 hours

Goto page 1, 2, 3, 4, 5, 6, 7, 8, 9  Next  
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
pijalu
Guru
Guru


Joined: 04 Oct 2004
Posts: 365

PostPosted: Tue May 10, 2005 2:39 am    Post subject: [HOWTO] Sony Vaio FS series FN keys Reply with quote

EDIT: a easiest way to get it working is available here

After searching a while i found out a way to change brightness... a little tricky but works fine on my FS-115M:

First, download the sony_acpi module from sonypi here
untar it
Code:

tar xzvf sony_acpi.tar.gz


Copy the following in a file (in the extracted dir, as sony_acpi.patch to keep simple)
Code:

--- sony_acpi_old/sony_acpi.c   2005-03-01 11:10:33.000000000 +0100
+++ sony_acpi/sony_acpi.c       2005-05-09 19:13:22.000000000 +0200
@@ -80,6 +80,11 @@
                .debug          = 0,
        },
        {
+               .name           = "fnkey",
+               .acpiget        = "GHKE",
+               .debug          = 0,
+       },
+       {
                .name           = "brightness_default",
                .acpiget        = "GPBR",
                .acpiset        = "SPBR",


If you copy the patch in the untared sony_acpi dir as sony_acpi.patch (you are a nice person if you follow my advice), patch the sony acpi ext (this will include the functions keys handling using acpi)
Code:

patch < sony_acpi.patch


Compile the patched sony_acpi
Code:

make


and move it your modules dir and update dep
Code:

cp sony_acpi.ko /lib/modules/`uname -r`/kernel/drivers/acpi
depmod -a


Modprobe it to check if fine
Code:

modprobe sony_acpi


Check in /proc/acpi/sony that you see 3 files
Code:

muaddib@vaio ~ $ ls /proc/acpi/sony/
brightness  brightness_default  fnkey


Add it to your autoload modules (if fine - otherwise check kernel messages)
Code:

echo "sony_acpi" >> /etc/modules.autoload.d/kernel-2.6


Now copy this content to a file called sonyfn.c somewhere
Code:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>

// sound stuff
#include <linux/soundcard.h>

// keys
#define  FN_F2  1       // cut sound
#define  FN_F3  2       // volume -
#define  FN_F4  4       // volume +
#define  FN_F5  8       // Brightness -
#define  FN_F6  16      // Brightness +
#define  FN_F7  32      // LCD/SCREEN
#define  FN_F10 128     // Zoom in
#define  FN_F12 64      // Suspend
#define  S1_BTN 4096    // S1 custom button
#define  S2_BTN 8192    // S2 custom button

// config hard coded :p
#define  MIXER_DEV      "/dev/mixer"

// SOUND HANDLER
int get_volume(int *value)
{
    int mixer = open(MIXER_DEV, O_RDONLY);

    if (mixer) {
        ioctl(mixer, SOUND_MIXER_READ_VOLUME, value);
        close(mixer);
        return 0;
    }
    else
        return 1;
}

int set_volume(int *value)
{
    int mixer = open(MIXER_DEV, O_RDWR);

    if (mixer) {
        ioctl(mixer, SOUND_MIXER_WRITE_VOLUME, value);
        close(mixer);
        return 0;
    }
    else
        return 1;
}

int volume_up()
{
    int value = 0;

    get_volume(&value);

    if (value < 0x5a5a)
        value += 0x0a0a;
    else
        value = 0x6464;

    set_volume(&value);

    return 0;
}

int volume_down()
{
    int value = 0;

    get_volume(&value);

    if (value > 0x0a0a)
        value -= 0x0a0a;
    else
        value = 0;

    set_volume(&value);

    return 0;
}

int oldvalue;
int mute()
{
    int value;

    get_volume(&value);

    if (value) {
            oldvalue=value;
            value=0;
            set_volume(&value);
    }
    else {
            if (!oldvalue) {
                volume_up();
            }
            else {
                set_volume(&oldvalue);
            }
    }

    return 0;
}
// END OF SOUND

/* Return current brightness of the screen */
int getBrightness() {
        FILE* handle;
        char buffer[2];
        int ret;

        if ((handle=fopen("/proc/acpi/sony/brightness","rb"))==NULL) {
                perror("Error opening /proc/acpi/sony/brightness");
                exit(-1);
        }
        if (fscanf(handle,"%d",&ret)!=1) {
                perror("Error reading /proc/acpi/sony/brightness");
                exit(-1);
        }
        fclose(handle);
        return ret;

}

/* Set the current brightness of the screen */
void setBrightness(int b) {
        FILE* handle;
        char buffer[2];

        // validate values
        if (b>8) {
                b=8;
        }
        else if (b<1) {
                b=1;
        }

        if ((handle=fopen("/proc/acpi/sony/brightness","wb"))==NULL) {
                perror("Error opening /proc/acpi/sony/brightness");
                exit(-1);
        }
        if (fprintf(handle,"%d",b)!=1) {
                perror("Error writing /proc/acpi/sony/brightness");
                exit(-1);
        }
        fclose(handle);
}

// Pool the fnkey status
int getCodes() {
        FILE* handle;
        char buffer[10];
        int ret;

        if ((handle=fopen("/proc/acpi/sony/fnkey","rb"))==NULL) {
                perror("Error opening /proc/acpi/sony/fnkey");
                exit(-1);
        }
        if (fscanf(handle,"%d",&ret)!=1) {
                perror("Error reading /proc/acpi/sony/fnkey");
                exit(-1);
        }
        fclose(handle);
        return ret;
}

// main and loop
int main(void) {
        int key;

        nice(10); // be a nice dirty code

        printf("SonyFN loaded\n");
        while(1) { // loop
                if (key=getCodes()) { // get Fn status
                        if ((key & FN_F5)==FN_F5) { // lower brightness
                                setBrightness(getBrightness()-1);
                        }
                        if ((key & FN_F6)==FN_F6) { // higher brightness
                                setBrightness(getBrightness()+1);
                        }
                        if ((key & FN_F2)==FN_F2){
                                mute();
                        }
                        if ((key & FN_F3)==FN_F3) {
                                volume_down();
                        }
                        if ((key & FN_F4)==FN_F4) {
                                volume_up();
                        }
                        // rest i don't care
                }
                usleep(300000);
        }
        return 0;
}


now, compile it and move it to your /usr/bin
Code:

gcc sonyfn.c -o sonyfn
mv sonyfn /usr/bin


As root, launch it (since it's a dirty handler, you need to put it in bg with & ;) )
Code:

sonyfn &


Check, normally, mute volume, volumes and brightness keys should works...
If works fine, add the handler to your local.start
Code:

echo "/usr/bin/sonyfn 1>&2 >>/var/log/sonyfn.log &" >>/etc/conf.d/local.start


Have fun


Last edited by pijalu on Thu Sep 15, 2005 5:36 pm; edited 2 times in total
Back to top
View user's profile Send private message
UB|K
l33t
l33t


Joined: 27 May 2004
Posts: 786
Location: Villeurbanne, France

PostPosted: Sat Jun 11, 2005 11:50 am    Post subject: Reply with quote

waooo!! i missed this great tip while i was on holidays... so thank you for this, it works great on my vaio (FS115E).

Looking quickly into the code of sonyfn.c showed my that a shortcut was already defined for "fn+F12 --> suspend" but i also noticed:
Code:
}
                        // rest i don't care
                }

:(
so it's not implemented in sonyfn...
Since i don't have any knowledge in programming (not even a litlle), i didn't succeeded to get this working. I've tried something like this:
Code:
                        if ((key & FN_F12)==FN_F12) {
                                hibernate();
                        }

but compilling fails (cause "hibernate" is an external prog and isn't defined :oops: ).
How could i do that??
thx in advance
_________________
Reality is that which, when you stop believing in it, doesn't go away.
Back to top
View user's profile Send private message
pijalu
Guru
Guru


Joined: 04 Oct 2004
Posts: 365

PostPosted: Sat Jun 11, 2005 12:27 pm    Post subject: Reply with quote

If the program you want to call is, for eg /bin/hibernate , this should to the trick....
if not, change the "/bin/hibernate" to the command/script you want to use
Just take care, no args...

Code:

...
if ((key & FN_F12)==FN_F12) {
            if (fork()==0) {
               if (execv("/bin/hibernate",NULL)==-1) {
                  perror("Cannot run hibernate");   
               }
            }
         }
...


If ok/not ok, let me know :-)
Back to top
View user's profile Send private message
UB|K
l33t
l33t


Joined: 27 May 2004
Posts: 786
Location: Villeurbanne, France

PostPosted: Sat Jun 11, 2005 1:44 pm    Post subject: Reply with quote

Thank you, it works perfectly and as sonyfn is runned as root, there no need to use sudo to launch the hibernate script.
Here is the correct patch:
Code:
--- sonyfn.c         2005-06-11 15:09:28.000000000 +0200
+++ sonyfn_susp.c    2005-06-11 15:11:42.000000000 +0200
@@ -192,6 +192,14 @@
                         if ((key & FN_F4)==FN_F4) {
                                 volume_up();
                         }
+
+                       if ((key & FN_F12)==FN_F12) {
+                               if (fork()==0) {
+                                       if (execv("/usr/sbin/hibernate",NULL)==-1) {
+                               perror("Cannot run hibernate");
+                                               }
+                               }
+                       }
                         // rest i don't care
                 }
                 usleep(300000);

_________________
Reality is that which, when you stop believing in it, doesn't go away.
Back to top
View user's profile Send private message
pijalu
Guru
Guru


Joined: 04 Oct 2004
Posts: 365

PostPosted: Sat Jun 11, 2005 2:46 pm    Post subject: Reply with quote

Cool, thanks for correcting the path :-)
I guess I really should take a look at the hibernate thing one of this day :lol:

For the note, you can add the same kind of code to map S1 and S2 buttons to some scripted actions... And as you already knows, they will be runned as root... this means this could be a security issue as well...

To finish, i made a dirty init script for sonyfn, so feel free to "c/p" it
Code:

#!/sbin/runscript
# Copyright 1999-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

depend() {
   need localmount
}

checkconfig() {
   if [ ! -e /proc/acpi/sony/fnkey ] ; then
      eerror "Sony key handler not found"
      return 1
   fi
}

start() {
   ebegin "Starting SonyFN key handler"
   /usr/bin/sonyfn 1>&2 >>/var/log/sonyfn.log &
   eend $?
}

stop() {
   ebegin "Stopping SonyFN key handler"
   killall sonyfn 1>&2 >/dev/null
   eend 0
}

For eg, save it as sonyfn in /etc/init.d/ and do a

Code:

rc-update add sonyfn default

You can now remove the call to sonyfn in local.start

Note: if the sonyfn code is not /usr/bin/sonyfn , change the start() and/or stop() path/name to reflect your own installation
Back to top
View user's profile Send private message
max.bl
n00b
n00b


Joined: 18 Jul 2005
Posts: 1

PostPosted: Mon Jul 18, 2005 8:27 am    Post subject: video out ?? Reply with quote

Hi guys,
have you got any idea about how to make video out switch (Fn-F7) working ?
I've a vaio fs-115s laptop with nvidia video card.
I'm using sony_acpi kernel module and sonyfn program (thanks for it !!).
Back to top
View user's profile Send private message
blinksilver
n00b
n00b


Joined: 23 Jul 2005
Posts: 13

PostPosted: Sat Jul 23, 2005 9:14 pm    Post subject: Reply with quote

Hey all, I maybe alittle late to post, but I just bought a Sony S460. Its very close to the FS (pretty much identical except for screen size) and I suspect that this will work.

When I try to patch the driver it give me an error, and refuse to patch one hunk out of one, I think that the driver has been updated(it is dated the 28 of june), and the patch no longer works. so I tried to hand patch it, just copied and pasted the 5 lines over (took out the +s) then compiled modprobed but " Fnkey" does not show up (the other two do). Could someone pm a patched version of sony_acpi.c?

It would really me out thanks.
Back to top
View user's profile Send private message
pijalu
Guru
Guru


Joined: 04 Oct 2004
Posts: 365

PostPosted: Sun Jul 24, 2005 1:51 am    Post subject: Reply with quote

I guess the patch problem must be due to a typo made when c/p the patch, but since i don't have any backup of the original sony_acpi.c i used, here come a patch done on the newly d/l sony_acpi.tar.gz
Code:

--- sony_acpi.c.old     2005-07-24 03:10:14.000000000 +0200
+++ sony_acpi.c 2005-07-24 03:40:03.000000000 +0200
@@ -33,7 +33,7 @@

 #define ACPI_SNC_CLASS         "sony"
 #define ACPI_SNC_HID           "SNY5001"
-#define ACPI_SNC_DRIVER_NAME   "ACPI Sony Notebook Control Driver v0.2"
+#define ACPI_SNC_DRIVER_NAME   "ACPI Sony Notebook Control Driver v0.2-PP"

 #define LOG_PFX                        KERN_WARNING "sony_acpi: "

@@ -88,6 +88,11 @@
                .debug          = 0,
        },
        {
+               .name           = "fnkey",
+               .acpiget        = "GHKE",
+               .debug          = 0,
+       },
+       {
                .name           = "cdpower",
                .acpiget        = "GCDP",
                .acpiset        = "SCDP",

Compile and copy to your kernel and give a try to
Code:

rmmod sony_acpi
modprobe sony_acpi

Now, check if the "patched" version of the modules loaded fine:
Code:

grep "Sony Notebook Control Driver v0.2-PP" /var/log/messages

(This last patch add -PP to the original version, so it should be easier to check if loaded fine)
You should get something like
Code:

Jul 24 03:41:06 vaio ACPI Sony Notebook Control Driver v0.2-PP successfully installed


Hope this will help...
Keep me uptodate about that :)

To finish: If not working, did you give a try to the sonypi thing ?
(cf http://popies.net/sonypi/
@max.bl: Sorry, i don't have the time to look for the crt out yet... If i find out how to make it work, i will post it here ;)
Back to top
View user's profile Send private message
blinksilver
n00b
n00b


Joined: 23 Jul 2005
Posts: 13

PostPosted: Mon Jul 25, 2005 3:24 am    Post subject: Reply with quote

i dumped linux off because, as is, its not doing me any good, I am too mobile to loss that much battery life, but i have a knoppix cd sitting around, will give it a shot with that.

will report back, but from what i have been reading it does not look good
Back to top
View user's profile Send private message
pijalu
Guru
Guru


Joined: 04 Oct 2004
Posts: 365

PostPosted: Thu Aug 25, 2005 2:01 am    Post subject: Reply with quote

Hi,

here comes a new sonyfn handler, who should eat less cpu...

This version uses the event interface to check for a possible hit to the Fn key and then try to figure out what happend...
The side effect is a faster handling....

Short note: the kernel MUST be compiled with event interface (in Input Device support , check "Event Interface") [this should be already done for the touchpad thing]

Anyway, check with something like
Code:

grep "INPUT_EVDEV" /usr/src/linux/.config

This should return
Code:

CONFIG_INPUT_EVDEV=y


and a
Code:

ls /dev/input/

should returns (something like this)
Code:

event0  event1  event2  event3  mice  mouse0  mouse1  mouse2


Your keyboard should be event0 , but you can do
Code:

sudo cat /dev/input/eventX

(with X the nb to check) and if you got "garbage" when hitting keyboard, then you know your keyboard exact eventX

Now, compile the following code (cf first post, just use this code for the handler)
Code:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>

// input thing
#include <linux/input.h>

// sound stuff
#include <linux/soundcard.h>

// keys
#define  FN_F2   1   // cut sound
#define  FN_F3  2   // volume -
#define  FN_F4  4   // volume +
#define  FN_F5   8   // Brightness -
#define  FN_F6   16   // Brightness +
#define  FN_F7  32   // LCD/SCREEN
#define  FN_F10 128   // Zoom in
#define    FN_F12 64   // Suspend
#define  S1_BTN 4096   // S1 custom button
#define    S2_BTN 8192   // S2 custom button

#define  FN_INPUT_VALUE   245   // Fn key generate a 245 value
#define  FN_INPUT_TYPE   4   // a 4 type
#define  FN_INPUT_CODE   4   // and a 4 code

// config hard coded :p
#define  MIXER_DEV   "/dev/mixer"

// SOUND HANDLER
int get_volume(int *value)
{
    int mixer = open(MIXER_DEV, O_RDONLY);

    if (mixer) {
        ioctl(mixer, SOUND_MIXER_READ_VOLUME, value);
        close(mixer);
        return 0;
    }
    else
        return 1;
}

int set_volume(int *value)
{
    int mixer = open(MIXER_DEV, O_RDWR);

    if (mixer) {
        ioctl(mixer, SOUND_MIXER_WRITE_VOLUME, value);
        close(mixer);
        return 0;
    }
    else
        return 1;
}

int volume_up()
{
    int value = 0;

    get_volume(&value);

    if (value < 0x5a5a)
        value += 0x0a0a;
    else
        value = 0x6464;

    set_volume(&value);

    return 0;
}

int volume_down()
{
    int value = 0;

    get_volume(&value);

    if (value > 0x0a0a)
        value -= 0x0a0a;
    else
        value = 0;

    set_volume(&value);

    return 0;
}

int oldvalue;
int mute()
{
    int value;
   
    get_volume(&value);
   
    if (value) {
       oldvalue=value;
       value=0;
       set_volume(&value);
    }
    else {
       if (!oldvalue) {
      volume_up();       
       }
       else {
          set_volume(&oldvalue);
       }
    }

    return 0;
}
// END OF SOUND

/* Return current brightness of the screen */
int getBrightness() {
   FILE* handle;
   char buffer[2];
   int ret;
   
   if ((handle=fopen("/proc/acpi/sony/brightness","rb"))==NULL) {
      perror("Error opening /proc/acpi/sony/brightness");
      exit(-1);
   }
   if (fscanf(handle,"%d",&ret)!=1) {
      perror("Error reading /proc/acpi/sony/brightness");
      exit(-1);
   }
   fclose(handle);
   return ret;
   
}

/* Set the current brightness of the screen */
void setBrightness(int b) {
   FILE* handle;
   char buffer[2];

   // validate values
   if (b>8) {
      b=8;
   }
   else if (b<1) {
      b=1;
   }
   
   if ((handle=fopen("/proc/acpi/sony/brightness","wb"))==NULL) {
      perror("Error opening /proc/acpi/sony/brightness");
      exit(-1);
   }
   if (fprintf(handle,"%d",b)!=1) {
      perror("Error writing /proc/acpi/sony/brightness");
      exit(-1);
   }
   fclose(handle);
}

// Pool the fnkey status
int getCodes() {
   FILE* handle;
   char buffer[10];
   int ret;
   if ((handle=fopen("/proc/acpi/sony/fnkey","rb"))==NULL) {
      perror("Error opening /proc/acpi/sony/fnkey");
      exit(-1);
   }
   if (fscanf(handle,"%d",&ret)!=1) {
      perror("Error reading /proc/acpi/sony/fnkey");
      exit(-1);
   }
   fclose(handle);
   return ret;   
}

// main and loop
int main(int argc, char **argv) {
   // event interface
        int fd = -1;        /* the file descriptor for the device */
       int i;           /* loop counter */
       size_t read_bytes;  /* how many bytes were read */
       struct input_event ev[64]; /* the events (up to 64 at once) */
      
   /* key code */
   int key;

   /* used if event hit fn */
   int hasSomething;
   
    /* open event interface*/
       if (argc != 2) {
      /* i don't like outputs...
      fprintf(stderr, "Using /dev/input/event0 for input\n");
      fprintf(stderr, "Overide with %s event-device\n", argv[0]);
      */
      if ((fd = open("/dev/input/event0", O_RDONLY)) < 0) {
         perror("event interface open failed");
         exit(1);
          }
       }
   else {   
          if ((fd = open(argv[1], O_RDONLY)) < 0) {
         perror("event interface open failed");
         exit(1);
          }
   }

   nice(10); // be a nice dirty code (less dirty but keep nice)

   
   while(1) { /* loop */
      hasSomething=0; /* nothing yet */
      
      /* read the event interface */
      read_bytes = read(fd, ev, sizeof(struct input_event) * 64);
      
      if (read_bytes < (int) sizeof(struct input_event)) {
             perror("sonyfn: short read");
             exit (1);
      }

      /* Loop for all readed events until we have something interesting.. */
      for (i = 0;! hasSomething && ( i < (int) (read_bytes / sizeof(struct input_event)) ); i++) {
         hasSomething= (ev[i].type == FN_INPUT_TYPE)
               && (ev[i].code == FN_INPUT_CODE)
               && (ev[i].value == FN_INPUT_VALUE);
          }   
      
      /* If we got a FN event, plz do something...*/
      if ( hasSomething && (key=getCodes()) ) {
         if ((key & FN_F5)==FN_F5) { // lower brightness
            setBrightness(getBrightness()-1);
         }
         if ((key & FN_F6)==FN_F6) { // higher brightness
            setBrightness(getBrightness()+1);
         }
         if ((key & FN_F2)==FN_F2){
            mute();
         }
         if ((key & FN_F3)==FN_F3) {
            volume_down();
         }
         if ((key & FN_F4)==FN_F4) {
            volume_up();
         }
         if ((key & FN_F12)==FN_F12) {
            if (fork()==0) {
               /* that's my home made script for swsusp
                #!/bin/sh
                sync
                echo "disk" > /sys/power/state
               */
               if (execv("/bin/hibernate",NULL)==-1) {
                  perror("Cannot run hibernate");   
               }
            }
         }
         /* rest i still don't care */      
      }
   }// while
   
   close(fd);
   return 0;
}


If your keyboard is /dev/input/event0 then you can just copy this handler on the "old" one , if the event handler is different, then it must me lauch using this synthax
Code:

sonyfn /dev/input/eventX

with X the right number...
Please update the exact call in previous post (init.d thing or local.start)

Have phun
Back to top
View user's profile Send private message
sound-mind
n00b
n00b


Joined: 30 Jan 2005
Posts: 21

PostPosted: Thu Aug 25, 2005 12:33 pm    Post subject: Reply with quote

pijalu wrote:
Hi,

here comes a new sonyfn handler, who should eat less cpu...
<snip...>
Have phun


That last version works great pijalu :D No cpu cycles used unless a user is typing. Just what the FS users needed!
Back to top
View user's profile Send private message
sound-mind
n00b
n00b


Joined: 30 Jan 2005
Posts: 21

PostPosted: Sun Aug 28, 2005 5:57 pm    Post subject: Reply with quote

Here's a diff against pijalu's latest post to add xosd support.

Compile:
Code:

gcc -Wall -o sonyfn sonyfn.c -lxosd -lX11


Patch:
Code:

--- sonyfn.c.old        2005-08-28 18:45:14.168313208 -0400
+++ sonyfn.c    2005-08-29 08:11:37.727686824 -0400
@@ -5,6 +5,11 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>

+// osd stuff
+#include <xosd.h>
+#include <locale.h>
+#include <X11/Xlib.h>
+
 // input thing
 #include <linux/input.h>

@@ -30,6 +35,88 @@
 // config hard coded :p
 #define  MIXER_DEV   "/dev/mixer"

+// The FS series seems to support 8 brightness levels
+#define MAX_BRIGHT 8
+#define MIN_BRIGHT 1
+
+// the volume osd color
+#define OSD_VCOLOR "red"
+// the brightness osd color
+#define OSD_BCOLOR "blue"
+// the osd font... change the 7th position for size
+// or use xfontsel to explore the options
+#define OSD_FONT "-*-*-*-*-*-*-20-*-*-*-*-*-*-*"
+// the length of time the osd is shown
+#define OSD_TIME 3
+
+// volume scaling factor for OSD
+#define OSD_VSCALE 250
+
+// the onscreen display
+static xosd *disp_obj = '\0';
+
+int osd_brightness(int level){
+       // the size of the increment
+       static int inc_size = 100.0 / (MAX_BRIGHT - 1);
+        int retval = 0;
+       int pos;
+
+        retval &= xosd_set_bar_length(disp_obj, 100);
+        retval &= xosd_set_pos(disp_obj, XOSD_bottom);
+        retval &= xosd_set_align(disp_obj, XOSD_center);
+        retval &= xosd_set_shadow_offset(disp_obj, 1);
+        retval &= xosd_set_outline_offset(disp_obj, 1);
+        retval &= xosd_set_vertical_offset(disp_obj, 30);
+        retval &= xosd_set_colour(disp_obj, OSD_BCOLOR);
+        retval &= xosd_set_timeout(disp_obj, OSD_TIME);
+        retval &= xosd_set_font(disp_obj, OSD_FONT);
+
+        if (retval){
+                fprintf(stderr,"Failed setup onscreen display: %s\n", xosd_error);
+        } else {
+               if (level == MAX_BRIGHT){
+                       pos = 100;
+               } else {
+                       pos = level * inc_size - inc_size;
+               }
+                retval = xosd_display(disp_obj, 0, XOSD_slider, pos);
+                retval = xosd_display(disp_obj, 1, XOSD_string, "Brightness");
+                if (retval == -1){
+                        fprintf(stderr,"Failed to display information onscreen: %s\nAre you running X?\n",
+                                       xosd_error);
+                }
+        }
+
+        return 1;
+}
+
+int osd_volume(int level){
+        int retval = 0;
+
+        retval &= xosd_set_bar_length(disp_obj, 100);
+        retval &= xosd_set_pos(disp_obj, XOSD_bottom);
+        retval &= xosd_set_align(disp_obj, XOSD_center);
+        retval &= xosd_set_shadow_offset(disp_obj, 1);
+        retval &= xosd_set_outline_offset(disp_obj, 1);
+        retval &= xosd_set_vertical_offset(disp_obj, 30);
+        retval &= xosd_set_colour(disp_obj, OSD_VCOLOR);
+        retval &= xosd_set_timeout(disp_obj, OSD_TIME);
+        retval &= xosd_set_font(disp_obj, OSD_FONT);
+
+        if (retval){
+                fprintf(stderr,"Failed setup onscreen display: %s\n", xosd_error);
+        } else {
+                retval = xosd_display(disp_obj, 0, XOSD_slider, level / OSD_VSCALE);
+                retval = xosd_display(disp_obj, 1, XOSD_string, "Volume");
+                if (retval == -1){
+                        fprintf(stderr,"Failed to display information onscreen: %s\nAre you running X?\n",
+                                       xosd_error);
+                }
+        }
+
+        return 1;
+}
+
 // SOUND HANDLER
 int get_volume(int *value)
 {
@@ -51,6 +138,7 @@
     if (mixer) {
         ioctl(mixer, SOUND_MIXER_WRITE_VOLUME, value);
         close(mixer);
+       osd_volume(*value);
         return 0;
     }
     else
@@ -117,7 +205,6 @@
 /* Return current brightness of the screen */
 int getBrightness() {
    FILE* handle;
-   char buffer[2];
    int ret;

    if ((handle=fopen("/proc/acpi/sony/brightness","rb"))==NULL) {
@@ -136,14 +223,13 @@
 /* Set the current brightness of the screen */
 void setBrightness(int b) {
    FILE* handle;
-   char buffer[2];

    // validate values
-   if (b>8) {
-      b=8;
+   if (b > MAX_BRIGHT) {
+      b = MAX_BRIGHT;
    }
-   else if (b<1) {
-      b=1;
+   else if (b < MIN_BRIGHT) {
+      b = MIN_BRIGHT;
    }

    if ((handle=fopen("/proc/acpi/sony/brightness","wb"))==NULL) {
@@ -155,12 +241,12 @@
       exit(-1);
    }
    fclose(handle);
+   osd_brightness(b);
 }

 // Pool the fnkey status
 int getCodes() {
    FILE* handle;
-   char buffer[10];
    int ret;
    if ((handle=fopen("/proc/acpi/sony/fnkey","rb"))==NULL) {
       perror("Error opening /proc/acpi/sony/fnkey");
@@ -185,8 +271,16 @@
    /* key code */
    int key;

+
    /* used if event hit fn */
    int hasSomething;
+
+       // initialize the osd
+        disp_obj = xosd_create(2);
+
+       if (setlocale(LC_ALL, "") == NULL || !XSupportsLocale())
+               fprintf(stderr, "Locale not available, expect problems with fonts.\n");
+

     /* open event interface*/
        if (argc != 2) {
@@ -244,7 +338,7 @@
          if ((key & FN_F4)==FN_F4) {
             volume_up();
          }
-         if ((key & FN_F12)==FN_F12) {
+        if ((key & FN_F12)==FN_F12) {
             if (fork()==0) {
                /* that's my home made script for swsusp
                 #!/bin/sh
@@ -255,11 +349,11 @@
                   perror("Cannot run hibernate");
                }
             }
-         }
+         }
          /* rest i still don't care */
       }
    }// while
-
+   xosd_destroy(disp_obj);
    close(fd);
    return 0;
 }


You may have to run this as root once you startx depending on your /proc permissions.

Edit: Code update to fix handling of xosd object (leaky threads :oops:)


Last edited by sound-mind on Mon Aug 29, 2005 12:34 pm; edited 1 time in total
Back to top
View user's profile Send private message
pijalu
Guru
Guru


Joined: 04 Oct 2004
Posts: 365

PostPosted: Sun Aug 28, 2005 6:15 pm    Post subject: Reply with quote

Excellent :-)
This is too sweet :-)

If you want to use it the easy way [avoid perm problem] (example: if the sonyfn is in /usr/bin)
Code:

sudo chown root /usr/bin/sonyfn
sudo chmod 4755 /usr/bin/sonyfn


This will allows any user to launch the handler as root
(it's a sticky bit - sonyfn then execute as it was launched by root - take care about it, it can lead to security issue...)
Back to top
View user's profile Send private message
G2k
l33t
l33t


Joined: 06 Mar 2004
Posts: 672
Location: Rome, Italy

PostPosted: Sun Aug 28, 2005 11:58 pm    Post subject: Reply with quote

When I try to apply the patch I get the following error
Code:
~/sony_acpi $ patch < fnkey.diff
patching file sony_acpi.c
Hunk #1 FAILED at 80.
1 out of 1 hunk FAILED -- saving rejects to file sony_acpi.c.rej
How can I fix this?
_________________
Animula vagula blandula,
Hospes comesque corporis,
Quae nunc abibis in loca
Pallidula rigida nudula,
Nec ut soles dabis iocos...
- Imp. Caesar Hadrianus
Back to top
View user's profile Send private message
pijalu
Guru
Guru


Joined: 04 Oct 2004
Posts: 365

PostPosted: Mon Aug 29, 2005 12:13 am    Post subject: Reply with quote

Hum, just to be sure, reextract the sony_acpi.tar.gz content and give a try to
Code:

patch -l --dry-run < fnkey.diff

(this try the patch without really applying it)

If it don't complain, then
Code:

patch -l < fnkey.diff


Otherwise, pm your email/or send me email and i will send it to you asap
Tip: the -l option inform patch to ignore white space during the procedure
Back to top
View user's profile Send private message
G2k
l33t
l33t


Joined: 06 Mar 2004
Posts: 672
Location: Rome, Italy

PostPosted: Mon Aug 29, 2005 1:14 am    Post subject: Reply with quote

k that worked, thanks
EDIT:
new problem. Modprobing tells me
Code:
FATAL: Module sony_acpi not found.
although the sony_acpi.ko is in /lib/modules/2.6.12-gentoo-r9/kernel/drivers/acpi/ where `uname -r` is 2.6.12-gentoo-r9. I have module loading enabled in my kernel.
_________________
Animula vagula blandula,
Hospes comesque corporis,
Quae nunc abibis in loca
Pallidula rigida nudula,
Nec ut soles dabis iocos...
- Imp. Caesar Hadrianus
Back to top
View user's profile Send private message
sound-mind
n00b
n00b


Joined: 30 Jan 2005
Posts: 21

PostPosted: Mon Aug 29, 2005 12:42 pm    Post subject: Reply with quote

I just updated the patch above. I mishandled the threaded xosd object and ended up leaking threads all over the floor :oops:

Now you should see a total of 3 processes reported by ps. Two of these are really just GUI handling threads used by the xosd libs that should sleep most of
the time. These could be avoided by creating and destroying the xosd object at each fnkey press. It is a tradeoff, two lightweight threads sleeping in the background vs. dynamically creating and destroying the threads each time a fnkey is pressed.

G2k: Have you run depmod -a?
Back to top
View user's profile Send private message
pijalu
Guru
Guru


Joined: 04 Oct 2004
Posts: 365

PostPosted: Mon Aug 29, 2005 2:44 pm    Post subject: Reply with quote

For me, 2 sleeping treads are way better than the overhead of recreating objects :-)

FYI: I totally forgot the depmod thing in the very first post...my fault...I just corrected that now...

Btw G2k, if still troubles, give a try to
Code:

insmod /path/to/sony_acpi.ko

This should force the load ;-)
Back to top
View user's profile Send private message
G2k
l33t
l33t


Joined: 06 Mar 2004
Posts: 672
Location: Rome, Italy

PostPosted: Mon Aug 29, 2005 3:43 pm    Post subject: Reply with quote

gah!
Code:
 gcc -Wall -o sonyfn sonyfn.c -lxosd -lX11
sonyfn.c:9:18: xosd.h: No such file or directory
sonyfn.c:56: error: syntax error before '*' token
sonyfn.c:56: warning: type defaults to `int' in declaration of `disp_obj'
sonyfn.c:56: warning: data definition has no type or storage class
sonyfn.c: In function `osd_brightness':
sonyfn.c:64: warning: implicit declaration of function `xosd_set_bar_length'
sonyfn.c:65: warning: implicit declaration of function `xosd_set_pos'
sonyfn.c:65: error: `XOSD_bottom' undeclared (first use in this function)
sonyfn.c:65: error: (Each undeclared identifier is reported only once
sonyfn.c:65: error: for each function it appears in.)
sonyfn.c:66: warning: implicit declaration of function `xosd_set_align'
sonyfn.c:66: error: `XOSD_center' undeclared (first use in this function)
sonyfn.c:67: warning: implicit declaration of function `xosd_set_shadow_offset'
sonyfn.c:68: warning: implicit declaration of function `xosd_set_outline_offset'
sonyfn.c:69: warning: implicit declaration of function `xosd_set_vertical_offset'
sonyfn.c:70: warning: implicit declaration of function `xosd_set_colour'
sonyfn.c:71: warning: implicit declaration of function `xosd_set_timeout'
sonyfn.c:72: warning: implicit declaration of function `xosd_set_font'
sonyfn.c:75: error: `xosd_error' undeclared (first use in this function)
sonyfn.c:82: warning: implicit declaration of function `xosd_display'
sonyfn.c:82: error: `XOSD_slider' undeclared (first use in this function)
sonyfn.c:83: error: `XOSD_string' undeclared (first use in this function)
sonyfn.c: In function `osd_volume':
sonyfn.c:97: error: `XOSD_bottom' undeclared (first use in this function)
sonyfn.c:98: error: `XOSD_center' undeclared (first use in this function)
sonyfn.c:107: error: `xosd_error' undeclared (first use in this function)
sonyfn.c:109: error: `XOSD_slider' undeclared (first use in this function)
sonyfn.c:110: error: `XOSD_string' undeclared (first use in this function)
sonyfn.c: In function `main':
sonyfn.c:279: warning: implicit declaration of function `xosd_create'
sonyfn.c:279: warning: assignment makes pointer from integer without a cast
sonyfn.c:356: warning: implicit declaration of function `xosd_destroy'
wouldn't it be easier if all the steps were in the right order on the first post on this page?? I'm not good at this kind of stuff :cry:
_________________
Animula vagula blandula,
Hospes comesque corporis,
Quae nunc abibis in loca
Pallidula rigida nudula,
Nec ut soles dabis iocos...
- Imp. Caesar Hadrianus
Back to top
View user's profile Send private message
sound-mind
n00b
n00b


Joined: 30 Jan 2005
Posts: 21

PostPosted: Mon Aug 29, 2005 3:52 pm    Post subject: Reply with quote

G2k: emerge xosd

I'll try to make an ebuild when I get some free time.
Back to top
View user's profile Send private message
pijalu
Guru
Guru


Joined: 04 Oct 2004
Posts: 365

PostPosted: Mon Aug 29, 2005 3:57 pm    Post subject: Reply with quote

G2k wrote:
gah!


Code:

emerge xosd

should help you...
edit: to slow

Actually, yap, but the things is i like the incremental way to do it... there is still one trade off... Or you use the nice X one or the other one with the init.d - but both of them is a not go...
(...I guess, didn't try this ;-)...)

Actually i think making a nice ebuild should be the thing to do and host it somewhere...
(and use nice #IFDEF thing to allows with/without xosd on one src...)
If someone is interested go ahead... I am quite in a buzz now... if not, will do that next week... ;-)
edit: LOL
Back to top
View user's profile Send private message
sound-mind
n00b
n00b


Joined: 30 Jan 2005
Posts: 21

PostPosted: Mon Aug 29, 2005 4:10 pm    Post subject: Reply with quote

pijalu wrote:


Actually, yap, but the things is i like the incremental way to do it... there is still one trade off... Or you use the nice X one or the other one with the init.d - but both of them is a not go...
(...I guess, didn't try this ;-)...)

Actually i think making a nice ebuild should be the thing to do and host it somewhere...
(and use nice #IFDEF thing to allows with/without xosd on one src...)
If someone is interested go ahead... I am quite in a buzz now... if not, will do that next week... ;-)
edit: LOL


Yup... I thought wrapping the functions and their calls in IFDEF's but didn't want to complicate things. I guess I could update this and make an ebuild... So whoever has free time first ;)

Actually I'll try to post an IFDEF'd wrapped version later today and you can just compile it with -DUSE_XOSD to make it easy.
Back to top
View user's profile Send private message
pijalu
Guru
Guru


Joined: 04 Oct 2004
Posts: 365

PostPosted: Mon Aug 29, 2005 4:22 pm    Post subject: Reply with quote

sound-mind wrote:

Yup... I thought wrapping the functions and their calls in IFDEF's but didn't want to complicate things. I guess I could update this and make an ebuild... So whoever has free time first ;)

Actually I'll try to post an IFDEF'd wrapped version later today and you can just compile it with -DUSE_XOSD to make it easy.


Ho, for the ifdef i thought the same way as you :), just telling that for the ebuild...Currently, Users decide a super ifdef : using patch or not using patch... :lol:

Don't bother with it, it will be a job for the ebuilder ;-)
Back to top
View user's profile Send private message
G2k
l33t
l33t


Joined: 06 Mar 2004
Posts: 672
Location: Rome, Italy

PostPosted: Mon Aug 29, 2005 8:05 pm    Post subject: Reply with quote

lol...uhm...I'm lazy. do you guys mind if I sit here and just wait for an e-build? :P
_________________
Animula vagula blandula,
Hospes comesque corporis,
Quae nunc abibis in loca
Pallidula rigida nudula,
Nec ut soles dabis iocos...
- Imp. Caesar Hadrianus
Back to top
View user's profile Send private message
pijalu
Guru
Guru


Joined: 04 Oct 2004
Posts: 365

PostPosted: Mon Aug 29, 2005 9:17 pm    Post subject: Reply with quote

:lol:
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Goto page 1, 2, 3, 4, 5, 6, 7, 8, 9  Next
Page 1 of 9

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum